Merge "[VOL-2600] Job timeout fixed."
diff --git a/jjb/cord-test/nightly-build-pipeline.yaml b/jjb/cord-test/nightly-build-pipeline.yaml
index d2240d1..b8cff5d 100644
--- a/jjb/cord-test/nightly-build-pipeline.yaml
+++ b/jjb/cord-test/nightly-build-pipeline.yaml
@@ -867,6 +867,7 @@
           default: '{onos-version}'
           description: 'ONOS version that needs to be configured'
 
+
       - bool:
           name: released
           default: '{released}'
@@ -978,6 +979,10 @@
           default: '{manifest-branch}'
           description: 'Repo manifest branch for code checkout (so we can display changes in Jenkins)'
 
+      - bool:
+          name: powerSwitch
+          default: '{power-switch}'
+          description: "Indicate whether POD has power switch to reboot ONUs/OLT remotely"
 
     concurrent: true
 
diff --git a/jjb/cord-test/voltha.yaml b/jjb/cord-test/voltha.yaml
index dabe712..d85577d 100644
--- a/jjb/cord-test/voltha.yaml
+++ b/jjb/cord-test/voltha.yaml
@@ -8,8 +8,9 @@
 
     build-timeout: '300'
 
-    onos-version: '1.13.9'
     with-kind: false
+    onos-version: '2.2'
+    power-switch: False
 
     jobs:
       # flex OCP pod with olt/onu - manual test job, voltha master build job
@@ -58,7 +59,6 @@
           config-pod: 'flex-ocp-cord'
           release: 'master'
           branch: 'master'
-          onos-version: '2.2'
           released: false
           test-repo: 'voltha-system-tests'
           Jenkinsfile: 'Jenkinsfile-voltha-bal31-build'
@@ -74,6 +74,7 @@
           release: 'master'
           branch: 'master'
           released: false
+          power-switch: True
           test-repo: 'voltha-system-tests'
           profile: 'Default'
 
@@ -84,7 +85,6 @@
           release: 'master'
           branch: 'master'
           released: false
-          onos-version: '2.2'
           test-repo: 'voltha-system-tests'
           Jenkinsfile: 'Jenkinsfile-voltha-bal31-build'
           oltDebVersion: 'openolt_asfvolt16_bal3.2.deb'
@@ -99,6 +99,7 @@
           release: 'master'
           branch: 'master'
           released: false
+          power-switch: True
           test-repo: 'voltha-system-tests'
           profile: '1T4GEM-bal31'
 
@@ -110,10 +111,10 @@
           branch: 'master'
           test-repo: 'voltha-system-tests'
           Jenkinsfile: 'Jenkinsfile-voltha-bal31-build'
-          oltDebVersion: 'openolt_asfvolt16.deb'
+          oltDebVersion: 'openolt_asfvolt16_bal3.2.deb'
           configurePod: true
           released: true
-          profile: 'Default'
+          profile: '1T4GEM-bal31'
           time: '4'
 
       # flex pod1 test job - released versions: uses tech profile on voltha branch
@@ -124,7 +125,7 @@
           branch: 'master'
           released: true
           test-repo: 'voltha-system-tests'
-          profile: 'Default'
+          profile: '1T4GEM-bal31'
 
       # Menlo pod with olt/onu - Default tech profile and timer based job
       - 'build_voltha_pod_release':
@@ -132,7 +133,6 @@
           config-pod: 'onf-demo-pod'
           release: 'master'
           branch: 'master'
-          onos-version: '1.13.10'
           released: false
           test-repo: 'voltha-system-tests'
           Jenkinsfile: 'Jenkinsfile-voltha-bal31-build'
@@ -160,7 +160,7 @@
           released: true
           test-repo: 'voltha-system-tests'
           Jenkinsfile: 'Jenkinsfile-voltha-bal31-build'
-          oltDebVersion: 'openolt_asfvolt16.deb'
+          oltDebVersion: 'openolt_asfvolt16_bal3.2.deb'
           configurePod: true
           profile: 'Default'
           time: '3'
@@ -181,7 +181,6 @@
           config-pod: 'onf-demo-pod'
           release: 'master'
           branch: 'master'
-          onos-version: '1.13.10'
           released: false
           test-repo: 'voltha-system-tests'
           Jenkinsfile: 'Jenkinsfile-voltha-bal31-build'
@@ -206,10 +205,9 @@
           config-pod: 'onf-demo-pod'
           release: 'master'
           branch: 'master'
-          onos-version: '1.13.10'
           test-repo: 'voltha-system-tests'
           Jenkinsfile: 'Jenkinsfile-voltha-bal31-build'
-          oltDebVersion: 'openolt_asfvolt16.deb'
+          oltDebVersion: 'openolt_asfvolt16_bal3.2.deb'
           configurePod: true
           profile: '1T4GEM-bal31'
       - 'build_pod_test':
@@ -228,7 +226,7 @@
           branch: 'master'
           test-repo: 'voltha-system-tests'
           Jenkinsfile: 'Jenkinsfile-voltha-bal31-build'
-          oltDebVersion: 'openolt_asfvolt16.deb'
+          oltDebVersion: 'openolt_asfvolt16_bal3.2.deb'
           configurePod: true
           profile: 'Default'
 
@@ -272,6 +270,7 @@
           config-pod: 'dt-berlin-pod'
           release: 'release'
           branch: 'master'
+          onos-version: '2.2'
           test-repo: 'voltha-system-tests'
           Jenkinsfile: 'Jenkinsfile-voltha-bal31-build'
           oltDebVersion: 'openolt_asfvolt16_bal3.2.deb'
@@ -291,4 +290,3 @@
           released: true
           test-repo: 'voltha-system-tests'
           profile: 'Default'
-
diff --git a/jjb/defaults.yaml b/jjb/defaults.yaml
index 6a32bd4..d2a34bd 100644
--- a/jjb/defaults.yaml
+++ b/jjb/defaults.yaml
@@ -90,7 +90,7 @@
 
     # matching repos that should be version tagged by the version-tag job
     # (basically the same as imagebuilder projects + helm charts + tools
