blob: 8c0849395975e5c3084064c0c78789ab639297da [file] [log] [blame]
/**
* Tests model manager UI
* API_GERRIT_REPO
* API_GERRIT_REF
* UI_GERRIT_REPO
* UI_GERRIT_REF
* API_DOCKER_IMG
* UI_DOCKER_IMG
* CVP_DOCKER_IMG
* DOCKER_REGISTRY
* DOCKER_REVIEW_REGISTRY
* MCP_VERSION
* FLAVOR
*/
def common = new com.mirantis.mk.Common()
def gerrit = new com.mirantis.mk.Gerrit()
def python = new com.mirantis.mk.Python()
def gerritCredentials = env.CREDENTIALS_ID ?: 'gerrit'
def slaveNode = env.SLAVE_NODE ?: 'python&&docker'
def event = env.GERRIT_EVENT_TYPE ?: null
def defaultRef = 'master'
def apiGerritRef = env.API_GERRIT_REF ?: defaultRef
def uiGerritRef = env.UI_GERRIT_REF ?: defaultRef
def version = env.MCP_VERSION ?: 'nightly'
def dockerRegistry = env.DOCKER_REGISTRY ?: 'docker-prod-local.docker.mirantis.net'
def dockerReviewRegistry = env.DOCKER_REVIEW_REGISTRY ?: 'docker-dev-local.docker.mirantis.net'
def cvpImageName = env.CVP_DOCKER_IMG ? "${dockerRegistry}/${env.CVP_DOCKER_IMG}:${version}" : "${dockerRegistry}/mirantis/cvp/cvp-trymcp-tests:${version}"
if (env.CVP_DEV_TAG && env.CVP_DOCKER_IMG) {
cvpImageName = "${dockerReviewRegistry}/${env.CVP_DOCKER_IMG}:${env.CVP_DEV_TAG}"
}
def checkouted = false
def testReportHTMLFile = 'reports/report.html'
def testReportXMLFile = 'reports/report.xml'
def manualTrigger = false
def apiProject = 'operations-api'
def uiProject = 'operations-ui'
def apiImage
def uiImage
def component = ''
timeout(time: 1, unit: 'HOURS') {
node(slaveNode) {
sh "mkdir -p reports ${apiProject} ${uiProject}"
def testImage = docker.image(cvpImageName)
def testImageOptions = "-u root:root --network=host -v ${env.WORKSPACE}/reports:/var/lib/qa_reports --entrypoint=''"
withCredentials([
[$class : 'UsernamePasswordMultiBinding',
credentialsId : 'scale-ci',
passwordVariable: 'JENKINS_PASSWORD',
usernameVariable: 'JENKINS_USER']
]) {
env.JENKINS_USER = JENKINS_USER
env.JENKINS_PASSWORD = JENKINS_PASSWORD
}
try {
stage("checkout") {
if (event) {
dir(env.FLAVOR) {
// job is triggered by Gerrit
def gerritChange = gerrit.getGerritChange(env.GERRIT_NAME, env.GERRIT_HOST, env.GERRIT_CHANGE_NUMBER, gerritCredentials, true)
if (gerritChange.commitMessage.contains("WIP")) {
common.successMsg("Commit message contains WIP, skipping tests") // do nothing
} else {
// test if change aren't already merged
def merged = gerritChange.status == "MERGED"
if (!merged) {
checkouted = gerrit.gerritPatchsetCheckout([
credentialsId: gerritCredentials
])
} else {
common.successMsg("Change ${env.GERRIT_CHANGE_NUMBER} is already merged, no need to test them")
}
}
}
} else {
common.successMsg('Gerrit variables are not set. Assuming it is manual trigger')
manualTrigger = true
}
if (checkouted) {
if (env.FLAVOR == apiProject) {
// Second project is UI
checkout([
$class : 'GitSCM',
branches : [[name: 'FETCH_HEAD'],],
extensions : [[$class: 'RelativeTargetDirectory', relativeTargetDir: uiProject]],
userRemoteConfigs: [[url: env.UI_GERRIT_REPO, refspec: uiGerritRef, credentialsId: gerritCredentials],],
])
apiImage = docker.image("${dockerReviewRegistry}/review/${env.FLAVOR}-${env.GERRIT_CHANGE_NUMBER}:${env.GERRIT_PATCHSET_NUMBER}")
uiImage = docker.image("${dockerRegistry}/${env.UI_DOCKER_IMG ?: "mirantis/model-generator/operations-ui"}:${version}")
component = "-k 'api'"
} else if (env.FLAVOR == uiProject) {
// Second project is API
checkout([
$class : 'GitSCM',
branches : [[name: 'FETCH_HEAD'],],
extensions : [[$class: 'RelativeTargetDirectory', relativeTargetDir: apiProject]],
userRemoteConfigs: [[url: env.API_GERRIT_REPO, refspec: apiGerritRef, credentialsId: gerritCredentials],],
])
apiImage = docker.image("${dockerRegistry}/${env.API_DOCKER_IMG ?: "mirantis/model-generator/operations-api"}:${version}")
uiImage = docker.image("${dockerReviewRegistry}/review/${env.FLAVOR}-${env.GERRIT_CHANGE_NUMBER}:${env.GERRIT_PATCHSET_NUMBER}")
component = "-k 'ui'"
}
} else if (manualTrigger) {
checkout([
$class : 'GitSCM',
branches : [[name: 'FETCH_HEAD'],],
extensions : [[$class: 'RelativeTargetDirectory', relativeTargetDir: apiProject]],
userRemoteConfigs: [[url: env.API_GERRIT_REPO, refspec: apiGerritRef, credentialsId: gerritCredentials],],
])
checkout([
$class : 'GitSCM',
branches : [[name: 'FETCH_HEAD'],],
extensions : [[$class: 'RelativeTargetDirectory', relativeTargetDir: uiProject]],
userRemoteConfigs: [[url: env.UI_GERRIT_REPO, refspec: uiGerritRef, credentialsId: gerritCredentials],],
])
apiImage = docker.image("${dockerRegistry}/${env.API_DOCKER_IMG ?: "mirantis/model-generator/operations-api"}:${version}")
uiImage = docker.image("${dockerRegistry}/${env.UI_DOCKER_IMG ?: "mirantis/model-generator/operations-ui"}:${version}")
} else {
throw new Exception('Cannot checkout gerrit repositories. Please verify that parameters for repositories are properly set')
}
}
stage('Pull docker images') {
common.retry(3, 5) {
apiImage.pull()
}
common.retry(3, 5) {
uiImage.pull()
}
common.retry(3, 5) {
testImage.pull()
}
}
stage('Prepare and run docker compose services') {
python.setupVirtualenv("${env.WORKSPACE}/venv", 'python2', ['docker-compose==1.22.0'])
// Make sure cockroach_data is cleaned up
if(fileExists("${apiProject}/cockroach_data")) {
testImage.inside(testImageOptions) {
sh("rm -rf ${env.WORKSPACE}/${apiProject}/cockroach_data")
}
}
dir(apiProject) {
python.runVirtualenvCommand("${env.WORKSPACE}/venv",
"export IMAGE=${apiImage.id}; export DOCKER_COMPOSE=docker-compose-test.yml; ./bootstrap_env.sh up")
common.retry(5, 20) {
sh 'curl -v http://127.0.0.1:8001/api/v1 > /dev/null'
}
}
dir(uiProject) {
python.runVirtualenvCommand("${env.WORKSPACE}/venv",
"export IMAGE=${uiImage.id}; docker-compose -f docker-compose-test.yml up -d")
common.retry(5, 20) {
sh 'curl -v http://127.0.0.1:3000 > /dev/null'
}
}
}
stage('Test') {
testImage.inside(testImageOptions) {
sh """
export TEST_LOGIN=test
export TEST_PASSWORD=default
export TEST_MODELD_URL=127.0.0.1
export TEST_MODELD_PORT=3000
export TEST_TIMEOUT=15
cd /var/lib/trymcp-tests
pytest ${component}
"""
}
}
} catch (Throwable e) {
// If there was an error or exception thrown, the build failed
currentBuild.result = "FAILURE"
throw e
} finally {
sh (script: """map=\$(docker ps --format '{{.Names}}:{{.ID}}' --filter name=operations);\
for cont in \$map ; do NAME="\${cont%%:*}";ID="\${cont##*:}"; docker logs \$ID > \$NAME.log 2>&1 ; done""")
archiveArtifacts "*.log"
if (fileExists(testReportHTMLFile)) {
archiveArtifacts artifacts: testReportHTMLFile
}
if (fileExists(testReportXMLFile)) {
archiveArtifacts artifacts: testReportXMLFile
}
stage("Cleanup") {
if (fileExists("${env.WORKSPACE}/venv")) {
dir(apiProject) {
python.runVirtualenvCommand("${env.WORKSPACE}/venv", "./bootstrap_env.sh down || true")
}
dir(uiProject) {
python.runVirtualenvCommand("${env.WORKSPACE}/venv", "docker-compose down || true")
}
sh "rm -rf ${env.WORKSPACE}/venv/"
}
try {
// to avoid issue PROD-29393 "pipeline freezes in `docker rmi` action"
timeout(time: 4, unit: 'MINUTES') {
if (apiImage && apiImage.id) {
sh "docker rmi ${apiImage.id}"
}
if (uiImage && uiImage.id) {
sh "docker rmi ${uiImage.id}"
}
}
} catch (Exception e) {
echo "Failed while cleaning docker images: ${e.toString()}"
}
// Remove everything what is owned by root
testImage.inside(testImageOptions) {
sh("rm -rf /var/lib/qa_reports/* ${env.WORKSPACE}/${apiProject} ${env.WORKSPACE}/${uiProject} ${env.WORKSPACE}/*.log")
}
}
}
}
}