blob: ae83d570097037e9ae189141bbc262e5345921b1 [file] [log] [blame]
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +04001import jenkins
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -05002from xml.dom import minidom
3from cvp_checks import utils
4import json
5import pytest
Mikhail Kraynov351e8412018-10-04 18:27:44 +04006import time
7import os
8from pygerrit2 import GerritRestAPI, HTTPBasicAuth
9from requests import HTTPError
10import git
11
12def join_to_gerrit(local_salt_client, gerrit_user, gerrit_password):
13 gerrit_port = local_salt_client.cmd(
14 'I@gerrit:client and not I@salt:master',
15 'pillar.get',
16 ['_param:haproxy_gerrit_bind_port'],
17 expr_form='compound').values()[0]
18 gerrit_address = local_salt_client.cmd(
19 'I@gerrit:client and not I@salt:master',
20 'pillar.get',
21 ['_param:haproxy_gerrit_bind_host'],
22 expr_form='compound').values()[0]
23 url = 'http://{0}:{1}'.format(gerrit_address,gerrit_port)
24 auth = HTTPBasicAuth(gerrit_user, gerrit_password)
25 rest = GerritRestAPI(url=url, auth=auth)
26 return rest
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -050027
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +040028def join_to_jenkins(local_salt_client, jenkins_user, jenkins_password):
29 jenkins_port = local_salt_client.cmd(
30 'I@jenkins:client and not I@salt:master',
31 'pillar.get',
32 ['_param:haproxy_jenkins_bind_port'],
33 expr_form='compound').values()[0]
34 jenkins_address = local_salt_client.cmd(
35 'I@jenkins:client and not I@salt:master',
36 'pillar.get',
37 ['_param:haproxy_jenkins_bind_host'],
38 expr_form='compound').values()[0]
39 jenkins_url = 'http://{0}:{1}'.format(jenkins_address,jenkins_port)
40 server = jenkins.Jenkins(jenkins_url, username=jenkins_user, password=jenkins_password)
41 return server
42
Mikhail Kraynov351e8412018-10-04 18:27:44 +040043def get_password(local_salt_client,service):
44 password = local_salt_client.cmd(
45 service,
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +040046 'pillar.get',
47 ['_param:openldap_admin_password'],
48 expr_form='pillar').values()[0]
Mikhail Kraynov351e8412018-10-04 18:27:44 +040049 return password
50
51def test_drivetrain_gerrit(local_salt_client):
52 gerrit_password = get_password(local_salt_client,'gerrit:client')
53 gerrit_error = ''
54 current_date = time.strftime("%Y%m%d-%H.%M.%S", time.localtime())
55 test_proj_name = "test-dt-{0}".format(current_date)
56 gerrit_port = local_salt_client.cmd(
57 'I@gerrit:client and not I@salt:master',
58 'pillar.get',
59 ['_param:haproxy_gerrit_bind_port'],
60 expr_form='compound').values()[0]
61 gerrit_address = local_salt_client.cmd(
62 'I@gerrit:client and not I@salt:master',
63 'pillar.get',
64 ['_param:haproxy_gerrit_bind_host'],
65 expr_form='compound').values()[0]
66 try:
67 #Connecting to gerrit and check connection
68 server = join_to_gerrit(local_salt_client,'admin',gerrit_password)
69 gerrit_check = server.get("/changes/?q=owner:self%20status:open")
70 #Check deleteproject plugin and skip test if the plugin is not installed
71 gerrit_plugins = server.get("/plugins/?all")
72 if 'deleteproject' not in gerrit_plugins:
73 pytest.skip("Delete-project plugin is not installed")
74 #Create test project and add description
75 server.put("/projects/"+test_proj_name)
76 server.put("/projects/"+test_proj_name+"/description",json={"description":"Test DriveTrain project","commit_message": "Update the project description"})
77 except HTTPError, e:
78 gerrit_error = e
79 try:
80 #Create test folder and init git
81 repo_dir = os.path.join(os.getcwd(),test_proj_name)
82 file_name = os.path.join(repo_dir, current_date)
83 repo = git.Repo.init(repo_dir)
84 #Add remote url for this git repo
85 origin = repo.create_remote('origin', 'http://admin:{1}@{2}:{3}/{0}.git'.format(test_proj_name,gerrit_password,gerrit_address,gerrit_port))
86 #Add commit-msg hook to automatically add Change-Id to our commit
87 os.system("curl -Lo {0}/.git/hooks/commit-msg 'http://admin:{1}@{2}:{3}/tools/hooks/commit-msg' > /dev/null 2>&1".format(repo_dir,gerrit_password,gerrit_address,gerrit_port))
88 os.system("chmod u+x {0}/.git/hooks/commit-msg".format(repo_dir))
89 #Create a test file
90 f = open(file_name, 'w+')
91 f.write("This is a test file for DriveTrain test")
92 f.close()
93 #Add file to git and commit it to Gerrit for review
94 repo.index.add([file_name])
95 repo.index.commit("This is a test commit for DriveTrain test")
96 repo.git.push("origin", "HEAD:refs/for/master")
97 #Get change id from Gerrit. Set Code-Review +2 and submit this change
98 changes = server.get("/changes/?q=project:{0}".format(test_proj_name))
99 last_change = changes[0].get('change_id')
100 server.post("/changes/{0}/revisions/1/review".format(last_change),json={"message":"All is good","labels":{"Code-Review":"+2"}})
101 server.post("/changes/{0}/submit".format(last_change))
102 except HTTPError, e:
103 gerrit_error = e
104 finally:
105 #Delete test project
106 server.post("/projects/"+test_proj_name+"/deleteproject~delete")
107 assert gerrit_error == '',\
108 'Something is wrong with Gerrit'.format(gerrit_error)
109
110
111def test_drivetrain_jenkins_job(local_salt_client):
112 jenkins_password = get_password(local_salt_client,'jenkins:client')
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +0400113 server = join_to_jenkins(local_salt_client,'admin',jenkins_password)
114 #Getting Jenkins test job name from configuration
115 config = utils.get_configuration()
116 jenkins_test_job = config['jenkins_test_job']
117 if not jenkins_test_job or jenkins_test_job == '':
118 jenkins_test_job = 'git-mirror-downstream-mk-pipelines'
119 if server.get_job_name(jenkins_test_job):
120 next_build_num = server.get_job_info(jenkins_test_job)['nextBuildNumber']
121 #If this is first build number skip building check
122 if next_build_num != 1:
123 #Check that test job is not running at this moment,
124 #Otherwise skip the test
125 last_build_num = server.get_job_info(jenkins_test_job)['lastBuild'].get('number')
126 last_build_status = server.get_build_info(jenkins_test_job,last_build_num)['building']
127 if last_build_status:
128 pytest.skip("Test job {0} is already running").format(jenkins_test_job)
129 #This jenkins module doesn't work with build_job function without parameters
130 #Just send some fake parameters. All others will be used from default values
131 param_dict = {'foo':'bar'}
132 server.build_job(jenkins_test_job, param_dict)
133 timeout = 0
134 #Use job status True by default to exclude timeout between build job and start job.
135 job_status = True
136 while job_status and ( timeout < 180 ):
Mikhail Kraynov351e8412018-10-04 18:27:44 +0400137 time.sleep(10)
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +0400138 timeout += 10
139 job_status = server.get_build_info(jenkins_test_job,next_build_num)['building']
140 job_result = server.get_build_info(jenkins_test_job,next_build_num)['result']
141 else:
142 pytest.skip("The job {0} was not found").format(test_job_name)
143 assert job_result == 'SUCCESS', \
144 '''Test job '{0}' build was not successfull or timeout is too small
145 '''.format(jenkins_test_job)
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -0500146
147def test_drivetrain_services_replicas(local_salt_client):
148 salt_output = local_salt_client.cmd(
Oleksii Zhurba0aeedf72018-07-30 11:24:01 -0500149 'I@gerrit:client',
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -0500150 'cmd.run',
151 ['docker service ls'],
152 expr_form='compound')
153 wrong_items = []
154 for line in salt_output[salt_output.keys()[0]].split('\n'):
155 if line[line.find('/') - 1] != line[line.find('/') + 1] \
156 and 'replicated' in line:
157 wrong_items.append(line)
158 assert len(wrong_items) == 0, \
159 '''Some DriveTrain services doesn't have expected number of replicas:
160 {}'''.format(json.dumps(wrong_items, indent=4))
161
162
163def test_drivetrain_components_and_versions(local_salt_client):
164 config = utils.get_configuration()
165 version = config['drivetrain_version'] or []
166 if not version or version == '':
167 pytest.skip("drivetrain_version is not defined. Skipping")
168 salt_output = local_salt_client.cmd(
Oleksii Zhurba0aeedf72018-07-30 11:24:01 -0500169 'I@gerrit:client',
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -0500170 'cmd.run',
171 ['docker service ls'],
172 expr_form='compound')
173 not_found_services = ['gerrit_db', 'gerrit_server', 'jenkins_master',
174 'jenkins_slave01', 'jenkins_slave02',
175 'jenkins_slave03', 'ldap_admin', 'ldap_server']
176 version_mismatch = []
177 for line in salt_output[salt_output.keys()[0]].split('\n'):
178 for service in not_found_services:
179 if service in line:
180 not_found_services.remove(service)
181 if version != line.split()[4].split(':')[1]:
182 version_mismatch.append("{0}: expected "
183 "version is {1}, actual - {2}".format(service,version,
184 line.split()[4].split(':')[1]))
185 continue
186 assert len(not_found_services) == 0, \
187 '''Some DriveTrain components are not found:
188 {}'''.format(json.dumps(not_found_services, indent=4))
189 assert len(version_mismatch) == 0, \
190 '''Version mismatch found:
191 {}'''.format(json.dumps(version_mismatch, indent=4))
192
193
194def test_jenkins_jobs_branch(local_salt_client):
195 config = utils.get_configuration()
196 expected_version = config['drivetrain_version'] or []
197 if not expected_version or expected_version == '':
198 pytest.skip("drivetrain_version is not defined. Skipping")
Mikhail Kraynov351e8412018-10-04 18:27:44 +0400199 jenkins_password = get_password(local_salt_client,'jenkins:client')
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -0500200 version_mismatch = []
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +0400201 server = join_to_jenkins(local_salt_client,'admin',jenkins_password)
202 for job_instance in server.get_jobs():
203 job_name = job_instance.get('name')
204 job_config = server.get_job_config(job_name)
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -0500205 xml_data = minidom.parseString(job_config)
206 BranchSpec = xml_data.getElementsByTagName('hudson.plugins.git.BranchSpec')
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +0400207 #We use master branch for pipeline-library in case of 'testing,stable,nighlty' versions
208 if expected_version in ['testing','nightly','stable']:
209 expected_version = 'master'
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -0500210 if BranchSpec:
211 actual_version = BranchSpec[0].getElementsByTagName('name')[0].childNodes[0].data
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +0400212 if ( actual_version != expected_version ) and ( job_name not in ['cvp-func','cvp-ha','cvp-perf'] ) :
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -0500213 version_mismatch.append("Job {0} has {1} branch."
Mikhail Kraynove5cc81b2018-10-03 13:01:06 +0400214 "Expected {2}".format(job_name,
Oleksii Zhurbaa25984b2018-06-15 15:30:41 -0500215 actual_version,
216 expected_version))
217 assert len(version_mismatch) == 0, \
218 '''Some DriveTrain jobs have version/branch mismatch:
219 {}'''.format(json.dumps(version_mismatch, indent=4))