Make distribution-check job logic more strict 75/47575/30
authorVratko Polak <vrpolak@cisco.com>
Fri, 20 Jan 2017 14:22:14 +0000 (15:22 +0100)
committerVratko Polak <vrpolak@cisco.com>
Fri, 20 Jan 2017 14:22:14 +0000 (15:22 +0100)
Multiple build steps use a fake remote repository
in order to discover missing POM references and other failure modes.

Change-Id: I28c2eb56c48fac3953acc0d2dfd858e0a3d914ed
Signed-off-by: Vratko Polak <vrpolak@cisco.com>
docs/jenkins.rst
jjb/releng-templates-java.yaml

index 2a9bb172aad5d02aa518781205ee0464bb2942dd..4657a25f078dca9cfb681ad36ef36883bbb1ee53 100644 (file)
@@ -577,7 +577,7 @@ TODO: Document test-{project}-{feature} and test-{project}-all.
         <td colspan="2">
           This job runs the PROJECT-distribution-check-BRANCH job which is
           building also integration/distribution project in order to run SingleFeatureTest.
-          It also performs other check in order to prevent the change to break autorelease.
+          It also performs various other checks in order to prevent the change to break autorelease.
         </td>
       </tr>
 
index bc26bdf9aaab34250238acfc698864fb5e176278..c952ff116ec830ce01e5f85cb8ac5f2df9db58f7 100644 (file)
             maven-version: 'mvn33'
 
 - job-template:
-    # Template: {name}-distribution-check-{stream}
-    # Goal: Build a patch and make sure the distribution can deploy with this change
+    # Template: {project-name}-distribution-check-{stream}
+    # Goal: Build a patch and make sure the distribution can deploy with this change.
     # Operation: This job template builds a patch, creates a distribution containing
-    #            the patch, and triggers the distribution deploy test
+    #            the patch (making sure dependencies are specified),
+    #            and performs the distribution deploy test.
 
     name: '{project-name}-distribution-check-{stream}'
     disabled: false
             files: '**'
 
     builders:
+        # Step zero: Wipe file repositories up front.
+        - shell: |
+            echo "wipe r: the local Maven repository"
+            rm -rfv /tmp/r
+            echo "wipe n: the fake remote (Nexus) repository"
+            rm -rfv /tmp/n
+            echo "wipe t: the transient repository used in some manipulations"
+            rm -rfv /tmp/t
+        # Step one: Online build of the project, using local repository /tmp/r/ and deploying artifacts to /tmp/n/.
+        # Ordinary SingleFeatureTest failures are detected in the verify job, so we can use "q" profile here.
         - maven-target:
             maven-version: 'mvn33'
             pom: '$GERRIT_PROJECT/pom.xml'
-            goals: 'clean install dependency:tree -DoutputFile=dependency_tree.txt -V -B -Pq -Djenkins -Dmaven.repo.local=/tmp/r -Dorg.ops4j.pax.url.mvn.localRepository=/tmp/r -Dstream={stream}'
+            goals: 'clean deploy dependency:tree -DoutputFile=dependency_tree.txt -V -B -Pq -Djenkins -Dstream={stream} -DaltDeploymentRepository=fake-nexus::default::file:///tmp/n/ -Dmaven.repo.local=/tmp/r -Dorg.ops4j.pax.url.mvn.localRepository=/tmp/r'
             java-opts:
                 - '-Xmx4096m -XX:MaxPermSize=1024m -Dmaven.compile.fork=true'
             settings: '{mvn-settings}'
             settings-type: cfp
             global-settings: 'odl-global-settings'
             global-settings-type: cfp
