Skip to content

Commit ced5c51

Browse files
Tanmay DasPrabhakar Kumar
authored andcommitted
Introduces integration tests for MATLAB Kernel with MATLAB. Run using pytest tests/integration.
Github Actions updated to run these tests on every push to main.
1 parent 5f2739a commit ced5c51

File tree

13 files changed

+824
-96
lines changed

13 files changed

+824
-96
lines changed

.github/workflows/release.yml

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,14 @@ on:
88
types: [created]
99

1010
jobs:
11-
python_tests:
12-
runs-on: ubuntu-latest
13-
14-
steps:
15-
- name: Checkout
16-
uses: actions/checkout@v3
17-
with:
18-
ref: ${{github.sha}}
19-
20-
- name: Set up Python 3.8
21-
uses: actions/setup-python@v4
22-
with:
23-
python-version: 3.8
24-
25-
- name: Install dependencies
26-
# Installing wheel package will slightly speed-up installing dependencies.
27-
# Installing the package with "[dev]" flag will install test dependecies as well,
28-
# enabling us to run pytest.
29-
run: |
30-
python3 -m pip install --upgrade pip
31-
python3 -m pip install wheel pytest
32-
python3 -m pip install .[dev]
33-
34-
- name: Run Python Tests
35-
run: python3 -m pytest
11+
call-unit-tests:
12+
# Runs unit tests
13+
uses: ./.github/workflows/run-unit-tests.yml
3614

3715
build_and_publish_pypi:
38-
needs: [python_tests]
16+
# TODO: Add integration-tests as a dependency to
17+
# the release pipeline.
18+
needs: [call-unit-tests]
3919
if: success()
4020
runs-on: ubuntu-latest
4121

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Copyright 2020-2023 The MathWorks, Inc
2+
3+
# Workflow that contains jobs to test MATLAB Jupyter Integration
4+
name: Integration testing MATLAB Jupyter Integration
5+
6+
on:
7+
# Reusable workflow
8+
# Trigger on workflow call
9+
workflow_call:
10+
11+
jobs:
12+
python_integration_tests:
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
#TODO: Add test coverage for macOs
17+
os: [ubuntu-latest, windows-latest]
18+
python-version: ["3.8", "3.11"]
19+
matlab-release: [R2020b, R2023a]
20+
21+
runs-on: ${{ matrix.os }}
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v3
25+
26+
- name: Set up MATLAB ${{ matrix.matlab-release }}
27+
# Use MATLAB Actions to get running MATLAB in GitHub Actions
28+
uses: matlab-actions/setup-matlab@v2-beta
29+
with:
30+
release: ${{ matrix.matlab-release }}
31+
products: MATLAB Symbolic_Math_Toolbox
32+
33+
- name: Set up Python ${{ matrix.python-version }}
34+
uses: actions/setup-python@v4
35+
with:
36+
python-version: ${{ matrix.python-version }}
37+
38+
- name: Install Python dependencies
39+
# Installing wheel package will slightly speed-up installing dependencies.
40+
# Installing the package with "[dev]" flag will install test dependecies as well,
41+
# enabling us to run pytest.
42+
run: |
43+
python3 -m pip install --upgrade pip
44+
python3 -m pip install wheel pytest
45+
python3 -m pip install .[dev]
46+
47+
- name: Ensure browsers are installed for playwright
48+
run: python3 -m playwright install --with-deps
49+
50+
- name: Integration test with pytest
51+
run: python3 -m pytest tests/integration
52+
env:
53+
TEST_USERNAME: ${{secrets.TEST_USERNAME}}
54+
TEST_PASSWORD: ${{secrets.TEST_PASSWORD}}

.github/workflows/run-tests.yml

Lines changed: 9 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,73 +4,17 @@
44
name: Testing MATLAB Jupyter Integration
55

66
on:
7+
workflow_dispatch:
78
push:
89
branches:
910
- "main"
1011

