Merge "SEBA-972 fix issues with physical redfish groovy script"
diff --git a/jjb/comac-in-a-box-github.yaml b/jjb/comac-in-a-box-github.yaml
new file mode 100644
index 0000000..60eeec0
--- /dev/null
+++ b/jjb/comac-in-a-box-github.yaml
@@ -0,0 +1,63 @@
+# COMAC in a box test for the omec projects on github
+
+- job-template:
+    id: 'omec-comac-in-a-box'
+    name: 'omec_{project}_comac-in-a-box'
+    project-type: pipeline
+
+    pipeline-script: 'comac-in-a-box-github.groovy'
+
+    description: |
+      Automated build on AMI executor using {pipeline-script}. <br /><br />
+      Created from job-template {id} from ci-management/jjb/comac-in-a-box-github.yaml <br />
+      Created by Jeremy Ronquillo, jeremyr@opennetworking.org <br />
+      Copyright (c) 2020 Open Networking Foundation (ONF)
+
+    properties:
+      - cord-infra-properties:
+          build-days-to-keep: '{build-days-to-keep}'
+          artifact-num-to-keep: '{artifact-num-to-keep}'
+      - github:
+          url: 'https://github.com/{github-organization}/{project}'
+
+    wrappers:
+      - lf-infra-wrappers:
+          build-timeout: '{build-timeout}'
+          jenkins-ssh-credential: '{jenkins-ssh-credential}'
+
+    parameters:
+      - string:
+          name: buildNode
+          default: '{build-node}'
+          description: 'Name of the Jenkins executor node to run the job on'
+
+      - string:
+          name: project
+          default: '{project}'
+          description: 'Name of the project'
+
+      - string:
+          name: branch
+          default: '$ghprbTargetBranch'
+          description: 'Replace value to test manually.'
+
+      - string:
+          name: ghprbPullId
+          default: '$ghprbPullId'
+          description: 'GitHub Pull-Request builder value. Delete default value to test manually.'
+
+      - string:
+          name: ghprbActualCommit
+          default: '$ghprbActualCommit'
+          description: 'GitHub Pull-Request builder value. Delete default value to test manually.'
+
+    triggers:
+      - cord-infra-github-pr-trigger:
+          github_pr_org_list: '{obj:github_pr_org_list}'
+          github_pr_auth_id: '{github_pr_auth_id}'
+          status_context: 'CORD Jenkins - COMAC-in-a-box Verification'
+
+    concurrent: false
+
+    project-type: pipeline
+    dsl: !include-raw-escape: pipeline/{pipeline-script}
diff --git a/jjb/docker-publish-github.yaml b/jjb/docker-publish-github.yaml
index 0551bac..c4fa695 100644
--- a/jjb/docker-publish-github.yaml
+++ b/jjb/docker-publish-github.yaml
@@ -67,7 +67,13 @@
           default: '{maintainers}'
           description: "The person that sould be notified if this job fails"
 
+      - string:
+          name: extraEnvironmentVars
+          default: '{extraEnvironmentVars}'
+          description: "Provide extra environment variables to the build"
+
     project-type: pipeline
     concurrent: true
+    extraEnvironmentVars: ""
 
     dsl: !include-raw-escape: pipeline/docker-publish.groovy
diff --git a/jjb/docker-publish.yaml b/jjb/docker-publish.yaml
index f9f878a..d264eb9 100644
--- a/jjb/docker-publish.yaml
+++ b/jjb/docker-publish.yaml
@@ -72,7 +72,13 @@
           default: '{maintainers}'
           description: "The person that sould be notified if this job fails"
 
+      - string:
+          name: extraEnvironmentVars
+          default: '{extraEnvironmentVars}'
+          description: "Provide extra environment variables to the build"
+
     project-type: pipeline
     concurrent: true
+    extraEnvironmentVars: ""
 
     dsl: !include-raw-escape: pipeline/docker-publish.groovy
diff --git a/jjb/omec-ci.yaml b/jjb/omec-ci.yaml
index fb0ce6c..4445543 100644
--- a/jjb/omec-ci.yaml
+++ b/jjb/omec-ci.yaml
@@ -55,6 +55,8 @@
           build-timeout: 30
           docker-repo: 'omecproject'
           build-node: 'ubuntu16.04-basebuild-4c-8g'
+      - 'omec-comac-in-a-box':
+          build-node: 'comac_in_a_box'
 
 # for c3po
 - project:
@@ -90,7 +92,9 @@
       - 'docker-publish-github':
           build-timeout: 30
           docker-repo: 'omecproject'
