Skip to content

Commit 3fdeb84

Browse files
committed
QA: New pipeline to generate test coverage of a Cucumber test suite (#491)
1 parent 93b6b12 commit 3fdeb84

2 files changed

Lines changed: 321 additions & 0 deletions

File tree

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
node('sumaform-cucumber') {
2+
properties([
3+
buildDiscarder(logRotator(numToKeepStr: '1', daysToKeepStr: '1', artifactNumToKeepStr: '1')),
4+
disableConcurrentBuilds(),
5+
parameters([
6+
string(name: 'cucumber_gitrepo', defaultValue: 'https://github.com/uyuni-project/uyuni.git', description: 'Testsuite Git Repository'),
7+
string(name: 'cucumber_ref', defaultValue: 'master', description: 'Testsuite Git reference (branch, tag...)'),
8+
string(name: 'tf_file', defaultValue: 'susemanager-ci/terracumber_config/tf_files/Uyuni-Master-tests-coverage.tf', description: 'Path to the tf file to be used'),
9+
string(name: 'sumaform_gitrepo', defaultValue: 'https://github.com/uyuni-project/sumaform.git', description: 'Sumaform Git Repository'),
10+
string(name: 'sumaform_ref', defaultValue: 'master', description: 'Sumaform Git reference (branch, tag...)'),
11+
choice(name: 'sumaform_backend', choices: ['libvirt', 'aws'], description: 'Sumaform backend to be used (see https://github.com/uyuni-project/sumaform#backend-choice)'),
12+
choice(name: 'terraform_bin', choices: ['/usr/bin/terraform'], description: 'Terraform binary path'),
13+
choice(name: 'terraform_bin_plugins', choices: ['/usr/bin'], description: 'Terraform plugins path'),
14+
string(name: 'terracumber_gitrepo', defaultValue: 'https://github.com/uyuni-project/terracumber.git', description: 'Terracumber Git Repository'),
15+
string(name: 'terracumber_ref', defaultValue: 'master', description: 'Terracumber Git ref (branch, tag...)'),
16+
booleanParam(name: 'terraform_init', defaultValue: true, description: 'Call terraform init (needed if modules are added or changes)'),
17+
booleanParam(name: 'terraform_taint', defaultValue: true, description: 'Call terraform taint (so the resources, except volumes, are recreated)'),
18+
booleanParam(name: 'use_previous_terraform_state', defaultValue: true, description: 'Use previous Terraform state'),
19+
booleanParam(name: 'must_deploy', defaultValue: false, description: 'Deploy'),
20+
choice(name: 'rake_namespace', choices: ['cucumber', 'parallel'], description: 'Choose [parallel] (Clients and some features will run in parallel) or [cucumber] (all sequential)'),
21+
extendedChoice(name: 'functional_scopes', multiSelectDelimiter: ',', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_CHECKBOX', visibleItemCount: 30, value: '@scope_smdba,@scope_spacecmd,@scope_spacewalk_utils,@scope_visualization,@scope_notification_message,@scope_virtual_host_manager,@scope_subscription_matching,@scope_formulas,@scope_sp_migration,@scope_cve_audit,@scope_onboarding,@scope_content_lifecycle_management,@scope_res,@scope_recurring_actions,@scope_maintenance_windows,@scope_cluster_management,@scope_building_container_images,@scope_kubernetes_integration,@scope_openscap,@scope_ubuntu,@scope_action_chains,@scope_salt_ssh,@scope_tomcat,@scope_changing_software_channels,@scope_monitoring,@scope_salt,@scope_cobbler,@scope_sumatoolbox,@scope_virtualization,@scope_hub,@scope_retail,@scope_configuration_channels,@scope_content_staging,@scope_proxy,@scope_traditional_client,@scope_xmlrpc,@scope_power_management,@scope_retracted_patches', description: 'Choose the functional scopes that you want to test')
22+
])
23+
])
24+
25+
timestamps {
26+
// Init path env variables
27+
env.resultdir = "${WORKSPACE}/results"
28+
env.resultdirbuild = "${resultdir}/${BUILD_NUMBER}"
29+
30+
// The junit plugin doesn't affect full paths
31+
junit_resultdir = "results/${BUILD_NUMBER}/results_junit"
32+
env.common_params = "--outputdir ${resultdir} --tf ${params.tf_file} --gitfolder ${resultdir}/sumaform --terraform-bin ${params.terraform_bin}"
33+
34+
// Start pipeline
35+
deployed = false
36+
try {
37+
stage('Clone terracumber, susemanager-ci and sumaform') {
38+
// Create a directory for to place the directory with the build results (if it does not exist)
39+
sh "mkdir -p ${resultdir}"
40+
git url: params.terracumber_gitrepo, branch: params.terracumber_ref
41+
dir("susemanager-ci") {
42+
checkout scm
43+
}
44+
// Clone sumaform
45+
sh "set +x; source /home/jenkins/.credentials set -x; ./terracumber-cli ${common_params} --gitrepo ${params.sumaform_gitrepo} --gitref ${params.sumaform_ref} --runstep gitsync"
46+
47+
// Restore Terraform states from artifacts
48+
if (params.use_previous_terraform_state) {
49+
copyArtifacts projectName: currentBuild.projectName, selector: specific("${currentBuild.previousBuild.number}")
50+
}
51+
}
52+
53+
stage('Deploy') {
54+
if(params.must_deploy) {
55+
// Provision the environment
56+
if (params.terraform_init) {
57+
env.TERRAFORM_INIT = '--init'
58+
} else {
59+
env.TERRAFORM_INIT = ''
60+
}
61+
env.TERRAFORM_TAINT = ''
62+
if (params.terraform_taint) {
63+
switch(params.sumaform_backend) {
64+
case "libvirt":
65+
env.TERRAFORM_TAINT = " --taint '.*(domain|main_disk).*'";
66+
break;
67+
case "aws":
68+
env.TERRAFORM_TAINT = " --taint '.*(host).*'";
69+
break;
70+
default:
71+
println("ERROR: Unknown backend ${params.sumaform_backend}");
72+
sh "exit 1";
73+
break;
74+
}
75+
}
76+
sh "set +x; source /home/jenkins/.credentials set -x; export TF_VAR_CUCUMBER_GITREPO=${params.cucumber_gitrepo}; export TF_VAR_CUCUMBER_BRANCH=${params.cucumber_ref}; export TERRAFORM=${params.terraform_bin}; export TERRAFORM_PLUGINS=${params.terraform_bin_plugins}; ./terracumber-cli ${common_params} --logfile ${resultdirbuild}/sumaform.log ${env.TERRAFORM_INIT} ${env.TERRAFORM_TAINT} --sumaform-backend ${params.sumaform_backend} --runstep provision"
77+
deployed = true
78+
}
79+
}
80+
81+
stage('Enable JaCoCo Agent') {
82+
def url = "https://search.maven.org/remotecontent?filepath=org/jacoco/org.jacoco.agent/0.8.7/org.jacoco.agent-0.8.7-runtime.jar"
83+
sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'ssh \$SERVER wget ${url} -O /tmp/jacocoagent.jar'"
84+
sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'ssh \$SERVER \"sed -i \'s/.\$/[:space:]-javaagent:\\/tmp\\/jacocoagent.jar=output=tcpserver,address=*,port=6300/\' /etc/sysconfig/tomcat\"'"
85+
sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'ssh \$SERVER echo '\"' >> /etc/sysconfig/tomcat'"
86+
sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'ssh \$SERVER systemctl restart tomcat.service'"
87+
}
88+
89+
stage('Sanity Check') {
90+
sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'cd /root/spacewalk/testsuite; rake cucumber:sanity_check'"
91+
}
92+
93+
stage('Core - Setup') {
94+
sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'cd /root/spacewalk/testsuite; rake cucumber:core'"
95+
}
96+
97+
stage('Dump Test Coverage results') {
98+
def url = "https://repo1.maven.org/maven2/org/jacoco/org.jacoco.cli/0.8.7/org.jacoco.cli-0.8.7-nodeps.jar"
99+
sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'ssh \$SERVER wget ${url} -O /tmp/jacococli.jar'"
100+
sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'ssh \$SERVER java -jar /tmp/jacococli.jar dump --address localhost --destfile /tmp/jacoco.exec --port 6300 --reset'"
101+
sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'ssh \$SERVER java -jar jacococli.jar report /tmp/jacoco.exec --html /srv/www/htdocs/pub/jacoco-cucumber-report --xml /srv/www/htdocs/pub/jacoco-cucumber-report.xml --classfiles /srv/tomcat/webapps/rhn/WEB-INF/lib'"
102+
}
103+
}
104+
105+
finally {
106+
stage('Save TF state') {
107+
archiveArtifacts artifacts: "results/sumaform/terraform.tfstate, results/sumaform/.terraform/**/*"
108+
}
109+
110+
stage('Get results') {
111+
def error = 0
112+
if (deployed) {
113+
try {
114+
sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'cd /root/spacewalk/testsuite; rake cucumber:finishing'"
115+
} catch(Exception ex) {
116+
println("ERROR: rake cucumber:finishing failed")
117+
error = 1
118+
}
119+
try {
120+
sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'cd /root/spacewalk/testsuite; rake utils:generate_test_report'"
121+
} catch(Exception ex) {
122+
println("ERROR: rake utils:generate_test_repor failed")
123+
error = 1
124+
}
125+
sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep getresults"
126+
publishHTML( target: [
127+
allowMissing: true,
128+
alwaysLinkToLastBuild: false,
129+
keepAll: true,
130+
reportDir: "${resultdirbuild}/cucumber_report/",
131+
reportFiles: 'cucumber_report.html',
132+
reportName: "TestSuite Report"]
133+
)
134+
junit allowEmptyResults: true, testResults: "${junit_resultdir}/*.xml"
135+
}
136+
// Send email
137+
sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/mail.log --runstep mail"
138+
// Clean up old results
139+
sh "./clean-old-results -r ${resultdir}"
140+
sh "exit ${error}"
141+
}
142+
}
143+
}
144+
}
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
// Mandatory variables for terracumber
2+
variable "URL_PREFIX" {
3+
type = string
4+
default = "https://ci.suse.de/view/Manager/view/Uyuni/job/uyuni-master-dev-acceptance-tests-sonarqube"
5+
}
6+
7+
// Not really used as this is for --runall parameter, and we run cucumber step by step
8+
variable "CUCUMBER_COMMAND" {
9+
type = string
10+
default = "export PRODUCT='Uyuni' && run-testsuite"
11+
}
12+
13+
variable "CUCUMBER_GITREPO" {
14+
type = string
15+
default = "https://github.com/uyuni-project/uyuni.git"
16+
}
17+
18+
variable "CUCUMBER_BRANCH" {
19+
type = string
20+
default = "master"
21+
}
22+
23+
variable "CUCUMBER_RESULTS" {
24+
type = string
25+
default = "/root/spacewalk/testsuite"
26+
}
27+
28+
variable "MAIL_SUBJECT" {
29+
type = string
30+
default = "Results Uyuni-Master-test-coverage $status: $tests scenarios ($failures failed, $errors errors, $skipped skipped, $passed passed)"
31+
}
32+
33+
variable "MAIL_TEMPLATE" {
34+
type = string
35+
default = "../mail_templates/mail-template-jenkins.txt"
36+
}
37+
38+
variable "MAIL_SUBJECT_ENV_FAIL" {
39+
type = string
40+
default = "Results Uyuni-Master: Environment setup failed"
41+
}
42+
43+
variable "MAIL_TEMPLATE_ENV_FAIL" {
44+
type = string
45+
default = "../mail_templates/mail-template-jenkins-env-fail.txt"
46+
}
47+
48+
variable "MAIL_FROM" {
49+
type = string
50+
default = "galaxy-ci@suse.de"
51+
}
52+
53+
variable "MAIL_TO" {
54+
type = string
55+
default = "galaxy-ci@suse.de"
56+
}
57+
58+
// sumaform specific variables
59+
variable "SCC_USER" {
60+
type = string
61+
}
62+
63+
variable "SCC_PASSWORD" {
64+
type = string
65+
}
66+
67+
variable "GIT_USER" {
68+
type = string
69+
default = null // Not needed for master, as it is public
70+
}
71+
72+
variable "GIT_PASSWORD" {
73+
type = string
74+
default = null // Not needed for master, as it is public
75+
}
76+
77+
terraform {
78+
required_version = "1.0.10"
79+
required_providers {
80+
libvirt = {
81+
source = "dmacvicar/libvirt"
82+
version = "0.6.3"
83+
}
84+
}
85+
}
86+
87+
provider "libvirt" {
88+
uri = "qemu+tcp://hyperion.mgr.prv.suse.net/system"
89+
}
90+
91+
module "cucumber_testsuite" {
92+
source = "./modules/cucumber_testsuite"
93+
94+
product_version = "uyuni-master"
95+
96+
// Cucumber repository configuration for the controller
97+
git_username = var.GIT_USER
98+
git_password = var.GIT_PASSWORD
99+
git_repo = var.CUCUMBER_GITREPO
100+
branch = var.CUCUMBER_BRANCH
101+
102+
cc_username = var.SCC_USER
103+
cc_password = var.SCC_PASSWORD
104+
105+
images = ["opensuse152o", "opensuse153o", "sles15sp2o", "sles15sp3o"]
106+
107+
use_avahi = false
108+
name_prefix = "suma-pr8-"
109+
domain = "mgr.prv.suse.net"
110+
from_email = "root@suse.de"
111+
112+
no_auth_registry = "registry.mgr.suse.de"
113+
auth_registry = "registry.mgr.suse.de:5000/cucutest"
114+
auth_registry_username = "cucutest"
115+
auth_registry_password = "cucusecret"
116+
git_profiles_repo = "https://github.com/uyuni-project/uyuni.git#:testsuite/features/profiles/internal_nue"
117+
118+
server_http_proxy = "http-proxy.mgr.suse.de:3128"
119+
120+
host_settings = {
121+
controller = {
122+
provider_settings = {
123+
mac = "aa:b2:92:04:00:7c"
124+
}
125+
}
126+
server = {
127+
provider_settings = {
128+
mac = "aa:b2:92:04:00:7d"
129+
memory = 10240
130+
}
131+
}
132+
proxy = {
133+
provider_settings = {
134+
mac = "aa:b2:92:04:00:7e"
135+
}
136+
additional_packages = [ "venv-salt-minion" ]
137+
install_salt_bundle = true
138+
}
139+
suse-client = {
140+
image = "sles15sp2o"
141+
name = "cli-sles15"
142+
provider_settings = {
143+
mac = "aa:b2:92:04:00:7f"
144+
}
145+
additional_packages = [ "venv-salt-minion" ]
146+
install_salt_bundle = true
147+
}
148+
suse-minion = {
149+
image = "sles15sp2o"
150+
name = "min-sles15"
151+
provider_settings = {
152+
mac = "aa:b2:92:04:00:80"
153+
}
154+
additional_packages = [ "venv-salt-minion" ]
155+
install_salt_bundle = true
156+
}
157+
suse-sshminion = {
158+
image = "sles15sp2o"
159+
name = "minssh-sles15"
160+
provider_settings = {
161+
mac = "aa:b2:92:04:00:81"
162+
}
163+
additional_packages = [ "venv-salt-minion" ]
164+
install_salt_bundle = true
165+
}
166+
}
167+
provider_settings = {
168+
pool = "ssd"
169+
network_name = null
170+
bridge = "br1"
171+
additional_network = "192.168.108.0/24"
172+
}
173+
}
174+
175+
output "configuration" {
176+
value = module.cucumber_testsuite.configuration
177+
}

0 commit comments

Comments
 (0)