| # pylint: disable=W0613 |
| |
| # Copyright (C) 2019 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| import hashlib |
| import json |
| import os.path |
| import time |
| |
| import pytest |
| import requests |
| |
| from kubernetes import client |
| from kubernetes.stream import stream |
| |
| PLUGINS = ["avatars-gravatar", "readonly"] |
| LIBS = ["global-refdb"] |
| GERRIT_VERSION = "3.8" |
| |
| |
| @pytest.fixture(scope="module") |
| def plugin_list(): |
| plugin_list = [] |
| for plugin in PLUGINS: |
| url = ( |
| f"https://gerrit-ci.gerritforge.com/view/Plugins-stable-{GERRIT_VERSION}/" |
| f"job/plugin-{plugin}-bazel-master-stable-{GERRIT_VERSION}/lastSuccessfulBuild/" |
| f"artifact/bazel-bin/plugins/{plugin}/{plugin}.jar" |
| ) |
| jar = requests.get(url, verify=False).content |
| plugin_list.append( |
| {"name": plugin, "url": url, "sha1": hashlib.sha1(jar).hexdigest()} |
| ) |
| return plugin_list |
| |
| |
| @pytest.fixture(scope="module") |
| def lib_list(): |
| lib_list = [] |
| for lib in LIBS: |
| url = ( |
| f"https://gerrit-ci.gerritforge.com/view/Plugins-stable-{GERRIT_VERSION}/" |
| f"job/module-{lib}-bazel-stable-{GERRIT_VERSION}/lastSuccessfulBuild/" |
| f"artifact/bazel-bin/plugins/{lib}/{lib}.jar" |
| ) |
| jar = requests.get(url, verify=False).content |
| lib_list.append( |
| {"name": lib, "url": url, "sha1": hashlib.sha1(jar).hexdigest()} |
| ) |
| return lib_list |
| |
| |
| @pytest.fixture( |
| scope="class", |
| params=[ |
| [{"name": "replication"}], |
| [{"name": "replication"}, {"name": "download-commands"}], |
| ], |
| ids=["single-packaged-plugin", "multiple-packaged-plugins"], |
| ) |
| def gerrit_deployment_with_packaged_plugins(request, gerrit_deployment): |
| gerrit_deployment.set_helm_value("gerrit.pluginManagement.plugins", request.param) |
| gerrit_deployment.install() |
| gerrit_deployment.create_admin_account() |
| |
| yield gerrit_deployment, request.param |
| |
| |
| @pytest.fixture( |
| scope="class", params=[1, 2], ids=["single-other-plugin", "multiple-other-plugins"] |
| ) |
| def gerrit_deployment_with_other_plugins( |
| request, |
| plugin_list, |
| gerrit_deployment, |
| ): |
| selected_plugins = plugin_list[: request.param] |
| |
| gerrit_deployment.set_helm_value( |
| "gerrit.pluginManagement.plugins", selected_plugins |
| ) |
| |
| gerrit_deployment.install() |
| gerrit_deployment.create_admin_account() |
| |
| yield gerrit_deployment, selected_plugins |
| |
| |
| @pytest.fixture(scope="class") |
| def gerrit_deployment_with_libs( |
| request, |
| lib_list, |
| gerrit_deployment, |
| ): |
| gerrit_deployment.set_helm_value("gerrit.pluginManagement.libs", lib_list) |
| |
| gerrit_deployment.install() |
| gerrit_deployment.create_admin_account() |
| |
| yield gerrit_deployment, lib_list |
| |
| |
| @pytest.fixture(scope="class") |
| def gerrit_deployment_with_other_plugin_wrong_sha(plugin_list, gerrit_deployment): |
| plugin = plugin_list[0] |
| plugin["sha1"] = "notAValidSha" |
| gerrit_deployment.set_helm_value("gerrit.pluginManagement.plugins", [plugin]) |
| |
| gerrit_deployment.install(wait=False) |
| |
| yield gerrit_deployment |
| |
| |
| def get_gerrit_plugin_list(gerrit_url, user="admin", password="secret"): |
| list_plugins_url = f"{gerrit_url}/a/plugins/?all" |
| response = requests.get(list_plugins_url, auth=(user, password)) |
| if not response.status_code == 200: |
| return None |
| body = response.text |
| return json.loads(body[body.index("\n") + 1 :]) |
| |
| |
| def get_gerrit_lib_list(gerrit_deployment): |
| response = ( |
| stream( |
| client.CoreV1Api().connect_get_namespaced_pod_exec, |
| gerrit_deployment.chart_name + "-gerrit-stateful-set-0", |
| gerrit_deployment.namespace, |
| command=["/bin/ash", "-c", "ls /var/gerrit/lib"], |
| stdout=True, |
| ) |
| .strip() |
| .split() |
| ) |
| return [os.path.splitext(r)[0] for r in response] |
| |
| |
| @pytest.mark.slow |
| @pytest.mark.incremental |
| @pytest.mark.integration |
| @pytest.mark.kubernetes |
| class TestgerritChartPackagedPluginInstall: |
| def _assert_installed_plugins(self, expected_plugins, installed_plugins): |
| for plugin in expected_plugins: |
| plugin_name = plugin["name"] |
| assert plugin_name in installed_plugins |
| assert installed_plugins[plugin_name]["filename"] == f"{plugin_name}.jar" |
| |
| @pytest.mark.timeout(300) |
| def test_install_packaged_plugins( |
| self, request, gerrit_deployment_with_packaged_plugins, ldap_credentials |
| ): |
| gerrit_deployment, expected_plugins = gerrit_deployment_with_packaged_plugins |
| response = None |
| while not response: |
| try: |
| response = get_gerrit_plugin_list( |
| f"http://{gerrit_deployment.hostname}", |
| "gerrit-admin", |
| ldap_credentials["gerrit-admin"], |
| ) |
| except requests.exceptions.ConnectionError: |
| time.sleep(1) |
| |
| self._assert_installed_plugins(expected_plugins, response) |
| |
| @pytest.mark.timeout(300) |
| def test_install_packaged_plugins_are_removed_with_update( |
| self, |
| request, |
| test_cluster, |
| gerrit_deployment_with_packaged_plugins, |
| ldap_credentials, |
| ): |
| gerrit_deployment, expected_plugins = gerrit_deployment_with_packaged_plugins |
| removed_plugin = expected_plugins.pop() |
| |
| gerrit_deployment.set_helm_value( |
| "gerrit.pluginManagement.plugins", expected_plugins |
| ) |
| gerrit_deployment.update() |
| |
| response = None |
| while True: |
| try: |
| response = get_gerrit_plugin_list( |
| f"http://{gerrit_deployment.hostname}", |
| "gerrit-admin", |
| ldap_credentials["gerrit-admin"], |
| ) |
| if response is not None and removed_plugin["name"] not in response: |
| break |
| except requests.exceptions.ConnectionError: |
| time.sleep(1) |
| |
| assert removed_plugin["name"] not in response |
| self._assert_installed_plugins(expected_plugins, response) |
| |
| |
| @pytest.mark.slow |
| @pytest.mark.incremental |
| @pytest.mark.integration |
| @pytest.mark.kubernetes |
| class TestGerritChartOtherPluginInstall: |
| def _assert_installed_plugins(self, expected_plugins, installed_plugins): |
| for plugin in expected_plugins: |
| assert plugin["name"] in installed_plugins |
| assert ( |
| installed_plugins[plugin["name"]]["filename"] == f"{plugin['name']}.jar" |
| ) |
| |
| @pytest.mark.timeout(300) |
| def test_install_other_plugins( |
| self, gerrit_deployment_with_other_plugins, ldap_credentials |
| ): |
| gerrit_deployment, expected_plugins = gerrit_deployment_with_other_plugins |
| response = None |
| while not response: |
| try: |
| response = get_gerrit_plugin_list( |
| f"http://{gerrit_deployment.hostname}", |
| "gerrit-admin", |
| ldap_credentials["gerrit-admin"], |
| ) |
| except requests.exceptions.ConnectionError: |
| continue |
| self._assert_installed_plugins(expected_plugins, response) |
| |
| @pytest.mark.timeout(300) |
| def test_install_other_plugins_are_removed_with_update( |
| self, gerrit_deployment_with_other_plugins, ldap_credentials |
| ): |
| gerrit_deployment, installed_plugins = gerrit_deployment_with_other_plugins |
| removed_plugin = installed_plugins.pop() |
| gerrit_deployment.set_helm_value( |
| "gerrit.pluginManagement.plugins", installed_plugins |
| ) |
| gerrit_deployment.update() |
| |
| response = None |
| while True: |
| try: |
| response = get_gerrit_plugin_list( |
| f"http://{gerrit_deployment.hostname}", |
| "gerrit-admin", |
| ldap_credentials["gerrit-admin"], |
| ) |
| if response is not None and removed_plugin["name"] not in response: |
| break |
| except requests.exceptions.ConnectionError: |
| time.sleep(1) |
| |
| assert removed_plugin["name"] not in response |
| self._assert_installed_plugins(installed_plugins, response) |
| |
| |
| @pytest.mark.slow |
| @pytest.mark.incremental |
| @pytest.mark.integration |
| @pytest.mark.kubernetes |
| class TestGerritChartLibModuleInstall: |
| def _assert_installed_libs(self, expected_libs, installed_libs): |
| for lib in expected_libs: |
| assert lib["name"] in installed_libs |
| |
| @pytest.mark.timeout(300) |
| def test_install_libs(self, gerrit_deployment_with_libs): |
| gerrit_deployment, expected_libs = gerrit_deployment_with_libs |
| response = get_gerrit_lib_list(gerrit_deployment) |
| self._assert_installed_libs(expected_libs, response) |
| |
| @pytest.mark.timeout(300) |
| def test_install_other_plugins_are_removed_with_update( |
| self, gerrit_deployment_with_libs |
| ): |
| gerrit_deployment, installed_libs = gerrit_deployment_with_libs |
| removed_lib = installed_libs.pop() |
| gerrit_deployment.set_helm_value("gerrit.pluginManagement.libs", installed_libs) |
| gerrit_deployment.update() |
| |
| response = None |
| while True: |
| try: |
| response = get_gerrit_lib_list(gerrit_deployment) |
| if response is not None and removed_lib["name"] not in response: |
| break |
| except requests.exceptions.ConnectionError: |
| time.sleep(1) |
| |
| assert removed_lib["name"] not in response |
| self._assert_installed_libs(installed_libs, response) |
| |
| |
| @pytest.mark.integration |
| @pytest.mark.kubernetes |
| @pytest.mark.timeout(180) |
| def test_install_other_plugins_fails_wrong_sha( |
| gerrit_deployment_with_other_plugin_wrong_sha, |
| ): |
| pod_labels = f"app.kubernetes.io/component=gerrit,release={gerrit_deployment_with_other_plugin_wrong_sha.chart_name}" |
| core_v1 = client.CoreV1Api() |
| pod_name = "" |
| while not pod_name: |
| pod_list = core_v1.list_namespaced_pod( |
| namespace=gerrit_deployment_with_other_plugin_wrong_sha.namespace, |
| watch=False, |
| label_selector=pod_labels, |
| ) |
| if len(pod_list.items) > 1: |
| raise RuntimeError("Too many gerrit pods with the same release name.") |
| elif len(pod_list.items) == 1: |
| pod_name = pod_list.items[0].metadata.name |
| |
| current_status = None |
| while not current_status: |
| pod = core_v1.read_namespaced_pod_status( |
| pod_name, gerrit_deployment_with_other_plugin_wrong_sha.namespace |
| ) |
| if not pod.status.init_container_statuses: |
| time.sleep(1) |
| continue |
| for init_container_status in pod.status.init_container_statuses: |
| if ( |
| init_container_status.name == "gerrit-init" |
| and init_container_status.last_state.terminated |
| ): |
| current_status = init_container_status |
| assert current_status.last_state.terminated.exit_code > 0 |
| return |
| |
| assert current_status.last_state.terminated.exit_code > 0 |