-          build-node: 'ubuntu16.04-basebuild-1c-2g'
+          build-node: 'ubuntu16.04-basebuild-8c-15g'
+      - 'omec-comac-in-a-box':
+          build-node: 'comac_in_a_box'
 
 # for openmme
 - project:
@@ -123,6 +127,8 @@
           build-timeout: 30
           docker-repo: 'omecproject'
           build-node: 'ubuntu16.04-basebuild-1c-2g'
+      - 'omec-comac-in-a-box':
+          build-node: 'comac_in_a_box'
 
 # for nucleus
 - project:
@@ -151,6 +157,8 @@
       - 'omec-reuse':
           pipeline-file: 'omec-reuse-scan.groovy'
           build-node: 'omec-qa'
+      - 'omec-comac-in-a-box':
+          build-node: 'comac_in_a_box'
 
 # for freediameter
 - project:
diff --git a/jjb/pipeline/comac-in-a-box-gerrit.groovy b/jjb/pipeline/comac-in-a-box-gerrit.groovy
index dc2be39..e3f20e9 100644
--- a/jjb/pipeline/comac-in-a-box-gerrit.groovy
+++ b/jjb/pipeline/comac-in-a-box-gerrit.groovy
@@ -66,11 +66,26 @@
 
     stage ("Run COMAC-in-a-box"){
       steps {
-        sh label: 'Run Makefile', script: """
-          cd $HOME/automation-tools/comac-in-a-box/
-          sudo make reset-test
-          sudo make test
-          """
+        script{
+          try{
+            sh label: 'Run Makefile', script: """
+              cd $HOME/automation-tools/comac-in-a-box/
+              sudo make reset-test
+              sudo make test
+              """
+          } finally {
+            sh label: 'Archive Logs', script: '''
+              mkdir logs
+              mkdir logs/pods
+              kubectl get pods -n omec > logs/kubectl_get_pods_omec.log
+              for pod in $(kubectl get pods -n omec | awk '{print $1}' | tail -n +2)
+              do
+                kubectl logs -n omec $pod --all-containers > logs/pods/$pod.log || true
+              done
+            '''
+            archiveArtifacts artifacts: "logs/**/*.log", allowEmptyArchive: true
+          }
+        }
       }
     }
   }