+        # Step two: Verify all deployed artifacts belong to the project's groupId.
+        # This is done by moving the allowed directories out of /tmp/n and checking no files remained there.
+        # The correct directory is derived from $GERRIT_PROJECT.
+        - shell: |
+            mkdir -p /tmp/t/org/opendaylight/$GERRIT_PROJECT
+            mv /tmp/n/org/opendaylight/$GERRIT_PROJECT/* /tmp/t/org/opendaylight/$GERRIT_PROJECT/
+            test -z `find /tmp/n/ -type f`
+            rm -rf /tmp/n
+            mv /tmp/t /tmp/n
+        # Step three: Online build of integration distribution.
+        # This step is mainly used for downloading other project artifacts.
+        # Running SingleFeaturesTest here does not seem to be required, so -Pq is used again.
         - maven-target:
             maven-version: 'mvn33'
             pom: 'distribution/pom.xml'
-            goals: 'clean install dependency:tree -DoutputFile=dependency_tree.txt -V -B -Djenkins -Dmaven.repo.local=/tmp/r -Dorg.ops4j.pax.url.mvn.localRepository=/tmp/r'
+            goals: 'clean install dependency:tree -DoutputFile=dependency_tree.txt -V -B -Pq -Djenkins -Dstream={stream} -Dmaven.repo.local=/tmp/r -Dorg.ops4j.pax.url.mvn.localRepository=/tmp/r'
             java-opts:
               - '-Xmx1024m -XX:MaxPermSize=256m -Dmaven.compile.fork=true'
             settings: '{mvn-settings}'
             settings-type: cfp
             global-settings: 'odl-global-settings'
             global-settings-type: cfp
+        # Step four: Delete snapshot artifacts from the local repository.
+        # This is critical to detect orphaned artifacts or missing project-internal dependency declarations.
+        # Also other files related to maven repository resolution are removed,
+        # and then empty directories are removed, in order to simplify debugging.
+        - shell: |
+            set +e  # To avoid failures in projects which generate zero snapshot artifacts.
+            find /tmp/r/org/opendaylight/$GERRIT_PROJECT/ -path *-SNAPSHOT* -delete
+            find /tmp/r/ -regex '.*/_remote.repositories\|.*/maven-metadata-local\.xml\|.*/maven-metadata-fake-nexus\.xml\|.*/resolver-status\.properties' -delete
+            find /tmp/r/ -type d -empty -delete
+            echo "# INFO: A listing of project related files left in local repository follows."
+            find /tmp/r/org/opendaylight/$GERRIT_PROJECT/
+            true  # To prevent the possibly non-zero return code from failing the job.
+        # Now the ugly part. It seems that the only way to tell Maven 2+
+        # which remote repositories to use is via settings.xml file.
+        # So we create such a file here, but it needs most of odlparent:settings.xml
+        - shell: |
+            echo '
+            <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
+              https://maven.apache.org/xsd/settings-1.0.0.xsd">
+              <profiles>
+                <profile>
+                  <id>opendaylight-release</id>
+                  <repositories>
+                    <repository>
+                      <id>opendaylight-mirror</id>
+                      <name>opendaylight</name>
+                      <url>https://nexus.opendaylight.org/content/repositories/public/</url>
+                      <releases><updatePolicy>never</updatePolicy></releases>
+                      <snapshots><enabled>false</enabled></snapshots>
+                    </repository>
+                  </repositories>
+                  <pluginRepositories>
+                    <pluginRepository>
+                      <id>opendaylight-plugin-mirror</id>
+                      <name>opendaylight-plugin</name>
+                      <url>https://nexus.opendaylight.org/content/repositories/public/</url>
+                      <releases><updatePolicy>never</updatePolicy></releases>
+                      <snapshots><enabled>false</enabled></snapshots>
+                    </pluginRepository>
+                  </pluginRepositories>
+                </profile>
+                <profile>
+                  <id>file-snapshots</id>
+                  <repositories>
+                    <repository>
+                      <id>file-snapshots</id>
+                      <name>file</name>
+                      <url>file:///tmp/n/</url>
+                      <releases><enabled>false</enabled></releases>
+                    </repository>
+                  </repositories>
+                  <pluginRepositories>
+                    <pluginRepository>
+                      <id>file-plugin-snapshots</id>
+                      <name>file-plugin</name>
+                      <url>file:///tmp/n/</url>
+                      <releases><enabled>false</enabled></releases>
+                    </pluginRepository>
+                  </pluginRepositories>
+                </profile>
+              </profiles>
+              <activeProfiles>
+                <activeProfile>file-snapshots</activeProfile>
+                <activeProfile>opendaylight-release</activeProfile>
+              </activeProfiles>
+            </settings>
+            ' > fake_remotes.xml
+        # # Notes: The settings are minimal in order to detect breakage scenarios while allowing for the following quirks:
+        # # * Some plugins seem to have hardcoded repos, for example check-license looks at repository.apache.org
+        # # * Some plugin artifacts (related to surefire) are not downloaded when tests are skipped.
+        # # * populate-local-repo looks at oss.sonatype.org and does not store things (like guava) to /tmp/r
+        # Step five: Repeat the distribution build but with the new settings.
+        # Here, only the project snapshot artifacts deployed to /tmp/n are available,
+        # which faithfully reproduces conditions in later verify-like job runs.
+        # We cannot use --offline, because: "Cannot access file (file:///tmp/n) in offline mode"
+        # This is where SingleFeatureTest is not skipped.
+        - maven-target:
+            maven-version: 'mvn33'
+            pom: 'distribution/pom.xml'
+            goals: 'clean install dependency:tree -DoutputFile=dependency_tree.txt -s fake_remotes.xml -V -B -Pq -DskipTests=false -Djenkins -Dstream={stream} -Dmaven.repo.local=/tmp/r -Dorg.ops4j.pax.url.mvn.localRepository=/tmp/r'
+            java-opts:
+              - '-Xmx1024m -XX:MaxPermSize=256m -Dmaven.compile.fork=true'
+        # Step six: Run Karaf and verify no critical failures are present.
         - integration-distribution-check
 
     publishers:
             global-settings-file: 'odl-global-settings'
             settings-file: '{mvn-settings}'
 
+    # TODO: Do we want to apply sophisticated checks as in *-distribution-check-*?
     maven:
         maven-name: 'mvn33'
         goals: '{mvn-goals} -V -B -Djenkins -Dmerge -Dstream={stream} -Dmaven.repo.local=/tmp/r -Dorg.ops4j.pax.url.mvn.localRepository=/tmp/r'