Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions 2.4-micro/test/run-pytest
1 change: 1 addition & 0 deletions 2.4-micro/test/test_container_httpd.py
1 change: 1 addition & 0 deletions 2.4-micro/test/test_container_httpd_s2i.py
1 change: 1 addition & 0 deletions 2.4-micro/test/test_container_ssl.py
1 change: 0 additions & 1 deletion 2.4-micro/test/test_httpd_ex_template.py

This file was deleted.

1 change: 0 additions & 1 deletion 2.4-micro/test/test_httpd_imagestream_s2i.py

This file was deleted.

1 change: 0 additions & 1 deletion 2.4-micro/test/test_httpd_imagestreams.py

This file was deleted.

1 change: 0 additions & 1 deletion 2.4-micro/test/test_httpd_integration.py

This file was deleted.

1 change: 0 additions & 1 deletion 2.4-micro/test/test_httpd_shared_helm_imagestreams.py

This file was deleted.

1 change: 0 additions & 1 deletion 2.4-micro/test/test_httpd_shared_helm_template.py

This file was deleted.

1 change: 1 addition & 0 deletions 2.4-micro/test/test_ocp_ex_template.py
1 change: 1 addition & 0 deletions 2.4-micro/test/test_ocp_imagestream_s2i.py
1 change: 1 addition & 0 deletions 2.4-micro/test/test_ocp_imagestreams.py
1 change: 1 addition & 0 deletions 2.4-micro/test/test_ocp_integration.py
1 change: 1 addition & 0 deletions 2.4-micro/test/test_ocp_shared_helm_imagestreams.py
1 change: 1 addition & 0 deletions 2.4-micro/test/test_ocp_shared_helm_template.py
1 change: 1 addition & 0 deletions 2.4/test/run-pytest
1 change: 1 addition & 0 deletions 2.4/test/test_container_httpd.py
1 change: 1 addition & 0 deletions 2.4/test/test_container_httpd_s2i.py
1 change: 1 addition & 0 deletions 2.4/test/test_container_ssl.py
1 change: 0 additions & 1 deletion 2.4/test/test_httpd_ex_template.py

This file was deleted.

1 change: 0 additions & 1 deletion 2.4/test/test_httpd_imagestream_s2i.py

This file was deleted.

1 change: 0 additions & 1 deletion 2.4/test/test_httpd_imagestreams.py

This file was deleted.

1 change: 0 additions & 1 deletion 2.4/test/test_httpd_integration.py

This file was deleted.

1 change: 0 additions & 1 deletion 2.4/test/test_httpd_shared_helm_imagestreams.py

This file was deleted.

1 change: 0 additions & 1 deletion 2.4/test/test_httpd_shared_helm_template.py

This file was deleted.

1 change: 1 addition & 0 deletions 2.4/test/test_ocp_ex_template.py
1 change: 1 addition & 0 deletions 2.4/test/test_ocp_imagestream_s2i.py
1 change: 1 addition & 0 deletions 2.4/test/test_ocp_imagestreams.py
1 change: 1 addition & 0 deletions 2.4/test/test_ocp_integration.py
1 change: 1 addition & 0 deletions 2.4/test/test_ocp_shared_helm_imagestreams.py
1 change: 1 addition & 0 deletions 2.4/test/test_ocp_shared_helm_template.py
15 changes: 15 additions & 0 deletions test/run-pytest
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash
#
# IMAGE_NAME specifies a name of the candidate image used for testing.
# The image has to be available before this script is executed.
# SINGLE_VERSION specifies the major version of httpd
# OS specifies RHEL version (e.g. OS=rhel8)
#

THISDIR=$(dirname ${BASH_SOURCE[0]})

PYTHON_VERSION="3.12"
if [[ ! -f "/usr/bin/python$PYTHON_VERSION" ]]; then
PYTHON_VERSION="3.13"
fi
cd "${THISDIR}" && "python${PYTHON_VERSION}" -m pytest -s -rA --showlocals -vv test_container_*.py
123 changes: 123 additions & 0 deletions test/test_container_httpd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import os
import re
import tempfile

from pathlib import Path

import pytest

from container_ci_suite.container_lib import ContainerTestLib
from container_ci_suite.utils import ContainerTestLibUtils


TEST_DIR = Path(__file__).parent.absolute()
VERSION = os.getenv("VERSION")
OS = os.getenv("OS").lower()
IMAGE_NAME = os.getenv("IMAGE_NAME")


