Skip to content

Commit 4617072

Browse files
pranaverma92krisctl
authored andcommitted
Integrates proxy manager infrastructure into integration testing framework for MATLAB proxy provisioning.
1 parent 538433d commit 4617072

File tree

8 files changed

+279
-129
lines changed

8 files changed

+279
-129
lines changed

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,19 @@ jobs:
4848
- name: Ensure browsers are installed for playwright
4949
run: python3 -m playwright install --with-deps
5050

51+
- name: License MATLAB Proxy
52+
env:
53+
TEST_USERNAME: ${{ secrets.TEST_USERNAME }}
54+
TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }}
55+
run: |
56+
python3 -c "from tests.integration.utils import licensing; licensing.start_and_license_matlab_proxy_using_jsp()"
57+
5158
- name: Integration test with pytest
52-
run: python3 -m pytest tests/integration -vs
5359
env:
54-
TEST_USERNAME: ${{secrets.TEST_USERNAME}}
55-
TEST_PASSWORD: ${{secrets.TEST_PASSWORD}}
60+
MWI_LOG_LEVEL: "DEBUG"
61+
MWI_LOG_FILE: ${{github.workspace}}/tests/integration/integ_logs.log
62+
63+
run: python3 -m pytest tests/integration -vs
5664

5765
- name: Preserve test logs
5866
if: ${{ always() }}

tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Copyright 2024 The MathWorks, Inc.

tests/integration/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Copyright 2024 The MathWorks, Inc.

tests/integration/conftest.py

Lines changed: 82 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,95 @@
11
# Copyright 2023-2024 The MathWorks, Inc.
22

3-
import os
4-
import shutil
5-
6-
import integration_test_utils
73
import matlab_proxy.util.event_loop as mwi_event_loop
4+
import os
85
import pytest
6+
import tests.integration.utils.integration_test_utils as utils
97
import requests.exceptions
108
from matlab_proxy import settings as mwi_settings
119

1210
_MATLAB_STARTUP_TIMEOUT = mwi_settings.get_process_startup_timeout()
1311