1112
jobs:
12-
python_tests:
13-
runs-on: ubuntu-latest
14-
env:
15-
code-cov-py: "3.10"
16-
strategy:
17-
fail-fast: false
18-
matrix:
19-
python-version: ["3.8", "3.9", "3.10", "3.11"]
20-
name: "Run Python Tests with Python ${{matrix.python-version}}"
21-
steps:
22-
- name: Checkout
23-
uses: actions/checkout@v3
24-
25-
- name: Set up Python ${{ matrix.python-version }}
26-
uses: actions/setup-python@v4
27-
with:
28-
python-version: ${{ matrix.python-version }}
29-
30-
- name: Install dependencies
31-
# Installing wheel package will slightly speed-up installing dependencies.
32-
# Installing the package with "[dev]" flag will install test dependecies as well,
33-
# enabling us to run pytest.
34-
run: |
35-
python3 -m pip install --upgrade pip
36-
python3 -m pip install wheel pytest
37-
python3 -m pip install .[dev]
38-
39-
- name: Lint with black
40-
run: black --check .
41-
42-
- name: Test with pytest
43-
if: ${{ matrix.python-version != env.code-cov-py }}
44-
run: python3 -m pytest
45-
46-
- name: Test with pytest and get code coverage for Python ${{env.code-cov-py}}
47-
if: ${{matrix.python-version == env.code-cov-py }}
48-
run: python3 -m pytest --cov --cov-report=xml
49-
50-
- name: Persist coverage data to be uploaded if all jobs are successful.
51-
if: ${{matrix.python-version == env.code-cov-py }}
52-
uses: actions/upload-artifact@v3
53-
with:
54-
name: coverage_file
55-
path: ./coverage.xml
56-
retention-days: 5
57-
58-
upload_code_coverage:
59-
name: "Upload Code Coverage using codecov"
60-
needs: [python_tests]
61-
if: success()
62-
runs-on: ubuntu-latest
63-
steps:
64-
- name: Get coverage files from previous job
65-
uses: actions/download-artifact@v3
66-
with:
67-
name: coverage_file
68-
69-
- name: Upload python coverage report to Codecov
70-
uses: codecov/codecov-action@v3
71-
with:
72-
directory: ./
73-
name: Python-codecov
74-
files: ./coverage.xml
75-
fail_ci_if_error: true
76-
verbose: true
13+
call-unit-tests:
14+
# Runs unit tests
15+
uses: ./.github/workflows/run-unit-tests.yml
16+
17+
call-integration-tests:
18+
# Runs integration tests
19+
uses: ./.github/workflows/run-integration-tests.yml
20+
secrets: inherit

