Rename deprecated mcp_qa helpers to tcp_qa
https://mirantis.jira.com/browse/PROD-11772
Change-Id: I15506ab2bff258735e086a360860d0295a416411
diff --git a/src/com/mirantis/tcp_qa/Common.groovy b/src/com/mirantis/tcp_qa/Common.groovy
new file mode 100644
index 0000000..817f893
--- /dev/null
+++ b/src/com/mirantis/tcp_qa/Common.groovy
@@ -0,0 +1,183 @@
+package com.mirantis.tcp_qa
+
+/**
+ * Get latest artifacts
+ * @param imageRepoName is the repo name where image is located
+ * @param imageTagName is the name of the image tag to be used
+ */
+
+def getLatestArtifacts(imageRepoName, imageTagName) {
+ def imageRepo = env.getAt(imageRepoName)
+ def imageTag = env.getAt(imageTagName)
+ if ( imageTag != null && (! imageTag || imageTag.equals('latest')) ) {
+ if ( imageRepo ) {
+ def registry = imageRepo.replaceAll(/\/.*/, '')
+ def image = imageRepo.minus(registry + '/')
+ def hyperkubeImageTag = latestImageTagLookup(registry, image)
+ return "${imageTagName}=${hyperkubeImageTag}"
+ } else {
+ echo "${imageRepoName} variable isn't set, can't inspect 'latest' image!"
+ return null
+ }
+ }
+}
+
+def jsonParse(def json) {
+ new groovy.json.JsonSlurperClassic().parseText(json)
+}
+
+/**
+ * Get digest metadata
+ * @param tag is the image tag to be used
+ * @param registry is the url of registry
+ * @param image is the image which info is looked for
+ */
+
+def get_digest(def tag, def registry, def image) {
+ def digest_link = sprintf('https://%1$s/v2/%2$s/manifests/%3$s', [registry, image, tag])
+ def digest_url = new URL(digest_link)
+ def connection = digest_url.openConnection()
+ connection.setRequestProperty('Accept', 'application/vnd.docker.distribution.manifest.v2+json')
+ def digest = connection.getHeaderField("Docker-Content-Digest")
+ return digest
+}
+
+/**
+ * Get latest tag metadata
+ * @param registry is the url of registry
+ * @param image is the image which tags are looked for
+ */
+
+def latestImageTagLookup(registry, image) {
+ def tags_link = sprintf('https://%1$s/v2/%2$s/tags/list', [registry, image])
+ def tags_url = new URL(tags_link)
+ def tags = jsonParse(tags_url.getText())['tags']
+ def latest_digest = get_digest('latest', registry, image)
+ def same_digest_tags = []
+
+ for (tag in tags) {
+ if (tag == 'latest') {
+ continue
+ }
+ if (get_digest(tag, registry, image) == latest_digest) {
+ same_digest_tags<< tag
+ }
+ }
+
+ return same_digest_tags[0] ?: 'latest'
+}
+
+
+/**
+ * Fetch custom refs
+ * @param gerritUrl is url of gerrit
+ * @param project is the name of project in gerrit
+ * @param targetDir is dir where to fetch changes
+ * @param refs is refs that need to be fetched
+ */
+
+def getCustomRefs(gerritUrl, project, targetDir, refs) {
+ def remote = "${gerritUrl}/${project}"
+ dir(targetDir) {
+ for(int i=0; i<refs.size(); i++) {
+ sh "git fetch ${remote} ${refs[i]} && git cherry-pick FETCH_HEAD"
+ }
+ }
+}
+
+/**
+ * Set downstream k8s artifacts
+ * @param jobSetParameters are current job parameters that can be extended with kubernetes tag
+ */
+
+def set_downstream_k8s_artifacts(jobSetParameters) {
+ def k8sTag = getLatestArtifacts('HYPERKUBE_IMAGE_REPO', 'HYPERKUBE_IMAGE_TAG')
+ if (k8sTag) {
+ jobSetParameters.add(k8sTag)
+ }
+ return jobSetParameters
+}
+
+/**
+ * Upload tests results to TestRail
+ *
+ * @param config LinkedHashMap
+ * config includes next parameters:
+ * - junitXml String, path to XML file with tests results
+ * - testPlanName String, name of test plan in TestRail
+ * - testSuiteName String, name of test suite in TestRail
+ * - testrailMilestone String, milestone name in TestRail
+ * - tesPlanDesc String, description of test plan in TestRail (optional)
+ * - jobURL String, URL of job build with tests (optional)
+ * - testrailURL String, TestRail URL (optional)
+ * - testrailProject String, project name in TestRail (optional)
+ *
+ *
+ * Usage example:
+ *
+ * uploadResultsTestRail([
+ * junitXml: './nosetests.xml',
+ * testPlanName: 'MCP test plan #1',
+ * testSuiteName: 'Calico component tests',
+ * jobURL: 'jenkins.example.com/job/tests.mcp/1',
+ * ])
+ *
+ */
+def uploadResultsTestRail(config) {
+ def venvPath = 'testrail-venv'
+ // TODO: install 'testrail_reporter' pypi when new version with eee508d commit is released
+ def testrailReporterPackage = 'git+git://github.com/gdyuldin/testrail_reporter.git'
+ def testrailReporterVersion = 'eee508d'
+
+ def requiredArgs = ['junitXml', 'testPlanName', 'testSuiteName', 'testrailMilestone']
+ def missingArgs = []
+ for (i in requiredArgs) { if (!config.containsKey(i)) { missingArgs << i }}
+ if (missingArgs) { println "Required arguments are missing for '${funcName}': ${missingArgs.join(', ')}" }
+
+ def junitXml = config.get('junitXml')
+ def testPlanName = config.get('testPlanName')
+ def testSuiteName = config.get('testSuiteName')
+ def testrailMilestone = config.get('testrailMilestone')
+ def testrailURL = config.get('testrailURL', 'https://mirantis.testrail.com')
+ def testrailProject = config.get('testrailProject', 'Mirantis Cloud Platform')
+ def tesPlanDesc = config.get('tesPlanDesc')
+ def jobURL = config.get('jobURL')
+
+ def reporterOptions = [
+ "--verbose",
+ "--testrail-run-update",
+ "--testrail-url '${testrailURL}'",
+ "--testrail-user \"\${TESTRAIL_USER}\"",
+ "--testrail-password \"\${TESTRAIL_PASSWORD}\"",
+ "--testrail-project '${testrailProject}'",
+ "--testrail-plan-name '${testPlanName}'",
+ "--testrail-milestone '${testrailMilestone}'",
+ "--testrail-suite '${testSuiteName}'",
+ "--xunit-name-template '{methodname}'",
+ "--testrail-name-template '{custom_test_group}'",
+ ]
+
+ if (tesPlanDesc) { reporterOptions << "--env-description '${tesPlanDesc}'" }
+ if (jobURL) { reporterOptions << "--test-results-link '${jobURL}'" }
+
+ // Install testrail reporter
+ sh """
+ virtualenv ${venvPath}
+ . ${venvPath}/bin/activate
+ pip install --upgrade ${testrailReporterPackage}@${testrailReporterVersion}
+ """
+
+ def script = """
+ . ${venvPath}/bin/activate
+ report ${reporterOptions.join(' ')} ${junitXml}
+ """
+
+ withCredentials([
+ [$class : 'UsernamePasswordMultiBinding',
+ credentialsId : 'testrail',
+ passwordVariable: 'TESTRAIL_PASSWORD',
+ usernameVariable: 'TESTRAIL_USER']
+ ]) {
+ return sh(script: script, returnStdout: true).trim().split().last()
+ }
+}
diff --git a/src/com/mirantis/tcp_qa/EnvActions.groovy b/src/com/mirantis/tcp_qa/EnvActions.groovy
new file mode 100644
index 0000000..add2c77
--- /dev/null
+++ b/src/com/mirantis/tcp_qa/EnvActions.groovy
@@ -0,0 +1,81 @@
+package com.mirantis.tcp_qa
+
+/**
+ * Activate virtual environment and update requirements if needed
+ */
+def prepareEnv() {
+ sh '''
+ if [ ! -r "${VENV_PATH}/bin/activate" ]; then
+ echo 'Python virtual environment not found! Set correct VENV_PATH!'
+ exit 1
+ fi
+ '''
+
+ sh '''
+ . ${VENV_PATH}/bin/activate
+ pip install --upgrade --upgrade-strategy=only-if-needed -r tcp_tests/requirements.txt
+ '''
+}
+
+
+/**
+ * Download an image for tests
+ */
+def prepareImage() {
+ sh '''
+ if [ -n "${IMAGE_LINK}" ]; then
+ IMAGE_FILE="$(basename "${IMAGE_LINK}")"
+ IMAGES_DIR="$(dirname "${IMAGE_PATH}")"
+ mkdir -p "${IMAGES_DIR}"
+ cd "${IMAGES_DIR}" && wget -N "${IMAGE_LINK}"
+ ln -sf "${IMAGES_DIR}/${IMAGE_FILE}" "${IMAGE_PATH}" || test -f "${IMAGE_PATH}"
+ fi
+
+ if [ ! -r "${IMAGE_PATH}" ]; then
+ echo "Image not found: ${IMAGE_PATH}"
+ exit 1
+ fi
+
+ '''
+}
+
+/**
+ * Check that bridge traffic is not filtered on the host
+ */
+def checkBridgeNetfilterDisabled () {
+ def res = sh(script: 'file /proc/sys/net/bridge/bridge-nf-call-iptables 2>/dev/null || echo "Not found"',
+ returnStdout: true).trim()
+ if ( ! res.equals('Not found') ) {
+ res = sh(script: 'cat /proc/sys/net/bridge/bridge-nf-call-iptables',
+ returnStdout: true).trim()
+ if ( ! res.equals('0') ) {
+ error("Kernel parameter 'net.bridge.bridge-nf-call-iptables' should be disabled to run the tests!")
+ }
+ } else {
+ echo("WARNING: it isn't possible to check net.bridge.bridge-nf-call-iptables value. Please make sure it is set to '0'!")
+ }
+}
+
+
+/**
+ * Destroy running environment
+ */
+def destroyEnv() {
+ if ( !(env.KEEP_BEFORE.equals('yes') || env.KEEP_BEFORE.equals('true')) ) {
+ sh '''
+ . ${VENV_PATH}/bin/activate
+ dos.py destroy ${ENV_NAME} || true
+ '''
+ }
+}
+
+/**
+ * Erase running environment
+ */
+def eraseEnv() {
+ sh '''
+ . ${VENV_PATH}/bin/activate
+ dos.py erase ${ENV_NAME} || true
+ '''
+}
+
diff --git a/src/com/mirantis/tcp_qa/RunTest.groovy b/src/com/mirantis/tcp_qa/RunTest.groovy
new file mode 100644
index 0000000..f64dd53
--- /dev/null
+++ b/src/com/mirantis/tcp_qa/RunTest.groovy
@@ -0,0 +1,23 @@
+package com.mirantis.tcp_qa
+
+/**
+ * Run tcp-qa test by specified group
+ * @param testGroup defines what tests to run, options are '-m test_mark', '-k test_expression'
+ * @param jobSetParameters is additional params needed to run mcp-qa test
+ */
+
+def runTest(testGroup, jobSetParameters) {
+ def testArgs = [ '-s', '-ra' ]
+ testArgs.add(testGroup)
+ jobSetParameters.add("TEST_ARGS=${testArgs.join(' ')}")
+ echo("The current tags, args, which were set by job: ${jobSetParameters.join(' ')}")
+ withEnv(jobSetParameters) {
+ sh '''\
+ . ${VENV_PATH}/bin/activate
+ if ! py.test ${TEST_ARGS}; then
+ echo "Tests failed!"
+ exit 1
+ fi
+ '''.stripIndent()
+ }
+}