14-
15-
@pytest.fixture(autouse=True, scope="module")
16-
def matlab_proxy_fixture(module_monkeypatch):
17-
"""
18-
Pytest fixture for managing a standalone matlab-proxy process
19-
for testing purposes. This fixture sets up a matlab-proxy process in
20-
the module scope, and tears it down after all the tests are executed.
21-
22-
Args:
23-
monkeypatch_module_scope (fixture): returns a MonkeyPatch object
24-
available in module scope
25-
"""
26-
27-
integration_test_utils.perform_basic_checks()
28-
29-
# Select a random free port to serve matlab-proxy for testing
30-
mwi_app_port = integration_test_utils.get_random_free_port()
31-
mwi_base_url = "/matlab-test"
32-
33-
# '127.0.0.1' is used instead 'localhost' for testing since Windows machines consume
34-
# some time to resolve 'localhost' hostname
35-
matlab_proxy_url = f"http://127.0.0.1:{mwi_app_port}{mwi_base_url}"
36-
37-
# Set the log path based on the test's execution environment
38-
log_path = "tests/integration/integ_logs.log"
39-
base_path = os.environ.get(
40-
"GITHUB_WORKSPACE", os.path.dirname(os.path.abspath(__name__))
41-
)
42-
matlab_proxy_logs_path = os.path.join(base_path, log_path)
43-
44-
# Start matlab-proxy-app for testing
45-
input_env = {
46-
# MWI_JUPYTER_TEST env variable is used in jupyter_matlab_kernel/kernel.py
47-
# to bypass jupyter server for testing
48-
"MWI_JUPYTER_TEST": "true",
49-
"MWI_APP_PORT": mwi_app_port,
50-
"MWI_BASE_URL": mwi_base_url,
51-
"MWI_LOG_FILE": str(matlab_proxy_logs_path),
52-
"MWI_JUPYTER_LOG_LEVEL": "WARN",
53-
"MWI_ENABLE_TOKEN_AUTH": "false",
54-
}
55-
56-
# Get event loop to start matlab-proxy in background
57-
loop = mwi_event_loop.get_event_loop()
58-
59-
# Run matlab-proxy in the background in an event loop
60-
matlab_proxy_process = loop.run_until_complete(
61-
integration_test_utils.start_matlab_proxy_app(input_env=input_env)
62-
)
63-
# Poll for matlab-proxy URL to respond
64-
integration_test_utils.poll_web_service(
65-
matlab_proxy_url,
66-
step=5,
67-
timeout=_MATLAB_STARTUP_TIMEOUT,
68-
ignore_exceptions=(
69-
requests.exceptions.ConnectionError,
70-
requests.exceptions.SSLError,
71-
),
72-
)
73-
# License matlab-proxy using playwright UI automation
74-
integration_test_utils.license_matlab_proxy(matlab_proxy_url)
75-
76-
# Wait for matlab-proxy to be up and running
77-
loop.run_until_complete(
78-
integration_test_utils.wait_matlab_proxy_ready(matlab_proxy_url)
79-
)
80-
81-
# Update the OS environment variables such as app port, base url etc.
82-
# so that they can be used by MATLAB Kernel to obtain MATLAB
83-
for key, value in input_env.items():
84-
module_monkeypatch.setenv(key, value)
85-
86-
# Run the jupyter kernel tests
87-
yield
88-
89-
# Request timeouts
90-
timeout = 120 # seconds
91-
# Send shutdown_integration request to MATLAB Proxy
92-
shutdown_url = f"{matlab_proxy_url}/shutdown_integration"
93-
try:
94-
requests.delete(shutdown_url, timeout=timeout)
95-
except requests.exceptions.Timeout:
96-
print("Timed out waiting for matlab-proxy to shutdown, killing process.")
97-
matlab_proxy_process.kill()
98-
99-
100-
@pytest.fixture(scope="module", autouse=True)
101-
def matlab_config_cleanup_fixture(request):
102-
"""
103-
Cleanup the directory that contains matlab config file
104-
before and after running the tests. This is done to make sure that
105-
matlab-proxy is unlicensed.
106-
"""
107-
108-
def delete_matlab_test_dir():
109-
# Delete matlab_config_file & its owning directory
110-
matlab_config_file = __get_matlab_config_file()
111-
matlab_config_dir = os.path.dirname(matlab_config_file)
12+
if os.getenv("MWI_USE_FALLBACK_KERNEL") != "false":
13+
14+
@pytest.fixture(autouse=True, scope="module")
15+
def matlab_proxy_fixture(module_monkeypatch):
16+
"""
17+
Pytest fixture for managing a standalone matlab-proxy process
18+
for testing purposes. This fixture sets up a matlab-proxy process in
19+
the module scope, and tears it down after all the tests are executed.
20+
21+
Args:
22+
monkeypatch_module_scope (fixture): returns a MonkeyPatch object
23+
available in module scope
24+
"""
25+
26+
utils.perform_basic_checks()
27+
28+
# Select a random free port to serve matlab-proxy for testing
29+
mwi_app_port = utils.get_random_free_port()
30+
mwi_base_url = "/matlab-test"
31+
32+
# '127.0.0.1' is used instead 'localhost' for testing since Windows machines consume
33+
# some time to resolve 'localhost' hostname
34+
matlab_proxy_url = f"http://127.0.0.1:{mwi_app_port}{mwi_base_url}"
35+
36+
# Set the log path based on the test's execution environment
37+
log_path = "tests/integration/integ_logs.log"
38+
base_path = os.environ.get(
39+
"GITHUB_WORKSPACE", os.path.dirname(os.path.abspath(__name__))
40+
)
41+
matlab_proxy_logs_path = os.path.join(base_path, log_path)
42+
43+
# Start matlab-proxy-app for testing
44+
input_env = {
45+
# MWI_JUPYTER_TEST env variable is used in jupyter_matlab_kernel/kernel.py
46+
# to bypass jupyter server for testing
47+
"MWI_JUPYTER_TEST": "true",
48+
"MWI_APP_PORT": mwi_app_port,
49+
"MWI_BASE_URL": mwi_base_url,
50+
"MWI_LOG_FILE": str(matlab_proxy_logs_path),
51+
"MWI_JUPYTER_LOG_LEVEL": "WARN",
52+
"MWI_ENABLE_TOKEN_AUTH": "false",
53+
}
54+
55+
# Get event loop to start matlab-proxy in background
56+
loop = mwi_event_loop.get_event_loop()
57+
58+
# Run matlab-proxy in the background in an event loop
59+
matlab_proxy_process = loop.run_until_complete(
60+
utils.start_matlab_proxy_app(input_env=input_env)
61+
)
62+
# Poll for matlab-proxy URL to respond
63+
utils.poll_web_service(
64+
matlab_proxy_url,
65+
step=5,
66+
timeout=_MATLAB_STARTUP_TIMEOUT,
67+
ignore_exceptions=(
68+
requests.exceptions.ConnectionError,
69+
requests.exceptions.SSLError,
70+
),
71+
)
72+
73+
# Wait for matlab-proxy to be up and running
74+
loop.run_until_complete(utils.wait_matlab_proxy_ready(matlab_proxy_url))
75+
76+
# Update the OS environment variables such as app port, base url etc.
77+
# so that they can be used by MATLAB Kernel to obtain MATLAB
78+
for key, value in input_env.items():
79+
module_monkeypatch.setenv(key, value)
80+
81+
# Run the jupyter kernel tests
82+
yield
83+
84+
# Request timeouts
85+
timeout = 120 # seconds
86+
# Send shutdown_integration request to MATLAB Proxy
87+
shutdown_url = f"{matlab_proxy_url}/shutdown_integration"
11288
try:
113-
shutil.rmtree(matlab_config_dir)
114-
except FileNotFoundError:
115-
pass
116-
117-
# Runs in the beginning to make sure that matlab-proxy is
118-
# not already licensed
119-
delete_matlab_test_dir()
120-
121-
# Runs in the end to cleanup licensing cache
122-
request.addfinalizer(delete_matlab_test_dir)
89+
requests.delete(shutdown_url, timeout=timeout)
90+
except requests.exceptions.Timeout:
91+
print("Timed out waiting for matlab-proxy to shutdown, killing process.")
92+
matlab_proxy_process.kill()
12393