-    version-tag-projects-regexp: '^(xos.*|.*helm-charts|automation-tools|cord-tester|chameleon|rcord|mcord|ecord|acordion|addressmanager|epc-service|exampleservice|fabric.*|globalxos|hippie-oss|hss_db|hypercache|internetemulator|kubernetes-service|monitoring|olt-service|onos-service|openstack|progran|sdn-controller|simpleexampleservice|templateservice|vEE|vEG|vBBU|venb|vHSS|vMME|vnaas|vPGWC|vPGWU|vrouter|vsg|vsg-hw|vSGW|vSM|vspgwc|vspgwu|vtn-service|vtr|.*-workflow-driver|ves-agent|voltha-bbsim|openolt|sadis-server|kafka-topic-exporter|pyvoltha||plyxproto|voltha-protos|alpine-grpc-base|cordctl|voltha-go|voltha-onos|device-management|cord-workflow.*|voltha-system-tests|openairinterface|omec-.*|bbsim|omci-sim|ponsim|pppoel2relay|voltha-api-server|aaa|config|dhcpl2relay|igmp|igmpproxy|kafka-onos|mcast|olt|sadis|vtn|voltha-.*-adapter|voltha-lib-go|voltha-python-base|voltha-docker-tools|mn-stratum-siab|ofagent.*|bng|voltctl|openolt-scale-tester)$'
+    version-tag-projects-regexp: '^(xos.*|.*helm-charts|automation-tools|cord-tester|chameleon|rcord|mcord|ecord|acordion|addressmanager|epc-service|exampleservice|fabric.*|globalxos|hippie-oss|hss_db|hypercache|internetemulator|kubernetes-service|monitoring|olt-service|onos-service|openstack|progran|sdn-controller|simpleexampleservice|templateservice|vEE|vEG|vBBU|venb|vHSS|vMME|vnaas|vPGWC|vPGWU|vrouter|vsg|vsg-hw|vSGW|vSM|vspgwc|vspgwu|vtn-service|vtr|.*-workflow-driver|ves-agent|voltha-bbsim|openolt|sadis-server|kafka-topic-exporter|pyvoltha||plyxproto|voltha-protos|alpine-grpc-base|cordctl|voltha-go|voltha-onos|device-management|cord-workflow.*|voltha-system-tests|openairinterface|omec-.*|bbsim|omci-sim|ponsim|pppoel2relay|voltha-api-server|aaa|config|dhcpl2relay|igmp|igmpproxy|kafka-onos|mcast|olt|sadis|vtn|voltha-.*-adapter.*|voltha-lib-go|voltha-python-base|voltha-docker-tools|mn-stratum-siab|ofagent.*|bng|voltctl|openolt-scale-tester|nem-ondemand-proxy|multifabric|openolt-test|omci-lib-go)$'
 
     # List of all repos that contribute to the CORD guide
     cord-guide-projects-regexp: '^(att-workflow-driver|cord-tester|cordctl|exampleservice|fabric|fabric-crossconnect|hippie-oss|kubernetes-service|olt-service|onos-service|openolt|openstack|rcord|simpleexampleservice|vrouter|vtn-service|xos|xos-gui|xos-tosca)$'
@@ -145,9 +145,15 @@
     siab-projects-regexp: '^(xos-core/.*|xos-profiles/seba-services/.*|xos-profiles/base-kubernetes/.*|xos-profiles/ponsim-pod/.*|workflows/att-workflow/.*|voltha/.*|onos/.*|mininet/.*|configs/seba-ponsim.yaml)$'
 
     # Optionally allow JUnit results to be empty when test framework is set up,
-    # but no tests exist. Default behavior is to fail when test results are empty.
+    # but no tests exist. Default behavior is to fail when test results are
+    # empty. Also will not vote if no test output exists - good for repos where
+    # tests or test output generation may not yet exist.
     junit-allow-empty-results: false
 
+    # Allow xunit to not vote if no test files exist. Default is true because
+    # jUnit is the more commonly supported output format.
+    xunit-skip-if-no-test-files: true
+
     # Unit test targets
     # List of targets to run when testing a patchset, run with make or similar
     # defaults to just 'test', multiple targets should be space separated
@@ -193,8 +199,3 @@
     # maintainers
     # Used to notify users in supported tests
     maintainers: 'zdw@opennetworking.org'
-
-    # onos version
-    # is used by the voltha-bbsim-tests.groovy and physical pod pipelines to
-    # know which sadis config needs to be pushed
-    onos-version: '1.13.9'
diff --git a/jjb/make-unit.yaml b/jjb/make-unit.yaml
index 9101df3..cceeb5f 100644
--- a/jjb/make-unit.yaml
+++ b/jjb/make-unit.yaml
@@ -54,6 +54,12 @@
       - junit:
           results: "**/*results.xml,**/*report.xml"
           allow-empty-results: '{junit-allow-empty-results}'
+      - xunit:
+          types:
+            - gtest:
+                pattern: "**/*xunit.xml"
+                deleteoutput: false
+                skip-if-no-test-files: '{xunit-skip-if-no-test-files}'
       - cobertura:
           report-file: "**/*coverage.xml"
           targets:
diff --git a/jjb/pipeline/voltha-bbsim-tests.groovy b/jjb/pipeline/voltha-bbsim-tests.groovy
index 0b77619..b1a7413 100644
--- a/jjb/pipeline/voltha-bbsim-tests.groovy
+++ b/jjb/pipeline/voltha-bbsim-tests.groovy
@@ -37,7 +37,7 @@
     DEPLOY_K8S="y"
     VOLTHA_LOG_LEVEL="DEBUG"
     CONFIG_SADIS="n"
