Skip to content

Commit dd7b3ef

Browse files
epaganonPrabhakar Kumar
authored and
Prabhakar Kumar
committed
Add tests for non-interactive Dockerfile, and fix failing/stalling tests.
1 parent 2ae11d7 commit dd7b3ef

File tree

14 files changed

+272
-24
lines changed

14 files changed

+272
-24
lines changed

.github/workflows/build-test-publish.yml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ jobs:
6363
if [ -f tests/requirements.txt ]; then pip install -r tests/requirements.txt; fi
6464
6565
- name: Generate license file
66-
run: echo '${{ secrets.MATLAB_LICENSE_SECRET }}' > ${{ env.LICENSE_FILE_PATH }}
66+
run: echo '${{ secrets.MATLAB_LICENSE_FILE_R2024A }}' > ${{ env.LICENSE_FILE_PATH }}
6767

6868
- name: Test container
6969
env:
@@ -72,9 +72,4 @@ jobs:
7272
run: python -m unittest
7373

7474
- name: Push the image to ghcr.io
75-
uses: docker/build-push-action@v4
76-
with:
77-
platforms: linux/amd64
78-
push: true
79-
tags: |
80-
${{ env.IMAGE_BASE_NAME }}:${{ matrix.matlab-release }}
75+
run: docker push ${{ env.IMAGE_BASE_NAME }}:${{ matrix.matlab-release }}

.github/workflows/from-matlab-docker-build-test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2023-2024 The MathWorks, Inc.
1+
# Copyright 2023 The MathWorks, Inc.
22

33
name: Build and Test the "Building on MATLAB Docker Image" Dockerfile
44

@@ -58,7 +58,7 @@ jobs:
5858
if [ -f tests/requirements.txt ]; then pip install -r tests/requirements.txt; fi
5959
6060
- name: Generate license file
61-
run: echo '${{ secrets.MATLAB_LICENSE_SECRET }}' > ${{ env.LICENSE_FILE_PATH }}
61+
run: echo '${{ secrets.MATLAB_LICENSE_FILE_R2024A }}' > ${{ env.LICENSE_FILE_PATH }}
6262

6363
- name: Test container
6464
working-directory: tests

.github/workflows/matlab-installer-build-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2023-2024 The MathWorks, Inc.
1+
# Copyright 2023 The MathWorks, Inc.
22

33
name: Build and Test the "MATLAB installer" Dockerfile
44

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Copyright 2024 The MathWorks, Inc.
2+
3+
name: Build and Test the "Non-Interactive" Dockerfile
4+
5+
# Trigger this workflow either manually or when a new change is pushed to the
6+
# repo (except .md files)
7+
on:
8+
workflow_dispatch:
9+
push:
10+
# Trigger the workflow when the Dockerfile or any file under tests/ is modified
11+
paths:
12+
- "alternates/non-interactive/Dockerfile"
13+
- "tests/**"
14+
- "!tests/**.md"
15+
schedule:
16+
# Run at 00:00 on every Monday (1st Day of the Week)
17+
- cron: "0 0 * * 1"
18+
19+
env:
20+
IMAGE_BASE_NAME: matlab-non-interactive
21+
ALT_PATH: alternates/non-interactive
22+
23+
jobs:
24+
build-test-image:
25+
runs-on: ubuntu-latest
26+
strategy:
27+
fail-fast: false
28+
matrix:
29+
matlab-release: [r2024a, r2023b, r2023a, r2022b, r2022a, r2021b, r2021a, r2020b]
30+
31+
steps:
32+
- name: Checkout repo
33+
uses: actions/checkout@v3
34+
35+
- name: Set up Docker Buildx
36+
uses: docker/setup-buildx-action@v2
37+
38+
- name: Build image locally
39+
uses: docker/build-push-action@v4
40+
with:
41+
platforms: linux/amd64
42+
context: ${{ env.ALT_PATH }}
43+
load: true
44+
build-args: |
45+
MATLAB_RELEASE=${{ matrix.matlab-release }}
46+
tags: |
47+
${{ env.IMAGE_BASE_NAME }}:${{ matrix.matlab-release }}
48+
49+
- name: Set up Python 3
50+
uses: actions/setup-python@v4
51+
with:
52+
python-version: "3.10"
53+
54+
- name: Install test dependencies
55+
run: |
56+
python -m pip install --upgrade pip
57+
if [ -f tests/requirements.txt ]; then pip install -r tests/requirements.txt; fi
58+
59+
- name: Test container
60+
working-directory: tests
61+
env:
62+
IMAGE_NAME: ${{ env.IMAGE_BASE_NAME }}:${{ matrix.matlab-release }}
63+
BATCH_TOKEN: ${{ secrets.MATLAB_BATCH_TOKEN_EXPIRES_03_2025 }}
64+
run: |
65+
python -m unittest ${{ env.ALT_PATH }}/test_matlabbatch.py