12494

12595
@pytest.fixture(scope="module", name="module_monkeypatch")
@@ -135,14 +105,3 @@ class object: Object of class MonkeyPatch
135105
"""
136106
with pytest.MonkeyPatch.context() as mp:
137107
yield mp
138-
139-
140-
def __get_matlab_config_file():
141-
"""
142-
Gets the path to MATLAB config file generated by matlab-proxy
143-
144-
Returns:
145-
string: MATLAB config file path
146-
"""
147-
148-
return mwi_settings.get()["matlab_config_file"]

tests/integration/test_matlab_integration.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ class MATLABKernelTests(jupyter_kernel_test.KernelTests):
3535
# Clears the cell output area
3636
code_clear_output = "clc"
3737

38+
# Increasing the default timeout value for execute_helper function to 60s
39+
# mitigate the test timeout in the case of MPM kernel
40+
def execute_helper(self, code, timeout=60, **kwargs):
41+
return super().execute_helper(code, timeout=timeout, **kwargs)
42+
3843
def setUp(self):
3944
self.flush_channels()
4045

@@ -114,10 +119,10 @@ def test_magics(self):
114119
self.assertIn("%%help", output_text)
115120

116121
# ---- Utility Functions ----
117-
def _run_code(self, code, timeout=30):
122+
def _run_code(self, code):
118123
"""Runs code in Jupyter notebook cell"""
119124

120-
reply, output_msgs = self.execute_helper(code=code, timeout=timeout)
125+
reply, output_msgs = self.execute_helper(code=code)
121126
return reply, output_msgs
122127

123128
def _get_output_header_msg_type(self, output_msgs):

tests/integration/utils/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Copyright 2024 The MathWorks, Inc.

tests/integration/integration_test_utils.py renamed to tests/integration/utils/integration_test_utils.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import os
66
import socket
77
import time
8-
98
import requests
109
from matlab_proxy.settings import get_process_startup_timeout
1110

0 commit comments

Comments
 (0)