-    ROBOT_MISC_ARGS="-d $WORKSPACE/RobotLogs -v teardown_device:False"
+    ROBOT_MISC_ARGS="-d $WORKSPACE/RobotLogs"
   }
 
   stages {
@@ -64,8 +64,7 @@
       steps {
         sh """
            pushd voltha
-           PROJECT_PATH=\$(xmllint --xpath "string(//project[@name=\\\"${gerritProject}\\\"]/@path)" .repo/manifest.xml)
-           repo download "\$PROJECT_PATH" "${gerritChangeNumber}/${gerritPatchsetNumber}"
+           repo download "${gerritProject}" "${gerritChangeNumber}/${gerritPatchsetNumber}"
            popd
            """
       }
@@ -84,16 +83,27 @@
     stage('Build Images') {
       steps {
         sh """
+           make-local () {
+             make -C $WORKSPACE/voltha/\$1 DOCKER_REPOSITORY=voltha/ DOCKER_TAG=citest docker-build
+           }
            if [ "${gerritProject}" = "pyvoltha" ]; then
-             cd $WORKSPACE/voltha/pyvoltha/
-             make dist
-             cd $WORKSPACE/voltha/voltha-openonu-adapter
+             make -C $WORKSPACE/voltha/pyvoltha/ dist
              export LOCAL_PYVOLTHA=$WORKSPACE/voltha/pyvoltha/
-             make local-pyvoltha
-             make DOCKER_REPOSITORY=voltha/ DOCKER_TAG=citest docker-build
+             make-local voltha-openonu-adapter
+           elif [ "${gerritProject}" = "voltha-lib-go" ]; then
+             make -C $WORKSPACE/voltha/voltha-lib-go/ build
+             export LOCAL_LIB_GO=$WORKSPACE/voltha/voltha-lib-go/
+             make-local voltha-go
+             make-local voltha-openolt-adapter
+           elif [ "${gerritProject}" = "voltha-protos" ]; then
+             make -C $WORKSPACE/voltha/voltha-protos/ build
+             export LOCAL_PROTOS=$WORKSPACE/voltha/voltha-protos/
+             make-local voltha-go
+             make-local voltha-openolt-adapter
+             make-local voltha-openonu-adapter
+             make-local ofagent-py
            elif ! [[ "${gerritProject}" =~ ^(voltha-helm-charts|voltha-system-tests)\$ ]]; then
-             cd $WORKSPACE/voltha/${gerritProject}/
-             make DOCKER_REPOSITORY=voltha/ DOCKER_TAG=citest docker-build
+             make-local ${gerritProject}
            fi
            """
       }
@@ -133,6 +143,10 @@
              IMAGES="bbsim "
            elif [ "${gerritProject}" = "pyvoltha" ]; then
              IMAGES="adapter_open_onu "
+           elif [ "${gerritProject}" = "voltha-lib-go" ]; then
+             IMAGES="rw_core ro_core adapter_open_olt "
+           elif [ "${gerritProject}" = "voltha-protos" ]; then
+             IMAGES="rw_core ro_core adapter_open_olt adapter_open_onu ofagent "
            else
              echo "No images to push"
            fi
@@ -160,82 +174,6 @@
       }
     }
 
-    stage('ONOS Config') {
-      steps {
-        sh '''
-          if [[ ${onosVersion} == "1.13.10" ]]; then
-            curl -sSL --user karaf:karaf \
-              -X POST \
-              -H Content-Type:application/json \
-              http://localhost:8181/onos/v1/network/configuration/apps \
-              --data @- << EOF
-              {
-                 "org.opencord.sadis":{
-                    "sadis":{
-                       "integration":{
-                          "cache":{
-                             "enabled":false,
-                             "maxsize":50,
-                             "ttl":"PT0m"
-                          }
-                       },
-                       "entries":[
-                          {
-                             "id":"BBSIM_OLT_0",
-                             "hardwareIdentifier":"0f:f1:ce:c0:ff:ee",
-                             "nasId":"BBSIMOLT000",
-                             "uplinkPort":1048576
-                          },
-                          {
-                             "id":"BBSM00000001-1",
-                             "nasPortId":"BBSM00000001-1",
-                             "circuitId":"BBSM00000001-1",
-                             "remoteId":"BBSM00000001-1",
-                             "uniTagList":[
-                                {
-                                   "ponCTag":900,
-                                   "ponSTag":900,
-                                   "technologyProfileId":64,
-                                   "downstreamBandwidthProfile":"Default",
-                                   "upstreamBandwidthProfile":"Default",
-                                   "isDhcpRequired":true
-                                }
-                             ]
-                          }
-                       ]
-                    },
-                    "bandwidthprofile":{
-                       "integration":{
-                          "cache":{
-                             "enabled":true,
-                             "maxsize":40,
-                             "ttl":"PT1m"
-                          }
-                       },
-                       "entries":[
-                          {
-                             "id":"Default",
-                             "cir":1000000,
-                             "cbs":1001,
-                             "eir":1002,
-                             "ebs":1003,
-                             "air":1004
-                          }
-                       ]
-                    }
-                 }
-              }
-            EOF
-            sshpass -p karaf ssh -p 30115 karaf@${deployment_config.nodes[0].ip} "cfg set org.opencord.olt.impl.OltFlowService enableDhcpOnProvisioning true"
-            sshpass -p karaf ssh -p 30115 karaf@${deployment_config.nodes[0].ip} "cfg set org.opencord.olt.impl.OltFlowService enableDhcpV4 true"
-            sshpass -p karaf ssh -p 30115 karaf@${deployment_config.nodes[0].ip} "cfg set org.opencord.olt.impl.OltFlowService enableEapol true"
-        else
-            echo "Using kind-voltha defaults"
-        fi
-        '''
-      }
-    }
-
     stage('Run E2E Tests') {
       steps {
         sh '''
@@ -308,7 +246,6 @@
             reportFileName: 'RobotLogs/report*.html',
             unstableThreshold: 0]);
          archiveArtifacts artifacts: '*.log,*.gz'
-
     }
   }
 }
diff --git a/jjb/pipeline/voltha-go-tests.groovy b/jjb/pipeline/voltha-go-tests.groovy
index e339fcc..33da214 100644
--- a/jjb/pipeline/voltha-go-tests.groovy
+++ b/jjb/pipeline/voltha-go-tests.groovy
@@ -74,7 +74,6 @@
         sh """
            cd kind-voltha/
            JUST_K8S=y ./voltha up
-           kail -n voltha -n default > $WORKSPACE/onos-voltha-combined.log &
            ./voltha up
            """
       }
@@ -86,6 +85,11 @@
            set +e
            mkdir -p $WORKSPACE/RobotLogs
            git clone https://gerrit.opencord.org/voltha-system-tests
+
+           cd $WORKSPACE/kind-voltha/scripts
+           ./log-collector.sh > /dev/null &
+           ./log-combine.sh > /dev/null &
+
            make -C $WORKSPACE/voltha-system-tests ${makeTarget} || true
            '''
       }
@@ -102,30 +106,13 @@
          kubectl get pods -o wide
          kubectl get pods -n voltha -o wide
 
-         sync
-         pkill kail || true
+         sleep 60 # Wait for log-collector and log-combine to complete
 
-         ## Pull out errors from log files
-         extract_errors_go() {
-           echo
-           echo "Error summary for $1:"
-           grep $1 $WORKSPACE/onos-voltha-combined.log | grep '"level":"error"' | cut -d ' ' -f 2- | jq -r '.msg'
-           echo
-         }
+         cd $WORKSPACE/kind-voltha/scripts/logger/combined/
+         tar czf $WORKSPACE/container-logs.tgz *
 
-         extract_errors_python() {
-           echo
-           echo "Error summary for $1:"
-           grep $1 $WORKSPACE/onos-voltha-combined.log | grep 'ERROR' | cut -d ' ' -f 2-
-           echo
-         }
-
-         extract_errors_go voltha-rw-core > $WORKSPACE/error-report.log
-         extract_errors_go adapter-open-olt >> $WORKSPACE/error-report.log
-         extract_errors_python adapter-open-onu >> $WORKSPACE/error-report.log
-         extract_errors_python voltha-ofagent >> $WORKSPACE/error-report.log
-
-         gzip $WORKSPACE/onos-voltha-combined.log
+         cd $WORKSPACE
+         gzip *-combined.log || true
 
          ## shut down voltha
          cd $WORKSPACE/kind-voltha/
@@ -140,7 +127,7 @@
             passThreshold: 100,
             reportFileName: 'RobotLogs/report*.html',
             unstableThreshold: 0]);
