diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..b7def541a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,26 @@ +name: Jinja CI +on: + pull_request: + paths: + - generate_dockerfiles.py + - test_generate_dockerfiles.py + branches: [ main ] + +permissions: + contents: read + +jobs: + ci: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + + - uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1 + with: + python-version: "3.x" + + - name: Install dependencies + run: "pip3 install -r requirements.txt" + + - name: Run tests + run: "python3 test_generate_dockerfiles.py" diff --git a/.gitignore b/.gitignore index a30cba8d4..47c207ac5 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ official-eclipse-temurin *hotspot.txt library/ .vscode/ + __pycache__/ diff --git a/test_generate_dockerfiles.py b/test_generate_dockerfiles.py new file mode 100644 index 000000000..72df464c6 --- /dev/null +++ b/test_generate_dockerfiles.py @@ -0,0 +1,202 @@ +import unittest +from unittest.mock import Mock, mock_open, patch + +from jinja2 import Environment, FileSystemLoader + +import generate_dockerfiles + + +class TestHelperFunctions(unittest.TestCase): + def test_archHelper(self): + test_data = [ + ("aarch64", "some-os", "aarch64|arm64"), + ("ppc64le", "some-os", "ppc64el|powerpc:common64"), + ("s390x", "some-os", "s390x|s390:64-bit"), + ("arm", "some-os", "armhf|arm"), + ("x64", "alpine-linux", "amd64|x86_64"), + ("x64", "ubuntu", "amd64|i386:x86-64"), + ("random-arch", "some-os", "random-arch"), + ] + + for arch, os_family, expected in test_data: + self.assertEqual(generate_dockerfiles.archHelper(arch, os_family), expected) + + def test_osFamilyHelper(self): + test_data = [ + ("ubuntu", "linux"), + ("centos", "linux"), + ("ubi9-minimal", "linux"), + ("nanoserver", "windows"), + ("servercore", "windows"), + ("random-os", "random-os"), + ] + + for os_name, expected in test_data: + self.assertEqual(generate_dockerfiles.osFamilyHelper(os_name), expected) + + @patch("requests.get") + def test_fetch_latest_release(self, mock_get): + # Mocking the request.get call + mock_response = Mock() + mock_response.raise_for_status.return_value = None + mock_response.json.return_value = [{"key": "value"}] + mock_get.return_value = mock_response + + url = "https://api.adoptium.net/v3/assets/feature_releases/some_version/ga?page=0&image_type=some_type&page_size=1&vendor=eclipse" + response = generate_dockerfiles.requests.get( + url, headers=generate_dockerfiles.headers + ) + data = response.json() + self.assertIn("key", data[0]) + self.assertEqual(data[0]["key"], "value") + + @patch("builtins.open", new_callable=mock_open, read_data="configurations: []") + def test_load_config(self, mock_file): + with open("config/hotspot.yml", "r") as file: + config = generate_dockerfiles.yaml.safe_load(file) + self.assertIn("configurations", config) + + +class TestJinjaRendering(unittest.TestCase): + def setUp(self): + # Setup the Jinja2 environment + self.env = Environment(loader=FileSystemLoader("docker_templates")) + + def test_armhf_ubuntu8_rendering(self): + template_name = "ubuntu.Dockerfile.j2" + template = self.env.get_template(template_name) + + arch_data = {} + + arch_data["armhf|arm"] = { + "download_url": "http://fake-url.com", + "checksum": "fake-checksum", + } + + # The context/variables to render the template + context = { + "architecture": "armhf|arm", + "os": "ubuntu", + "version": "8", + "arch_data": arch_data, + } + rendered_template = template.render(**context) + + # Expected string/partial in the rendered output + expected_string = "# Fixes libatomic.so.1: cannot open shared object file" + self.assertIn(expected_string, rendered_template) + + def test_version_checker(self): + template_name = "partials/version-check.j2" + template = self.env.get_template(template_name) + + with self.subTest(): + # The context/variables to render the template + context = {"version": "11", "image_type": "jdk"} + rendered_template = template.render(**context) + + # Expected string/partial in the rendered output + expected_string = "&& echo javac --version && javac --version" + self.assertIn(expected_string, rendered_template) + + with self.subTest(): + # The context/variables to render the template + context = {"version": "8", "image_type": "jdk"} + rendered_template = template.render(**context) + + # Expected string/partial in the rendered output + expected_string = "&& echo javac -version && javac -version" + self.assertIn(expected_string, rendered_template) + + with self.subTest(): + # The context/variables to render the template + context = {"version": "11", "image_type": "jre"} + rendered_template = template.render(**context) + + # Expected string/partial in the rendered output + expected_string = "&& echo javac --version && javac --version" + self.assertNotIn(expected_string, rendered_template) + + with self.subTest(): + # The context/variables to render the template + context = {"version": "8", "image_type": "jre"} + rendered_template = template.render(**context) + + # Expected string/partial in the rendered output + expected_string = "&& echo javac -version && javac -version" + self.assertNotIn(expected_string, rendered_template) + + def test_version_checker_windows(self): + template_name = "partials/version-check-windows.j2" + template = self.env.get_template(template_name) + + with self.subTest(): + # The context/variables to render the template + context = {"version": "11", "image_type": "jdk"} + rendered_template = template.render(**context) + + # Expected string/partial in the rendered output + expected_string = "Write-Host 'javac --version'; javac --version;" + self.assertIn(expected_string, rendered_template) + + with self.subTest(): + # The context/variables to render the template + context = {"version": "8", "image_type": "jdk"} + rendered_template = template.render(**context) + + # Expected string/partial in the rendered output + expected_string = "Write-Host 'javac -version'; javac -version;" + self.assertIn(expected_string, rendered_template) + + with self.subTest(): + # The context/variables to render the template + context = {"version": "11", "image_type": "jre"} + rendered_template = template.render(**context) + + # Expected string/partial in the rendered output + expected_string = "Write-Host 'javac --version'; javac --version;" + self.assertNotIn(expected_string, rendered_template) + + with self.subTest(): + # The context/variables to render the template + context = {"version": "8", "image_type": "jre"} + rendered_template = template.render(**context) + + # Expected string/partial in the rendered output + expected_string = "Write-Host 'javac -version'; javac -version;" + self.assertNotIn(expected_string, rendered_template) + + def test_jdk11plus_jshell_cmd(self): + template_name = "partials/jshell.j2" + template = self.env.get_template(template_name) + + with self.subTest(): + # The context/variables to render the template + context = {"version": "11", "image_type": "jdk"} + rendered_template = template.render(**context) + + # Expected string/partial in the rendered output + expected_string = 'CMD ["jshell"]' + self.assertIn(expected_string, rendered_template) + + with self.subTest(): + # The context/variables to render the template + context = {"version": "17", "image_type": "jre"} + rendered_template = template.render(**context) + + # Expected string/partial in the rendered output + expected_string = 'CMD ["jshell"]' + self.assertNotIn(expected_string, rendered_template) + + with self.subTest(): + # The context/variables to render the template + context = {"version": "8", "image_type": "jdk"} + rendered_template = template.render(**context) + + # Expected string/partial in the rendered output + expected_string = 'CMD ["jshell"]' + self.assertNotIn(expected_string, rendered_template) + + +if __name__ == "__main__": + unittest.main()