tests/alternates/building-on-matlab-docker-image/test_container.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def test_packages_present(self):
5959
with self.subTest(package=pkg):
6060
self.assertTrue(
6161
self.host.package(pkg).is_installed,
62-
f"package {pkg} is not installed",
62+
f"Package {pkg} is not installed",
6363
)
6464

6565

tests/alternates/building-on-matlab-docker-image/test_entrypoint.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def test_vnc_option(self):
9797
self.assertRegex(
9898
table_lines[-1],
9999
expected_port,
100-
f"command {vnc_list_cmd} returned:\n{vnc_list_output}",
100+
f"Command {vnc_list_cmd} returned:\n{vnc_list_output}",
101101
)
102102

103103
def test_browser_option(self):

tests/alternates/matlab-installer/test_failing_build.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def test_mismatching_releases_displays_err_msg(self):
7979

8080
self.assertTrue(
8181
any([expected_fail_msg in l.get("stream", "") for l in build_log]),
82-
f"expected error message '{expected_fail_msg}' not found in build log\n{build_log}",
82+
f"Expected error message '{expected_fail_msg}' not found in build log\n{build_log}",
8383
)
8484

8585
def test_install_error_message(self):
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Copyright 2024 The MathWorks, Inc.
2+
3+
"""
4+
Test class to validate the "non-interactive" Dockerfile.
5+
This test suite require a valid batch licensing token.
6+
"""
7+
8+
from utils import base, helpers
9+
import docker
10+
import os
11+
import unittest
12+
13+
################################################################################
14+
15+
16+
class TestMatlabBatch(base.TestCase):
17+
"""Extend the test methods of the base TestCase class."""
18+
19+
@classmethod
20+
def setUpClass(cls):
21+
"""Run the container"""
22+
cls.client = docker.from_env()
23+
image_name = helpers.get_image_name()
24+
cls.container = cls.client.containers.run(
25+
image=image_name,
26+
detach=True,
27+
stdin_open=True,
28+
environment = {"MLM_LICENSE_TOKEN": os.getenv("BATCH_TOKEN")},
29+
)
30+
cls.expected_ddux_force_enable = "true"
31+
cls.expected_ddux_tags = [
32+
"MATLAB:BATCHLICENSING:DOCKERFILE:V1",
33+
]
34+
cls.install_dirname = "mpm"
35+
cls.release_tag = helpers.get_release_tag(image_name)
36+
super().setUpClass()
37+
38+
@classmethod
39+
def tearDownClass(cls):
40+
"""Stop and remove the container"""
41+
cls.container.stop()
42+
cls.container.remove()
43+
cls.client.close()
44+
45+
############################################################################
46+
47+
def test_matlabbatch_runs(self):
48+
"""Test that matlab-batch runs successfully and that the matlab release is the correct one."""
49+
matlabbatch_cmd = 'matlab-batch "disp(version(\'-release\'))"'
50+
cmd_output = self.host.run(matlabbatch_cmd)
51+
self.assertTrue(
52+
cmd_output.succeeded,
53+
f"Unable to run matlab-batch correctly: {cmd_output.stdout}",
54+
)
55+
expectedRelease=self.release_tag.strip().lstrip("Rr")
56+
self.assertRegex(cmd_output.stdout, expectedRelease)
57+
58+
def test_matlabbatch_version(self):
59+
"""Test the version of matlab-batch installed in the container"""
60+
readme_filepath = "../alternates/non-interactive/MATLAB-BATCH.md"
61+
expected_version = helpers.get_changelog_mb_version(readme_filepath)
62+
expected_output = f"matlab-batch {expected_version} (glnxa64)"
63+
version_cmd = f"matlab-batch -version"
64+
self.assertEqual(
65+
expected_output,
66+
self.host.check_output(version_cmd),
67+
"Mismatching versions of matlab-batch in changelog",
68+
)
69+
70+
71+
################################################################################
72+
73+
if __name__ == "__main__":
74+
unittest.main()