-         archiveArtifacts artifacts: '*.log,*.gz'
+         archiveArtifacts artifacts: '*.log,*.gz,*.tgz'
 
     }
   }
diff --git a/jjb/pipeline/voltha-physical-build-and-tests.groovy b/jjb/pipeline/voltha-physical-build-and-tests.groovy
index 0769878..ffb45b6 100644
--- a/jjb/pipeline/voltha-physical-build-and-tests.groovy
+++ b/jjb/pipeline/voltha-physical-build-and-tests.groovy
@@ -36,7 +36,7 @@
     label "${params.buildNode}"
   }
   options {
-      timeout(time: 60, unit: 'MINUTES')
+      timeout(time: 90, unit: 'MINUTES')
   }
 
   environment {
@@ -95,8 +95,7 @@
       steps {
         sh returnStdout: false, script: """
         cd voltha
-        PROJECT_PATH=\$(xmllint --xpath "string(//project[@name=\\\"${gerritProject}\\\"]/@path)" .repo/manifest.xml)
-        repo download "\$PROJECT_PATH" "${gerritChangeNumber}/${gerritPatchsetNumber}"
+        repo download "${gerritProject}" "${gerritChangeNumber}/${gerritPatchsetNumber}"
         """
       }
     }
@@ -371,7 +370,7 @@
         otherFiles: '',
         outputFileName: 'RobotLogs/output*.xml',
         outputPath: '.',
-        passThreshold: 80,
+        passThreshold: 100,
         reportFileName: 'RobotLogs/report*.html',
         unstableThreshold: 0]);
       archiveArtifacts artifacts: '*.log,*.gz'
