Add integration tests for gerrit-slave container
This change adds test, that test whether the container slave correctly
starts up. Most tests are implemented in a scenario using a H2-database,
in which it is tested, whether...
- Gerrit starts successfully
- externally supplied configuration is available in the correct location
- the All-Projects and All-Users repositories are created
- cloning works using a configured port
- the UI is not available
In a second scenario, it is tested, whether the MySQL driver is downloaded,
if MySQL is configured to be used as a database.
Change-Id: Ic3992115482625635532e154c80717def576a1e4
diff --git a/tests/container-images/gerrit-slave/test_container_integration_gerrit_slave.py b/tests/container-images/gerrit-slave/test_container_integration_gerrit_slave.py
new file mode 100644
index 0000000..972205e
--- /dev/null
+++ b/tests/container-images/gerrit-slave/test_container_integration_gerrit_slave.py
@@ -0,0 +1,198 @@
+# pylint: disable=W0613
+
+# Copyright (C) 2018 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.
+
+from glob import glob
+
+import os
+import os.path
+import re
+import time
+
+import git
+import pytest
+import requests
+
+CONFIG_FILES = ["gerrit.config", "secure.config"]
+
+class GerritSlaveTestSetup():
+
+ def __init__(self, docker_client, docker_network, tmp_dir, image,
+ gerrit_config, port):
+ self.docker_client = docker_client
+ self.docker_network = docker_network
+ self.tmp_dir = tmp_dir
+ self.image = image
+ self.gerrit_config = gerrit_config
+ self.port = port
+
+ self.gerrit_container = None
+
+ self._start_gerrit_container()
+
+ def _create_config_files(self):
+ tmp_config_dir = os.path.join(self.tmp_dir, "configs")
+ if not os.path.isdir(tmp_config_dir):
+ os.mkdir(tmp_config_dir)
+ configs = {}
+ for config in CONFIG_FILES:
+ gerrit_config_file = os.path.join(tmp_config_dir, config)
+ with open(gerrit_config_file, "w") as config_file:
+ config_file.write(self.gerrit_config)
+ configs[config] = gerrit_config_file
+ return configs
+
+ def _define_volume_mounts(self):
+ volumes = {v: {
+ "bind": "/var/config/%s" % k,
+ "mode": "rw"
+ } for (k, v) in self._create_config_files().items()}
+ volumes[os.path.join(self.tmp_dir, "lib")] = {
+ "bind": "/var/gerrit/lib",
+ "mode": "rw"
+ }
+ return volumes
+
+ def _start_gerrit_container(self):
+ self.gerrit_container = self.docker_client.containers.run(
+ image=self.image.id,
+ user="gerrit",
+ volumes=self._define_volume_mounts(),
+ ports={
+ str(self.port): str(self.port)
+ },
+ network=self.docker_network.name,
+ detach=True,
+ auto_remove=True
+ )
+
+ def stop_gerrit_container(self):
+ self.gerrit_container.stop(timeout=1)
+
+
+@pytest.fixture(scope="module")
+def tmp_dir(tmp_path_factory):
+ return tmp_path_factory.mktemp("gerrit-slave-test")
+
+@pytest.fixture(scope="class")
+def container_run_h2(request, docker_client, docker_network, tmp_dir,
+ gerrit_slave_image):
+ config = """
+ [gerrit]
+ basePath = git
+
+ [database]
+ type = H2
+
+ [httpd]
+ listenUrl = http://*:8081
+
+ [container]
+ slave = true
+
+ [test]
+ success = True
+ """
+ test_setup = GerritSlaveTestSetup(
+ docker_client, docker_network, tmp_dir, gerrit_slave_image, config, 8081)
+
+ request.addfinalizer(test_setup.stop_gerrit_container)
+
+ return test_setup.gerrit_container
+
+@pytest.fixture(scope="class")
+def container_run_mysql(request, docker_client, docker_network, tmp_dir,
+ gerrit_slave_image):
+ config = """
+ [gerrit]
+ basePath = git
+
+ [database]
+ type = MySQL
+
+ [httpd]
+ listenUrl = http://*:8082
+
+ [container]
+ slave = true
+ """
+ test_setup = GerritSlaveTestSetup(
+ docker_client, docker_network, tmp_dir, gerrit_slave_image, config, 8082)
+
+ request.addfinalizer(test_setup.stop_gerrit_container)
+
+ return test_setup.gerrit_container
+
+@pytest.mark.slow
+@pytest.mark.incremental
+class TestGerritSlaveH2(object):
+
+ @pytest.fixture(params=CONFIG_FILES)
+ def config_file_to_test(self, request):
+ return request.param
+
+ @pytest.fixture(params=["All-Users.git", "All-Projects.git"])
+ def expected_repository(self, request):
+ return request.param
+
+ def test_gerrit_slave_gerrit_starts_up(self, container_run_h2):
+ timeout = time.time() + 60
+ while time.time() < timeout:
+ last_log_line = container_run_h2.logs().decode("utf-8")
+ if re.search(r"Gerrit Code Review .+ ready", last_log_line):
+ break
+ time.sleep(2)
+ assert timeout > time.time()
+
+ def test_gerrit_slave_custom_gerrit_config_available(
+ self, container_run_h2, config_file_to_test):
+ exit_code, output = container_run_h2.exec_run(
+ "git config --file=/var/gerrit/etc/%s --get test.success" % config_file_to_test)
+ output = output.decode("utf-8").strip()
+ assert exit_code == 0
+ assert output == "True"
+
+ def test_gerrit_slave_repository_exists(self, container_run_h2, expected_repository):
+ exit_code, _ = container_run_h2.exec_run(
+ "test -d /var/gerrit/git/%s" % expected_repository)
+ assert exit_code == 0
+
+ def test_gerrit_slave_clone_repo_works(self, container_run_h2, tmp_path_factory):
+ container_run_h2.exec_run("git init --bare /var/gerrit/git/test.git")
+ clone_dest = tmp_path_factory.mktemp("gerrit_slave_clone_test")
+ repo = git.Repo.clone_from("http://localhost:8081/test.git", clone_dest)
+ assert repo.git_dir == os.path.join(clone_dest, ".git")
+
+ def test_gerrit_slave_webui_not_accessible(self, container_run_h2):
+ response = requests.get("http://localhost:8081")
+ assert response.status_code == 404
+ assert response.text == "Not Found"
+
+
+@pytest.mark.slow
+def test_gerrit_slave_downloads_mysql_driver(container_run_mysql, tmp_dir):
+ timeout = time.time() + 20
+ while time.time() < timeout:
+ _, output = container_run_mysql.exec_run(
+ "find /var/gerrit/lib -name 'mysql-connector-java-*.jar'")
+ output = output.decode("utf-8").strip()
+ if re.match(r"/var/gerrit/lib/mysql-connector-java-.*\.jar", output):
+ break
+
+ assert timeout > time.time()
+
+ driver_path_pattern = os.path.join(tmp_dir, "lib", "mysql-connector-java-*.jar")
+ lib_files = [f for f in glob(driver_path_pattern) if os.path.isfile(f)]
+ assert lib_files