Verify changes with Buck and Bazel in parallel

Run all the verification jobs in parallel, combining:
- tools (buck, build)
- mode (standard, notedb, polygerrit)

Then get all results and combine them together in a
single verification feedback.

This avoids keeping on spamming the change multiple times
and giving +1 and -1 that are often misleading for the
author of the change to interpret.

Change-Id: Iebbaec91373a4088a9ef957ee42db33a5ad1dcbc
diff --git a/jenkins/gerrit-bazel-test.sh b/jenkins/gerrit-bazel-test.sh
index 5f2aebf..a826e52 100644
--- a/jenkins/gerrit-bazel-test.sh
+++ b/jenkins/gerrit-bazel-test.sh
@@ -15,7 +15,7 @@
 
 echo 'Test in Note DB mode'
 echo '----------------------------------------------'
-GERRIT_ENABLE_NOTEDB=TRUE bazel test $BAZEL_OPTS //...
+bazel test --test_env=GERRIT_NOTEDB=READ_WRITE $BAZEL_OPTS //...
 
 echo 'Test PolyGerrit locally'
 echo '----------------------------------------------'
diff --git a/jenkins/gerrit-bazel-verifier-test.sh b/jenkins/gerrit-bazel-verifier-test.sh
index 01e7f86..759765b 100644
--- a/jenkins/gerrit-bazel-verifier-test.sh
+++ b/jenkins/gerrit-bazel-verifier-test.sh
@@ -7,24 +7,25 @@
 echo "Test with mode=$MODE"
 echo '----------------------------------------------'
 
-if [ "$MODE" == "notedb" ]
+export BAZEL_OPTS="--spawn_strategy=standalone --genrule_strategy=standalone \
+                 --test_output errors \
+                 --test_summary detailed --flaky_test_attempts 3 \
+                 --test_verbose_timeout_warnings --build_tests_only \
+                 --nocache_test_results \
+                 --test_tag_filters=-elastic,-flaky"
+
+if [[ "$MODE" == *"reviewdb"* ]]
 then
-  GERRIT_NOTEDB="--test_env=GERRIT_NOTEDB=READ_WRITE"
+  bazel test $BAZEL_OPTS //...
 fi
 
-if [ "$MODE" == "default" ] || [ "$MODE" == "notedb" ]
+if [[ "$MODE" == *"notedbReadWrite"* ]]
 then
-  export BAZEL_OPTS="--spawn_strategy=standalone --genrule_strategy=standalone \
-                   --test_output errors \
-                   --test_summary detailed --flaky_test_attempts 3 \
-                   --test_verbose_timeout_warnings --build_tests_only \
-                   --nocache_test_results \
-                   --test_tag_filters=-elastic,-flaky"
-
+  GERRIT_NOTEDB="--test_env=GERRIT_NOTEDB=READ_WRITE"
   bazel test $GERRIT_NOTEDB $BAZEL_OPTS //...
 fi
 
-if [ "$MODE" == "polygerrit" ]
+if [[ "$MODE" == *"polygerrit"* ]]
 then
   if [ -z "$DISPLAY" ]
   then
diff --git a/jenkins/gerrit-buck-test.sh b/jenkins/gerrit-buck-test.sh
index c691157..38f4c74 100644
--- a/jenkins/gerrit-buck-test.sh
+++ b/jenkins/gerrit-buck-test.sh
@@ -18,7 +18,8 @@
 
   echo 'Test in Node DB mode'
   echo '----------------------------------------------'
-  GERRIT_ENABLE_NOTEDB=TRUE buck test --no-results-cache --exclude flaky
+  export GERRIT_NOTEDB=READ_WRITE
+  buck test --no-results-cache --exclude flaky
 
   if [ ! -d polygerrit-ui ]
   then
diff --git a/jenkins/gerrit-buck-verifier-test.sh b/jenkins/gerrit-buck-verifier-test.sh
index 4c74ddf..b0d5813 100644
--- a/jenkins/gerrit-buck-verifier-test.sh
+++ b/jenkins/gerrit-buck-verifier-test.sh
@@ -11,17 +11,18 @@
   echo "Test with mode=$MODE"
   echo '----------------------------------------------'
 
-  if [ "$MODE" == "notedb" ]
-  then
-    export GERRIT_NOTEDB=READ_WRITE
-  fi
-
-  if [ "$MODE" == "default" ] || [ "$MODE" == "notedb" ]
+  if [[ "$MODE" == *"reviewdb"* ]]
   then
     buck test --no-results-cache --exclude flaky
   fi
 