diff --git a/jjb/pipeline/voltha-physical-functional-tests.groovy b/jjb/pipeline/voltha-physical-functional-tests.groovy
index f4ca083..51eb413 100644
--- a/jjb/pipeline/voltha-physical-functional-tests.groovy
+++ b/jjb/pipeline/voltha-physical-functional-tests.groovy
@@ -59,10 +59,12 @@
         git clone -b ${branch} ${cordRepoUrl}/cord-tester
         mkdir -p $WORKSPACE/bin
         bash <( curl -sfL https://raw.githubusercontent.com/boz/kail/master/godownloader.sh) -b "$WORKSPACE/bin"
+        cd $WORKSPACE
+        git clone https://github.com/ciena/kind-voltha.git
         """
       }
     }
-    stage('Subscriber Validation and Ping Tests') {
+    stage('Functional Tests') {
       environment {
         ROBOT_CONFIG_FILE="$WORKSPACE/${configBaseDir}/${configDeploymentDir}/${configFileName}.yaml"
         ROBOT_FILE="Voltha_PODTests.robot"
@@ -70,7 +72,10 @@
       }
       steps {
         sh """
-        kail -n voltha -n default --since=20m > $WORKSPACE/Functional_onos-voltha-combined.log &
+        cd $WORKSPACE/kind-voltha/scripts
+        ./log-collector.sh > /dev/null &
+        ./log-combine.sh > /dev/null &
+
         mkdir -p $ROBOT_LOGS_DIR
         if  ( ${released} ); then
             export ROBOT_MISC_ARGS="--removekeywords wuks -i released -i sanity -e bbsim -e notready -d $ROBOT_LOGS_DIR -v POD_NAME:${configFileName} -v KUBERNETES_CONFIGS_DIR:$WORKSPACE/${configBaseDir}/${configKubernetesDir} -v container_log_dir:$WORKSPACE"
@@ -78,16 +83,11 @@
             export ROBOT_MISC_ARGS="--removekeywords wuks -e bbsim -e notready -d $ROBOT_LOGS_DIR -v POD_NAME:${configFileName} -v KUBERNETES_CONFIGS_DIR:$WORKSPACE/${configBaseDir}/${configKubernetesDir} -v container_log_dir:$WORKSPACE"
         fi
         make -C $WORKSPACE/voltha/voltha-system-tests voltha-test || true
-        sync
-        pkill kail || true
         """
       }
     }
 
     stage('Failure/Recovery Tests') {
-      when {
-        expression { ! params.released }
-      }
       environment {
         ROBOT_CONFIG_FILE="$WORKSPACE/${configBaseDir}/${configDeploymentDir}/${configFileName}.yaml"
         ROBOT_FILE="Voltha_FailureScenarios.robot"
@@ -95,20 +95,20 @@
       }
       steps {
         sh """
-        kail -n voltha -n default > $WORKSPACE/FailureScenarios_onos-voltha-combined.log &
         mkdir -p $ROBOT_LOGS_DIR
-        export ROBOT_MISC_ARGS="--removekeywords wuks -L TRACE -i functional -d $ROBOT_LOGS_DIR -v POD_NAME:${configFileName} -v KUBERNETES_CONFIGS_DIR:$WORKSPACE/${configBaseDir}/${configKubernetesDir} -v container_log_dir:$WORKSPACE"
+        if  ( ${released} ); then
+            export ROBOT_MISC_ARGS="--removekeywords wuks -i released -e bbsim -e notready -d $ROBOT_LOGS_DIR -v POD_NAME:${configFileName} -v KUBERNETES_CONFIGS_DIR:$WORKSPACE/${configBaseDir}/${configKubernetesDir} -v container_log_dir:$WORKSPACE"
+        elif ( ${powerSwitch} ); then
+             export ROBOT_MISC_ARGS="--removekeywords wuks -L TRACE -i functional -i PowerSwitch -e bbsim -e notready -d $ROBOT_LOGS_DIR -v POD_NAME:${configFileName} -v KUBERNETES_CONFIGS_DIR:$WORKSPACE/${configBaseDir}/${configKubernetesDir} -v container_log_dir:$WORKSPACE"
+        else
+             export ROBOT_MISC_ARGS="--removekeywords wuks -L TRACE -i functional -e PowerSwitch -e bbsim -e notready -d $ROBOT_LOGS_DIR -v POD_NAME:${configFileName} -v KUBERNETES_CONFIGS_DIR:$WORKSPACE/${configBaseDir}/${configKubernetesDir} -v container_log_dir:$WORKSPACE"
+        fi
         make -C $WORKSPACE/voltha/voltha-system-tests voltha-test || true
-        sync
-        pkill kail || true
         """
       }
     }
 
     stage('Error Scenario Tests') {
-      when {
-        expression { ! params.released }
-      }
       environment {
         ROBOT_CONFIG_FILE="$WORKSPACE/${configBaseDir}/${configDeploymentDir}/${configFileName}.yaml"
         ROBOT_FILE="Voltha_ErrorScenarios.robot"
@@ -116,12 +116,13 @@
       }
       steps {
         sh """
-        kail -n voltha -n default > $WORKSPACE/ErrorScenarios_onos-voltha-combined.log &
         mkdir -p $ROBOT_LOGS_DIR
-        export ROBOT_MISC_ARGS="--removekeywords wuks -L TRACE -i functional -d $ROBOT_LOGS_DIR -v POD_NAME:${configFileName} -v KUBERNETES_CONFIGS_DIR:$WORKSPACE/${configBaseDir}/${configKubernetesDir} -v container_log_dir:$WORKSPACE"
+        if  ( ${released} ); then
+            export ROBOT_MISC_ARGS="--removekeywords wuks -i released -e bbsim -e notready -d $ROBOT_LOGS_DIR -v POD_NAME:${configFileName} -v KUBERNETES_CONFIGS_DIR:$WORKSPACE/${configBaseDir}/${configKubernetesDir} -v container_log_dir:$WORKSPACE"
+        else
+            export ROBOT_MISC_ARGS="--removekeywords wuks -L TRACE -i functional -e bbsim -e notready -d $ROBOT_LOGS_DIR -v POD_NAME:${configFileName} -v KUBERNETES_CONFIGS_DIR:$WORKSPACE/${configBaseDir}/${configKubernetesDir} -v container_log_dir:$WORKSPACE"
+        fi
         make -C $WORKSPACE/voltha/voltha-system-tests voltha-test || true
-        sync
-        pkill kail || true
         """
       }
     }
@@ -134,31 +135,13 @@
       kubectl get nodes -o wide
       kubectl get pods -n voltha -o wide
 
-      sync
-      pkill kail || true
+      sleep 60 # Wait for log-collector and log-combine to complete
 
-      ## Pull out errors from log files
-      extract_errors_go() {
-        echo
-        echo "Error summary for $1:"
-        grep $1 $WORKSPACE/*onos-voltha-combined.log | grep '"level":"error"' | cut -d ' ' -f 2- | jq -r '.msg'
-        echo
-      }
+      cd $WORKSPACE/kind-voltha/scripts/logger/combined/
+      tar czf $WORKSPACE/container-logs.tgz *
 
-      extract_errors_python() {
-        echo
-        echo "Error summary for $1:"
-        grep $1 $WORKSPACE/*onos-voltha-combined.log | grep 'ERROR' | cut -d ' ' -f 2-
-        echo
-      }
-
-      extract_errors_go voltha-rw-core > $WORKSPACE/error-report.log
-      extract_errors_go adapter-open-olt >> $WORKSPACE/error-report.log
-      extract_errors_python adapter-open-onu >> $WORKSPACE/error-report.log
-      extract_errors_python voltha-ofagent >> $WORKSPACE/error-report.log
-
-      gzip $WORKSPACE/*onos-voltha-combined.log
-
+      cd $WORKSPACE
+      gzip *-combined.log || true
       '''
       script {
         deployment_config.olts.each { olt ->
@@ -178,7 +161,7 @@
         reportFileName: '**/report*.html',
         unstableThreshold: 0
         ]);
-      archiveArtifacts artifacts: '*.log,*.gz'
+      archiveArtifacts artifacts: '*.log,*.gz,*.tgz'
     }
     unstable {
       step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: "${notificationEmail}", sendToIndividuals: false])
diff --git a/jjb/pipeline/xos-core.groovy b/jjb/pipeline/xos-core.groovy
index b6001fb..e0681bd 100644
--- a/jjb/pipeline/xos-core.groovy
+++ b/jjb/pipeline/xos-core.groovy
@@ -84,6 +84,7 @@
            helm init
            sleep 60
            helm repo add incubator https://kubernetes-charts-incubator.storage.googleapis.com/
+           helm repo add cord https://charts.opencord.org
            '''
       }
     }
diff --git a/jjb/pipeline/xos-service-upgrade.groovy b/jjb/pipeline/xos-service-upgrade.groovy
index 6ddd7ef..5e34c48 100644
--- a/jjb/pipeline/xos-service-upgrade.groovy
+++ b/jjb/pipeline/xos-service-upgrade.groovy
@@ -136,7 +136,7 @@
            ## get pod logs
            for pod in \$(kubectl get pods --no-headers | awk '{print \$1}');
            do
-             kubectl logs \$pod> $WORKSPACE/\$pod.log;
+             kubectl logs \${pod} > $WORKSPACE/\${pod}_pre.log;
            done
            """
       }
