blob: 1f04bc12db07ad060b2a7a704103a6080d2b01ca [file] [log] [blame]
Oleg Basov79b9b732019-04-15 15:23:46 +02001/*
Oleg Basovc478c2d2019-01-23 02:38:09 +01002 *
3 * Launch CVP Shaker network tests
4 *
5 * Expected parameters:
Oleg Basov79b9b732019-04-15 15:23:46 +02006 *
Oleg Basovc478c2d2019-01-23 02:38:09 +01007 * SALT_MASTER_URL URL of Salt master
8 * SALT_MASTER_CREDENTIALS Credentials that are used in this Jenkins for accessing Salt master (usually "salt")
9 * IMAGE Docker image link to use for running container with Shaker.
10 * SHAKER_PARAMS Yaml context which contains parameters for running Shaker
11 *
Oleg Basov79b9b732019-04-15 15:23:46 +020012*/
Oleg Basovc478c2d2019-01-23 02:38:09 +010013
14/*
15SHAKER_PARAMS yaml example:
16---
17 SHAKER_SERVER_ENDPOINT: '10.13.0.15:5999'
18 SHAKER_SCENARIOS: 'scenarios/essential'
19 SKIP_LIST: ''
Oleg Basov523d1e32019-02-15 15:38:00 +010020 MATRIX: '{host:[ping.online.net, bouygues.iperf.fr]}'
Oleg Basovc478c2d2019-01-23 02:38:09 +010021 image_builder:
22 - SHAKER_FLAVOR_DISK=4
23 - SHAKER_FLAVOR_RAM=512
24 - SHAKER_FLAVOR_VCPUS=1
25 - SHAKER_IMAGE_BUILDER_MODE='dib'
26 shaker:
27 - SHAKER_AGENT_JOIN_TIMEOUT=300
28 - SHAKER_AGENT_LOSS_TIMEOUT=120
29 - SCENARIO_AVAILABILITY_ZONE='nova,internal'
30 - SCENARIO_COMPUTE_NODES=2
31 - SHAKER_EXTERNAL_NET='public'
32
33Where:
34 "SHAKER_SERVER_ENDPOINT" - Address for Shaker server connections (host:port). Should be accessible
35 from tenant's VM network (usually equals to public address of cicd node)
36 "SHAKER_SCENARIOS" - Path to shaker scenarios in the cvp-shaker docker image
37 (can be directory or specific file). Main categories are
38 scenarios/essential/l2
39 scenarios/essential/l3
40 scenarios/additional/cross_az
41 scenarios/additional/external
42 scenarios/additional/qos
Oleg Basov523d1e32019-02-15 15:38:00 +010043 "MATRIX" - Set the matrix of extra parameters for the scenario. The value is specified in JSON format.
44 To override a scenario duration one may provide: "{time: 10}", or to override list of hosts:
45 "{host:[ping.online.net, iperf.eenet.ee]}". When several parameters are overridden all combinations are
46 tested. It is a required field for some of external-category scenarios when the host name with iperf3
47 server needs to be provided as a command-line parameter, e.g. ``{host: 10.13.100.4}``.
Oleg Basovc478c2d2019-01-23 02:38:09 +010048 "SKIP_LIST" - Comma-separated list of Shaker scenarios to skip, directories or files inside scenarios/
49 of cvp-shaker, e.g. "dense_l2.yaml,full_l2.yaml,l3"
50 "image_builder" - shaker-image-builder env variables
51 SHAKER_FLAVOR_DISK=4
52 SHAKER_FLAVOR_RAM=512
53 SHAKER_FLAVOR_VCPUS=1
54 SHAKER_IMAGE_BUILDER_MODE='dib'
55 "shaker" - main shaker runner env variables
56 SHAKER_AGENT_JOIN_TIMEOUT=300
57 SHAKER_AGENT_LOSS_TIMEOUT=120
58 SCENARIO_AVAILABILITY_ZONE='nova,internal'
59 SCENARIO_COMPUTE_NODES=2
60 SHAKER_EXTERNAL_NET='public'
Oleg Basov523d1e32019-02-15 15:38:00 +010061
Oleg Basovc478c2d2019-01-23 02:38:09 +010062For the more detailed description of the last two categories please refer to the shaker documentation
63https://pyshaker.readthedocs.io/en/latest/tools.html
64*/
65
66common = new com.mirantis.mk.Common()
67salt = new com.mirantis.mk.Salt()
68validate = new com.mirantis.mcp.Validate()
69salt_testing = new com.mirantis.mk.SaltModelTesting()
70
71
72def IMAGE = (env.getProperty('IMAGE')) ?: 'docker-prod-local.docker.mirantis.net/mirantis/cvp/cvp-shaker:proposed'
73def SLAVE_NODE = (env.getProperty('SLAVE_NODE')) ?: 'docker'
74def SHAKER_PARAMS = readYaml(text: env.getProperty('SHAKER_PARAMS')) ?: [:]
75def artifacts_dir = 'validation_artifacts'
76def configRun = [:]
Oleg Basov79b9b732019-04-15 15:23:46 +020077def workdir = '/opt/shaker/'
78def container_artifacts = '/artifacts'
79def html_file = "${container_artifacts}/shaker-report.html"
80def cmd_shaker_args = "--debug --cleanup-on-error --report ${html_file}"
Oleg Basovc478c2d2019-01-23 02:38:09 +010081
82node (SLAVE_NODE) {
Oleg Basov79b9b732019-04-15 15:23:46 +020083 stage('Initialization') {
Oleg Basovc478c2d2019-01-23 02:38:09 +010084
Oleg Basov79b9b732019-04-15 15:23:46 +020085 // prepare artifacts directory
86 sh "rm -rf ${artifacts_dir} || true"
87 sh "mkdir -p ${artifacts_dir}"
88 // Get Openstack credentials
89 def saltMaster = salt.connection(SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
90 try {
Oleg Basovc478c2d2019-01-23 02:38:09 +010091 keystone_creds = validate._get_keystone_creds_v3(saltMaster)
92 if (!keystone_creds) {
93 keystone_creds = validate._get_keystone_creds_v2(saltMaster)
94 }
Oleg Basov79b9b732019-04-15 15:23:46 +020095 } catch (Throwable e) {
96 error("This test requires Openstack keystone credentials to start (${e.toString()})")
Oleg Basovc478c2d2019-01-23 02:38:09 +010097 }
98
Oleg Basov79b9b732019-04-15 15:23:46 +020099 // Get shaker env variables
100 def general_params = [
101 SHAKER_SERVER_ENDPOINT: (SHAKER_PARAMS.get('SHAKER_SERVER_ENDPOINT')),
102 SHAKER_SCENARIOS: (SHAKER_PARAMS.get('SHAKER_SCENARIOS')) ?: 'scenarios/essential',
103 SKIP_LIST: (SHAKER_PARAMS.get('SKIP_LIST')),
104 MATRIX: (SHAKER_PARAMS.get('MATRIX'))
105 ]
106 if (! general_params['SHAKER_SERVER_ENDPOINT']) {
107 throw new Exception("SHAKER_SERVER_ENDPOINT address was not set in the SHAKER_PARAMS")
108 }
109 def builder_vars = SHAKER_PARAMS.get("image_builder") ?: [
110 "SHAKER_FLAVOR_DISK=4",
111 "SHAKER_FLAVOR_RAM=512",
112 "SHAKER_FLAVOR_VCPUS=1"
113 ]
114 def shaker_vars = SHAKER_PARAMS.get("shaker") ?: []
115 def env_vars_list = general_params.collect{ "${it.key}=${it.value}" }
116 env_vars_list = env_vars_list + keystone_creds + builder_vars + shaker_vars
117
118 // Get shaker scenarios cmd
119 def scen_cmd = validate.bundle_up_scenarios(
120 workdir +
121 general_params['SHAKER_SCENARIOS'].replaceAll("^/+", ""),
122 general_params['SKIP_LIST']
123 )
124
125 // Override scenarios params:
126 if (general_params['MATRIX']) {
127 cmd_shaker_args += " --matrix '${general_params.MATRIX}'"
Oleg Basovc478c2d2019-01-23 02:38:09 +0100128 }
129
Oleg Basov79b9b732019-04-15 15:23:46 +0200130 // Define docker commands
131 def commands = [
132 '001_build_image': "shaker-image-builder --debug",
133 '002_run_shaker': scen_cmd +
134 "|paste -sd ',' - " +
135 "|xargs shaker ${cmd_shaker_args} --scenario"
136 ]
137 def commands_list = commands.collectEntries{ [ (it.key) : { sh("${it.value}") } ] }
Oleg Basovc478c2d2019-01-23 02:38:09 +0100138
Oleg Basov79b9b732019-04-15 15:23:46 +0200139 configRun = [
140 'image': IMAGE,
141 'baseRepoPreConfig': false,
142 'dockerMaxCpus': 2,
143 // suppress sudo resolve warnings
144 // which break image build
145 'dockerHostname': 'localhost',
146 'dockerExtraOpts': [
147 "--network=host",
148 "--privileged",
149 "-v ${env.WORKSPACE}/${artifacts_dir}/:${container_artifacts}"
150 ],
151 'envOpts' : env_vars_list,
152 'runCommands' : commands_list
153 ]
Oleg Basovc478c2d2019-01-23 02:38:09 +0100154 }
Oleg Basov79b9b732019-04-15 15:23:46 +0200155
156 stage('Run Shaker tests') {
Oleg Basovbe22e8a2019-05-30 15:14:37 +0200157 timeout(time: 10, unit: 'HOURS') {
158 if (! salt_testing.setupDockerAndTest(configRun)) {
159 common.warningMsg('Docker contrainer failed to run Shaker')
160 currentBuild.result = 'FAILURE'
161 }
Oleg Basov79b9b732019-04-15 15:23:46 +0200162 }
163 }
164
165 stage('Collect results') {
166 archiveArtifacts artifacts: "${artifacts_dir}/*"
167 }
168
Oleg Basovc478c2d2019-01-23 02:38:09 +0100169}