-  if [ "$MODE" == "polygerrit" ]
+  if [[ "$MODE" == *"notedbReadWrite"* ]]
+  then
+    export GERRIT_NOTEDB=READ_WRITE
+    buck test --no-results-cache --exclude flaky
+  fi
+
+  if [[ "$MODE" == *"polygerrit"* ]]
   then
     if [ -z "$DISPLAY" ]
     then
diff --git a/jenkins/gerrit-verifier-change.groovy b/jenkins/gerrit-verifier-change.groovy
index 80b9422..6fd540a 100644
--- a/jenkins/gerrit-verifier-change.groovy
+++ b/jenkins/gerrit-verifier-change.groovy
@@ -32,8 +32,10 @@
   static int numRetryBuilds = 3
   static int myAccountId = 1022687
   static int waitForResultTimeout = 10000
+  static Map buildsList = [:]
 }
 
+
 def gerritPost(url, jsonPayload) {
   def gerritPostUrl = Globals.gerrit + url
   def curl = ['curl', '-n', '-s', '-S',
@@ -87,31 +89,32 @@
                     "{\"message\": \"$msgPrefix Gerrit-CI Flow: $buildUrl\", \"notify\" : \"NONE\" }")
 }
 
-def waitForResult(build) {
-  def result = null
+def waitForResult(b) {
+  def res = null
   def startWait = System.currentTimeMillis()
-  while(result == null && (System.currentTimeMillis() - startWait) < Globals.waitForResultTimeout) {
-    result = build.getResult()
-    if(result == null) {
+  while(res == null && (System.currentTimeMillis() - startWait) < Globals.waitForResultTimeout) {
+    res = b.getResult()
+    if(res == null) {
       Thread.sleep(100) {
       }
     }
   }
-  return result == null ? Result.FAILURE : result
+  return res == null ? Result.FAILURE : res
 }
 
-def getVerified(result) {
-  if(result == null) {
-    return 0;
-  }
-
-  switch(result) {
-    case Result.SUCCESS:
-      return +1;
-    case Result.FAILURE:
-      return -1;
-    default:
-      return 0;
+def getVerified(acc, res) {
+  switch(acc) {
+        case 0: return 0
+        case 1:
+          if(res == null) {
+            return 0;
+          }
+          switch(res) {
+            case Result.SUCCESS: return +1;
+            case Result.FAILURE: return -1;
+            default: return 0;
+          }
+        case -1: return -1
   }
 }
 
@@ -127,6 +130,26 @@
   } != null
 }
 
+def buildsForMode(refspec,sha1,changeUrl,mode,tools) {
+    def builds = []
+    for (tool in tools) {
+      def buildName = "Gerrit-verifier-$tool"
+      def key = "$tool/$mode"
+      builds += {
+                  retry ( Globals.numRetryBuilds ) {
+                    Globals.buildsList.put(key, 
+                      build(buildName, REFSPEC: refspec, BRANCH: sha1,
+                            CHANGE_URL: changeUrl, MODE: mode))
+                    println "Builds status:"
+                    Globals.buildsList.each {
+                      n, v -> println "  $n : ${v.getResult()}\n    (${v.getBuildUrl() + "console"})"
+                    }
+                  }
+                }
+    }
+    return builds
+}
+
 def buildChange(change) {
   def sha1 = change.current_revision
   def changeNum = change._number
@@ -136,42 +159,42 @@
   def branch = change.branch
   def changeUrl = Globals.gerrit + "#/c/" + changeNum + "/" + patchNum
   def refspec = "+" + ref + ":" + ref.replaceAll('ref/', 'ref/remotes/origin/')
+  def tools = ["buck"]
+  def modes = ["reviewdb"]
+
+  if(branch == "master") {
+    tools += ["bazel"]
+  }
 
   println "Building Change " + changeUrl
 
-  def b
+  if(branch == "master") {
+    modes += "notedbReadWrite"
+
+    if(polygerritTouched(changeNum, sha1)) {
+      modes += " polygerrit"
+    }
+  }
+
+  def builds = []
+  modes.collect { buildsForMode(refspec,sha1,changeUrl,it,tools,branch) }.each { builds += it }
+
   ignore(FAILURE) {
-    retry ( Globals.numRetryBuilds ) {
-      b = build("Gerrit-verifier", REFSPEC: refspec, BRANCH: sha1,
-                CHANGE_URL: changeUrl, MODE: "default")
-    }
-  }
-  def result = waitForResult(b)
-  gerritReview(b.getBuildUrl() + "consoleText",changeNum,sha1,getVerified(result), "")
-
-  if (result == Result.SUCCESS && polygerritTouched(changeNum, sha1)) {
-    ignore(FAILURE) {
-      retry(Globals.numRetryBuilds) {
-        b = build("Gerrit-verifier", REFSPEC: refspec, BRANCH: sha1,
-            CHANGE_URL: changeUrl, MODE: "polygerrit")
-      }
-    }
-
-    result = waitForResult(b)
-    gerritReview(b.getBuildUrl() + "consoleText", changeNum, sha1,
-        getVerified(result), "PolyGerrit - ")
+    parallel (builds)
   }
 
-  if(result == Result.SUCCESS && branch=="master") {
-    ignore(FAILURE) {
-      retry ( Globals.numRetryBuilds ) {
-        b = build("Gerrit-verifier", REFSPEC: refspec, BRANCH: sha1,
-                  CHANGE_URL: changeUrl, MODE: "notedb")
-      }
-    }
+  def results = Globals.buildsList.values().collect { waitForResult(it) }
+  def res = results.inject(1) { acc, buildResult -> getVerified(acc, buildResult) }
 
-    result = waitForResult(b)
-    gerritReview(b.getBuildUrl() + "consoleText",changeNum,sha1, getVerified(result), "NoteDB - ")
+  gerritReview(build.startJob.getBuildUrl() + "console", changeNum, sha1, res, "")
+
+  switch(res) {
+    case 0: build.state.result = ABORTED
+            break
+    case 1: build.state.result = SUCCESS
+            break
+    case -1: build.state.result = FAILURE
+             break
   }
 }
 
diff --git a/jenkins/gerrit-verifier.yaml b/jenkins/gerrit-verifier.yaml
index f5cb7ad..5138b9b 100644
--- a/jenkins/gerrit-verifier.yaml
+++ b/jenkins/gerrit-verifier.yaml
@@ -23,9 +23,8 @@
           echo "Updating all submodules ..."
           git submodule update || ( fetch_submodules && git submodule update )
 
-- job:
-    name: Gerrit-verifier
-    description: "Gerrit build of open change with BUCK\n"
+- defaults:
+    name: verifier-defaults
     concurrent: true
     parameters:
       - string:
@@ -40,15 +39,13 @@
       - choice:
           name: MODE
           choices:
-            - default
-            - notedb
+            - reviewdb
+            - notedbReadWrite
             - polygerrit
           description: "Type of verification to execute"
-
     logrotate:
       numToKeep: 256
       artifactNumToKeep: 1
-
     properties:
        - authorization:
            anonymous:
@@ -64,18 +61,6 @@
          disable-submodules: true
          skip-tag: true
          basedir: gerrit
-
-    builders:
-      - fetch-all-submodules
-      - shell:
-         !include-raw-escape: gerrit-buck-build.sh
-      - shell:
-         !include-raw-escape: gerrit-buck-verifier-test.sh
-      - shell:
-         !include-raw-escape: gerrit-bazel-build.sh
-      - shell:
-         !include-raw-escape: gerrit-bazel-verifier-test.sh
-
     wrappers:
       - xvfb:
           installation-name: Xvfb
@@ -97,6 +82,32 @@
       - groovy-postbuild:
           script: "manager.logContains('timed out') ? manager.buildAborted() : false"
 
+
+- job:
+    name: Gerrit-verifier-buck
+    description: "Gerrit build of open change with BUCK\n"
+    defaults: verifier-defaults
+
+    builders:
+      - fetch-all-submodules
+      - shell:
+         !include-raw-escape: gerrit-buck-build.sh
+      - shell:
+         !include-raw-escape: gerrit-buck-verifier-test.sh
+
+- job:
+    name: Gerrit-verifier-bazel
+    description: "Gerrit build of open change with BUCK\n"
+    defaults: verifier-defaults
+    node: bazel
+
+    builders:
+      - fetch-all-submodules
+      - shell:
+         !include-raw-escape: gerrit-bazel-build.sh
+      - shell:
+         !include-raw-escape: gerrit-bazel-verifier-test.sh
+
 - job:
     name: 'Gerrit-verifier-change'
     project-type: flow