Merge "Switch to UTF-8 for all container-images"
diff --git a/README.md b/README.md
index 656824f..9cda08a 100644
--- a/README.md
+++ b/README.md
@@ -172,6 +172,9 @@
 pipenv run pytest --skip-slow
 ```
 
+There are also other marks, allowing to select tests (refer to
+[this section](#test-marks)).
+
 To run specific tests, execute one of the following:
 
 ```sh
@@ -184,7 +187,39 @@
 # Run a specific test
 pipenv run \
   pytest tests/container-images/base/test_container_build_base.py::test_build_base
+
+# Run tests with a specific marker
+pipenv run pytest -m "docker"
 ```
 
 For a more detailed description of how to use `pytest`, refer to the
 [official documentation](https://docs.pytest.org/en/latest/contents.html).
+
+## Test marks
+
+### docker
+
+Marks tests which start up docker containers. These tests will interact with
+the containers by either using `docker exec` or sending HTTP-requests. Make
+sure that your system supports this kind of interaction.
+
+### incremental
+
+Marks test classes in which the contained test functions have to run
+incrementally.
+
+### integration
+
+Marks integration tests. These tests test interactions between containers,
+between outside clients and containers and between the components installed
+by a helm chart.
+
+### slow
+
+Marks tests that need an above average time to run.
+
+### structure
+
+Marks structure tests. These tests are meant to test, whether certain components
+exist in a container. These tests ensure that components expected by the users
+of the container, e.g. the helm charts, are present in the containers.
diff --git a/container-images/gerrit-base/Dockerfile b/container-images/gerrit-base/Dockerfile
index f2195a3..ec61049 100644
--- a/container-images/gerrit-base/Dockerfile
+++ b/container-images/gerrit-base/Dockerfile
@@ -11,7 +11,7 @@
     mkdir -p /var/war
 
 # Download Gerrit release
-ARG GERRIT_WAR_URL=https://gerrit-releases.storage.googleapis.com/gerrit-3.0.1.war
+ARG GERRIT_WAR_URL=https://gerrit-releases.storage.googleapis.com/gerrit-3.0.3.war
 RUN curl -k -o /var/war/gerrit.war ${GERRIT_WAR_URL} && \
     ln -s /var/war/gerrit.war /var/gerrit/bin/gerrit.war
 
diff --git a/helm-charts/gerrit-master/Chart.yaml b/helm-charts/gerrit-master/Chart.yaml
index 8217192..f41fa5e 100644
--- a/helm-charts/gerrit-master/Chart.yaml
+++ b/helm-charts/gerrit-master/Chart.yaml
@@ -1,5 +1,5 @@
 apiVersion: v1
-appVersion: 3.0.1
+appVersion: 3.0.3
 description: |-
     Gerrit is a free, web-based team code collaboration tool. Software developers
     in a team can review each other's modifications on their source code using
diff --git a/helm-charts/gerrit-slave/Chart.yaml b/helm-charts/gerrit-slave/Chart.yaml
index f85e02f..d4f202d 100644
--- a/helm-charts/gerrit-slave/Chart.yaml
+++ b/helm-charts/gerrit-slave/Chart.yaml
@@ -1,5 +1,5 @@
 apiVersion: v1
-appVersion: 3.0.1
+appVersion: 3.0.3
 description: |-
     The Gerrit slave serves as a read-only Gerrit instance to serve repositories
     that it receives from a Gerrit master instance via replication. It can be
diff --git a/setup.cfg b/setup.cfg
index 1f82615..7708c62 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,2 +1,9 @@
 [tool:pytest]
-norecursedirs=tests/helpers
+norecursedirs = tests/helpers
+
+markers =
+  docker: Tests that require to run and interact with a docker container
+  incremental: Test classes containing tests that need to run incrementally
+  integration: Integration tests
+  slow: Tests that run slower than the average test
+  structure: Structure tests
diff --git a/tests/container-images/apache-git-http-backend/test_container_build_apache_git_http_backend.py b/tests/container-images/apache-git-http-backend/test_container_build_apache_git_http_backend.py
index d0b0f09..984d6be 100644
--- a/tests/container-images/apache-git-http-backend/test_container_build_apache_git_http_backend.py
+++ b/tests/container-images/apache-git-http-backend/test_container_build_apache_git_http_backend.py
@@ -15,6 +15,7 @@
 import pytest
 
 
+@pytest.mark.structure
 def test_build_apache_git_http_backend_image(
     apache_git_http_backend_image, tag_of_cached_container
 ):
diff --git a/tests/container-images/apache-git-http-backend/test_container_disable_protocol_apache_git_http_backend.py b/tests/container-images/apache-git-http-backend/test_container_disable_protocol_apache_git_http_backend.py
index ad6b4e6..d75d13f 100755
--- a/tests/container-images/apache-git-http-backend/test_container_disable_protocol_apache_git_http_backend.py
+++ b/tests/container-images/apache-git-http-backend/test_container_disable_protocol_apache_git_http_backend.py
@@ -37,6 +37,8 @@
     return container_run, request.param
 
 
+@pytest.mark.docker
+@pytest.mark.integration
 @pytest.mark.slow
 def test_apache_git_http_backend_disable_protocol(
     container_run_with_disabled_protocol,
diff --git a/tests/container-images/apache-git-http-backend/test_container_integration_apache_git_http_backend.py b/tests/container-images/apache-git-http-backend/test_container_integration_apache_git_http_backend.py
index 6bc4416..8a3efde 100755
--- a/tests/container-images/apache-git-http-backend/test_container_integration_apache_git_http_backend.py
+++ b/tests/container-images/apache-git-http-backend/test_container_integration_apache_git_http_backend.py
@@ -44,6 +44,8 @@
     return repo
 
 
+@pytest.mark.docker
+@pytest.mark.integration
 def test_apache_git_http_backend_apache_running(
     container_run, base_url, apache_credentials_dir
 ):
@@ -53,6 +55,8 @@
     assert request.status_code == 200
 
 
+@pytest.mark.docker
+@pytest.mark.integration
 def test_apache_git_http_backend_repo_creation(
     container_run, apache_credentials_dir, basic_auth_creds, repo_creation_url
 ):
@@ -66,6 +70,8 @@
     assert request.status_code == 201
 
 
+@pytest.mark.docker
+@pytest.mark.integration
 def test_apache_git_http_backend_repo_creation_fails_without_credentials(
     container_run, apache_credentials_dir, repo_creation_url
 ):
@@ -75,6 +81,8 @@
     assert request.status_code == 401
 
 
+@pytest.mark.docker
+@pytest.mark.integration
 def test_apache_git_http_backend_repo_creation_fails_wrong_fs_permissions(
     container_run, apache_credentials_dir, basic_auth_creds, repo_creation_url
 ):
@@ -90,6 +98,8 @@
     assert request.status_code == 500
 
 
+@pytest.mark.docker
+@pytest.mark.integration
 def test_apache_git_http_backend_repo_creation_push_repo(
     container_run,
     base_url,
diff --git a/tests/container-images/apache-git-http-backend/test_container_structure_apache_git_http_backend.py b/tests/container-images/apache-git-http-backend/test_container_structure_apache_git_http_backend.py
index 241e42d..de3e8bc 100755
--- a/tests/container-images/apache-git-http-backend/test_container_structure_apache_git_http_backend.py
+++ b/tests/container-images/apache-git-http-backend/test_container_structure_apache_git_http_backend.py
@@ -12,7 +12,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import pytest
 
+
+@pytest.mark.structure
 def test_apache_git_http_backend_inherits_from_base(apache_git_http_backend_image):
     contains_tag = False
     for layer in apache_git_http_backend_image.history():
@@ -22,11 +25,15 @@
     assert contains_tag
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_apache_git_http_backend_contains_apache2(container_run):
     exit_code, _ = container_run.exec_run("which httpd")
     assert exit_code == 0
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_apache_git_http_backend_http_site_configured(container_run):
     exit_code, _ = container_run.exec_run(
         "test -f /etc/apache2/conf.d/git-http-backend.conf"
@@ -34,6 +41,8 @@
     assert exit_code == 0
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_apache_git_http_backend_https_site_configured(container_run):
     exit_code, _ = container_run.exec_run(
         "test -f /etc/apache2/conf.d/git-https-backend.conf"
@@ -41,16 +50,21 @@
     assert exit_code == 0
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_apache_git_http_backend_contains_start_script(container_run):
     exit_code, _ = container_run.exec_run("test -f /var/tools/start")
     assert exit_code == 0
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_apache_git_http_backend_contains_repo_creation_cgi_script(container_run):
     exit_code, _ = container_run.exec_run("test -f /var/cgi/create_repo.sh")
     assert exit_code == 0
 
 
+@pytest.mark.structure
 def test_apache_git_http_backend_has_entrypoint(apache_git_http_backend_image):
     entrypoint = apache_git_http_backend_image.attrs["ContainerConfig"]["Entrypoint"]
     assert len(entrypoint) == 2
diff --git a/tests/container-images/base/test_container_build_base.py b/tests/container-images/base/test_container_build_base.py
index 251cac4..2a3afa5 100644
--- a/tests/container-images/base/test_container_build_base.py
+++ b/tests/container-images/base/test_container_build_base.py
@@ -15,6 +15,7 @@
 import pytest
 
 
+@pytest.mark.structure
 def test_build_base(base_image, tag_of_cached_container):
     if tag_of_cached_container:
         pytest.skip("Cached image used for testing. Build will not be tested.")
diff --git a/tests/container-images/base/test_container_structure_base.py b/tests/container-images/base/test_container_structure_base.py
index 0af742b..528d2b4 100755
--- a/tests/container-images/base/test_container_structure_base.py
+++ b/tests/container-images/base/test_container_structure_base.py
@@ -22,11 +22,15 @@
     container_run.stop(timeout=1)
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_base_contains_git(container_run):
     exit_code, _ = container_run.exec_run("which git")
     assert exit_code == 0
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_base_has_non_root_user_gerrit(container_run):
     exit_code, output = container_run.exec_run("id -u gerrit")
     assert exit_code == 0
@@ -34,6 +38,8 @@
     assert uid != 0
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_base_gerrit_no_root_permissions(container_run):
     exit_code, _ = container_run.exec_run("su -c 'rm -rf /bin' gerrit")
     assert exit_code > 0
diff --git a/tests/container-images/gerrit-base/test_container_build_gerrit_base.py b/tests/container-images/gerrit-base/test_container_build_gerrit_base.py
index 9c6ac1e..93954d8 100644
--- a/tests/container-images/gerrit-base/test_container_build_gerrit_base.py
+++ b/tests/container-images/gerrit-base/test_container_build_gerrit_base.py
@@ -15,6 +15,7 @@
 import pytest
 
 
+@pytest.mark.structure
 def test_build_gerrit_base(gerrit_base_image, tag_of_cached_container):
     if tag_of_cached_container:
         pytest.skip("Cached image used for testing. Build will not be tested.")
diff --git a/tests/container-images/gerrit-base/test_container_structure_gerrit_base.py b/tests/container-images/gerrit-base/test_container_structure_gerrit_base.py
index 08a311c..fb70532 100755
--- a/tests/container-images/gerrit-base/test_container_structure_gerrit_base.py
+++ b/tests/container-images/gerrit-base/test_container_structure_gerrit_base.py
@@ -24,6 +24,7 @@
     container_run.stop(timeout=1)
 
 
+@pytest.mark.structure
 def test_gerrit_base_inherits_from_base(gerrit_base_image):
     contains_tag = False
     for layer in gerrit_base_image.history():
@@ -33,12 +34,16 @@
     assert contains_tag
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_gerrit_base_contains_java8(container_run):
     _, output = container_run.exec_run("java -version")
     output = output.strip().decode("utf-8")
     assert re.search(re.compile('openjdk version "1.8.[0-9]_[0-9]+"'), output)
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_gerrit_base_java_path(container_run):
     exit_code, output = container_run.exec_run(
         '/bin/ash -c "readlink -f $(which java)"'
@@ -48,6 +53,8 @@
     assert output == "/usr/lib/jvm/java-1.8-openjdk/jre/bin/java"
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_gerrit_base_contains_gerrit_war(container_run):
     exit_code, _ = container_run.exec_run("test -f /var/war/gerrit.war")
     assert exit_code == 0
@@ -56,6 +63,8 @@
     assert exit_code == 0
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_gerrit_base_war_contains_gerrit(container_run):
     exit_code, output = container_run.exec_run("java -jar /var/war/gerrit.war version")
     assert exit_code == 0
@@ -70,16 +79,21 @@
     assert re.search(re.compile("gerrit version.*"), output)
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_gerrit_base_site_permissions(container_run):
     exit_code, _ = container_run.exec_run("test -O /var/gerrit")
     assert exit_code == 0
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_gerrit_base_war_dir_permissions(container_run):
     exit_code, _ = container_run.exec_run("test -O /var/war")
     assert exit_code == 0
 
 
+@pytest.mark.structure
 def test_gerrit_base_has_entrypoint(gerrit_base_image):
     entrypoint = gerrit_base_image.attrs["ContainerConfig"]["Entrypoint"]
     assert "/var/tools/start" in entrypoint
diff --git a/tests/container-images/gerrit-init/test_container_build_gerrit_init.py b/tests/container-images/gerrit-init/test_container_build_gerrit_init.py
index 1ce4edb..dc16d74 100644
--- a/tests/container-images/gerrit-init/test_container_build_gerrit_init.py
+++ b/tests/container-images/gerrit-init/test_container_build_gerrit_init.py
@@ -15,6 +15,7 @@
 import pytest
 
 
+@pytest.mark.structure
 def test_build_gerrit_init(gerrit_init_image, tag_of_cached_container):
     if tag_of_cached_container:
         pytest.skip("Cached image used for testing. Build will not be tested.")
diff --git a/tests/container-images/gerrit-init/test_container_integration_gerrit_init.py b/tests/container-images/gerrit-init/test_container_integration_gerrit_init.py
index 6118c23..057f5ba 100644
--- a/tests/container-images/gerrit-init/test_container_integration_gerrit_init.py
+++ b/tests/container-images/gerrit-init/test_container_integration_gerrit_init.py
@@ -60,7 +60,9 @@
     container_run.stop(timeout=1)
 
 
+@pytest.mark.docker
 @pytest.mark.incremental
+@pytest.mark.integration
 class TestGerritInitEmptySite:
     @pytest.mark.timeout(60)
     def test_gerrit_init_gerrit_is_initialized(self, container_run_default):
@@ -86,7 +88,9 @@
         assert container_run_default.attrs["State"]["ExitCode"] == 0
 
 
+@pytest.mark.docker
 @pytest.mark.incremental
+@pytest.mark.integration
 class TestGerritInitPluginInstallation:
     def test_gerrit_init_plugins_are_installed(self, container_run_endless):
         exit_code, _ = container_run_endless.exec_run(
diff --git a/tests/container-images/gerrit-init/test_container_structure_gerrit_init.py b/tests/container-images/gerrit-init/test_container_structure_gerrit_init.py
index 0b6c3bf..2e5051f 100755
--- a/tests/container-images/gerrit-init/test_container_structure_gerrit_init.py
+++ b/tests/container-images/gerrit-init/test_container_structure_gerrit_init.py
@@ -35,6 +35,7 @@
     return request.param
 
 
+@pytest.mark.structure
 def test_gerrit_init_inherits_from_gerrit_base(gerrit_init_image):
     contains_tag = False
     for layer in gerrit_init_image.history():
@@ -46,16 +47,21 @@
     assert contains_tag
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_gerrit_init_contains_expected_scripts(container_run, expected_script):
     exit_code, _ = container_run.exec_run("test -f %s" % expected_script)
     assert exit_code == 0
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_gerrit_init_contains_expected_tools(container_run, expected_tool):
     exit_code, _ = container_run.exec_run("which %s" % expected_tool)
     assert exit_code == 0
 
 
+@pytest.mark.structure
 def test_gerrit_init_has_entrypoint(gerrit_init_image):
     entrypoint = gerrit_init_image.attrs["ContainerConfig"]["Entrypoint"]
     assert len(entrypoint) >= 1
diff --git a/tests/container-images/gerrit-master/test_container_build_gerrit_master.py b/tests/container-images/gerrit-master/test_container_build_gerrit_master.py
index 95ec4b9..6c7c784 100644
--- a/tests/container-images/gerrit-master/test_container_build_gerrit_master.py
+++ b/tests/container-images/gerrit-master/test_container_build_gerrit_master.py
@@ -15,6 +15,7 @@
 import pytest
 
 
+@pytest.mark.structure
 def test_build_gerrit_master(gerrit_master_image, tag_of_cached_container):
     if tag_of_cached_container:
         pytest.skip("Cached image used for testing. Build will not be tested.")
diff --git a/tests/container-images/gerrit-master/test_container_integration_gerrit_master.py b/tests/container-images/gerrit-master/test_container_integration_gerrit_master.py
index 025d18a..0cbdaf4 100644
--- a/tests/container-images/gerrit-master/test_container_integration_gerrit_master.py
+++ b/tests/container-images/gerrit-master/test_container_integration_gerrit_master.py
@@ -69,8 +69,10 @@
     return request.param
 
 
-@pytest.mark.slow
+@pytest.mark.docker
 @pytest.mark.incremental
+@pytest.mark.integration
+@pytest.mark.slow
 class TestGerritMasterStartScript:
     @pytest.mark.timeout(60)
     def test_gerrit_master_gerrit_starts_up(self, container_run):
diff --git a/tests/container-images/gerrit-master/test_container_structure_gerrit_master.py b/tests/container-images/gerrit-master/test_container_structure_gerrit_master.py
index a45e7b1..c4b9e68 100755
--- a/tests/container-images/gerrit-master/test_container_structure_gerrit_master.py
+++ b/tests/container-images/gerrit-master/test_container_structure_gerrit_master.py
@@ -22,6 +22,7 @@
     container_run.stop(timeout=1)
 
 
+@pytest.mark.structure
 def test_gerrit_master_inherits_from_gerrit_base(gerrit_master_image):
     contains_tag = False
     for layer in gerrit_master_image.history():
@@ -33,6 +34,8 @@
     assert contains_tag
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_gerrit_master_contains_start_script(container_run):
     exit_code, _ = container_run.exec_run("test -f /var/tools/start")
     assert exit_code == 0
diff --git a/tests/container-images/gerrit-slave/test_container_build_gerrit_slave.py b/tests/container-images/gerrit-slave/test_container_build_gerrit_slave.py
index 422f197..88fa51c 100644
--- a/tests/container-images/gerrit-slave/test_container_build_gerrit_slave.py
+++ b/tests/container-images/gerrit-slave/test_container_build_gerrit_slave.py
@@ -15,6 +15,7 @@
 import pytest
 
 
+@pytest.mark.structure
 def test_build_gerrit_slave(gerrit_slave_image, tag_of_cached_container):
     if tag_of_cached_container:
         pytest.skip("Cached image used for testing. Build will not be tested.")
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
index ff6ac92..9753258 100644
--- a/tests/container-images/gerrit-slave/test_container_integration_gerrit_slave.py
+++ b/tests/container-images/gerrit-slave/test_container_integration_gerrit_slave.py
@@ -69,8 +69,10 @@
     return test_setup.gerrit_container
 
 
-@pytest.mark.slow
+@pytest.mark.docker
 @pytest.mark.incremental
+@pytest.mark.integration
+@pytest.mark.slow
 class TestGerritSlave:
     @pytest.fixture(params=CONFIG_FILES)
     def config_file_to_test(self, request):
diff --git a/tests/container-images/gerrit-slave/test_container_structure_gerrit_slave.py b/tests/container-images/gerrit-slave/test_container_structure_gerrit_slave.py
index 25b5ea2..2e43077 100755
--- a/tests/container-images/gerrit-slave/test_container_structure_gerrit_slave.py
+++ b/tests/container-images/gerrit-slave/test_container_structure_gerrit_slave.py
@@ -27,6 +27,7 @@
     return request.param
 
 
+@pytest.mark.structure
 def test_gerrit_slave_inherits_from_gerrit_base(gerrit_slave_image):
     contains_tag = False
     for layer in gerrit_slave_image.history():
@@ -38,16 +39,22 @@
     assert contains_tag
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_gerrit_slave_contains_expected_scripts(container_run, expected_script):
     exit_code, _ = container_run.exec_run("test -f %s" % expected_script)
     assert exit_code == 0
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_gerrit_slave_contains_initialized_gerrit_site(container_run):
     exit_code, _ = container_run.exec_run("/var/gerrit/bin/gerrit.sh check")
     assert exit_code == 3
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_gerrit_slave_gerrit_is_configured_slave(container_run):
     exit_code, output = container_run.exec_run(
         "git config -f /var/gerrit/etc/gerrit.config --get container.slave"
diff --git a/tests/container-images/git-gc/test_container_build_gitgc.py b/tests/container-images/git-gc/test_container_build_gitgc.py
index 8a3a770..a640d20 100644
--- a/tests/container-images/git-gc/test_container_build_gitgc.py
+++ b/tests/container-images/git-gc/test_container_build_gitgc.py
@@ -15,6 +15,7 @@
 import pytest
 
 
+@pytest.mark.structure
 def test_build_gitgc(gitgc_image, tag_of_cached_container):
     if tag_of_cached_container:
         pytest.skip("Cached image used for testing. Build will not be tested.")
diff --git a/tests/container-images/git-gc/test_container_structure_gitgc.py b/tests/container-images/git-gc/test_container_structure_gitgc.py
index 9abbd20..c088ab0 100644
--- a/tests/container-images/git-gc/test_container_structure_gitgc.py
+++ b/tests/container-images/git-gc/test_container_structure_gitgc.py
@@ -22,6 +22,7 @@
     container_run.stop(timeout=1)
 
 
+@pytest.mark.structure
 def test_gitgc_inherits_from_base(gitgc_image):
     contains_tag = False
     for layer in gitgc_image.history():
@@ -31,16 +32,21 @@
     assert contains_tag
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_gitgc_log_dir_writable_by_gerrit(container_run):
     exit_code, _ = container_run.exec_run("touch /var/log/git/test.log")
     assert exit_code == 0
 
 
+@pytest.mark.docker
+@pytest.mark.structure
 def test_gitgc_contains_gc_script(container_run):
     exit_code, _ = container_run.exec_run("test -f /var/tools/gc-all.sh")
     assert exit_code == 0
 
 
+@pytest.mark.structure
 def test_gitgc_has_entrypoint(gitgc_image):
     entrypoint = gitgc_image.attrs["ContainerConfig"]["Entrypoint"]
     assert len(entrypoint) == 1