Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 1 | import git |
Mikhail Kraynov | e5cc81b | 2018-10-03 13:01:06 +0400 | [diff] [blame] | 2 | import jenkins |
Oleksii Zhurba | a25984b | 2018-06-15 15:30:41 -0500 | [diff] [blame] | 3 | import json |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 4 | import logging |
| 5 | import os |
Oleksii Zhurba | a25984b | 2018-06-15 15:30:41 -0500 | [diff] [blame] | 6 | import pytest |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 7 | import time |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 8 | import utils |
| 9 | from builtins import range |
| 10 | from ldap3 import ( |
| 11 | Connection, |
| 12 | Server, |
| 13 | Reader, |
| 14 | LDIF, |
| 15 | MODIFY_ADD, |
| 16 | MODIFY_DELETE, |
| 17 | SUBTREE, |
| 18 | ALL_ATTRIBUTES) |
| 19 | from ldap3.core.exceptions import LDAPException |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 20 | from pygerrit2 import GerritRestAPI, HTTPBasicAuth |
| 21 | from requests import HTTPError |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 22 | from xml.dom import minidom |
Ievgeniia Zadorozhna | 4f47044 | 2020-01-09 13:22:14 +0200 | [diff] [blame] | 23 | from collections import defaultdict |
Hanna Arhipova | e792be5 | 2019-02-13 13:28:11 +0200 | [diff] [blame] | 24 | |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 25 | |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 26 | def join_to_gerrit(local_salt_client, gerrit_user, gerrit_password): |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 27 | # Workaround for issue in test_drivetrain.join_to_jenkins https://github.com/kennethreitz/requests/issues/3829 |
| 28 | os.environ["PYTHONHTTPSVERIFY"] = "0" |
| 29 | |
| 30 | pytest.gerrit_port = local_salt_client.pillar_get( |
Oleksii Zhurba | 4bfd2ee | 2019-04-10 21:56:58 -0500 | [diff] [blame] | 31 | tgt='I@gerrit:client and not I@salt:master', |
| 32 | param='_param:haproxy_gerrit_bind_port', |
| 33 | expr_form='compound') |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 34 | pytest.gerrit_address = local_salt_client.pillar_get( |
Oleksii Zhurba | 4bfd2ee | 2019-04-10 21:56:58 -0500 | [diff] [blame] | 35 | tgt='I@gerrit:client and not I@salt:master', |
| 36 | param='_param:haproxy_gerrit_bind_host', |
| 37 | expr_form='compound') |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 38 | |
| 39 | pytest.gerrit_protocol = local_salt_client.pillar_get( |
| 40 | tgt='I@gerrit:client and not I@salt:master', |
| 41 | param="gerrit:client:server:protocol", |
| 42 | expr_form='compound') |
| 43 | |
| 44 | gerrit_url = '{protocol}://{address}:{port}'.format( |
| 45 | protocol=pytest.gerrit_protocol, |
| 46 | address=pytest.gerrit_address, |
| 47 | port=pytest.gerrit_port) |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 48 | auth = HTTPBasicAuth(gerrit_user, gerrit_password) |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 49 | rest = GerritRestAPI(url=gerrit_url, auth=auth) |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 50 | return rest |
Oleksii Zhurba | a25984b | 2018-06-15 15:30:41 -0500 | [diff] [blame] | 51 | |
Hanna Arhipova | e792be5 | 2019-02-13 13:28:11 +0200 | [diff] [blame] | 52 | |
Mikhail Kraynov | e5cc81b | 2018-10-03 13:01:06 +0400 | [diff] [blame] | 53 | def join_to_jenkins(local_salt_client, jenkins_user, jenkins_password): |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 54 | |
| 55 | pytest.jenkins_port = local_salt_client.pillar_get( |
Oleksii Zhurba | 4bfd2ee | 2019-04-10 21:56:58 -0500 | [diff] [blame] | 56 | tgt='I@jenkins:client and not I@salt:master', |
| 57 | param='_param:haproxy_jenkins_bind_port', |
| 58 | expr_form='compound') |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 59 | pytest.jenkins_address = local_salt_client.pillar_get( |
Oleksii Zhurba | 4bfd2ee | 2019-04-10 21:56:58 -0500 | [diff] [blame] | 60 | tgt='I@jenkins:client and not I@salt:master', |
| 61 | param='_param:haproxy_jenkins_bind_host', |
| 62 | expr_form='compound') |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 63 | pytest.jenkins_protocol = local_salt_client.pillar_get( |
| 64 | tgt='I@gerrit:client and not I@salt:master', |
| 65 | param="_param:jenkins_master_protocol", |
| 66 | expr_form='compound') |
| 67 | |
| 68 | jenkins_url = '{protocol}://{address}:{port}'.format( |
| 69 | protocol=pytest.jenkins_protocol, |
| 70 | address=pytest.jenkins_address, |
| 71 | port=pytest.jenkins_port) |
Mikhail Kraynov | e5cc81b | 2018-10-03 13:01:06 +0400 | [diff] [blame] | 72 | server = jenkins.Jenkins(jenkins_url, username=jenkins_user, password=jenkins_password) |
| 73 | return server |
| 74 | |
Hanna Arhipova | e792be5 | 2019-02-13 13:28:11 +0200 | [diff] [blame] | 75 | |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 76 | def get_password(local_salt_client,service): |
Oleksii Zhurba | 4bfd2ee | 2019-04-10 21:56:58 -0500 | [diff] [blame] | 77 | password = local_salt_client.pillar_get( |
| 78 | tgt=service, |
| 79 | param='_param:openldap_admin_password') |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 80 | return password |
| 81 | |
Hanna Arhipova | e792be5 | 2019-02-13 13:28:11 +0200 | [diff] [blame] | 82 | |
Oleksii Zhurba | 5b15b9b | 2019-05-09 18:53:40 -0500 | [diff] [blame] | 83 | @pytest.mark.full |
Hanna Arhipova | b7e866c | 2019-04-10 13:49:56 +0300 | [diff] [blame] | 84 | def test_drivetrain_gerrit(local_salt_client, check_cicd): |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 85 | |
| 86 | gerrit_password = get_password(local_salt_client, 'gerrit:client') |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 87 | gerrit_error = '' |
| 88 | current_date = time.strftime("%Y%m%d-%H.%M.%S", time.localtime()) |
| 89 | test_proj_name = "test-dt-{0}".format(current_date) |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 90 | |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 91 | try: |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 92 | # Connecting to gerrit and check connection |
| 93 | server = join_to_gerrit(local_salt_client, 'admin', gerrit_password) |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 94 | gerrit_check = server.get("/changes/?q=owner:self%20status:open") |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 95 | # Check deleteproject plugin and skip test if the plugin is not installed |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 96 | gerrit_plugins = server.get("/plugins/?all") |
| 97 | if 'deleteproject' not in gerrit_plugins: |
| 98 | pytest.skip("Delete-project plugin is not installed") |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 99 | # Create test project and add description |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 100 | server.put("/projects/"+test_proj_name) |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 101 | server.put("/projects/"+test_proj_name+"/description", |
| 102 | json={"description": "Test DriveTrain project", "commit_message": "Update the project description"}) |
Hanna Arhipova | 56eab94 | 2019-05-06 20:14:18 +0300 | [diff] [blame] | 103 | except HTTPError as e: |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 104 | gerrit_error = e |
| 105 | try: |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 106 | # Create test folder and init git |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 107 | repo_dir = os.path.join(os.getcwd(),test_proj_name) |
| 108 | file_name = os.path.join(repo_dir, current_date) |
| 109 | repo = git.Repo.init(repo_dir) |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 110 | # Add remote url for this git repo |
| 111 | origin = repo.create_remote('origin', '{http}://admin:{password}@{address}:{port}/{project}.git'.format( |
| 112 | project=test_proj_name, |
| 113 | password=gerrit_password, |
| 114 | http=pytest.gerrit_protocol, |
| 115 | address=pytest.gerrit_address, |
| 116 | port=pytest.gerrit_port)) |
| 117 | # Add commit-msg hook to automatically add Change-Id to our commit |
| 118 | os.system("curl -Lo {repo}/.git/hooks/commit-msg '{http}://admin:{password}@{address}:{port}/tools/hooks/commit-msg' > /dev/null 2>&1".format( |
| 119 | repo=repo_dir, |
| 120 | password=gerrit_password, |
| 121 | address=pytest.gerrit_address, |
| 122 | http=pytest.gerrit_protocol, |
| 123 | port=pytest.gerrit_port)) |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 124 | os.system("chmod u+x {0}/.git/hooks/commit-msg".format(repo_dir)) |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 125 | # Create a test file |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 126 | f = open(file_name, 'w+') |
| 127 | f.write("This is a test file for DriveTrain test") |
| 128 | f.close() |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 129 | # Add file to git and commit it to Gerrit for review |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 130 | repo.index.add([file_name]) |
| 131 | repo.index.commit("This is a test commit for DriveTrain test") |
| 132 | repo.git.push("origin", "HEAD:refs/for/master") |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 133 | # Get change id from Gerrit. Set Code-Review +2 and submit this change |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 134 | changes = server.get("/changes/?q=project:{0}".format(test_proj_name)) |
| 135 | last_change = changes[0].get('change_id') |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 136 | server.post("/changes/{0}/revisions/1/review".format(last_change), json={"message": "All is good","labels":{"Code-Review":"+2"}}) |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 137 | server.post("/changes/{0}/submit".format(last_change)) |
Hanna Arhipova | 56eab94 | 2019-05-06 20:14:18 +0300 | [diff] [blame] | 138 | except HTTPError as e: |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 139 | gerrit_error = e |
| 140 | finally: |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 141 | # Delete test project |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 142 | server.post("/projects/"+test_proj_name+"/deleteproject~delete") |
Dmitriy Kruglov | a34a304 | 2019-08-20 11:45:35 +0200 | [diff] [blame] | 143 | assert gerrit_error == '', ( |
| 144 | 'There is an error during Gerrit operations:\n{}'.format(gerrit_error)) |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 145 | |
Hanna Arhipova | e792be5 | 2019-02-13 13:28:11 +0200 | [diff] [blame] | 146 | |
Oleksii Zhurba | 5b15b9b | 2019-05-09 18:53:40 -0500 | [diff] [blame] | 147 | @pytest.mark.full |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 148 | @pytest.mark.skip |
| 149 | # Temporary skipped, ldap3 package add\search user is not working |
Hanna Arhipova | b7e866c | 2019-04-10 13:49:56 +0300 | [diff] [blame] | 150 | def test_drivetrain_openldap(local_salt_client, check_cicd): |
Hanna Arhipova | 16a8f41 | 2019-04-08 17:10:38 +0300 | [diff] [blame] | 151 | """ |
| 152 | 1. Create a test user 'DT_test_user' in openldap |
| 153 | 2. Add the user to admin group |
| 154 | 3. Login using the user to Jenkins |
| 155 | 4. Check that no error occurred |
| 156 | 5. Add the user to devops group in Gerrit and then login to Gerrit |
| 157 | using test_user credentials. |
| 158 | 6 Start job in jenkins from this user |
| 159 | 7. Get info from gerrit from this user |
| 160 | 6. Finally, delete the user from admin |
| 161 | group and openldap |
| 162 | """ |
| 163 | |
| 164 | # TODO split to several test cases. One check - per one test method. Make the login process in fixture |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 165 | ldap_password = get_password(local_salt_client, 'openldap:client') |
| 166 | # Check that ldap_password is exists, otherwise skip test |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 167 | if not ldap_password: |
| 168 | pytest.skip("Openldap service or openldap:client pillar \ |
| 169 | are not found on this environment.") |
Oleksii Zhurba | 4bfd2ee | 2019-04-10 21:56:58 -0500 | [diff] [blame] | 170 | ldap_port = local_salt_client.pillar_get( |
| 171 | tgt='I@openldap:client and not I@salt:master', |
| 172 | param='_param:haproxy_openldap_bind_port', |
| 173 | expr_form='compound') |
| 174 | ldap_address = local_salt_client.pillar_get( |
| 175 | tgt='I@openldap:client and not I@salt:master', |
| 176 | param='_param:haproxy_openldap_bind_host', |
| 177 | expr_form='compound') |
| 178 | ldap_dc = local_salt_client.pillar_get( |
| 179 | tgt='openldap:client', |
| 180 | param='_param:openldap_dn') |
| 181 | ldap_con_admin = local_salt_client.pillar_get( |
| 182 | tgt='openldap:client', |
| 183 | param='openldap:client:server:auth:user') |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 184 | ldap_url = 'ldap://{0}:{1}'.format(ldap_address, ldap_port) |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 185 | ldap_error = '' |
| 186 | ldap_result = '' |
| 187 | gerrit_result = '' |
| 188 | gerrit_error = '' |
| 189 | jenkins_error = '' |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 190 | # Test user's CN |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 191 | test_user_name = 'DT_test_user' |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 192 | test_user = 'cn={0},ou=people,{1}'.format(test_user_name, ldap_dc) |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 193 | # Admins group CN |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 194 | admin_gr_dn = 'cn=admins,ou=groups,{0}'.format(ldap_dc) |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 195 | user_pass = 'aSecretPassw' |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 196 | # List of attributes for test user |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 197 | attrs = {} |
Hanna Arhipova | 16a8f41 | 2019-04-08 17:10:38 +0300 | [diff] [blame] | 198 | attrs['objectclass'] = ['organizationalRole', 'simpleSecurityObject', 'shadowAccount'] |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 199 | attrs['cn'] = test_user_name |
| 200 | attrs['uid'] = test_user_name |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 201 | attrs['userPassword'] = user_pass |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 202 | attrs['description'] = 'Test user for CVP DT test' |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 203 | # search_filter = '(cn={0})'.format(test_user_name) |
| 204 | search_filter = '(cn={})'.format(test_user_name) |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 205 | # Get a test job name from config |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 206 | config = utils.get_configuration() |
mkraynov | 058ee12 | 2018-11-30 13:15:49 +0400 | [diff] [blame] | 207 | jenkins_cvp_job = config['jenkins_cvp_job'] |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 208 | logging.warning('test_user: {}'.format(test_user)) |
| 209 | logging.warning('ldap_address: {}'.format(ldap_address)) |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 210 | # Open connection to ldap and creating test user in admins group |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 211 | try: |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 212 | ldap_server = Server(host=ldap_address, port=ldap_port, |
| 213 | use_ssl=False, get_info='NO_INFO') |
| 214 | conn = Connection(ldap_server, client_strategy=LDIF) |
| 215 | conn.bind() |
| 216 | new_user = conn.add(test_user, test_user_name, attrs) |
| 217 | logging.warning('new_user: {}'.format(new_user)) |
| 218 | conn.modify(admin_gr_dn, |
| 219 | {'memberUid': (MODIFY_ADD, [test_user_name]) |
| 220 | }) |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 221 | # Check search test user in LDAP |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 222 | conn2 = Connection(ldap_server) |
| 223 | conn2.bind() |
| 224 | ldap_result = conn2.search(search_base='dc=heat-cicd-queens-contrail41-sl,dc=local', |
| 225 | search_filter=search_filter, search_scope='SUBTREE', attributes=['cn']) |
| 226 | logging.warning('ldap_result: {}'.format(ldap_result)) |
| 227 | logging.warning('conn2.entries.: {}'.format(conn2.entries)) |
| 228 | except LDAPException as e: |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 229 | ldap_error = e |
| 230 | try: |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 231 | # Check if user is created before connect from Jenkins |
| 232 | assert ldap_result, "Test user {} is not found".format(ldap_result) |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 233 | # Check connection between Jenkins and LDAP |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 234 | jenkins_server = join_to_jenkins(local_salt_client, test_user_name, user_pass) |
mkraynov | 058ee12 | 2018-11-30 13:15:49 +0400 | [diff] [blame] | 235 | jenkins_version = jenkins_server.get_job_name(jenkins_cvp_job) |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 236 | # Check connection between Gerrit and LDAP |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 237 | gerrit_server = join_to_gerrit(local_salt_client, 'admin', ldap_password) |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 238 | gerrit_check = gerrit_server.get("/changes/?q=owner:self%20status:open") |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 239 | # Add test user to devops-contrib group in Gerrit and check login |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 240 | _link = "/groups/devops-contrib/members/{0}".format(test_user_name) |
| 241 | gerrit_add_user = gerrit_server.put(_link) |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 242 | gerrit_server = join_to_gerrit(local_salt_client, test_user_name, user_pass) |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 243 | gerrit_result = gerrit_server.get("/changes/?q=owner:self%20status:open") |
Hanna Arhipova | 56eab94 | 2019-05-06 20:14:18 +0300 | [diff] [blame] | 244 | except HTTPError as e: |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 245 | gerrit_error = e |
Hanna Arhipova | 56eab94 | 2019-05-06 20:14:18 +0300 | [diff] [blame] | 246 | except jenkins.JenkinsException as e: |
mkraynov | 360c30d | 2018-09-27 17:02:45 +0400 | [diff] [blame] | 247 | jenkins_error = e |
| 248 | finally: |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 249 | conn.modify(admin_gr_dn, |
| 250 | {'memberUid': (MODIFY_DELETE, [test_user_name]) |
| 251 | }) |
| 252 | conn.delete(test_user) |
| 253 | conn.unbind() |
| 254 | conn2.unbind() |
| 255 | |
Dmitriy Kruglov | a34a304 | 2019-08-20 11:45:35 +0200 | [diff] [blame] | 256 | assert ldap_error == '', ( |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 257 | "There is an error with connection to LDAP:\n{}".format(ldap_error)) |
Dmitriy Kruglov | a34a304 | 2019-08-20 11:45:35 +0200 | [diff] [blame] | 258 | assert jenkins_error == '', ( |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 259 | "Connection to Jenkins is not established:\n{}".format(jenkins_error)) |
Dmitriy Kruglov | a34a304 | 2019-08-20 11:45:35 +0200 | [diff] [blame] | 260 | assert gerrit_error == '', ( |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 261 | "Connection to Gerrit is not established:\n{}".format(gerrit_error)) |
| 262 | |
Mikhail Kraynov | 351e841 | 2018-10-04 18:27:44 +0400 | [diff] [blame] | 263 | |
Hanna Arhipova | e792be5 | 2019-02-13 13:28:11 +0200 | [diff] [blame] | 264 | |
Oleksii Zhurba | 5b15b9b | 2019-05-09 18:53:40 -0500 | [diff] [blame] | 265 | @pytest.mark.sl_dup |
| 266 | #DockerService***Outage |
| 267 | @pytest.mark.full |
Oleksii Zhurba | 67aaec9 | 2019-04-15 18:05:13 -0500 | [diff] [blame] | 268 | def test_drivetrain_services_replicas(local_salt_client, check_cicd): |
Hanna Arhipova | 16a8f41 | 2019-04-08 17:10:38 +0300 | [diff] [blame] | 269 | """ |
| 270 | # Execute ` salt -C 'I@gerrit:client' cmd.run 'docker service ls'` command to get info for each docker service like that: |
| 271 | "x5nzktxsdlm6 jenkins_slave02 replicated 0/1 docker-prod-local.artifactory.mirantis.com/mirantis/cicd/jnlp-slave:2019.2.0 " |
| 272 | # Check that each service has all replicas |
| 273 | """ |
Hanna Arhipova | f2660bd | 2019-02-08 17:25:39 +0200 | [diff] [blame] | 274 | # TODO: replace with rerunfalures plugin |
Hanna Arhipova | 16a8f41 | 2019-04-08 17:10:38 +0300 | [diff] [blame] | 275 | wrong_items = [] |
Hanna Arhipova | f2660bd | 2019-02-08 17:25:39 +0200 | [diff] [blame] | 276 | for _ in range(4): |
Hanna Arhipova | 16a8f41 | 2019-04-08 17:10:38 +0300 | [diff] [blame] | 277 | docker_services_by_nodes = local_salt_client.cmd( |
Oleksii Zhurba | 4bfd2ee | 2019-04-10 21:56:58 -0500 | [diff] [blame] | 278 | tgt='I@gerrit:client', |
| 279 | param='docker service ls', |
Hanna Arhipova | f2660bd | 2019-02-08 17:25:39 +0200 | [diff] [blame] | 280 | expr_form='compound') |
| 281 | wrong_items = [] |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 282 | for line in docker_services_by_nodes[list(docker_services_by_nodes.keys())[0]].split('\n'): |
Hanna Arhipova | f2660bd | 2019-02-08 17:25:39 +0200 | [diff] [blame] | 283 | if line[line.find('/') - 1] != line[line.find('/') + 1] \ |
| 284 | and 'replicated' in line: |
| 285 | wrong_items.append(line) |
| 286 | if len(wrong_items) == 0: |
| 287 | break |
| 288 | else: |
Hanna Arhipova | f2660bd | 2019-02-08 17:25:39 +0200 | [diff] [blame] | 289 | time.sleep(5) |
Dmitriy Kruglov | a34a304 | 2019-08-20 11:45:35 +0200 | [diff] [blame] | 290 | assert len(wrong_items) == 0, ( |
| 291 | "Some DriveTrain services don't have expected number of replicas:\n" |
| 292 | "{}".format(json.dumps(wrong_items, indent=4)) |
| 293 | ) |
Oleksii Zhurba | a25984b | 2018-06-15 15:30:41 -0500 | [diff] [blame] | 294 | |
| 295 | |
Oleksii Zhurba | 5b15b9b | 2019-05-09 18:53:40 -0500 | [diff] [blame] | 296 | @pytest.mark.full |
Hanna Arhipova | b7e866c | 2019-04-10 13:49:56 +0300 | [diff] [blame] | 297 | def test_drivetrain_components_and_versions(local_salt_client, check_cicd): |
Oleksii Zhurba | b91c314 | 2019-03-26 16:49:44 -0500 | [diff] [blame] | 298 | """ |
Hanna Arhipova | 16a8f41 | 2019-04-08 17:10:38 +0300 | [diff] [blame] | 299 | 1. Execute command `docker service ls --format "{{.Image}}"'` on the 'I@gerrit:client' target |
| 300 | 2. Execute ` salt -C 'I@gerrit:client' pillar.get docker:client:images` |
| 301 | 3. Check that list of images from step 1 is the same as a list from the step2 |
| 302 | 4. Check that all docker services has label that equals to mcp_version |
| 303 | |
| 304 | """ |
Hanna Arhipova | 04344f1 | 2019-06-12 13:56:36 +0300 | [diff] [blame] | 305 | def get_name(long_name): |
| 306 | return long_name.rsplit(':', 1)[0] |
| 307 | |
| 308 | def get_tag(long_name): |
| 309 | return long_name.rsplit(':', 1)[-1] |
| 310 | |
Oleksii Zhurba | 4bfd2ee | 2019-04-10 21:56:58 -0500 | [diff] [blame] | 311 | table_with_docker_services = local_salt_client.cmd(tgt='I@gerrit:client', |
| 312 | param='docker service ls --format "{{.Image}}"', |
Hanna Arhipova | e792be5 | 2019-02-13 13:28:11 +0200 | [diff] [blame] | 313 | expr_form='compound') |
Hanna Arhipova | 8cc3a98 | 2019-07-22 14:58:03 +0300 | [diff] [blame] | 314 | stack_info = local_salt_client.pillar_get(tgt='gerrit:client', |
| 315 | param='docker:client:stack') |
| 316 | |
Ievgeniia Zadorozhna | 4f47044 | 2020-01-09 13:22:14 +0200 | [diff] [blame] | 317 | expected_images_list = list() |
Hanna Arhipova | 8cc3a98 | 2019-07-22 14:58:03 +0300 | [diff] [blame] | 318 | # find services in list of docker clients |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 319 | for key, stack in list(stack_info.items()): |
Hanna Arhipova | 8cc3a98 | 2019-07-22 14:58:03 +0300 | [diff] [blame] | 320 | if stack.get('service'): |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 321 | stack = [item.get('image') for _,item in list(stack.get('service').items()) if item.get('image')] |
Ievgeniia Zadorozhna | 4f47044 | 2020-01-09 13:22:14 +0200 | [diff] [blame] | 322 | expected_images_list += stack |
| 323 | expected_images = defaultdict(list) |
Hanna Arhipova | 8cc3a98 | 2019-07-22 14:58:03 +0300 | [diff] [blame] | 324 | |
Ievgeniia Zadorozhna | 4f47044 | 2020-01-09 13:22:14 +0200 | [diff] [blame] | 325 | # collect unique tags for each image in same structure as for actual images |
| 326 | for image in expected_images_list: |
| 327 | if get_name(image) in expected_images: |
| 328 | if get_tag(image) not in expected_images[get_name(image)]: |
| 329 | expected_images[get_name(image)].append(get_tag(image)) |
| 330 | else: |
| 331 | expected_images[get_name(image)].append(get_tag(image)) |
| 332 | |
| 333 | # collect tags for each image in same structure as for expected images |
| 334 | actual_images = defaultdict(list) |
Ekaterina Chernova | e32e3f9 | 2019-11-12 14:56:03 +0300 | [diff] [blame] | 335 | for image in set(table_with_docker_services[list(table_with_docker_services.keys())[0]].split('\n')): |
Ievgeniia Zadorozhna | 4f47044 | 2020-01-09 13:22:14 +0200 | [diff] [blame] | 336 | actual_images[get_name(image)].append(get_tag(image)) |
Hanna Arhipova | 8cc3a98 | 2019-07-22 14:58:03 +0300 | [diff] [blame] | 337 | |
Ievgeniia Zadorozhna | 4f47044 | 2020-01-09 13:22:14 +0200 | [diff] [blame] | 338 | # find difference between defaultdicts |
| 339 | total_diff = 0 |
| 340 | for i in expected_images: |
| 341 | diff = set(expected_images[i]) - set(actual_images[i]) |
| 342 | total_diff += len(diff) |
| 343 | |
| 344 | assert actual_images == expected_images, ( |
Dmitriy Kruglov | a34a304 | 2019-08-20 11:45:35 +0200 | [diff] [blame] | 345 | "Some DriveTrain components do not have expected versions:\n{}".format( |
Ievgeniia Zadorozhna | 4f47044 | 2020-01-09 13:22:14 +0200 | [diff] [blame] | 346 | json.dumps(total_diff, indent=4)) |
Dmitriy Kruglov | a34a304 | 2019-08-20 11:45:35 +0200 | [diff] [blame] | 347 | ) |
Oleksii Zhurba | a25984b | 2018-06-15 15:30:41 -0500 | [diff] [blame] | 348 | |
| 349 | |
Oleksii Zhurba | 5b15b9b | 2019-05-09 18:53:40 -0500 | [diff] [blame] | 350 | @pytest.mark.full |
Oleksii Zhurba | 67aaec9 | 2019-04-15 18:05:13 -0500 | [diff] [blame] | 351 | def test_jenkins_jobs_branch(local_salt_client, check_cicd): |
Oleksii Zhurba | d52b5fe | 2019-03-28 11:11:35 -0500 | [diff] [blame] | 352 | """ This test compares Jenkins jobs versions |
| 353 | collected from the cloud vs collected from pillars. |
| 354 | """ |
Hanna Arhipova | 91dc815 | 2019-07-04 12:43:16 +0300 | [diff] [blame] | 355 | |
Oleksii Zhurba | 4bfd2ee | 2019-04-10 21:56:58 -0500 | [diff] [blame] | 356 | excludes = ['upgrade-mcp-release', 'deploy-update-salt', |
| 357 | 'git-mirror-downstream-mk-pipelines', |
| 358 | 'git-mirror-downstream-pipeline-library'] |
Hanna Arhipova | 6f34fbb | 2019-02-08 11:19:41 +0200 | [diff] [blame] | 359 | |
Oleksii Zhurba | a25984b | 2018-06-15 15:30:41 -0500 | [diff] [blame] | 360 | config = utils.get_configuration() |
Hanna Arhipova | 6f34fbb | 2019-02-08 11:19:41 +0200 | [diff] [blame] | 361 | drivetrain_version = config.get('drivetrain_version', '') |
Hanna Arhipova | e792be5 | 2019-02-13 13:28:11 +0200 | [diff] [blame] | 362 | jenkins_password = get_password(local_salt_client, 'jenkins:client') |
Oleksii Zhurba | a25984b | 2018-06-15 15:30:41 -0500 | [diff] [blame] | 363 | version_mismatch = [] |
Hanna Arhipova | e792be5 | 2019-02-13 13:28:11 +0200 | [diff] [blame] | 364 | server = join_to_jenkins(local_salt_client, 'admin', jenkins_password) |
Mikhail Kraynov | e5cc81b | 2018-10-03 13:01:06 +0400 | [diff] [blame] | 365 | for job_instance in server.get_jobs(): |
| 366 | job_name = job_instance.get('name') |
Hanna Arhipova | 6f34fbb | 2019-02-08 11:19:41 +0200 | [diff] [blame] | 367 | if job_name in excludes: |
| 368 | continue |
| 369 | |
Mikhail Kraynov | e5cc81b | 2018-10-03 13:01:06 +0400 | [diff] [blame] | 370 | job_config = server.get_job_config(job_name) |
Oleksii Zhurba | a25984b | 2018-06-15 15:30:41 -0500 | [diff] [blame] | 371 | xml_data = minidom.parseString(job_config) |
| 372 | BranchSpec = xml_data.getElementsByTagName('hudson.plugins.git.BranchSpec') |
Hanna Arhipova | 6f34fbb | 2019-02-08 11:19:41 +0200 | [diff] [blame] | 373 | |
| 374 | # We use master branch for pipeline-library in case of 'testing,stable,nighlty' versions |
| 375 | # Leave proposed version as is |
| 376 | # in other cases we get release/{drivetrain_version} (e.g release/2019.2.0) |
Hanna Arhipova | 16a8f41 | 2019-04-08 17:10:38 +0300 | [diff] [blame] | 377 | if drivetrain_version in ['testing', 'nightly', 'stable']: |
Mikhail Kraynov | e5cc81b | 2018-10-03 13:01:06 +0400 | [diff] [blame] | 378 | expected_version = 'master' |
Hanna Arhipova | 6f34fbb | 2019-02-08 11:19:41 +0200 | [diff] [blame] | 379 | else: |
Oleksii Zhurba | 4bfd2ee | 2019-04-10 21:56:58 -0500 | [diff] [blame] | 380 | expected_version = local_salt_client.pillar_get( |
| 381 | tgt='gerrit:client', |
| 382 | param='jenkins:client:job:{}:scm:branch'.format(job_name)) |
Hanna Arhipova | 6f34fbb | 2019-02-08 11:19:41 +0200 | [diff] [blame] | 383 | |
| 384 | if not BranchSpec: |
Hanna Arhipova | 56eab94 | 2019-05-06 20:14:18 +0300 | [diff] [blame] | 385 | logging.debug("No BranchSpec has found for {} job".format(job_name)) |
Hanna Arhipova | 6f34fbb | 2019-02-08 11:19:41 +0200 | [diff] [blame] | 386 | continue |
| 387 | |
| 388 | actual_version = BranchSpec[0].getElementsByTagName('name')[0].childNodes[0].data |
Oleksii Zhurba | 075cc7a | 2019-05-17 14:04:28 -0500 | [diff] [blame] | 389 | if expected_version and actual_version not in expected_version: |
Hanna Arhipova | 6f34fbb | 2019-02-08 11:19:41 +0200 | [diff] [blame] | 390 | version_mismatch.append("Job {0} has {1} branch." |
| 391 | "Expected {2}".format(job_name, |
| 392 | actual_version, |
| 393 | expected_version)) |
Dmitriy Kruglov | a34a304 | 2019-08-20 11:45:35 +0200 | [diff] [blame] | 394 | assert len(version_mismatch) == 0, ( |
| 395 | "Some DriveTrain jobs have version/branch mismatch:\n{}".format( |
| 396 | json.dumps(version_mismatch, indent=4)) |
| 397 | ) |
Hanna Arhipova | 16a8f41 | 2019-04-08 17:10:38 +0300 | [diff] [blame] | 398 | |
| 399 | |
Oleksii Zhurba | 5b15b9b | 2019-05-09 18:53:40 -0500 | [diff] [blame] | 400 | @pytest.mark.full |
Hanna Arhipova | b7e866c | 2019-04-10 13:49:56 +0300 | [diff] [blame] | 401 | def test_drivetrain_jenkins_job(local_salt_client, check_cicd): |
Hanna Arhipova | 16a8f41 | 2019-04-08 17:10:38 +0300 | [diff] [blame] | 402 | """ |
| 403 | # Login to Jenkins on jenkins:client |
| 404 | # Read the name of jobs from configuration 'jenkins_test_job' |
| 405 | # Start job |
| 406 | # Wait till the job completed |
| 407 | # Check that job has completed with "SUCCESS" result |
| 408 | """ |
| 409 | job_result = None |
| 410 | |
| 411 | jenkins_password = get_password(local_salt_client, 'jenkins:client') |
| 412 | server = join_to_jenkins(local_salt_client, 'admin', jenkins_password) |
| 413 | # Getting Jenkins test job name from configuration |
| 414 | config = utils.get_configuration() |
| 415 | jenkins_test_job = config['jenkins_test_job'] |
| 416 | if not server.get_job_name(jenkins_test_job): |
| 417 | server.create_job(jenkins_test_job, jenkins.EMPTY_CONFIG_XML) |
| 418 | if server.get_job_name(jenkins_test_job): |
| 419 | next_build_num = server.get_job_info(jenkins_test_job)['nextBuildNumber'] |
| 420 | # If this is first build number skip building check |
| 421 | if next_build_num != 1: |
| 422 | # Check that test job is not running at this moment, |
| 423 | # Otherwise skip the test |
| 424 | last_build_num = server.get_job_info(jenkins_test_job)['lastBuild'].get('number') |
| 425 | last_build_status = server.get_build_info(jenkins_test_job, last_build_num)['building'] |
| 426 | if last_build_status: |
| 427 | pytest.skip("Test job {0} is already running").format(jenkins_test_job) |
| 428 | server.build_job(jenkins_test_job) |
| 429 | timeout = 0 |
| 430 | # Use job status True by default to exclude timeout between build job and start job. |
| 431 | job_status = True |
| 432 | while job_status and (timeout < 180): |
| 433 | time.sleep(10) |
| 434 | timeout += 10 |
| 435 | job_status = server.get_build_info(jenkins_test_job, next_build_num)['building'] |
| 436 | job_result = server.get_build_info(jenkins_test_job, next_build_num)['result'] |
| 437 | else: |
| 438 | pytest.skip("The job {0} was not found").format(jenkins_test_job) |
Dmitriy Kruglov | a34a304 | 2019-08-20 11:45:35 +0200 | [diff] [blame] | 439 | assert job_result == 'SUCCESS', ( |
| 440 | "Test job '{}' build is not successful or timeout is too " |
| 441 | "small.".format(jenkins_test_job) |
| 442 | ) |