class TestHttpdAppContainer:

def setup_method(self):
self.app = ContainerTestLib(image_name=IMAGE_NAME, s2i_image=True)

def teardown_method(self):
self.app.cleanup()

@pytest.mark.parametrize(
"container_arg",
[
"",
"--user 0"
]
)
def test_default_page(self, container_arg):
assert self.app.create_container(cid_file_name="test_default_page", container_args=container_arg)
cip = self.app.get_cip("test_default_page")
assert cip
response = "HTTP Server"
assert self.app.test_response(url=cip, expected_code=403, expected_output=response, max_attempts=3)

def test_run_s2i_usage(self):
output = self.app.s2i_usage()
assert output

@pytest.mark.parametrize(
"dockerfile",
[
"Dockerfile",
"Dockerfile.s2i"
]
)
def test_dockerfiles(self, dockerfile):
assert self.app.build_test_container(
dockerfile=TEST_DIR / "examples" / dockerfile, app_url="https://github.com/sclorg/httpd-ex.git",
app_dir="app-src"
)
assert self.app.test_app_dockerfile()
cip = self.app.get_cip()
assert cip
assert self.app.test_response(url=f"{cip}", expected_code=200, expected_output="Welcome to your static httpd application on OpenShift")

@pytest.mark.parametrize(
"mpm_config",
[
"worker",
"event",
"prefork",
]
)
def test_mpm_config(self, mpm_config):
cid_name = f"test_mpm_{mpm_config}"
assert self.app.create_container(cid_file_name=cid_name, container_args=f"-e HTTPD_MPM={mpm_config} --user 1001")
cip = self.app.get_cip(cid_file_name=cid_name)
# Let's check that server really response HTTP-403
# See function here: in test/run `_run_mpm_config_test`
# https://github.com/sclorg/httpd-container/blob/master/test/run#L97
assert self.app.test_response(url=f"{cip}", port=8080, expected_code=403)
logs = self.app.get_logs(cid_file_name=cid_name)
assert re.search(f"mpm_{mpm_config}:notice.*resuming normal operations", logs)


def test_log_to_data_volume(self):
data_dir = tempfile.mkdtemp(prefix="/tmp/httpd-test_log_dir")
ContainerTestLibUtils.commands_to_run(
commands_to_run = [
f"mkdir -p {data_dir}",
f"chown -R 1001:1001 {data_dir}",
f"chcon -Rvt svirt_sandbox_file_t {data_dir}/"
]
)
assert self.app.create_container(
cid_file_name="test_log_dir",
container_args=f"-e HTTPD_LOG_TO_VOLUME=1 --user 0 -v {data_dir}:/var/log/httpd"
)
cip = self.app.get_cip(cid_file_name="test_log_dir")
assert self.app.test_response(url=f"{cip}", port=8080, expected_code=403)
assert ContainerTestLibUtils.check_files_are_present(
dir_name=data_dir, file_name_to_check=[
"access_log",
"error_log",
"ssl_access_log",
"ssl_error_log",
"ssl_request_log",
]
)

def test_data_volume(self):
data_dir = tempfile.mkdtemp(prefix="/tmp/httpd-test-volume")
ContainerTestLibUtils.commands_to_run(
commands_to_run = [
f"mkdir -p {data_dir}/html",
f"echo hello > {data_dir}/html/index.html",
f"chown -R 1001:1001 {data_dir}",
f"chcon -Rvt svirt_sandbox_file_t {data_dir}/"
]
)
assert self.app.create_container(
cid_file_name="doc_root",
container_args=f"-v {data_dir}:/var/www"
)
cip = self.app.get_cip(cid_file_name="doc_root")
assert cip
assert self.app.test_response(url=f"{cip}", port=8080, expected_code=200, expected_output="hello")
135 changes: 135 additions & 0 deletions test/test_container_httpd_s2i.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import os
import time
import tempfile

from pathlib import Path

from container_ci_suite.container_lib import ContainerTestLib
from container_ci_suite.utils import ContainerTestLibUtils
from container_ci_suite.engines.podman_wrapper import PodmanCLIWrapper


TEST_DIR = Path(__file__).parent.absolute()
VERSION = os.getenv("VERSION")
OS = os.getenv("TARGET")
IMAGE_NAME = os.getenv("IMAGE_NAME")


pre_init_test_app = TEST_DIR / "pre-init-test-app"
sample_test_app = TEST_DIR / "sample-test-app"