.github/workflows/run-unit-tests.yml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Copyright 2020-2023 The MathWorks, Inc
2+
3+
# Workflow that contains jobs to test MATLAB Jupyter Integration
4+
name: Unit Testing MATLAB Jupyter Integration
5+
6+
on:
7+
# Reusable workflow
8+
# Trigger on workflow call
9+
workflow_call:
10+
11+
jobs:
12+
python_unit_tests:
13+
env:
14+
code-cov-py: "3.11"
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
os: [ubuntu-latest, windows-latest, macos-latest]
19+
python-version: ["3.8", "3.11"]
20+
21+
runs-on: ${{ matrix.os }}
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v3
25+
26+
- name: Set up Python ${{ matrix.python-version }}
27+
uses: actions/setup-python@v4
28+
with:
29+
python-version: ${{ matrix.python-version }}
30+
31+
- name: Install dependencies
32+
# Installing wheel package will slightly speed-up installing dependencies.
33+
# Installing the package with "[dev]" flag will install test dependecies as well,
34+
# enabling us to run pytest.
35+
run: |
36+
python3 -m pip install --upgrade pip
37+
python3 -m pip install wheel pytest
38+
python3 -m pip install .[dev]
39+
40+
- name: Lint with black
41+
run: black --check .
42+
43+
- name: Test with pytest
44+
if: ${{ matrix.python-version != env.code-cov-py }}
45+
run: python3 -m pytest tests/unit
46+
47+
- name: Test with pytest and get code coverage for Python ${{env.code-cov-py}}
48+
if: ${{matrix.python-version == env.code-cov-py }}
49+
run: python3 -m pytest --cov --cov-report=xml tests/unit
50+
51+
- name: Persist coverage data to be uploaded if all jobs are successful.
52+
if: ${{matrix.python-version == env.code-cov-py }}
53+
uses: actions/upload-artifact@v3
54+
with:
55+
name: coverage_file
56+
path: ./coverage.xml
57+
retention-days: 5
58+
59+
upload_code_coverage:
60+
name: "Upload Code Coverage using codecov"
61+
needs: [python_unit_tests]
62+
if: success()
63+
runs-on: ubuntu-latest
64+
steps:
65+
- name: Checkout
66+
uses: actions/checkout@v3
67+
68+
- name: Get coverage files from previous job
69+
uses: actions/download-artifact@v3
70+
with:
71+
name: coverage_file
72+
73+
- name: Upload python coverage report to Codecov
74+
uses: codecov/codecov-action@v3
75+
with:
76+
directory: ./
77+
name: Python-codecov
78+
files: ./coverage.xml
79+
fail_ci_if_error: true
80+
verbose: true

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@ htmlcov/
1010
coverage.xml
1111
cov_html
1212
.python-version
13+
*.env
14+
*node_modules
15+
*playwright-report
16+
*test-results

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ dependencies = [
5555
Homepage = "https://github.com/mathworks/jupyter-matlab-proxy"
5656

5757
[project.optional-dependencies]
58-
dev = ["black", "ruamel.yaml", "pytest", "pytest-cov"]
58+
dev = ["black", "pytest", "pytest-cov", "jupyter-kernel-test", "pytest-playwright"]
5959

6060
[project.entry-points.jupyter_serverproxy_servers]
6161
matlab = "jupyter_matlab_proxy:setup_matlab"

src/jupyter_matlab_kernel/kernel.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,49 @@ def __init__(self, message=None):
2929
super().__init__(message)
3030

3131

32+
def is_jupyter_testing_enabled():
33+
"""
34+
Checks if testing mode is enabled
35+
36+
Returns:
37+
bool: True if MWI_JUPYTER_TEST environment variable is set to 'true'
38+
else False
39+
"""
40+
41+
return os.environ.get("MWI_JUPYTER_TEST", "false").lower() == "true"
42+
43+
44+
def start_matlab_proxy_for_testing():
45+
"""
46+
Only used for testing purposes. Gets the matlab-proxy server configuration
47+
from environment variables and mocks the 'start_matlab_proxy' function
48+
49+
Returns:
50+
Tuple (string, string, dict):
51+
url (string): Complete URL to send HTTP requests to matlab-proxy
52+
base_url (string): Complete base url for matlab-proxy obtained from tests
53+
headers (dict): Empty dictionary
54+
"""
55+
56+
import matlab_proxy.util.mwi.environment_variables as mwi_env
57+
58+
# These environment variables are being set by tests, using dictionary lookup
59+
# instead of '.getenv' to make sure that the following line fails with the
60+
# Exception 'KeyError' in case the environment variables are not set
61+
matlab_proxy_base_url = os.environ[mwi_env.get_env_name_base_url()]
62+
matlab_proxy_app_port = os.environ[mwi_env.get_env_name_app_port()]
63+
64+
# '127.0.0.1' is used instead 'localhost' for testing since Windows machines consume
65+
# some time to resolve 'localhost' hostname
66+
url = "{protocol}://127.0.0.1:{port}{base_url}".format(
67+
protocol="http",
68+
port=matlab_proxy_app_port,
69+
base_url=matlab_proxy_base_url,
70+
)
71+
headers = {}
72+
return url, matlab_proxy_base_url, headers
73+
74+
3275
def start_matlab_proxy():
3376
"""
3477
Start matlab-proxy registered with the jupyter server which started the
@@ -45,6 +88,12 @@ def start_matlab_proxy():
4588
headers (dict): HTTP headers required while sending HTTP requests to matlab-proxy
4689
"""
4790

91+
# If jupyter testing is enabled, then a standalone matlab-proxy server would be
92+
# launched by the tests and kernel would expect the configurations of this matlab-proxy
93+
# server which is provided through environment variables to 'start_matlab_proxy_for_testing'
94+
if is_jupyter_testing_enabled():
95+
return start_matlab_proxy_for_testing()
96+
4897
nb_server_list = []
4998

5099
# The matlab-proxy server, if running, could have been started by either
@@ -176,7 +225,7 @@ def __init__(self, *args, **kwargs):
176225
# Call superclass constructor to initialize ipykernel infrastructure
177226
super(MATLABKernel, self).__init__(*args, **kwargs)
178227
try:
179-
# Start matlab-proxy using the jupyter-matlab-proxy registered endpoint
228+
# Start matlab-proxy using the jupyter-matlab-proxy registered endpoint.
180229
self.murl, self.server_base_url, self.headers = start_matlab_proxy()
181230
(
182231
self.is_matlab_licensed,

0 commit comments

Comments
 (0)