matlab-proxy 0.26.0__py3-none-any.whl → 0.27.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of matlab-proxy might be problematic. Click here for more details.
- matlab_proxy/app.py +13 -15
- matlab_proxy/app_state.py +8 -2
- matlab_proxy/default_configuration.py +2 -2
- matlab_proxy/gui/index.html +1 -1
- matlab_proxy/gui/static/js/{index.CZgGkMCD.js → index.BcDShXfH.js} +16 -16
- matlab_proxy/settings.py +3 -2
- matlab_proxy/util/list_servers.py +2 -2
- matlab_proxy/util/mwi/environment_variables.py +5 -0
- matlab_proxy/util/mwi/session_name.py +28 -0
- matlab_proxy/util/mwi/validators.py +2 -4
- {matlab_proxy-0.26.0.dist-info → matlab_proxy-0.27.0.dist-info}/METADATA +37 -25
- {matlab_proxy-0.26.0.dist-info → matlab_proxy-0.27.0.dist-info}/RECORD +19 -49
- {matlab_proxy-0.26.0.dist-info → matlab_proxy-0.27.0.dist-info}/WHEEL +1 -2
- matlab_proxy_manager/README.md +85 -0
- matlab_proxy_manager/lib/README.md +53 -0
- matlab_proxy_manager/storage/README.md +54 -0
- matlab_proxy_manager/web/README.md +37 -0
- matlab_proxy-0.26.0.dist-info/top_level.txt +0 -3
- tests/integration/__init__.py +0 -1
- tests/integration/integration_tests_with_license/__init__.py +0 -1
- tests/integration/integration_tests_with_license/conftest.py +0 -47
- tests/integration/integration_tests_with_license/test_http_end_points.py +0 -397
- tests/integration/integration_tests_without_license/__init__.py +0 -1
- tests/integration/integration_tests_without_license/conftest.py +0 -116
- tests/integration/integration_tests_without_license/test_matlab_is_down_if_unlicensed.py +0 -49
- tests/integration/utils/__init__.py +0 -1
- tests/integration/utils/integration_tests_utils.py +0 -352
- tests/integration/utils/licensing.py +0 -152
- tests/unit/__init__.py +0 -1
- tests/unit/conftest.py +0 -66
- tests/unit/test_app.py +0 -1299
- tests/unit/test_app_state.py +0 -1094
- tests/unit/test_constants.py +0 -7
- tests/unit/test_ddux.py +0 -22
- tests/unit/test_devel.py +0 -246
- tests/unit/test_non_dev_mode.py +0 -169
- tests/unit/test_settings.py +0 -679
- tests/unit/util/__init__.py +0 -3
- tests/unit/util/mwi/__init__.py +0 -1
- tests/unit/util/mwi/embedded_connector/__init__.py +0 -1
- tests/unit/util/mwi/embedded_connector/test_helpers.py +0 -29
- tests/unit/util/mwi/embedded_connector/test_request.py +0 -64
- tests/unit/util/mwi/test_custom_http_headers.py +0 -281
- tests/unit/util/mwi/test_download.py +0 -152
- tests/unit/util/mwi/test_logger.py +0 -82
- tests/unit/util/mwi/test_token_auth.py +0 -303
- tests/unit/util/mwi/test_validators.py +0 -364
- tests/unit/util/test_cookie_jar.py +0 -252
- tests/unit/util/test_mw.py +0 -550
- tests/unit/util/test_util.py +0 -221
- tests/utils/__init__.py +0 -1
- tests/utils/logging_util.py +0 -81
- {matlab_proxy-0.26.0.dist-info → matlab_proxy-0.27.0.dist-info}/entry_points.txt +0 -0
- {matlab_proxy-0.26.0.dist-info → matlab_proxy-0.27.0.dist-info/licenses}/LICENSE.md +0 -0
tests/unit/util/test_util.py
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
# Copyright 2020-2025 The MathWorks, Inc.
|
|
2
|
-
|
|
3
|
-
import asyncio
|
|
4
|
-
import pytest
|
|
5
|
-
import psutil
|
|
6
|
-
|
|
7
|
-
import inspect
|
|
8
|
-
|
|
9
|
-
from matlab_proxy import util
|
|
10
|
-
from matlab_proxy.util import get_child_processes, system, add_signal_handlers, prettify
|
|
11
|
-
from matlab_proxy.util import system
|
|
12
|
-
from matlab_proxy.util.mwi.exceptions import (
|
|
13
|
-
UIVisibleFatalError,
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def test_get_supported_termination_signals():
|
|
18
|
-
"""Test to check for supported OS signals."""
|
|
19
|
-
assert len(system.get_supported_termination_signals()) >= 1
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def test_add_signal_handlers(event_loop: asyncio.AbstractEventLoop):
|
|
23
|
-
"""Test to check if signal handlers are being added to asyncio event_loop
|
|
24
|
-
|
|
25
|
-
Args:
|
|
26
|
-
event_loop (asyncio event loop): built-in pytest fixture.
|
|
27
|
-
"""
|
|
28
|
-
|
|
29
|
-
event_loop = add_signal_handlers(event_loop)
|
|
30
|
-
|
|
31
|
-
# In posix systems, event loop is modified with new signal handlers
|
|
32
|
-
if system.is_posix():
|
|
33
|
-
assert event_loop._signal_handlers is not None
|
|
34
|
-
assert event_loop._signal_handlers.items() is not None
|
|
35
|
-
|
|
36
|
-
else:
|
|
37
|
-
import signal
|
|
38
|
-
|
|
39
|
-
# In a windows system, the signal handlers are added to the 'signal' package.
|
|
40
|
-
for interrupt_signal in system.get_supported_termination_signals():
|
|
41
|
-
assert signal.getsignal(interrupt_signal) is not None
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def test_prettify():
|
|
45
|
-
"""Tests if text is prettified"""
|
|
46
|
-
txt_arr = ["Hello world"]
|
|
47
|
-
|
|
48
|
-
prettified_txt = prettify(boundary_filler="=", text_arr=txt_arr)
|
|
49
|
-
|
|
50
|
-
assert txt_arr[0] in prettified_txt
|
|
51
|
-
assert "=" in prettified_txt
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def test_get_child_processes_no_children_initially(mocker):
|
|
55
|
-
import time
|
|
56
|
-
|
|
57
|
-
# Create mock processes
|
|
58
|
-
mock_parent_process_psutil = mocker.MagicMock(spec=psutil.Process)
|
|
59
|
-
mock_child_processes = [mocker.MagicMock(spec=psutil.Process) for _ in range(2)]
|
|
60
|
-
|
|
61
|
-
# Mock the Process class from psutil
|
|
62
|
-
mocker.patch("psutil.Process", return_value=mock_parent_process_psutil)
|
|
63
|
-
mock_parent_process_psutil.is_running.return_value = True
|
|
64
|
-
|
|
65
|
-
# Function that changes the behavior of .children() after a delay
|
|
66
|
-
def children_side_effect(*args, **kwargs):
|
|
67
|
-
# Wait for a specific time to simulate delay in the child process being present
|
|
68
|
-
time.sleep(0.4)
|
|
69
|
-
return mock_child_processes
|
|
70
|
-
|
|
71
|
-
mock_parent_process_psutil.children.side_effect = children_side_effect
|
|
72
|
-
|
|
73
|
-
# Create a mock for asyncio.subprocess.Process with a dummy pid
|
|
74
|
-
parent_process = mocker.MagicMock(spec=asyncio.subprocess.Process)
|
|
75
|
-
parent_process.pid = 12345
|
|
76
|
-
|
|
77
|
-
# Call the function with the mocked parent process
|
|
78
|
-
child_processes = get_child_processes(parent_process)
|
|
79
|
-
|
|
80
|
-
# Assert that the return value is our list of mock child processes
|
|
81
|
-
assert child_processes == mock_child_processes
|
|
82
|
-
|
|
83
|
-
# Assert that is_running and children methods were called on the mock
|
|
84
|
-
mock_parent_process_psutil.children.assert_called_with(recursive=False)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
def test_get_child_processes_no_children(mocker):
|
|
88
|
-
# Create a mock for asyncio.subprocess.Process with a dummy pid
|
|
89
|
-
parent_process = mocker.MagicMock(spec=asyncio.subprocess.Process)
|
|
90
|
-
parent_process.pid = 12345
|
|
91
|
-
|
|
92
|
-
# Mock the Process class from psutil
|
|
93
|
-
mock_parent_process_psutil = mocker.MagicMock(spec=psutil.Process)
|
|
94
|
-
mocker.patch("psutil.Process", return_value=mock_parent_process_psutil)
|
|
95
|
-
mock_parent_process_psutil.is_running.return_value = True
|
|
96
|
-
mock_parent_process_psutil.children.return_value = []
|
|
97
|
-
|
|
98
|
-
# Call the function with the mocked parent process
|
|
99
|
-
with pytest.raises(UIVisibleFatalError):
|
|
100
|
-
get_child_processes(parent_process)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
def test_get_child_processes_with_children(mocker):
|
|
104
|
-
# Create mock processes
|
|
105
|
-
mock_parent_process_psutil = mocker.MagicMock(spec=psutil.Process)
|
|
106
|
-
mock_child_process = mocker.MagicMock(spec=psutil.Process)
|
|
107
|
-
|
|
108
|
-
# Mock the Process class from psutil
|
|
109
|
-
mocker.patch("psutil.Process", return_value=mock_parent_process_psutil)
|
|
110
|
-
mock_parent_process_psutil.is_running.return_value = True
|
|
111
|
-
|
|
112
|
-
# Mock a list of child processes that psutil would return
|
|
113
|
-
mock_parent_process_psutil.children.return_value = [mock_child_process]
|
|
114
|
-
|
|
115
|
-
# Create a mock for asyncio.subprocess.Process with a dummy pid
|
|
116
|
-
parent_process = mocker.MagicMock(spec=asyncio.subprocess.Process)
|
|
117
|
-
parent_process.pid = 12345
|
|
118
|
-
|
|
119
|
-
# Call the function with the mocked parent process
|
|
120
|
-
child_processes = get_child_processes(parent_process)
|
|
121
|
-
|
|
122
|
-
# Assert that the returned value is a list containing the mock child process
|
|
123
|
-
assert child_processes == [mock_child_process]
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
def test_get_child_processes_parent_not_running(mocker):
|
|
127
|
-
# Mock the Process class from psutil
|
|
128
|
-
mock_parent_process_psutil = mocker.MagicMock(spec=psutil.Process)
|
|
129
|
-
mocker.patch("psutil.Process", return_value=mock_parent_process_psutil)
|
|
130
|
-
mock_parent_process_psutil.is_running.return_value = False
|
|
131
|
-
|
|
132
|
-
# Create a mock for asyncio.subprocess.Process with a dummy pid
|
|
133
|
-
parent_process = mocker.MagicMock(spec=asyncio.subprocess.Process)
|
|
134
|
-
parent_process.pid = 12345
|
|
135
|
-
|
|
136
|
-
# Calling the function with a non-running parent process should raise an AssertionError
|
|
137
|
-
with pytest.raises(
|
|
138
|
-
AssertionError,
|
|
139
|
-
match="Can't check for child processes as the parent process is no longer running.",
|
|
140
|
-
):
|
|
141
|
-
get_child_processes(parent_process)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def test_get_caller_name():
|
|
145
|
-
"""Test to check if caller name is not empty"""
|
|
146
|
-
# Arrange
|
|
147
|
-
|
|
148
|
-
# Act
|
|
149
|
-
caller_name = util.get_caller_name()
|
|
150
|
-
|
|
151
|
-
# Assert
|
|
152
|
-
assert caller_name is not None
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
@pytest.fixture
|
|
156
|
-
def tracking_lock():
|
|
157
|
-
"""Pytest fixture which returns an instance of TrackingLock for testing purposes."""
|
|
158
|
-
return util.TrackingLock("test_purpose")
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
async def test_TrackingLock(tracking_lock):
|
|
162
|
-
"""Test to check various methods of TrackingLock class
|
|
163
|
-
|
|
164
|
-
Args:
|
|
165
|
-
tracking_lock (TrackingLock): Pytest fixture
|
|
166
|
-
"""
|
|
167
|
-
name_of_current_fn = inspect.currentframe().f_code.co_name
|
|
168
|
-
|
|
169
|
-
await tracking_lock.acquire()
|
|
170
|
-
assert tracking_lock.acquired_by == name_of_current_fn
|
|
171
|
-
assert tracking_lock.locked()
|
|
172
|
-
|
|
173
|
-
await tracking_lock.release()
|
|
174
|
-
tracking_lock.acquired_by is None
|
|
175
|
-
assert not tracking_lock.locked()
|
|
176
|
-
|
|
177
|
-
assert tracking_lock.purpose is not None
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
async def test_validate_lock_for_caller_when_not_locked(tracking_lock):
|
|
181
|
-
"""Test to check if validate_lock_for_caller returns False when the lock is not acquired
|
|
182
|
-
|
|
183
|
-
Args:
|
|
184
|
-
tracking_lock (TrackingLock): Pytest fixture
|
|
185
|
-
"""
|
|
186
|
-
assert not tracking_lock.validate_lock_for_caller("some_caller")
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
async def test_validate_lock_for_caller_happy_path(tracking_lock):
|
|
190
|
-
"""Test to check if validate_lock_for_caller returns True when the lock was acquired by the
|
|
191
|
-
same function as the caller.
|
|
192
|
-
|
|
193
|
-
Args:
|
|
194
|
-
tracking_lock (TrackingLock): Pytest fixture
|
|
195
|
-
"""
|
|
196
|
-
name_of_current_fn = inspect.currentframe().f_code.co_name
|
|
197
|
-
|
|
198
|
-
await tracking_lock.acquire()
|
|
199
|
-
assert tracking_lock.validate_lock_for_caller(name_of_current_fn)
|
|
200
|
-
await tracking_lock.release()
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
async def test_validate_lock_for_caller_lock_acquired_by_other_function(tracking_lock):
|
|
204
|
-
"""Test to check if validate_lock_for_caller returns False when the lock was acquired by
|
|
205
|
-
some other function
|
|
206
|
-
|
|
207
|
-
Args:
|
|
208
|
-
tracking_lock (TrackingLock): Pytest fixture
|
|
209
|
-
"""
|
|
210
|
-
# Arrange
|
|
211
|
-
name_of_current_fn = inspect.currentframe().f_code.co_name
|
|
212
|
-
|
|
213
|
-
# Acquire lock inside a nested function
|
|
214
|
-
def nested_fn():
|
|
215
|
-
tracking_lock.acquire()
|
|
216
|
-
|
|
217
|
-
# Act
|
|
218
|
-
nested_fn()
|
|
219
|
-
|
|
220
|
-
# Assert
|
|
221
|
-
assert not tracking_lock.validate_lock_for_caller(name_of_current_fn)
|
tests/utils/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# Copyright 2023-2024 The MathWorks, Inc.
|
tests/utils/logging_util.py
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
# Copyright 2024 The MathWorks, Inc.
|
|
2
|
-
|
|
3
|
-
import logging
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from os import getenv
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def create_integ_test_logger(
|
|
9
|
-
log_name,
|
|
10
|
-
log_level=getenv("MWI_TEST_LOG_LEVEL", "WARNING"),
|
|
11
|
-
log_file_path=getenv("MWI_INTEG_TESTS_LOG_FILE_PATH"),
|
|
12
|
-
):
|
|
13
|
-
return create_test_logger(
|
|
14
|
-
log_name, log_level, log_file_path, output_prefix="INTEG TEST"
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def create_unit_test_logger(
|
|
19
|
-
log_name,
|
|
20
|
-
log_level=getenv("MWI_TEST_LOG_LEVEL", "WARNING"),
|
|
21
|
-
log_file_path=getenv("MWI_UNIT_TESTS_LOG_FILE_PATH"),
|
|
22
|
-
):
|
|
23
|
-
return create_test_logger(
|
|
24
|
-
log_name, log_level, log_file_path, output_prefix="UNIT TEST"
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def create_test_logger(
|
|
29
|
-
log_name,
|
|
30
|
-
log_level=getenv("MWI_TEST_LOG_LEVEL", "WARNING"),
|
|
31
|
-
log_file_path=None,
|
|
32
|
-
output_prefix="TEST",
|
|
33
|
-
):
|
|
34
|
-
"""
|
|
35
|
-
Returns a logger with specified name and level
|
|
36
|
-
|
|
37
|
-
Args:
|
|
38
|
-
log_file_path (string): Log file path to which the logs should be written
|
|
39
|
-
log_level (logger level attribute): Log level to be set for the logger
|
|
40
|
-
log_name (string): Name of the logger to be used
|
|
41
|
-
"""
|
|
42
|
-
|
|
43
|
-
# Create a logger with the name 'TEST'
|
|
44
|
-
logger = logging.getLogger(output_prefix + " - " + log_name)
|
|
45
|
-
|
|
46
|
-
# Create a formatter
|
|
47
|
-
formatter = logging.Formatter(
|
|
48
|
-
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
# Set the logging level (e.g., DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
|
52
|
-
logger.setLevel(log_level)
|
|
53
|
-
|
|
54
|
-
if log_file_path:
|
|
55
|
-
file_path = Path(log_file_path)
|
|
56
|
-
|
|
57
|
-
# Create a file handler
|
|
58
|
-
file_handler = logging.FileHandler(filename=file_path, mode="a")
|
|
59
|
-
|
|
60
|
-
# Set a logging level for the file
|
|
61
|
-
file_handler.setLevel(log_level)
|
|
62
|
-
|
|
63
|
-
# Set the formatter for the console handler
|
|
64
|
-
file_handler.setFormatter(formatter)
|
|
65
|
-
|
|
66
|
-
# Add the console handler to the logger
|
|
67
|
-
logger.addHandler(file_handler)
|
|
68
|
-
|
|
69
|
-
# Create a console handler
|
|
70
|
-
console_handler = logging.StreamHandler()
|
|
71
|
-
|
|
72
|
-
# Set a logging level for the console handler
|
|
73
|
-
console_handler.setLevel(log_level)
|
|
74
|
-
|
|
75
|
-
# Set the formatter for the console handler
|
|
76
|
-
console_handler.setFormatter(formatter)
|
|
77
|
-
|
|
78
|
-
# Add the console handler to the logger
|
|
79
|
-
logger.addHandler(console_handler)
|
|
80
|
-
|
|
81
|
-
return logger
|
|
File without changes
|
|
File without changes
|