@@ -241,12 +241,6 @@
            echo \$SERVICES
            cd $WORKSPACE/cord/test/cord-tester/src/test/cord-api/Tests
            for i in \$SERVICES; do bash -c "robot -v SETUP_FLAG:Setup -i get -d Log -T -v TESTLIBRARY:${serviceName}_library.robot \$i\$testname"; sleep 2; done || true
-
-           ## get pod logs
-           for pod in \$(kubectl get pods --no-headers | awk '{print \$1}');
-           do
-             kubectl logs \$pod> $WORKSPACE/\$pod.log;
-           done || true
            """
       }
     }
@@ -297,6 +291,12 @@
   post {
     always {
       sh """
+         ## get pod logs
+         for pod in \$(kubectl get pods --no-headers | awk '{print \$1}');
+         do
+           kubectl logs \${pod} > $WORKSPACE/\${pod}_post.log;
+         done
+
          # copy robot logs
          if [ -d RobotLogs ]; then rm -r RobotLogs; fi; mkdir RobotLogs
          cp -r $WORKSPACE/cord/test/cord-tester/src/test/cord-api/Tests/Log/*ml ./RobotLogs
diff --git a/jjb/shell/tagcollisionreject.sh b/jjb/shell/tagcollisionreject.sh
index a7ba04e..4a791b6 100755
--- a/jjb/shell/tagcollisionreject.sh
+++ b/jjb/shell/tagcollisionreject.sh
@@ -107,7 +107,7 @@
     for df_parent in "${df_parents[@]}"
     do
 
-      df_pattern="FROM (.*):(.*)"
+      df_pattern="FROM ([^:]*):(.*)"
       if [[ "$df_parent" =~ $df_pattern ]]
       then
 
@@ -117,6 +117,10 @@
         if [[ "${p_version}" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]
         then
           echo "  OK: Parent '$p_image:$p_version' is a released SemVer version"
+        elif [[ "${p_version}" =~ ^.*@sha256:[0-9a-f]{64}.*$ ]]
+        then
+          # allow sha256 hashes to be used as version specifiers
+          echo "  OK: Parent '$p_image:$p_version' is using a specific sha256 hash as a version"
         elif [[ "${p_version}" =~ ^.*([0-9]+)\.([0-9]+).*$ ]]
         then
           # handle non-SemVer versions that have a Major.Minor version specifier in the name
diff --git a/jjb/shell/versiontag.sh b/jjb/shell/versiontag.sh
index 41971ce..d4091e6 100755
--- a/jjb/shell/versiontag.sh
+++ b/jjb/shell/versiontag.sh
@@ -108,7 +108,7 @@
     for df_parent in "${df_parents[@]}"
     do
 
-      df_pattern="FROM (.*):(.*)"
+      df_pattern="FROM ([^:]*):(.*)"
       if [[ "$df_parent" =~ $df_pattern ]]
       then
 
@@ -118,6 +118,10 @@
         if [[ "${p_version}" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]
         then
           echo "  OK: Parent '$p_image:$p_version' is a released SemVer version"
+        elif [[ "${p_version}" =~ ^.*@sha256:[0-9a-f]{64}.*$ ]]
+        then
+          # allow sha256 hashes to be used as version specifiers
+          echo "  OK: Parent '$p_image:$p_version' is using a specific sha256 hash as a version"
         elif [[ "${p_version}" =~ ^.*([0-9]+)\.([0-9]+).*$ ]]
         then
           # handle non-SemVer versions that have a Major.Minor version specifier in the name
diff --git a/jjb/verify/cord-tester.yaml b/jjb/verify/cord-tester.yaml
index 38db018..60d7ccb 100644
--- a/jjb/verify/cord-tester.yaml
+++ b/jjb/verify/cord-tester.yaml
@@ -8,6 +8,9 @@
     jobs:
       - 'verify-cord-tester-jobs':
           branch-regexp: '{supported-branches-regexp}'
+      - 'publish-cord-tester-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+          pypi-index: 'pypi'
 
 - job-group:
     name: 'verify-cord-tester-jobs'
@@ -15,3 +18,15 @@
       - 'verify-licensed'
       - 'tag-collision-reject':
           dependency-jobs: 'verify_cord-tester_licensed'
+      - 'make-unit-test':
+          dependency-jobs: 'verify_cord-tester_tag-collision'
+          unit-test-targets: 'lint test'
+          junit-allow-empty-results: true
+
+- job-group:
+    name: 'publish-cord-tester-jobs'
+    jobs:
+      - 'pypi-publish':
+          pypi-module-dirs: 'cord-robot'
+          project-regexp: '^{name}$'
+          dependency-jobs: 'version-tag'
diff --git a/jjb/verify/ofagent-go.yaml b/jjb/verify/ofagent-go.yaml
index f2b00fd..48f6269 100644
--- a/jjb/verify/ofagent-go.yaml
+++ b/jjb/verify/ofagent-go.yaml
@@ -20,7 +20,7 @@
       - 'make-unit-test':
           build-node: 'ubuntu16.04-basebuild-1c-2g'
           dest-gopath: "github.com/opencord"
-          unit-test-targets: 'lint'
+          unit-test-targets: 'lint sca test'
           unit-test-keep-going: 'true'
           junit-allow-empty-results: true
 
diff --git a/jjb/verify/omci-lib-go.yaml b/jjb/verify/omci-lib-go.yaml
new file mode 100644
index 0000000..e37dca1
--- /dev/null
+++ b/jjb/verify/omci-lib-go.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'omci-lib-go' repo
+
+- project:
+    name: omci-lib-go
+    project: '{name}'
+
+    jobs:
+      - 'verify-omci-lib-go-jobs':
+          branch-regexp: '{all-branches-regexp}'
+
+- job-group:
+    name: 'verify-omci-lib-go-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'tag-collision-reject'
+      - 'make-unit-test'
diff --git a/jjb/verify/openolt-test.yaml b/jjb/verify/openolt-test.yaml
new file mode 100644
index 0000000..c8ef753
--- /dev/null
+++ b/jjb/verify/openolt-test.yaml
@@ -0,0 +1,30 @@
+---
+# verification jobs for 'openolt-test' repo
+
+- project:
+    name: openolt-test
+    project: '{name}'
+
+    jobs:
+      - 'verify-openolt-test-jobs':
+          branch-regexp: '{all-branches-regexp}'
+      - 'publish-openolt-test-jobs'
+
+- job-group:
+    name: 'verify-openolt-test-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'tag-collision-reject'
+      - 'make-unit-test':
+          build-node: 'ubuntu16.04-basebuild-2c-4g'
+          build-timeout: 60
+          unit-test-targets: 'lint docker-build'
+          junit-allow-empty-results: true
+
+- job-group:
+    name: 'publish-openolt-test-jobs'
+    jobs:
+      - 'docker-publish':
+          build-timeout: 60
+          docker-repo: 'voltha'
+          dependency-jobs: 'version-tag'
diff --git a/jjb/verify/openolt.yaml b/jjb/verify/openolt.yaml
index edec421..91159f6 100644
--- a/jjb/verify/openolt.yaml
+++ b/jjb/verify/openolt.yaml
@@ -13,10 +13,18 @@
     name: 'verify-openolt-jobs'
     jobs:
       - 'verify-licensed'
-      - 'tag-collision-reject':
-          dependency-jobs: 'verify_openolt_licensed'
-      - 'verify-sonarqube':
-          dependency-jobs: 'verify_openolt_tag-collision'
+      - 'tag-collision-reject'
+      - 'make-unit-test':
+          build-node: 'ubuntu16.04-basebuild-2c-4g'
+          unit-test-targets: 'test'
+          # openolt uses gtest which outputs in xunit format
+          junit-allow-empty-results: true
+          xunit-skip-if-no-test-files: false
+
+# This and the job-template below were written in October 2018
+#
+# Unknown if it is still relevant - the executor in Jenkins does not exist.
+#
 #      - 'openolt-tests':
 #          dependency-jobs: 'verify_openolt_sonarqube'
 
diff --git a/jjb/verify/pyvoltha.yaml b/jjb/verify/pyvoltha.yaml
index 8bc15db..4100715 100644
--- a/jjb/verify/pyvoltha.yaml
+++ b/jjb/verify/pyvoltha.yaml
@@ -22,6 +22,7 @@
           dependency-jobs: 'verify_pyvoltha_tag-collision'
       - 'voltha-patch-test':
           pipeline-script: 'voltha-bbsim-tests.groovy'
+          skip-vote: true
 
 - job-group:
     name: 'publish-pyvoltha-jobs'
diff --git a/jjb/verify/voltctl.yaml b/jjb/verify/voltctl.yaml
index 08e9f52..ead09ef 100644
--- a/jjb/verify/voltctl.yaml
+++ b/jjb/verify/voltctl.yaml
@@ -20,7 +20,7 @@
       - 'tag-collision-reject':
           dependency-jobs: 'verify_voltctl_licensed'
       - 'make-unit-test':
-          unit-test-targets: 'lint test'
+          unit-test-targets: 'lint sca test'
           unit-test-keep-going: 'true'
           dependency-jobs: 'verify_voltctl_tag-collision'
 
diff --git a/jjb/verify/voltha-helm-charts.yaml b/jjb/verify/voltha-helm-charts.yaml
index fd88c24..c7389bb 100644
--- a/jjb/verify/voltha-helm-charts.yaml
+++ b/jjb/verify/voltha-helm-charts.yaml
@@ -21,4 +21,4 @@
           dependency-jobs: 'verify_voltha-helm-charts_helm-lint'
           build-timeout: 20
           pipeline-script: 'voltha-bbsim-tests.groovy'
-          extra-helm-flags: '--set defaults.image_tag=null,images.onos.tag=2.2.0'
+          extra-helm-flags: '--set defaults.image_tag=null,images.onos.tag=4.0.0,images.onos.repository=voltha/voltha-onos'
diff --git a/jjb/verify/voltha-lib-go.yaml b/jjb/verify/voltha-lib-go.yaml
index 448cb7e..fee00c3 100644
--- a/jjb/verify/voltha-lib-go.yaml
+++ b/jjb/verify/voltha-lib-go.yaml
@@ -19,5 +19,8 @@
           build-node: 'ubuntu16.04-basebuild-2c-4g'
           build-timeout: 20
           dest-gopath: "github.com/opencord"
-          unit-test-targets: 'lint test'
+          unit-test-targets: 'lint sca test'
           unit-test-keep-going: 'true'
+      - 'voltha-patch-test':
+          pipeline-script: 'voltha-bbsim-tests.groovy'
+          skip-vote: true
diff --git a/jjb/verify/voltha-onos.yaml b/jjb/verify/voltha-onos.yaml
index 9f1672d..7d426ca 100644
--- a/jjb/verify/voltha-onos.yaml
+++ b/jjb/verify/voltha-onos.yaml
@@ -6,18 +6,13 @@
     project: '{name}'
 
     jobs:
-      - 'verify-voltha-onos-jobs-common':
+      - 'verify-voltha-onos-jobs':
           branch-regexp: '{all-branches-regexp}'
-      - 'verify-voltha-onos-jobs-master':
-          branch-regexp: 'master'
-      - 'verify-voltha-onos-jobs-branches':
-          branch-regexp: '^(onos-1.13.10|onos-2.2)$'
-          name-extension: '-branches'
       - 'publish-voltha-onos-jobs':
-        branch-regexp: '{all-branches-regexp}'
+          branch-regexp: '{all-branches-regexp}'
 
 - job-group:
-    name: 'verify-voltha-onos-jobs-common'
+    name: 'verify-voltha-onos-jobs'
     jobs:
       - 'verify-licensed'
       - 'tag-collision-reject':
@@ -25,21 +20,10 @@
       - 'make-unit-test':
           unit-test-targets: 'build'
           junit-allow-empty-results: true
-
-- job-group:
-    name: 'verify-voltha-onos-jobs-master'
-    jobs:
       - 'voltha-patch-test':
           pipeline-script: 'voltha-bbsim-tests.groovy'
 
 - job-group:
-    name: 'verify-voltha-onos-jobs-branches'
-    jobs:
-      - 'voltha-patch-test':
-          pipeline-script: 'voltha-bbsim-tests.groovy'
-          onos-version: '1.13.10'
-
-- job-group:
     name: 'publish-voltha-onos-jobs'
     jobs:
       - 'docker-publish':
diff --git a/jjb/verify/voltha-openonu-adapter-go.yaml b/jjb/verify/voltha-openonu-adapter-go.yaml
new file mode 100644
index 0000000..d3e9cba
--- /dev/null
+++ b/jjb/verify/voltha-openonu-adapter-go.yaml
@@ -0,0 +1,30 @@
+---
+# verification jobs for 'voltha-openonu-adapter-go' repo
+
+- project:
+    name: voltha-openonu-adapter-go
+    project: '{name}'
+
+    jobs:
+      - 'verify-voltha-openonu-adapter-go-jobs':
+          branch-regexp: '{all-branches-regexp}'
+      - 'publish-voltha-openonu-adapter-go-jobs':
+          branch-regexp: '{all-branches-regexp}'
+
+- job-group:
+    name: 'verify-voltha-openonu-adapter-go-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'tag-collision-reject'
+      - 'make-unit-test'
+# Add this job later when working with kind-voltha and bbsim
+#     - 'voltha-patch-test':
+#         pipeline-script: 'voltha-bbsim-tests.groovy'
+
+- job-group:
+    name: 'publish-voltha-openonu-adapter-go-jobs'
+    jobs:
+      - 'docker-publish':
+          build-timeout: 30
+          docker-repo: 'voltha'
+          dependency-jobs: 'version-tag'
diff --git a/jjb/verify/voltha-protos.yaml b/jjb/verify/voltha-protos.yaml
index aefda8b..ef7b6ab 100644
--- a/jjb/verify/voltha-protos.yaml
+++ b/jjb/verify/voltha-protos.yaml
@@ -23,6 +23,9 @@
           build-timeout: 20
           unit-test-targets: 'test'
           unit-test-keep-going: 'true'
+      - 'voltha-patch-test':
+          pipeline-script: 'voltha-bbsim-tests.groovy'
+          skip-vote: true
 
 - job-group:
     name: 'post-merge-voltha-protos-jobs'
diff --git a/jjb/voltha-e2e.yaml b/jjb/voltha-e2e.yaml
index 751f267..f898a90 100644
--- a/jjb/voltha-e2e.yaml
+++ b/jjb/voltha-e2e.yaml
@@ -164,6 +164,7 @@
     id: 'voltha-patch-test'
     name: 'verify_{project}_sanity-test{name-extension}'
     extra-helm-flags: ''
+    skip-vote: false
 
     description: |
       <!-- Managed by Jenkins Job Builder -->
@@ -216,27 +217,41 @@
           default: '{extra-helm-flags}'
           description: 'Helm flags to pass to ./voltha up'
 
-      - string:
-          name: onosVersion
-          default: '{onos-version}'
-          description: 'ONOS version that needs to be configured'
-
     project-type: pipeline
     concurrent: true
 
     dsl: !include-raw-escape: pipeline/{pipeline-script}
 
     triggers:
-      - cord-infra-gerrit-trigger-patchset:
-          gerrit-server-name: '{gerrit-server-name}'
-          project-regexp: '^{project}$'
-          branch-regexp: '{branch-regexp}'
+      - gerrit:
+          server-name: '{gerrit-server-name}'
           dependency-jobs: '{dependency-jobs}'
-          file-include-regexp: '{all-files-regexp}'
+          silent-start: true
+          trigger-on:
+            - patchset-created-event:
+                exclude-drafts: true
+                exclude-trivial-rebase: false
+                exclude-no-code-change: true
+            - draft-published-event
+            - comment-added-contains-event:
+                comment-contains-value: '(?i)^.*recheck$'
+          projects:
+            - project-compare-type: REG_EXP
+              project-pattern: '^{project}$'
+              branches:
+                - branch-compare-type: REG_EXP
+                  branch-pattern: '{branch-regexp}'
+              file-paths:
+                - compare-type: REG_EXP
+                  pattern: '{all-files-regexp}'
+          skip-vote:
+            successful: '{skip-vote}'
+            failed: '{skip-vote}'
+            unstable: '{skip-vote}'
+            notbuilt: '{skip-vote}'
 
 # POD Per Patchset Pipeline Jobs
 
-
 - job-template:
     name: '{name}'
     id: verify_physical_voltha_patchset_auto
diff --git a/packer/provision/basebuild.sh b/packer/provision/basebuild.sh
index c433d2d..41c358c 100644
--- a/packer/provision/basebuild.sh
+++ b/packer/provision/basebuild.sh
@@ -146,7 +146,7 @@
         grpcio-tools \
         httpie==1.0.3 \
         isort \
-        linkchecker \
+        git+https://github.com/linkchecker/linkchecker.git@v9.4.0 \
         more-itertools==5.0.0 \
         mock \
         netaddr \