diff --git a/jjb/pipeline/comac-in-a-box-github.groovy b/jjb/pipeline/comac-in-a-box-github.groovy
new file mode 100644
index 0000000..f2791ec
--- /dev/null
+++ b/jjb/pipeline/comac-in-a-box-github.groovy
@@ -0,0 +1,157 @@
+// Copyright 2020-present Open Networking Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// comac-in-a-box-github build+test
+// steps taken from https://guide.opencord.org/profiles/comac/install/ciab.html
+
+docker_tag = ""
+abbreviated_commit_hash = ""
+
+pipeline {
+
+  /* no label, executor is determined by JJB */
+  agent {
+    label "${params.buildNode}"
+  }
+
+  options {
+    timeout(time: 1, unit: 'HOURS')
+  }
+
+  environment {
+
+    omec_cp = "$HOME/cord/helm-charts/omec/omec-control-plane/values.yaml"
+    omec_dp = "$HOME/cord/helm-charts/omec/omec-data-plane/values.yaml"
+  }
+
+  stages {
+    stage ("Environment Setup"){
+      steps {
+        sh label: 'Clean Logs', script: """
+          rm -rf logs/
+          """
+        sh label: 'Run COMAC-in-a-box reset-test', script: """
+          echo $HOME
+          cd $HOME/automation-tools/comac-in-a-box/
+          sudo make reset-test
+          """
+        sh label: 'Cleanup Docker Images', script: '''
+          sudo docker rmi -f $(sudo docker images --format '{{.Repository}} {{.ID}}' | grep 'none' | awk '{print $2}') || true
+          sudo docker rmi -f $(sudo docker images --format '{{.Repository}}:{{.Tag}}' | grep 'openmme') || true
+          sudo docker rmi -f $(sudo docker images --format '{{.Repository}}:{{.Tag}}' | grep 'ngic') || true
+          sudo docker rmi -f $(sudo docker images --format '{{.Repository}}:{{.Tag}}' | grep 'c3po') || true
+          '''
+        sh label: 'helm-charts Repo Fresh Clone', script: """
+          cd $HOME/cord/
+          sudo rm -rf helm-charts/
+          git clone https://gerrit.opencord.org/helm-charts
+          """
+      }
+    }
+
+    stage ("Build Local Docker Image"){
+      steps {
+        script {
+          if (params.ghprbPullId == ""){
+            docker_tag = "jenkins_debug"
+          } else {
+            pull_request_num = "PR_${params.ghprbPullId}"
+            abbreviated_commit_hash = params.ghprbActualCommit.substring(0, 7)
+            docker_tag = "${params.branch}-${pull_request_num}-${abbreviated_commit_hash}"
+          }
+        }
+        sh label: 'Clone repo', script: """
+          rm -rf ${params.project}
+          if [ "${params.project}" = "c3po" ]
+          then
+            git clone https://github.com/omec-project/${params.project} --recursive
+          else
+            git clone https://github.com/omec-project/${params.project}
+          fi
+          cd ${params.project}
+          if [ ! -z "${params.ghprbPullId}" ]
+          then
+            echo "Checking out GitHub Pull Request: ${params.ghprbPullId}"
+            git fetch origin pull/${params.ghprbPullId}/head && git checkout FETCH_HEAD
+          else
+            echo "GERRIT_REFSPEC not provided. Checking out target branch."
+            git checkout ${params.branch}
+          fi
+          sudo make DOCKER_TAG=${docker_tag} docker-build
+        """
+
+      }
+    }
+
+    stage ("Change Helm-Charts Docker Tags"){
+      steps {
+        sh label: 'Change Helm-Charts Docker Tags', script: """
+          if [ "${params.project}" = "c3po" ]
+          then
+            sed -i "s;hssdb: docker.*;hssdb: \\"c3po-hssdb:${docker_tag}\\";" ${omec_cp}
+            sed -i "s;hss: .*;hss: \\"c3po-hss:${docker_tag}\\";" ${omec_cp}
+            echo "Changed hssdb and hss tag: ${docker_tag}"
+          elif [ "${params.project}" = "openmme" ]
+          then
+            sed -i "s;mme: .*;mme: \\"openmme:${docker_tag}\\";" ${omec_cp}
+            echo "Changed mme tag: ${docker_tag}"
+          elif [ "${params.project}" = "Nucleus" ]
+          then
+            sed -i "s;mme: .*;mme: \\"openmme:${docker_tag}\\";" ${omec_cp} # nucleus shares the same docker name as openmme.
+            echo "Changed mme tag: ${docker_tag}"
+          elif [ "${params.project}" = "ngic-rtc" ]
+          then
+            sed -i "s;spgwc: .*;spgwc: \\"ngic-cp:${docker_tag}\\";" ${omec_cp}
+            sed -i "s;spgwu: .*;spgwu: \\"ngic-dp:${docker_tag}-debug\\";" ${omec_dp}
+            echo "Changed spgwc and spgwu tag: ${docker_tag}"
+          else
+            echo "The project ${params.project} is not supported. Aborting job."
+            exit 1
+          fi
+
+          echo "omec_cp:"
+          cat "${omec_cp}"
+
+          echo "omec_dp:"
+          cat "${omec_dp}"
+        """
+      }
+    }
+
+    stage ("Run COMAC-in-a-box"){
+      steps {
+        script{
+          try{
+            sh label: 'Run Makefile', script: """
+              cd $HOME/automation-tools/comac-in-a-box/
+              sudo make reset-test
+              sudo make test
+              """
+          } finally {
+            sh label: 'Archive Logs', script: '''
+              mkdir logs
+              mkdir logs/pods
+              kubectl get pods -n omec > logs/kubectl_get_pods_omec.log
+              for pod in $(kubectl get pods -n omec | awk '{print $1}' | tail -n +2)
+              do
+                kubectl logs -n omec $pod --all-containers > logs/pods/$pod.log || true
+              done
+            '''
+            archiveArtifacts artifacts: "logs/**/*.log", allowEmptyArchive: true
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/jjb/pipeline/docker-publish.groovy b/jjb/pipeline/docker-publish.groovy
index a21eda9..316d429 100644
--- a/jjb/pipeline/docker-publish.groovy
+++ b/jjb/pipeline/docker-publish.groovy
@@ -31,6 +31,7 @@
             [$class: 'WipeWorkspace'],
             [$class: 'RelativeTargetDirectory', relativeTargetDir: "${params.projectName}"],
             [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false],
+            [$class: 'SubmoduleOption', recursiveSubmodules: true],
           ],
         ])
         script {
@@ -54,7 +55,7 @@
 
           # Build w/branch
           echo "Building image with branch"
-          make DOCKER_TAG="$branchName" docker-build 2>&1 | tee "$WORKSPACE/docker-build.log"
+          $extraEnvironmentVars DOCKER_TAG="$branchName" make docker-build 2>&1 | tee "$WORKSPACE/docker-build.log"
 
           # Build w/tags if they exist
           if [ -n "$git_tags" ]
@@ -67,7 +68,7 @@
               # remove leading 'v' on funky golang tags
               clean_tag=\$(echo \$tag | sed 's/^v//g')
               echo "Building image with tag: \$clean_tag (should reuse cached layers)"
-              make DOCKER_TAG="\$clean_tag" docker-build
+              $extraEnvironmentVars DOCKER_TAG="\$clean_tag" make docker-build
             done
           fi
         """)
@@ -91,7 +92,7 @@
 
               # Push w/branch
               echo "Pushing image with branch"
-              make DOCKER_TAG="$branchName" docker-push 2>&1 | tee "$WORKSPACE/docker-push.log"
+              $extraEnvironmentVars DOCKER_TAG="$branchName" make docker-push 2>&1 | tee "$WORKSPACE/docker-push.log"
 
               # Push w/tags if they exist
               if [ -n "$git_tags" ]
@@ -103,7 +104,7 @@
                   # remove leading 'v' on funky golang tags
                   clean_tag=\$(echo \$tag | sed 's/^v//g')
                   echo "Pushing image with tag: \$clean_tag (should reuse cached layers)"
-                  make DOCKER_TAG="\$clean_tag" docker-push
+                  $extraEnvironmentVars DOCKER_TAG="\$clean_tag" make docker-push
                 done
               fi
             """)
diff --git a/jjb/pipeline/omec-fossa-scan.groovy b/jjb/pipeline/omec-fossa-scan.groovy
index c70f3eb..c7a3f3f 100644
--- a/jjb/pipeline/omec-fossa-scan.groovy
+++ b/jjb/pipeline/omec-fossa-scan.groovy
@@ -81,6 +81,12 @@
 
                         echo "Testing project: ${params.project}"
 
+                        if [ ! -f ".fossa.yml" ]
+                        then
+                          echo ".fossa.yml not found. This file is mandatory for the test to proceed."
+                          exit 1
+                        fi
+
                         echo "Run 'fossa init'"
                         fossa init --no-ansi --verbose
 
diff --git a/jjb/pipeline/omec-postmerge.groovy b/jjb/pipeline/omec-postmerge.groovy
index 5f23be4..9291f16 100644
--- a/jjb/pipeline/omec-postmerge.groovy
+++ b/jjb/pipeline/omec-postmerge.groovy
@@ -35,13 +35,17 @@
       steps {
         script {
           abbreviated_commit_hash = commitHash.substring(0, 7)
+          tags_to_build = [ "${branchName}-latest",
+                            "${branchName}-${abbreviated_commit_hash}"]
+          tags_to_build.each { tag ->
+            build job: "docker-publish-github_$repoName", parameters: [
+                  string(name: 'gitUrl', value: "${repoUrl}"),
+                  string(name: 'gitRef', value: "${branchName}"),
+                  string(name: 'branchName', value: "${tag}"),
+                  string(name: 'projectName', value: "${repoName}"),
+                ]
+          }
         }
-        build job: "docker-publish-github_$repoName", parameters: [
-              string(name: 'gitUrl', value: "${repoUrl}"),
-              string(name: 'gitRef', value: "${branchName}"),
-              string(name: 'branchName', value: "${branchName}-${abbreviated_commit_hash}"),
-              string(name: 'projectName', value: "${repoName}"),
-            ]
       }
     }
 
diff --git a/jjb/pipeline/voltha-bbsim-tests.groovy b/jjb/pipeline/voltha-bbsim-tests.groovy
index 7dfd54e..485fdbf 100644
--- a/jjb/pipeline/voltha-bbsim-tests.groovy
+++ b/jjb/pipeline/voltha-bbsim-tests.groovy
@@ -30,14 +30,9 @@
     VOLTCONFIG="$HOME/.volt/config-minimal"
     PATH="$WORKSPACE/voltha/kind-voltha/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
     TYPE="minimal"
+    VOLTHA_LOG_LEVEL="DEBUG"
     FANCY=0
     WITH_SIM_ADAPTERS="n"
-    WITH_RADIUS="y"
-    WITH_BBSIM="y"
-    DEPLOY_K8S="y"
-    VOLTHA_LOG_LEVEL="DEBUG"
-    CONFIG_SADIS="n"
-    ROBOT_MISC_ARGS="-d $WORKSPACE/RobotLogs"
   }
 
   stages {
@@ -144,7 +139,11 @@
            '''
       }
     }
-    stage('Deploy Voltha') {
+
+    stage('ATT workflow') {
+      environment {
+        ROBOT_LOGS_DIR="$WORKSPACE/RobotLogs/ATTWorkflow"
+      }
       steps {
         sh '''
            if [ "${branch}" != "master" ]; then
@@ -154,6 +153,12 @@
              echo "on master, using default settings for kind-voltha"
            fi
 
+           # Workflow-specific flags
+           export WITH_RADIUS=yes
+           export WITH_BBSIM=yes
+           export DEPLOY_K8S=yes
+           export CONFIG_SADIS=no
+
            export EXTRA_HELM_FLAGS+="--set log_agent.enabled=False ${extraHelmFlags} "
 
            IMAGES=""
@@ -205,32 +210,71 @@
              md5sum $WORKSPACE/voltha/kind-voltha/bin/voltctl
            fi
 
-           cd $WORKSPACE/voltha/kind-voltha/
-           echo \$EXTRA_HELM_FLAGS
+           printenv
            kail -n voltha -n default > $WORKSPACE/onos-voltha-combined.log &
-           ./voltha up
-           '''
-      }
-    }
 
-    stage('Run E2E Tests') {
-      steps {
-        sh '''
-           mkdir -p $WORKSPACE/RobotLogs
+           cd $WORKSPACE/voltha/kind-voltha/
+           ./voltha up
+
+           # minimal-env.sh contains the environment we used
+           # Save value of EXTRA_HELM_FLAGS there to use in subsequent stages
+           echo export EXTRA_HELM_FLAGS=\\"\$EXTRA_HELM_FLAGS\\" >> minimal-env.sh
+
+           mkdir -p $ROBOT_LOGS_DIR
+           export ROBOT_MISC_ARGS="-d $ROBOT_LOGS_DIR"
 
            # By default, all tests tagged 'sanity' are run.  This covers basic functionality
            # like running through the ATT workflow for a single subscriber.
-           export TEST_TAGS=sanity
+           export TARGET=sanity-single-kind
 
            # If the Gerrit comment contains a line with "functional tests" then run the full
            # functional test suite.  This covers tests tagged either 'sanity' or 'functional'.
            # Note: Gerrit comment text will be prefixed by "Patch set n:" and a blank line
            REGEX="functional tests"
            if [[ "$GERRIT_EVENT_COMMENT_TEXT" =~ \$REGEX ]]; then
-             TEST_TAGS=sanityORfunctional
+             TARGET=functional-single-kind
            fi
 
-           make -C $WORKSPACE/voltha/voltha-system-tests single-kind || true
+           make -C $WORKSPACE/voltha/voltha-system-tests \$TARGET || true
+           '''
+      }
+    }
+
+    stage('DT workflow') {
+      environment {
+        ROBOT_LOGS_DIR="$WORKSPACE/RobotLogs/DTWorkflow"
+      }
+      steps {
+        sh '''
+           cd $WORKSPACE/voltha/kind-voltha/
+           source minimal-env.sh
+           WAIT_ON_DOWN=y DEPLOY_K8S=n ./voltha down
+
+           # Workflow-specific flags
+           export WITH_RADIUS=no
+           export WITH_EAPOL=no
+           export WITH_DHCP=no
+           export WITH_IGMP=no
+           export CONFIG_SADIS=no
+
+           DEPLOY_K8S=n ./voltha up
+
+           mkdir -p $ROBOT_LOGS_DIR
+           export ROBOT_MISC_ARGS="-d $ROBOT_LOGS_DIR"
+
+           # By default, all tests tagged 'sanityDt' are run.  This covers basic functionality
+           # like running through the DT workflow for a single subscriber.
+           export TARGET=sanity-kind-dt
+
+           # If the Gerrit comment contains a line with "functional tests" then run the full
+           # functional test suite.  This covers tests tagged either 'sanityDt' or 'functionalDt'.
+           # Note: Gerrit comment text will be prefixed by "Patch set n:" and a blank line
+           REGEX="functional tests"
+           if [[ "$GERRIT_EVENT_COMMENT_TEXT" =~ \$REGEX ]]; then
+             TARGET=functional-single-kind-dt
+           fi
+
+           make -C $WORKSPACE/voltha/voltha-system-tests \$TARGET || true
            '''
       }
     }
@@ -272,27 +316,15 @@
          extract_errors_python voltha-ofagent >> $WORKSPACE/error-report.log
 
          gzip $WORKSPACE/onos-voltha-combined.log
-
-
-         ## shut down kind-voltha
-         if [ "${branch}" != "master" ]; then
-           echo "on branch: ${branch}, sourcing kind-voltha/releases/${branch}"
-           source "$WORKSPACE/voltha/kind-voltha/releases/${branch}"
-         else
-           echo "on master, using default settings for kind-voltha"
-         fi
-
-         cd $WORKSPACE/voltha/kind-voltha
-	       WAIT_ON_DOWN=y ./voltha down
          '''
          step([$class: 'RobotPublisher',
             disableArchiveOutput: false,
-            logFileName: 'RobotLogs/log*.html',
+            logFileName: 'RobotLogs/*/log*.html',
             otherFiles: '',
-            outputFileName: 'RobotLogs/output*.xml',
+            outputFileName: 'RobotLogs/*/output*.xml',
             outputPath: '.',
-            passThreshold: 80,
-            reportFileName: 'RobotLogs/report*.html',
+            passThreshold: 100,
+            reportFileName: 'RobotLogs/*/report*.html',
             unstableThreshold: 0]);
          archiveArtifacts artifacts: '*.log,*.gz'
     }
diff --git a/jjb/pipeline/voltha-nightly-tests-bbsim.groovy b/jjb/pipeline/voltha-nightly-tests-bbsim.groovy
new file mode 100644
index 0000000..d3d28ab
--- /dev/null
+++ b/jjb/pipeline/voltha-nightly-tests-bbsim.groovy
@@ -0,0 +1,204 @@
+// Copyright 2017-present Open Networking Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// voltha-2.x e2e tests
+// uses kind-voltha to deploy voltha-2.X
+// uses bbsim to simulate OLT/ONUs
+
+pipeline {
+
+  /* no label, executor is determined by JJB */
+  agent {
+    label "${params.buildNode}"
+  }
+  options {
+      timeout(time: 40, unit: 'MINUTES')
+  }
+  environment {
+    KUBECONFIG="$HOME/.kube/kind-config-voltha-minimal"
+    VOLTCONFIG="$HOME/.volt/config-minimal"
+    PATH="$HOME/kind-voltha/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+    TYPE="minimal"
+    FANCY=0
+    WITH_SIM_ADAPTERS="no"
+    WITH_RADIUS="yes"
+    WITH_BBSIM="yes"
+    DEPLOY_K8S="yes"
+    VOLTHA_LOG_LEVEL="DEBUG"
+    CONFIG_SADIS="no"
+    ROBOT_MISC_ARGS="${params.extraRobotArgs}"
+  }
+  stages {
+
+    stage('Repo') {
+      steps {
+        step([$class: 'WsCleanup'])
+        checkout(changelog: true,
+          poll: false,
+          scm: [$class: 'RepoScm',
+            manifestRepositoryUrl: "${params.manifestUrl}",
+            manifestBranch: "${params.branch}",
+            currentBranch: true,
+            destinationDir: 'voltha',
+            forceSync: true,
+            resetFirst: true,
+            quiet: true,
+            jobs: 4,
+            showAllChanges: true]
+          )
+      }
+    }
+
+    stage('Download kind-voltha') {
+      steps {
+        sh """
+           cd $HOME
+           [ -d kind-voltha ] || git clone https://gerrit.opencord.org/kind-voltha
+           rm -rf $HOME/kind-voltha/scripts/logger
+           cd $HOME/kind-voltha
+           git pull
+           """
+      }
+    }
+
+    stage('Deploy Voltha') {
+      steps {
+        sh """
+           export EXTRA_HELM_FLAGS=""
+           if [ "${branch}" != "master" ]; then
+             echo "on branch: ${branch}, sourcing kind-voltha/releases/${branch}"
+             source "$HOME/kind-voltha/releases/${branch}"
+           else
+             echo "on master, using default settings for kind-voltha"
+           fi
+
+           EXTRA_HELM_FLAGS+="--set log_agent.enabled=False ${params.extraHelmFlags} "
+
+           cd $HOME/kind-voltha/
+           WAIT_ON_DOWN=y DEPLOY_K8S=n ./voltha down || ./voltha down
+           ./voltha up
+           """
+      }
+    }
+
+    stage('Functional Tests') {
+      environment {
+        ROBOT_LOGS_DIR="$WORKSPACE/RobotLogs/FunctionalTests"
+      }
+      steps {
+        sh '''
+           set +e
+           mkdir -p $ROBOT_LOGS_DIR
+           cd $HOME/kind-voltha/scripts
+           ./log-collector.sh > /dev/null &
+           ./log-combine.sh > /dev/null &
+
+           export ROBOT_MISC_ARGS="-d $ROBOT_LOGS_DIR"
+           make -C $WORKSPACE/voltha/voltha-system-tests functional-single-kind || true
+           '''
+      }
+    }
+
+    stage('Failure/Recovery Tests') {
+      environment {
+        ROBOT_LOGS_DIR="$WORKSPACE/RobotLogs/FailureTests"
+      }
+      steps {
+        sh '''
+           set +e
+           mkdir -p $WORKSPACE/RobotLogs
+
+           export ROBOT_MISC_ARGS="-d $ROBOT_LOGS_DIR"
+           make -C $WORKSPACE/voltha/voltha-system-tests bbsim-failurescenarios || true
+           '''
+      }
+    }
+
+    stage('Error Tests') {
+      environment {
+        ROBOT_LOGS_DIR="$WORKSPACE/RobotLogs/ErrorTests"
+      }
+      steps {
+        sh '''
+           set +e
+           mkdir -p $WORKSPACE/RobotLogs
+
+           export ROBOT_MISC_ARGS="-d $ROBOT_LOGS_DIR"
+           make -C $WORKSPACE/voltha/voltha-system-tests bbsim-errorscenarios || true
+           '''
+      }
+    }
+
+
+  }
+
+  post {
+    always {
+      sh '''
+         set +e
+         cp $HOME/kind-voltha/install-minimal.log $WORKSPACE/
+         kubectl get pods --all-namespaces -o jsonpath="{range .items[*].status.containerStatuses[*]}{.image}{'\\n'}" | sort | uniq
+         kubectl get pods --all-namespaces -o jsonpath="{range .items[*].status.containerStatuses[*]}{.imageID}{'\\n'}" | sort | uniq
+         kubectl get nodes -o wide
+         kubectl get pods -o wide
+         kubectl get pods -n voltha -o wide
+
+         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 '"level":"error"' $HOME/kind-voltha/scripts/logger/combined/$1*
+           echo
+         }
+
+         extract_errors_python() {
+           echo
+           echo "Error summary for $1:"
+           grep 'ERROR' $HOME/kind-voltha/scripts/logger/combined/$1*
+           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_go voltha-ofagent >> $WORKSPACE/error-report.log
+         extract_errors_python onos >> $WORKSPACE/error-report.log
+
+         cd $HOME/kind-voltha/scripts/logger/combined/
+         tar czf $WORKSPACE/container-logs.tgz *
+
+         cd $WORKSPACE
+         gzip *-combined.log || true
+
+         ## shut down voltha but leave kind-voltha cluster
+         cd $HOME/kind-voltha/
+         DEPLOY_K8S=n WAIT_ON_DOWN=y ./voltha down
+         '''
+         step([$class: 'RobotPublisher',
+            disableArchiveOutput: false,
+            logFileName: '**/log*.html',
+            otherFiles: '',
+            outputFileName: '**/output*.xml',
+            outputPath: 'RobotLogs',
+            passThreshold: 100,
+            reportFileName: '**/report*.html',
+            unstableThreshold: 0]);
+
+         archiveArtifacts artifacts: '*.log,*.gz,*.tgz'
+
+    }
+  }
+}
diff --git a/jjb/shell/github-release.sh b/jjb/shell/github-release.sh
index 40705c6..80b346f 100644
--- a/jjb/shell/github-release.sh
+++ b/jjb/shell/github-release.sh
@@ -95,7 +95,7 @@
 
   # create release
   echo "Creating Release: $GERRIT_PROJECT - $GIT_VERSION"
-  gothub release \
+  github-release release \
     --user "$GITHUB_ORGANIZATION" \
     --repo "$GERRIT_PROJECT" \
     --tag  "$GIT_VERSION" \
@@ -116,7 +116,7 @@
     for rel_file in *
     do
       echo "Uploading file: $rel_file"
-      gothub upload \
+      github-release upload \
         --user "$GITHUB_ORGANIZATION" \
         --repo "$GERRIT_PROJECT" \
         --tag  "$GIT_VERSION" \
diff --git a/jjb/verify/voltha-go.yaml b/jjb/verify/voltha-go.yaml
index c40242d..089eaa5 100644
--- a/jjb/verify/voltha-go.yaml
+++ b/jjb/verify/voltha-go.yaml
@@ -41,3 +41,4 @@
           build-timeout: 30
           docker-repo: 'voltha'
           dependency-jobs: 'version-tag'
+          extraEnvironmentVars: BUILD_PROFILED=true
diff --git a/jjb/verify/voltha-openolt-adapter.yaml b/jjb/verify/voltha-openolt-adapter.yaml
index 893ec19..6f9c4c8 100644
--- a/jjb/verify/voltha-openolt-adapter.yaml
+++ b/jjb/verify/voltha-openolt-adapter.yaml
@@ -41,3 +41,4 @@
           build-timeout: 30
           docker-repo: 'voltha'
           dependency-jobs: 'version-tag'
+          extraEnvironmentVars: BUILD_PROFILED=true
diff --git a/jjb/voltha-e2e.yaml b/jjb/voltha-e2e.yaml
index 2c4361f..4d4ad98 100644
--- a/jjb/voltha-e2e.yaml
+++ b/jjb/voltha-e2e.yaml
@@ -27,10 +27,11 @@
           time-trigger: "H H/6 * * *"
 
       - 'voltha-periodic-test':
-          name: 'periodic-voltha-functional-test'
+          name: 'periodic-voltha-test-bbsim'
+          pipeline-script: 'voltha-nightly-tests-bbsim.groovy'
           build-node: 'qct-pod4-node2'
-          code-branch: 'master'
           make-target: functional-single-kind
+          code-branch: 'master'
           onus: 1
           pons: 1
           time-trigger: "H H/12 * * *"
@@ -45,24 +46,6 @@
           time-trigger: "H H/12 * * *"
 
       - 'voltha-periodic-test':
-          name: 'periodic-voltha-errorscenarios-test'
-          build-node: 'qct-pod4-node2'
-          code-branch: 'master'
-          make-target: bbsim-errorscenarios
-          onus: 1
-          pons: 1
-          time-trigger: "H H/6 * * *"
-
-      - 'voltha-periodic-test':
-          name: 'periodic-voltha-failurescenarios-test'
-          build-node: 'ubuntu16.04-basebuild-4c-8g'
-          code-branch: 'master'
-          make-target: bbsim-failurescenarios
-          onus: 1
-          pons: 1
-          time-trigger: "H H/12 * * *"
-
-      - 'voltha-periodic-test':
           name: 'periodic-voltha-system-test'
           pipeline-script: 'voltha-system-test-bbsim.groovy'
           build-node: 'ubuntu16.04-basebuild-4c-8g'
diff --git a/jjb/voltha-scale.yaml b/jjb/voltha-scale.yaml
index a1a37ef..0c03a30 100644
--- a/jjb/voltha-scale.yaml
+++ b/jjb/voltha-scale.yaml
@@ -50,6 +50,16 @@
           # multi-adapter
           extraHelmFlags: "--set replicas.adapter_open_onu=8"
       - 'voltha-scale-measurements-periodic':
+          name: 'voltha-scale-measurements-periodic-16-32-20s'
+          build-node: 'onf-pod1-head-node'
+          time-trigger: "H H/4 * * *"
+          onuPerPon: 32
+          ponPorts: 16
+          expectedOnus: 512
+          BBSIMdelay: 20000
+          # multi-adapter
+          extraHelmFlags: "--set replicas.adapter_open_onu=8"
+      - 'voltha-scale-measurements-periodic':
           name: 'voltha-scale-measurements-periodic-16-64-200ms'
           build-node: 'onf-pod1-head-node'
           time-trigger: "H H/4 * * *"
@@ -60,6 +70,16 @@
           # multi-adapter
           extraHelmFlags: "--set replicas.adapter_open_onu=8"
       - 'voltha-scale-measurements-periodic':
+          name: 'voltha-scale-measurements-periodic-16-64-20s'
+          build-node: 'onf-pod1-head-node'
+          time-trigger: "H H/4 * * *"
+          onuPerPon: 64
+          ponPorts: 16
+          expectedOnus: 1024
+          BBSIMdelay: 20000
+          # multi-adapter
+          extraHelmFlags: "--set replicas.adapter_open_onu=8"
+      - 'voltha-scale-measurements-periodic':
           name: 'voltha-scale-measurements-periodic-4-64-200ms'
           build-node: 'onf-pod1-head-node'
           time-trigger: "H H/4 * * *"
@@ -142,6 +162,7 @@
           flowStatInterval: 5
           portsStatInterval: 5
           expectedFlows: 201
+          extraHelmFlags: "--set replicas.adapter_open_onu=2"
       - 'voltha-scale-measurements':
           name: 'voltha-scale-measurements-dev'
           build-node: 'voltha-scale'
diff --git a/packer/provision/basebuild.sh b/packer/provision/basebuild.sh
index 95d0307..18f2d89 100644
--- a/packer/provision/basebuild.sh
+++ b/packer/provision/basebuild.sh
@@ -193,8 +193,8 @@
     go get -v github.com/t-yuki/gocover-cobertura
     go get -v github.com/jstemmer/go-junit-report
 
-    # gothub - uploader for github artifacts
-    go get -v github.com/itchio/gothub
+    # github-release - uploader for github artifacts
+    go get -v github.com/github-release/github-release
 
     # dep for go package dependencies w/versioning, version 0.5.2, adapted from:
     #  https://golang.github.io/dep/docs/installation.html#install-from-source