class TestHttpdS2IPreInitContainer:

def setup_method(self):
self.container_lib = ContainerTestLib(IMAGE_NAME)
print(self.container_lib)
app_name = pre_init_test_app.name
print(app_name)
self.s2i_app = self.container_lib.build_as_df(
app_path=pre_init_test_app,
s2i_args="--pull-policy=never",
src_image=IMAGE_NAME,
dst_image=f"{IMAGE_NAME}-{app_name}"
)

def teardown_method(self):
self.s2i_app.cleanup()

def test_run_pre_init_test(self):
assert self.s2i_app.create_container(cid_file_name=self.s2i_app.app_name, container_args="--user 1000")
cip = self.s2i_app.get_cip(cid_file_name=self.s2i_app.app_name)
assert cip
assert self.s2i_app.test_response(
url=cip,
expected_code=200,
expected_output="This content was replaced by pre-init script."
)


class TestHttpdS2ISampleAppContainer:

def setup_method(self):
self.ci = ContainerTestLib(IMAGE_NAME)
app_name = sample_test_app.name
self.s2i_app = self.ci.build_as_df(
app_path=sample_test_app,
s2i_args="--pull-policy=never",
src_image=IMAGE_NAME,
dst_image=f"{IMAGE_NAME}-{app_name}"
)

def teardown_method(self):
self.s2i_app.cleanup()

def test_sample_app(self):
assert self.s2i_app.create_container(cid_file_name=self.s2i_app.app_name, container_args="--user 1000")
cip = self.s2i_app.get_cip(cid_file_name=self.s2i_app.app_name)
assert cip
response = "This is a sample s2i application with static content."
assert self.s2i_app.test_response(
url=cip,
expected_code=200,
expected_output=response
)
assert self.s2i_app.test_response(
url=f"https://{cip}",
port=8443,
expected_output=response
)


class TestHttpdCertAgeContainer:

def setup_method(self):
self.ci = ContainerTestLib(IMAGE_NAME)
app_name = sample_test_app.name
self.s2i_app = self.ci.build_as_df(
app_path=sample_test_app,
s2i_args="--pull-policy=never",
src_image=IMAGE_NAME,
dst_image=f"{IMAGE_NAME}-{app_name}"
)

def teardown_method(self):
self.s2i_app.cleanup()

"""
This tests checks whether the certificate was freshly generated after the image
We need to make sure the certificate is generated no sooner than in assemble phase,
because shipping the same certs in the image would make it easy to exploit
Let's see how old the certificate is and compare with how old the image is
"""
def test_cert_age(self):
assert self.s2i_app.create_container(cid_file_name=self.s2i_app.app_name, container_args="--user 1000")
image_age_s = PodmanCLIWrapper.podman_inspect(
field="{{.Created}}", src_image=IMAGE_NAME
).strip().split(' ')
image_age = time.time() - float(ContainerTestLibUtils.run_command(
cmd=f"date -d '{image_age_s[0]} {image_age_s[1]} {image_age_s[2]}' '+%s'"
))
cid = self.s2i_app.get_cid(self.s2i_app.app_name)
# Testing of not presence of a certificate in the production image
certificate_content = PodmanCLIWrapper.podman_exec_shell_command(
cid_file_name=cid, cmd="cat \\$HTTPD_TLS_CERT_PATH/localhost.crt"
)
assert certificate_content
certificate_dir = tempfile.mkdtemp(prefix="/tmp/cert_dir")
with open(Path(certificate_dir) / "cert", mode="w") as f:
f.write(certificate_content.strip())
certificate_age_s = ContainerTestLibUtils.run_command(
cmd=f"openssl x509 -startdate -noout -in {Path(certificate_dir)}/cert"
).strip().replace("notBefore=", "")
certificate_age = time.time() - float(ContainerTestLibUtils.run_command(
cmd=f"date '+%s' --date='{certificate_age_s}'")
)
# Testing whether the certificate was freshly generated after the image
assert certificate_age < image_age
# Testing presence and permissions of the generated certificate
assert PodmanCLIWrapper.podman_exec_shell_command(
cid_file_name=cid, cmd="ls -l \\$HTTPD_TLS_CERT_PATH/localhost.crt"
)
# Testing presence and permissions of the generated certificate
assert PodmanCLIWrapper.podman_exec_shell_command(
cid_file_name=cid, cmd="ls -l \\$HTTPD_TLS_CERT_PATH/localhost.key"
)
Loading