Merge "Notify about salt-formulas test results in test_reclass_notify channel"
diff --git a/cloud-deploy-pipeline.groovy b/cloud-deploy-pipeline.groovy
index 66e4bc7..e4847ee 100644
--- a/cloud-deploy-pipeline.groovy
+++ b/cloud-deploy-pipeline.groovy
@@ -409,7 +409,10 @@
                         orchestrate.installOpenstackNetwork(venvPepper)
                     }
 
-                    salt.cmdRun(venvPepper, 'I@keystone:server', '. /root/keystonercv3; openstack network list')
+                    // Wait for network to come up, 150s should be enough
+                    common.retry(10, 15) {
+                        salt.cmdRun(venvPepper, 'I@keystone:server', '. /root/keystonercv3; openstack network list')
+                    }
                 }
 
                 if (salt.testTarget(venvPepper, 'I@ironic:conductor')){
diff --git a/generate-cookiecutter-products.groovy b/generate-cookiecutter-products.groovy
index a2a4907..0a2888e 100644
--- a/generate-cookiecutter-products.groovy
+++ b/generate-cookiecutter-products.groovy
@@ -223,7 +223,7 @@
                 }
 
                 for (i in common.entries(smc)) {
-                    sh "sed -i \"s,export ${i[0]}=.*,export ${i[0]}=${i[1]},\" user_data.sh"
+                    sh "sed -i 's,export ${i[0]}=.*,export ${i[0]}=${i[1]},' user_data.sh"
                 }
 
                 // create cfg config-drive
diff --git a/test-salt-formulas-pipeline.groovy b/test-salt-formulas-pipeline.groovy
index 1d74a00..849bda3 100644
--- a/test-salt-formulas-pipeline.groovy
+++ b/test-salt-formulas-pipeline.groovy
@@ -4,6 +4,8 @@
  *  DEFAULT_GIT_URL
  *  CREDENTIALS_ID
  *  KITCHEN_TESTS_PARALLEL
+ *  RUN_TEST_IN_DOCKER     If true, run test stage in docker
+ *  SMOKE_TEST_DOCKER_IMG  Docker image for run test (default "ubuntu:16.04")
  */
 common = new com.mirantis.mk.Common()
 def gerrit = new com.mirantis.mk.Gerrit()
@@ -108,7 +110,28 @@
           saltVersion = "" // default value is empty string, means latest
         }
         withEnv(["SALT_VERSION=${saltVersion}"]) {
-          sh("make clean && make test")
+          boolean run_test_in_docker = (env.RUN_TEST_IN_DOCKER ?: false).asBoolean()
+          if (run_test_in_docker) {
+            def dockerLib = new com.mirantis.mk.Docker()
+            def img = dockerLib.getImage(env.SMOKE_TEST_DOCKER_IMG, "ubuntu:16.04")
+            def workspace = common.getWorkspace()
+            img.inside("-u root:root -v ${workspace}/:/formula/") {
+              sh("""cd /etc/apt/ && echo > sources.list \
+              && echo "deb [arch=amd64] http://cz.archive.ubuntu.com/ubuntu xenial main restricted universe multiverse" >> sources.list \
+              && echo "deb [arch=amd64] http://cz.archive.ubuntu.com/ubuntu xenial-updates main restricted universe multiverse" >> sources.list \
+              && echo "deb [arch=amd64] http://cz.archive.ubuntu.com/ubuntu xenial-backports main restricted universe multiverse" >> sources.list \
+              && echo 'Acquire::Languages "none";' > apt.conf.d/docker-no-languages \
+              && echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > apt.conf.d/docker-gzip-indexes \
+              && echo 'APT::Get::Install-Recommends "false"; APT::Get::Install-Suggests "false";' > apt.conf.d/docker-recommends \
+              && apt-get update \
+              && apt-get install -y git-core wget curl apt-transport-https \
+              && apt-get install -y python-pip python3-pip python-virtualenv python3-virtualenv python-yaml autoconf build-essential""")
+              sh("cd /formula/ && make clean && make test")
+            }
+          } else {
+            common.warningMsg("Those tests should be always be run in clean env! Recommends to use docker env!")
+            sh("make clean && make test")
+          }
         }
       }
     }
diff --git a/validate-cloud.groovy b/validate-cloud.groovy
index 5dd8008..dbfc94b 100644
--- a/validate-cloud.groovy
+++ b/validate-cloud.groovy
@@ -70,13 +70,7 @@
 
             stage('Run Rally tests') {
                 if (RUN_RALLY_TESTS.toBoolean() == true) {
-                    def report_dir = '/root/qa_results'
-                    try {
-                         if(REPORT_DIR != ""){
-                             report_dir = REPORT_DIR
-                         }
-                    } catch (MissingPropertyException e) {
-                    }
+                    def report_dir = env.REPORT_DIR ?: '/root/qa_results'
                     def rally_variables = ["floating_network=${FLOATING_NETWORK}",
                                            "rally_image=${RALLY_IMAGE}",
                                            "rally_flavor=${RALLY_FLAVOR}",