tests/requirements.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
# Copyright 2022-2023 The MathWorks, Inc.
1+
# Copyright 2022-2024 The MathWorks, Inc.
22

3-
docker>=6.1.2
4-
pytest-testinfra>=8.1.0
3+
docker
4+
markdown-it-py
5+
pytest-testinfra

tests/test_running_matlab.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def test_matlab_runs(self):
8585
def test_matlab_version(self):
8686
"""Test that the release number written to VER_OUTPUT_FILE and
8787
the one from the image name coincide."""
88-
helpers.wait_for_file(self.host, self.diaryfullpath, timeout=10)
88+
helpers.wait_for_file(self.host, self.diaryfullpath, timeout=30)
8989
ver_from_mat = self.host.file(self.diaryfullpath).content_string.rstrip("\n")
9090
self.assertEqual(
9191
helpers.get_release_from_string(self.image_name).upper().lstrip("R"),

tests/utils/base.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import testinfra
99
import unittest
1010

11-
1211
class TestCase(unittest.TestCase):
1312
"""Base test class for Docker tests"""
1413

tests/utils/dockertool.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def run(self, timeout=DOCKER_RUN_TIMEOUT):
8585
"""run the tests in the docker container and report the logs"""
8686
client = docker.from_env()
8787
logging.info(
88-
f"running command:\n\t{self.command}\nin a '{self.image_name}' container"
88+
f"Running command:\n\t{self.command}\nin a '{self.image_name}' container"
8989
)
9090
container = client.containers.run(
9191
image=self.image_name,

tests/utils/helpers.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
# Copyright 2023 The MathWorks, Inc.
1+
# Copyright 2023-2024 The MathWorks, Inc.
22

33
"""
44
Set of helpers functions for Docker tests.
55
"""
66

7+
from . import mdparser
78
import re
89
import os
910
import time
@@ -13,7 +14,7 @@ def _getenv_(key):
1314
try:
1415
return os.environ.get(key)
1516
except:
16-
raise ValueError(f"environment variable {key} not defined")
17+
raise ValueError(f"Environment variable {key} not defined")
1718

1819

1920
def get_image_name():
@@ -23,11 +24,11 @@ def get_image_name():
2324
def get_license_filepath():
2425
filepath = _getenv_("LICENSE_FILE_PATH")
2526
if filepath == "":
26-
raise ValueError("environment variable 'LICENSE_FILE_PATH' is empty")
27+
raise ValueError("Environment variable 'LICENSE_FILE_PATH' is empty")
2728
if not os.path.exists(filepath):
28-
raise ValueError(f"license file {filepath} does not exist")
29+
raise ValueError(f"License file {filepath} does not exist")
2930
if os.stat(filepath).st_size <= 1:
30-
raise ValueError(f"license file {filepath} is empty")
31+
raise ValueError(f"License file {filepath} is empty")
3132
return filepath
3233

3334

@@ -59,6 +60,34 @@ def remove_file(filepath):
5960
except OSError:
6061
pass
6162

63+
def get_changelog_mb_version(filepath):
64+
"""Get the latest version of matlab-batch from a .md file"""
65+
## look for the vYYYY.MM.N pattern, where
66+
# YYYY is the year
67+
# MM is the month
68+
# N is the patch number
69+
pattern = "v(20[2-9][0-9]\.[0-9]{1,2}\.[0-9]+)"
70+
ver_regexp = re.compile(pattern)
71+
72+
headings_tree=mdparser.get_headings_tree(filepath)
73+
74+
target_heading = "Changelog"
75+
path_to_target = mdparser.find_element(headings_tree, target_heading)
76+
if not path_to_target:
77+
raise ValueError(f"Unable to find '{target_heading}' in the heading tree of {filepath}")
78+
79+
version_list = mdparser.get_children(headings_tree, path_to_target)
80+
if not version_list:
81+
raise ValueError(f"The heading '{target_heading}' does not have sub-headings")
82+
83+
latest_version=version_list[0]
84+
match = ver_regexp.search(latest_version)
85+
if match is None:
86+
raise ValueError(
87+
f"The pattern '{pattern}' cannot be found in the content of {filepath}"
88+
)
89+
return match.group(1)
90+
6291

6392
## Wait functions ##
6493

0 commit comments

Comments
 (0)