matlab-proxy 0.24.2__py3-none-any.whl → 0.25.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 +1 -3
- matlab_proxy/app_state.py +39 -13
- matlab_proxy/constants.py +2 -1
- matlab_proxy/gui/index.html +1 -1
- matlab_proxy/gui/static/js/index.qK3VCGVb.js +64 -0
- matlab_proxy/matlab/startup.m +1 -4
- matlab_proxy/settings.py +15 -11
- matlab_proxy/util/mwi/environment_variables.py +2 -27
- matlab_proxy/util/mwi/exceptions.py +14 -1
- {matlab_proxy-0.24.2.dist-info → matlab_proxy-0.25.0.dist-info}/METADATA +31 -19
- {matlab_proxy-0.24.2.dist-info → matlab_proxy-0.25.0.dist-info}/RECORD +23 -23
- {matlab_proxy-0.24.2.dist-info → matlab_proxy-0.25.0.dist-info}/WHEEL +1 -1
- {matlab_proxy-0.24.2.dist-info → matlab_proxy-0.25.0.dist-info}/entry_points.txt +0 -1
- tests/integration/integration_tests_with_license/test_http_end_points.py +4 -5
- tests/unit/test_app.py +94 -45
- tests/unit/test_app_state.py +8 -7
- tests/unit/test_non_dev_mode.py +4 -4
- tests/unit/test_settings.py +0 -15
- tests/unit/util/mwi/test_token_auth.py +5 -5
- tests/unit/util/test_mw.py +2 -2
- tests/unit/util/test_util.py +7 -7
- matlab_proxy/gui/static/js/index.c3NLxnRM.js +0 -64
- {matlab_proxy-0.24.2.dist-info → matlab_proxy-0.25.0.dist-info}/LICENSE.md +0 -0
- {matlab_proxy-0.24.2.dist-info → matlab_proxy-0.25.0.dist-info}/top_level.txt +0 -0
matlab_proxy/matlab/startup.m
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
% Copyright 2020-
|
|
1
|
+
% Copyright 2020-2025 The MathWorks, Inc.
|
|
2
2
|
|
|
3
|
-
if (strlength(getenv('MWI_BASE_URL')) > 0)
|
|
4
|
-
connector.internal.setConfig('contextRoot', getenv('MWI_BASE_URL'));
|
|
5
|
-
end
|
|
6
3
|
evalc('connector.internal.Worker.start');
|
|
7
4
|
|
|
8
5
|
% Add-on explorer is not supported in this environment.
|
matlab_proxy/settings.py
CHANGED
|
@@ -218,6 +218,7 @@ def get_dev_settings(config):
|
|
|
218
218
|
),
|
|
219
219
|
"warnings": [],
|
|
220
220
|
"is_xvfb_available": False,
|
|
221
|
+
"is_windowmanager_available": False,
|
|
221
222
|
"mwi_idle_timeout": None,
|
|
222
223
|
}
|
|
223
224
|
|
|
@@ -271,12 +272,21 @@ def get(config_name=matlab_proxy.get_default_config_name(), dev=False):
|
|
|
271
272
|
settings.update(get_server_settings(config_name))
|
|
272
273
|
|
|
273
274
|
settings["is_xvfb_available"] = True if shutil.which("Xvfb") else False
|
|
275
|
+
settings["is_windowmanager_available"] = (
|
|
276
|
+
True if shutil.which("fluxbox") else False
|
|
277
|
+
)
|
|
274
278
|
|
|
275
279
|
# Warn user if xvfb is not available on system path.
|
|
276
|
-
if system.is_linux()
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
+
if system.is_linux():
|
|
281
|
+
if not settings["is_xvfb_available"]:
|
|
282
|
+
warning = " Unable to find Xvfb on the system PATH. Xvfb enables graphical abilities like plots and figures in the MATLAB desktop.\nConsider adding Xvfb to the system PATH and restart matlab-proxy.\nFor details, see https://github.com/mathworks/matlab-proxy#requirements."
|
|
283
|
+
logger.warning(warning)
|
|
284
|
+
settings["warnings"].append(warning)
|
|
285
|
+
|
|
286
|
+
if not settings["is_windowmanager_available"]:
|
|
287
|
+
warning = " Unable to find fluxbox on the system PATH. To use Simulink Online, add Fluxbox to the system PATH and restart matlab-proxy. For details, see https://github.com/mathworks/matlab-proxy#requirements."
|
|
288
|
+
logger.warning(warning)
|
|
289
|
+
settings["warnings"].append(warning)
|
|
280
290
|
|
|
281
291
|
settings.update(get_matlab_settings())
|
|
282
292
|
|
|
@@ -674,12 +684,6 @@ def _get_matlab_cmd(matlab_executable_path, code_to_execute, nlm_conn_str):
|
|
|
674
684
|
if system.is_windows():
|
|
675
685
|
flag_to_hide_desktop.extend(["-noDisplayDesktop", "-wait", "-log"])
|
|
676
686
|
|
|
677
|
-
mpa_flags = (
|
|
678
|
-
mwi_env.Experimental.get_mpa_flags()
|
|
679
|
-
if mwi_env.Experimental.is_mpa_enabled()
|
|
680
|
-
else ""
|
|
681
|
-
)
|
|
682
|
-
|
|
683
687
|
profile_matlab_startup = (
|
|
684
688
|
"-timing" if mwi_env.Experimental.is_matlab_startup_profiling_enabled() else ""
|
|
685
689
|
)
|
|
@@ -691,7 +695,7 @@ def _get_matlab_cmd(matlab_executable_path, code_to_execute, nlm_conn_str):
|
|
|
691
695
|
"-softwareopengl",
|
|
692
696
|
# " v=mvm ",
|
|
693
697
|
*matlab_lic_mode,
|
|
694
|
-
|
|
698
|
+
"-externalUI",
|
|
695
699
|
profile_matlab_startup,
|
|
696
700
|
"-r",
|
|
697
701
|
code_to_execute,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2020-
|
|
1
|
+
# Copyright 2020-2025 The MathWorks, Inc.
|
|
2
2
|
"""This file lists and exposes the environment variables which are used by the integration."""
|
|
3
3
|
|
|
4
4
|
import os
|
|
@@ -189,26 +189,6 @@ class Experimental:
|
|
|
189
189
|
"""Returns true if the simulink online is enabled."""
|
|
190
190
|
return _is_env_set_to_true(Experimental.get_env_name_enable_simulink())
|
|
191
191
|
|
|
192
|
-
@staticmethod
|
|
193
|
-
def should_use_mos_html():
|
|
194
|
-
"""Returns true if matlab-proxy should use MOS htmls to load MATLAB"""
|
|
195
|
-
return _is_env_set_to_true("MWI_USE_MOS")
|
|
196
|
-
|
|
197
|
-
@staticmethod
|
|
198
|
-
def should_use_mre_html():
|
|
199
|
-
"""Returns true if matlab-proxy should provide MRE parameter to the htmls used to load MATLAB"""
|
|
200
|
-
return _is_env_set_to_true("MWI_USE_MRE")
|
|
201
|
-
|
|
202
|
-
@staticmethod
|
|
203
|
-
def get_env_name_enable_mpa():
|
|
204
|
-
"""Returns the environment variable name used to enable MPA support"""
|
|
205
|
-
return "MWI_ENABLE_MPA"
|
|
206
|
-
|
|
207
|
-
@staticmethod
|
|
208
|
-
def is_mpa_enabled():
|
|
209
|
-
"""Returns true if the simulink online is enabled."""
|
|
210
|
-
return _is_env_set_to_true(Experimental.get_env_name_enable_mpa())
|
|
211
|
-
|
|
212
192
|
@staticmethod
|
|
213
193
|
def get_env_name_profile_matlab_startup():
|
|
214
194
|
"""Returns the environment variable name used to enable MPA support"""
|
|
@@ -216,10 +196,5 @@ class Experimental:
|
|
|
216
196
|
|
|
217
197
|
@staticmethod
|
|
218
198
|
def is_matlab_startup_profiling_enabled():
|
|
219
|
-
"""Returns true if the
|
|
199
|
+
"""Returns true if the startup profiling is enabled."""
|
|
220
200
|
return _is_env_set_to_true(Experimental.get_env_name_profile_matlab_startup())
|
|
221
|
-
|
|
222
|
-
@staticmethod
|
|
223
|
-
def get_mpa_flags():
|
|
224
|
-
"""Returns list of flags required to enable MPA"""
|
|
225
|
-
return ["-webui", "-externalUI"]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2020-
|
|
1
|
+
# Copyright 2020-2025 The MathWorks, Inc.
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class AppError(Exception):
|
|
@@ -139,6 +139,19 @@ class XvfbError(AppError):
|
|
|
139
139
|
pass
|
|
140
140
|
|
|
141
141
|
|
|
142
|
+
class WindowManagerError(AppError):
|
|
143
|
+
"""A Class which inherits the AppError class.
|
|
144
|
+
|
|
145
|
+
This class represents any errors raised when instantiating a Window Manager within the Xvfb DISPLAY.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
AppError (Class): Parent Class containing attributes to store
|
|
149
|
+
messages, logs and stacktrace.
|
|
150
|
+
"""
|
|
151
|
+
|
|
152
|
+
pass
|
|
153
|
+
|
|
154
|
+
|
|
142
155
|
class EmbeddedConnectorError(MatlabError):
|
|
143
156
|
"""A Class which inherits the MatlabError class.
|
|
144
157
|
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: matlab-proxy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.25.0
|
|
4
4
|
Summary: Python® package enables you to launch MATLAB® and access it from a web browser.
|
|
5
5
|
Home-page: https://github.com/mathworks/matlab-proxy/
|
|
6
6
|
Author: The MathWorks, Inc.
|
|
7
7
|
Author-email: cloud@mathworks.com
|
|
8
8
|
License: MATHWORKS CLOUD REFERENCE ARCHITECTURE LICENSE
|
|
9
9
|
Keywords: Proxy,MATLAB Proxy,MATLAB,MATLAB Javascript Desktop,MATLAB Web Desktop,Remote MATLAB Web Access
|
|
10
|
-
Platform: UNKNOWN
|
|
11
10
|
Classifier: Intended Audience :: Developers
|
|
12
11
|
Classifier: Natural Language :: English
|
|
13
12
|
Classifier: Programming Language :: Python
|
|
@@ -17,12 +16,14 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
17
|
Requires-Python: ~=3.8
|
|
19
18
|
Description-Content-Type: text/markdown
|
|
20
|
-
|
|
19
|
+
License-File: LICENSE.md
|
|
20
|
+
Requires-Dist: aiohttp>=3.7.4
|
|
21
21
|
Requires-Dist: aiohttp-session[secure]
|
|
22
22
|
Requires-Dist: importlib-metadata
|
|
23
23
|
Requires-Dist: importlib-resources
|
|
24
24
|
Requires-Dist: psutil
|
|
25
25
|
Requires-Dist: watchdog
|
|
26
|
+
Requires-Dist: requests
|
|
26
27
|
Provides-Extra: dev
|
|
27
28
|
Requires-Dist: aiohttp-devtools; extra == "dev"
|
|
28
29
|
Requires-Dist: black; extra == "dev"
|
|
@@ -34,7 +35,6 @@ Requires-Dist: pytest-mock; extra == "dev"
|
|
|
34
35
|
Requires-Dist: pytest-aiohttp; extra == "dev"
|
|
35
36
|
Requires-Dist: psutil; extra == "dev"
|
|
36
37
|
Requires-Dist: urllib3; extra == "dev"
|
|
37
|
-
Requires-Dist: requests; extra == "dev"
|
|
38
38
|
Requires-Dist: pytest-playwright; extra == "dev"
|
|
39
39
|
|
|
40
40
|
# MATLAB Proxy
|
|
@@ -42,11 +42,11 @@ Requires-Dist: pytest-playwright; extra == "dev"
|
|
|
42
42
|
|
|
43
43
|
----
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
Use this Python® package `matlab-proxy` to start MATLAB® and access it from a web browser.
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
Install this package to create an executable `matlab-proxy-app`, which starts MATLAB and provides you a URL to access it.
|
|
48
|
+
|
|
49
|
+
MATLAB Proxy is under active development. For support or to report issues, see [Feedback](#feedback).
|
|
50
50
|
|
|
51
51
|
----
|
|
52
52
|
|
|
@@ -62,17 +62,19 @@ The MATLAB Proxy is under active development. For support or to report issues, s
|
|
|
62
62
|
- [Feedback](#feedback)
|
|
63
63
|
|
|
64
64
|
## Requirements
|
|
65
|
-
* MATLAB® R2020b or later
|
|
65
|
+
* MATLAB® R2020b or later, installed and added to the system PATH.
|
|
66
66
|
```bash
|
|
67
67
|
# Confirm MATLAB is on the PATH
|
|
68
68
|
which matlab
|
|
69
69
|
```
|
|
70
70
|
* The dependencies required to run MATLAB.
|
|
71
|
-
|
|
71
|
+
For details, refer to the Dockerfiles in the [matlab-deps](https://github.com/mathworks-ref-arch/container-images/tree/master/matlab-deps) repository for your desired version of MATLAB.
|
|
72
|
+
|
|
73
|
+
* X Virtual Frame Buffer (Xvfb) (only for Linux® based systems):
|
|
72
74
|
|
|
73
|
-
|
|
75
|
+
Installing Xvfb is optional (starting v0.11.0 of matlab-proxy) but highly recommended. Xvfb enables graphical abilities like plots and figures in the MATLAB desktop.
|
|
76
|
+
To install Xvfb on your Linux machine, use:
|
|
74
77
|
|
|
75
|
-
Install it on your linux machine using:
|
|
76
78
|
```bash
|
|
77
79
|
# On a Debian/Ubuntu based system:
|
|
78
80
|
$ sudo apt install xvfb
|
|
@@ -84,8 +86,18 @@ The MATLAB Proxy is under active development. For support or to report issues, s
|
|
|
84
86
|
|
|
85
87
|
$ sudo yum install xorg-x11-server-Xvfb
|
|
86
88
|
```
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
* Fluxbox Window Manager (only for Linux® based systems):
|
|
92
|
+
|
|
93
|
+
Installing fluxbox is optional but required to use Simulink Online.
|
|
94
|
+
|
|
95
|
+
Install fluxbox using:
|
|
96
|
+
```bash
|
|
97
|
+
# On a Debian/Ubuntu based system:
|
|
98
|
+
$ sudo apt install fluxbox
|
|
99
|
+
```
|
|
87
100
|
|
|
88
|
-
*Note: The installation of Xvfb is **optional** (w.e.f. v0.11.0 of matlab-proxy). However, we highly recommend installing it.*
|
|
89
101
|
* Python versions: **3.8** | **3.9** | **3.10** | **3.11**
|
|
90
102
|
* [Browser Requirements](https://www.mathworks.com/support/requirements/browser-requirements.html)
|
|
91
103
|
* Supported Operating Systems:
|
|
@@ -123,7 +135,7 @@ which matlab-proxy-app
|
|
|
123
135
|
|
|
124
136
|
Once the `matlab-proxy` package is installed.
|
|
125
137
|
|
|
126
|
-
* Open a
|
|
138
|
+
* Open a terminal and start `matlab-proxy-app`. On Linux, the command would be
|
|
127
139
|
```bash
|
|
128
140
|
env MWI_BASE_URL="/matlab" matlab-proxy-app
|
|
129
141
|
```
|
|
@@ -170,7 +182,7 @@ The following options are available in the status panel (some options are only a
|
|
|
170
182
|
|
|
171
183
|
## Examples
|
|
172
184
|
* For installing/usage in a Docker container, see this [Dockerfile](./examples/Dockerfile) and its [README](./examples/README.md).
|
|
173
|
-
* For upgrading **matlab-proxy** in an existing Docker image, see this [Dockerfile.upgrade.matlab-proxy](./examples/Dockerfile.upgrade.matlab-proxy) and its [README](./examples/README.md#upgrading-matlab-proxy-package-in-a-docker-image)
|
|
185
|
+
* For upgrading **matlab-proxy** in an existing Docker image, see this [Dockerfile.upgrade.matlab-proxy](./examples/Dockerfile.upgrade.matlab-proxy) and its [README](./examples/README.md#upgrading-matlab-proxy-package-in-a-docker-image).
|
|
174
186
|
* For usage in a Jupyter environment, see [jupyter-matlab-proxy](https://github.com/mathworks/jupyter-matlab-proxy).
|
|
175
187
|
|
|
176
188
|
## Platform Support
|
|
@@ -208,8 +220,10 @@ To install `matlab-proxy` in WSL 2, follow the steps mentioned in the [Installat
|
|
|
208
220
|
`matlab-proxy` version `v0.7.0` introduces support for using an existing MATLAB license. Use the Existing License option only if you have an activated MATLAB. This allows you to start MATLAB without authenticating every time.
|
|
209
221
|
|
|
210
222
|
## Limitations
|
|
211
|
-
This package supports the same
|
|
212
|
-
[
|
|
223
|
+
This package supports the same set of MATLAB features and commands as MATLAB® Online. For the full list, see
|
|
224
|
+
[Specifications and Limitations for MATLAB Online](https://www.mathworks.com/products/matlab-online/limitations.html).
|
|
225
|
+
|
|
226
|
+
Simulink Online is supported exclusively on Linux platforms starting from MATLAB R2024b.
|
|
213
227
|
|
|
214
228
|
## Security
|
|
215
229
|
We take your security concerns seriously, and will attempt to address all concerns.
|
|
@@ -229,5 +243,3 @@ If you encounter a technical issue or have an enhancement request, create an iss
|
|
|
229
243
|
Copyright 2020-2025 The MathWorks, Inc.
|
|
230
244
|
|
|
231
245
|
---
|
|
232
|
-
|
|
233
|
-
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
matlab_proxy/__init__.py,sha256=6cwi8buKCMtw9OeWaOYUHEoqwl5MyJ_s6GxgNuqPuNg,1673
|
|
2
|
-
matlab_proxy/app.py,sha256
|
|
3
|
-
matlab_proxy/app_state.py,sha256=
|
|
4
|
-
matlab_proxy/constants.py,sha256=
|
|
2
|
+
matlab_proxy/app.py,sha256=-lqRLDnDVdz01tPTzE58mRfxxqLKSUptXsI746a6i_k,34566
|
|
3
|
+
matlab_proxy/app_state.py,sha256=jiPSjLZt4UHRElGaYMHf2o6kJXhliwER61mQZeezX0o,73407
|
|
4
|
+
matlab_proxy/constants.py,sha256=So0UJC1QGvP4-nJWhau-xOlzBEdDpdExynzzbvEhtqk,1189
|
|
5
5
|
matlab_proxy/default_configuration.py,sha256=tBHaEq_bYsX2uC9pPA9mi_8M6o94ij-rxq8mbvcYpFc,1874
|
|
6
6
|
matlab_proxy/devel.py,sha256=nR6XPVBUEdQ-RZGtYvX1YHTp8gj9cuw5Hp8ahasMBc8,14310
|
|
7
|
-
matlab_proxy/settings.py,sha256
|
|
7
|
+
matlab_proxy/settings.py,sha256=31WrxQjqJWpvwU_4dehmkadaj8Vvn-8p8SZljFQDd8s,28540
|
|
8
8
|
matlab_proxy/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
matlab_proxy/gui/favicon.ico,sha256=7w7Ki1uQP2Rgwc64dOV4-NrTu97I3WsZw8OvRSoY1A0,130876
|
|
10
|
-
matlab_proxy/gui/index.html,sha256=
|
|
10
|
+
matlab_proxy/gui/index.html,sha256=MAmmegXIfx13SVifeeQIptqktZuWc8fxzpdljx8QsfM,720
|
|
11
11
|
matlab_proxy/gui/manifest.json,sha256=NwDbrALM5auYyj2bbEf4aGwAUDqNl1FzMFQpPiG2Ty4,286
|
|
12
12
|
matlab_proxy/gui/robots.txt,sha256=kNJLw79pisHhc3OVAimMzKcq3x9WT6sF9IS4xI0crdI,67
|
|
13
13
|
matlab_proxy/gui/static/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
14
|
matlab_proxy/gui/static/css/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
matlab_proxy/gui/static/css/index.BSVLACuY.css,sha256=LzuRvV10Z0pF0ugGSnj5zKJvT4AHwwBbCd-wSH4mHjg,305333
|
|
16
16
|
matlab_proxy/gui/static/js/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
matlab_proxy/gui/static/js/index.
|
|
17
|
+
matlab_proxy/gui/static/js/index.qK3VCGVb.js,sha256=v0SfcphW6I8hwDZWViAqDFWp9uHbgKBIeVN9jAP1kd0,279950
|
|
18
18
|
matlab_proxy/gui/static/media/MATLAB-env-blur.NupTbPv_.png,sha256=QpmQTLDvBu2-b7ev83Rvpt0Q72R6wdQGkuJMPPpjv7M,220290
|
|
19
19
|
matlab_proxy/gui/static/media/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
20
|
matlab_proxy/gui/static/media/glyphicons-halflings-regular.BKjkU69z.woff,sha256=omOU9-3hAMoRjv8u2ghZYnWpg5uVnCJuFUOVV6WoB0I,23424
|
|
@@ -38,7 +38,7 @@ matlab_proxy/gui/static/media/trigger-error.QEdsGL-m.svg,sha256=3zzT0uTrl4M_HlAj
|
|
|
38
38
|
matlab_proxy/gui/static/media/trigger-ok.Dzg8OIrk.svg,sha256=mD-7N9cc4ARdMBFcplnogJv6nA4Yh3jQuYbZDUi18LU,4997
|
|
39
39
|
matlab_proxy/icons/matlab.svg,sha256=xh5uYebQd8I-ISvenjU9A-PkClzW_lU9wvm3doXOFKM,13366
|
|
40
40
|
matlab_proxy/matlab/evaluateUserMatlabCode.m,sha256=R8w6nPdGtadR4UUFJaspcrGQL7cJwUItdrfc531w3bM,2420
|
|
41
|
-
matlab_proxy/matlab/startup.m,sha256=
|
|
41
|
+
matlab_proxy/matlab/startup.m,sha256=UcA4i2lAMytwBsO783uPIQoP5Pzw1R0xrUywbBBtTjw,533
|
|
42
42
|
matlab_proxy/util/__init__.py,sha256=JkVIsTOae5giDK0cQ7jcxQSHa8zo1umdq-1C0grDZwk,11712
|
|
43
43
|
matlab_proxy/util/event_loop.py,sha256=sX_0tKlirCY5ImLxkss_XO4Ksj65u6JHtwMj25oGL94,1816
|
|
44
44
|
matlab_proxy/util/list_servers.py,sha256=M93coVZjyQCdIvCCxsNOU_XDWNjBSysOJ5tWXaTjP8Y,1369
|
|
@@ -48,8 +48,8 @@ matlab_proxy/util/windows.py,sha256=_5gl2IyHIfw8-D3_G5uHkycZVGGFVXtjkd6_aP3g2Ts,
|
|
|
48
48
|
matlab_proxy/util/mwi/__init__.py,sha256=zI-X1lafr8H3j17PyA0oSZ0q5nINfK-WDA7VmJKmSAQ,158
|
|
49
49
|
matlab_proxy/util/mwi/custom_http_headers.py,sha256=kfDjSnEXEVzoF2pZuEn76LKayeD2WKoQEDu2Y9EMOAo,7154
|
|
50
50
|
matlab_proxy/util/mwi/download.py,sha256=-GJj3yOsL4vF_9baqRXkgBI-vu_OwjZMQVkJXFS8GMc,4965
|
|
51
|
-
matlab_proxy/util/mwi/environment_variables.py,sha256=
|
|
52
|
-
matlab_proxy/util/mwi/exceptions.py,sha256=
|
|
51
|
+
matlab_proxy/util/mwi/environment_variables.py,sha256=ffKEm56nt18CKYLaTihfAyqhzgYRdtNfHSu3e1Fw1yg,6568
|
|
52
|
+
matlab_proxy/util/mwi/exceptions.py,sha256=8o4PZmira_ZonnOROzu8ERIiSn9y-456JO89gqjCags,5446
|
|
53
53
|
matlab_proxy/util/mwi/logger.py,sha256=GoisSphy3Jyi5-6-X0WRl1YkdrKx2xzjSxBN_w3oTU8,3802
|
|
54
54
|
matlab_proxy/util/mwi/token_auth.py,sha256=UbIWqo7qADaZdijFvorLYsZbxzaB8TycGP8nk305ru0,9997
|
|
55
55
|
matlab_proxy/util/mwi/validators.py,sha256=dg2OXL686vWie_JoTNpFSje2m_UqdpvpTVHJl5tmxSo,13247
|
|
@@ -76,7 +76,7 @@ matlab_proxy_manager/web/watcher.py,sha256=89JHjBAQtOrllstaJFxqrjHwckpRmu3qfUqeq
|
|
|
76
76
|
tests/integration/__init__.py,sha256=ttzJ8xKWGxOJZz56qOiWOn6sp5LGomkZMn_w4KJLRMU,42
|
|
77
77
|
tests/integration/integration_tests_with_license/__init__.py,sha256=vVYZCur-QhmIGCxUmn-WZjIywtDQidaLDmlmrRHRlgY,37
|
|
78
78
|
tests/integration/integration_tests_with_license/conftest.py,sha256=sCaIXB8d4vf05C7JWSVA7g5gnPjbpRq3dftuBpWyp1s,1599
|
|
79
|
-
tests/integration/integration_tests_with_license/test_http_end_points.py,sha256=
|
|
79
|
+
tests/integration/integration_tests_with_license/test_http_end_points.py,sha256=SDqYARwZKNXDS8-GzRKZvttCbmjq5ETwduN61ZVgOk8,14441
|
|
80
80
|
tests/integration/integration_tests_without_license/__init__.py,sha256=vVYZCur-QhmIGCxUmn-WZjIywtDQidaLDmlmrRHRlgY,37
|
|
81
81
|
tests/integration/integration_tests_without_license/conftest.py,sha256=n-oppKWxavyy1O0J6DywO3DnOHuYc7yUZRXm3Bt4szU,3526
|
|
82
82
|
tests/integration/integration_tests_without_license/test_matlab_is_down_if_unlicensed.py,sha256=tkdyhfZBpfJpbnEzjURyV-GE0p43YxOa9xooJf-JoM4,1653
|
|
@@ -85,30 +85,30 @@ tests/integration/utils/integration_tests_utils.py,sha256=IbJ9CedFHiz3k85FBY-8Gw
|
|
|
85
85
|
tests/integration/utils/licensing.py,sha256=rEBjvMXO8R3mL6KnePu2lojmOsjD4GXl9frf9N0Wacs,4842
|
|
86
86
|
tests/unit/__init__.py,sha256=KfwQxxM5a1kMRtNbhz8tb7YfHp8e2d0tNLB55wYvDS8,37
|
|
87
87
|
tests/unit/conftest.py,sha256=FIL7bhw2-9B5OEspqt9toZ2ZlN18pOsPEFjeQmVNcSk,1916
|
|
88
|
-
tests/unit/test_app.py,sha256=
|
|
89
|
-
tests/unit/test_app_state.py,sha256=
|
|
88
|
+
tests/unit/test_app.py,sha256=VZt64uhdhsdmZL3Pb9LGtxxgt0H18mzRZRzSyiud6nQ,40028
|
|
89
|
+
tests/unit/test_app_state.py,sha256=ZhywxbZb9HCxLQjgW1QEHccaydCeGKX20YOFFjpKWYM,38047
|
|
90
90
|
tests/unit/test_constants.py,sha256=2nXxTmDP8utr8krsfZ4c_Bh4_mWPcDO5uI8MXeq4Usg,158
|
|
91
91
|
tests/unit/test_ddux.py,sha256=a2J2iM8j_nnfJVuMI38p5AjwrRdoMj3N88gFgS2I4hg,713
|
|
92
92
|
tests/unit/test_devel.py,sha256=A-1iVhSSwmywaW65QIRcUS2Fk7nJxceCcCm7CJtNdEc,7982
|
|
93
|
-
tests/unit/test_non_dev_mode.py,sha256=
|
|
94
|
-
tests/unit/test_settings.py,sha256=
|
|
93
|
+
tests/unit/test_non_dev_mode.py,sha256=Jqs5W-ax6WNM9v5SeTjpmVsojjA95itPC8Lqhs2U3Oc,5533
|
|
94
|
+
tests/unit/test_settings.py,sha256=CZDopczxa7zMC1LIpRckwnG4v2Ag4RBLqPE1TaypNYM,23271
|
|
95
95
|
tests/unit/util/__init__.py,sha256=GInSQBb2SoVD5LZfmSCQa9-UZJT_UP-jNfrojkgCybU,87
|
|
96
|
-
tests/unit/util/test_mw.py,sha256=
|
|
97
|
-
tests/unit/util/test_util.py,sha256=
|
|
96
|
+
tests/unit/util/test_mw.py,sha256=hweBw3ijcdh_2QdECjAWNkmh_7P5Df728cgD51DFkT8,18571
|
|
97
|
+
tests/unit/util/test_util.py,sha256=n-xSkwdqXfq550jWYsmjhGjx6L98URhWeLJLKhGekOw,7476
|
|
98
98
|
tests/unit/util/mwi/__init__.py,sha256=pl5jqyCHEwZEviiL8OC-SHulb1rBecstQCFF6qVjL9Y,37
|
|
99
99
|
tests/unit/util/mwi/test_custom_http_headers.py,sha256=UfrhclS0j6WhShtg1ki2oF1kK8JqRC29uevH4tuDqF4,11182
|
|
100
100
|
tests/unit/util/mwi/test_download.py,sha256=jYwPJFYGrPKqnkIJW42XYSe1fowmzChAkOx0k0xVldo,4779
|
|
101
101
|
tests/unit/util/mwi/test_logger.py,sha256=S0Q5TirFxysrH2YSxRzGY9mWoWB83hG3q3XpGENCpcw,3150
|
|
102
|
-
tests/unit/util/mwi/test_token_auth.py,sha256
|
|
102
|
+
tests/unit/util/mwi/test_token_auth.py,sha256=0gp41Y7zZFqeFDCA0V3Arv_CqnQKo5RZqijIccvezYM,10562
|
|
103
103
|
tests/unit/util/mwi/test_validators.py,sha256=GvLP3lSvoOQAjoclYunKPfxPIagUsnVGHRskHELResE,11765
|
|
104
104
|
tests/unit/util/mwi/embedded_connector/__init__.py,sha256=pl5jqyCHEwZEviiL8OC-SHulb1rBecstQCFF6qVjL9Y,37
|
|
105
105
|
tests/unit/util/mwi/embedded_connector/test_helpers.py,sha256=vYTWNUTuDeaygo16JGMTvWeI_CLOnvPkwNJmLndvJhE,890
|
|
106
106
|
tests/unit/util/mwi/embedded_connector/test_request.py,sha256=PR-jddnXDEiip-lD7A_QSvRwEkwo3eQ8owZlk-r9vnk,1867
|
|
107
107
|
tests/utils/__init__.py,sha256=ttzJ8xKWGxOJZz56qOiWOn6sp5LGomkZMn_w4KJLRMU,42
|
|
108
108
|
tests/utils/logging_util.py,sha256=VBy_NRvwau3C_CVTBjK5RMROrQimnJYHO2U0aKSZiRw,2234
|
|
109
|
-
matlab_proxy-0.
|
|
110
|
-
matlab_proxy-0.
|
|
111
|
-
matlab_proxy-0.
|
|
112
|
-
matlab_proxy-0.
|
|
113
|
-
matlab_proxy-0.
|
|
114
|
-
matlab_proxy-0.
|
|
109
|
+
matlab_proxy-0.25.0.dist-info/LICENSE.md,sha256=oF0h3UdSF-rlUiMGYwi086ZHqelzz7yOOk9HFDv9ELo,2344
|
|
110
|
+
matlab_proxy-0.25.0.dist-info/METADATA,sha256=8vT3BKQB6VLmlygF55mESkydtp0j3BkvJprloc0MGWM,10505
|
|
111
|
+
matlab_proxy-0.25.0.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
|
|
112
|
+
matlab_proxy-0.25.0.dist-info/entry_points.txt,sha256=3wztwXpt6wdGfTwscc4qHbCeWzi0E2XhyJbMDndyQKc,304
|
|
113
|
+
matlab_proxy-0.25.0.dist-info/top_level.txt,sha256=KF-347aoRGsfHTpiSqfIPUZ95bzK5-oMIu8S_TUcu-w,40
|
|
114
|
+
matlab_proxy-0.25.0.dist-info/RECORD,,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2023-
|
|
1
|
+
# Copyright 2023-2025 The MathWorks, Inc.
|
|
2
2
|
|
|
3
3
|
"""
|
|
4
4
|
Contains integration tests which exercise HTTP endpoints of interest exposed by matlab-proxy-app
|
|
@@ -246,24 +246,23 @@ class RealMATLABServer:
|
|
|
246
246
|
# Fixtures
|
|
247
247
|
@pytest.fixture
|
|
248
248
|
def matlab_proxy_app_fixture(
|
|
249
|
-
|
|
249
|
+
event_loop,
|
|
250
250
|
):
|
|
251
251
|
"""A pytest fixture which yields a real matlab server to be used by tests.
|
|
252
252
|
|
|
253
253
|
Args:
|
|
254
|
-
|
|
254
|
+
event_loop (Event loop): The built-in event loop provided by pytest.
|
|
255
255
|
|
|
256
256
|
Yields:
|
|
257
257
|
real_matlab_server : A real matlab web server used by tests.
|
|
258
258
|
"""
|
|
259
259
|
|
|
260
260
|
try:
|
|
261
|
-
with RealMATLABServer(
|
|
261
|
+
with RealMATLABServer(event_loop) as matlab_proxy_app:
|
|
262
262
|
yield matlab_proxy_app
|
|
263
263
|
except ProcessLookupError as e:
|
|
264
264
|
_logger.debug("ProcessLookupError found in matlab proxy app fixture")
|
|
265
265
|
_logger.debug(e)
|
|
266
|
-
pass
|
|
267
266
|
|
|
268
267
|
|
|
269
268
|
@pytest.fixture
|
tests/unit/test_app.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2020-
|
|
1
|
+
# Copyright 2020-2025 The MathWorks, Inc.
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import datetime
|
|
@@ -9,13 +9,18 @@ import time
|
|
|
9
9
|
from datetime import timedelta, timezone
|
|
10
10
|
from http import HTTPStatus
|
|
11
11
|
|
|
12
|
-
import aiohttp
|
|
13
12
|
import pytest
|
|
14
|
-
|
|
13
|
+
from aiohttp import WSMsgType
|
|
14
|
+
from aiohttp.web import WebSocketResponse
|
|
15
|
+
from multidict import CIMultiDict
|
|
15
16
|
|
|
17
|
+
import tests.unit.test_constants as test_constants
|
|
16
18
|
from matlab_proxy import app, util
|
|
19
|
+
from matlab_proxy.app import matlab_view
|
|
17
20
|
from matlab_proxy.util.mwi import environment_variables as mwi_env
|
|
18
21
|
from matlab_proxy.util.mwi.exceptions import EntitlementError, MatlabInstallError
|
|
22
|
+
from tests.unit.fixtures.fixture_auth import patch_authenticate_access_decorator
|
|
23
|
+
from tests.unit.mocks.mock_client import MockWebSocketClient
|
|
19
24
|
|
|
20
25
|
|
|
21
26
|
@pytest.mark.parametrize(
|
|
@@ -61,7 +66,7 @@ def test_configure_no_proxy_in_env(monkeypatch, no_proxy_user_configuration):
|
|
|
61
66
|
)
|
|
62
67
|
|
|
63
68
|
|
|
64
|
-
def test_create_app(
|
|
69
|
+
def test_create_app(event_loop):
|
|
65
70
|
"""Test if aiohttp server is being created successfully.
|
|
66
71
|
|
|
67
72
|
Checks if the aiohttp server is created successfully, routes, startup and cleanup
|
|
@@ -75,7 +80,7 @@ def test_create_app(loop):
|
|
|
75
80
|
# Verify app server has a cleanup task
|
|
76
81
|
# By default there is 1 for clean up task
|
|
77
82
|
assert len(test_server.on_cleanup) > 1
|
|
78
|
-
|
|
83
|
+
event_loop.run_until_complete(test_server["state"].stop_server_tasks())
|
|
79
84
|
|
|
80
85
|
|
|
81
86
|
def get_email():
|
|
@@ -245,9 +250,33 @@ class FakeServer:
|
|
|
245
250
|
self.loop.run_until_complete(self.server.cleanup())
|
|
246
251
|
|
|
247
252
|
|
|
253
|
+
@pytest.fixture
|
|
254
|
+
def mock_request(mocker):
|
|
255
|
+
"""Creates a mock request with required attributes"""
|
|
256
|
+
req = mocker.MagicMock()
|
|
257
|
+
req.app = {
|
|
258
|
+
"state": mocker.MagicMock(matlab_port=8000),
|
|
259
|
+
"settings": {"matlab_protocol": "http", "mwapikey": "test-key"},
|
|
260
|
+
}
|
|
261
|
+
req.headers = CIMultiDict()
|
|
262
|
+
req.cookies = {}
|
|
263
|
+
return req
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
@pytest.fixture(name="mock_websocket_messages")
|
|
267
|
+
def mock_messages(mocker):
|
|
268
|
+
# Mock WebSocket messages
|
|
269
|
+
return [
|
|
270
|
+
mocker.MagicMock(type=WSMsgType.TEXT, data="test message"),
|
|
271
|
+
mocker.MagicMock(type=WSMsgType.BINARY, data=b"test binary"),
|
|
272
|
+
mocker.MagicMock(type=WSMsgType.PING),
|
|
273
|
+
mocker.MagicMock(type=WSMsgType.PONG),
|
|
274
|
+
]
|
|
275
|
+
|
|
276
|
+
|
|
248
277
|
@pytest.fixture(name="test_server")
|
|
249
278
|
def test_server_fixture(
|
|
250
|
-
|
|
279
|
+
event_loop,
|
|
251
280
|
aiohttp_client,
|
|
252
281
|
monkeypatch,
|
|
253
282
|
):
|
|
@@ -263,7 +292,7 @@ def test_server_fixture(
|
|
|
263
292
|
# Disabling the authentication token mechanism explicitly
|
|
264
293
|
monkeypatch.setenv(mwi_env.get_env_name_enable_mwi_auth_token(), "False")
|
|
265
294
|
try:
|
|
266
|
-
with FakeServer(
|
|
295
|
+
with FakeServer(event_loop, aiohttp_client) as test_server:
|
|
267
296
|
yield test_server
|
|
268
297
|
except ProcessLookupError:
|
|
269
298
|
pass
|
|
@@ -306,8 +335,6 @@ async def test_get_env_config(test_server):
|
|
|
306
335
|
test_server (aiohttp_client): A aiohttp_client server for sending GET request.
|
|
307
336
|
"""
|
|
308
337
|
expected_json_structure = {
|
|
309
|
-
"useMOS": False,
|
|
310
|
-
"useMRE": False,
|
|
311
338
|
"authentication": {"enabled": False, "status": False},
|
|
312
339
|
"matlab": {
|
|
313
340
|
"status": "up",
|
|
@@ -350,7 +377,7 @@ async def test_start_matlab_route(test_server):
|
|
|
350
377
|
await __check_for_matlab_status(test_server, "starting")
|
|
351
378
|
|
|
352
379
|
|
|
353
|
-
async def __check_for_matlab_status(test_server, status):
|
|
380
|
+
async def __check_for_matlab_status(test_server, status, sleep_interval=0.5):
|
|
354
381
|
"""Helper function to check if the status of MATLAB returned by the server is either of the values mentioned in statuses
|
|
355
382
|
|
|
356
383
|
Args:
|
|
@@ -369,7 +396,7 @@ async def __check_for_matlab_status(test_server, status):
|
|
|
369
396
|
break
|
|
370
397
|
else:
|
|
371
398
|
count += 1
|
|
372
|
-
await asyncio.sleep(
|
|
399
|
+
await asyncio.sleep(sleep_interval)
|
|
373
400
|
if count > test_constants.FIVE_MAX_TRIES:
|
|
374
401
|
raise ConnectionError
|
|
375
402
|
|
|
@@ -592,19 +619,6 @@ async def test_matlab_proxy_http_post_request(proxy_payload, test_server):
|
|
|
592
619
|
raise ConnectionError
|
|
593
620
|
|
|
594
621
|
|
|
595
|
-
# While acceessing matlab-proxy directly, the web socket request looks like
|
|
596
|
-
# {
|
|
597
|
-
# "connection": "Upgrade",
|
|
598
|
-
# "Upgrade": "websocket",
|
|
599
|
-
# }
|
|
600
|
-
# whereas while accessing matlab-proxy with nginx as the reverse proxy, the nginx server
|
|
601
|
-
# modifies the web socket request to
|
|
602
|
-
# {
|
|
603
|
-
# "connection": "upgrade",
|
|
604
|
-
# "upgrade": "websocket",
|
|
605
|
-
# }
|
|
606
|
-
|
|
607
|
-
|
|
608
622
|
async def test_set_licensing_info_put_nlm(test_server):
|
|
609
623
|
"""Test to check endpoint : "/set_licensing_info"
|
|
610
624
|
|
|
@@ -641,35 +655,70 @@ async def test_set_licensing_info_put_invalid_license(test_server):
|
|
|
641
655
|
assert resp.status == HTTPStatus.BAD_REQUEST
|
|
642
656
|
|
|
643
657
|
|
|
658
|
+
# While acceessing matlab-proxy directly, the web socket request looks like
|
|
659
|
+
# {
|
|
660
|
+
# "connection": "Upgrade",
|
|
661
|
+
# "Upgrade": "websocket",
|
|
662
|
+
# }
|
|
663
|
+
# whereas while accessing matlab-proxy with nginx as the reverse proxy, the nginx server
|
|
664
|
+
# modifies the web socket request to
|
|
665
|
+
# {
|
|
666
|
+
# "connection": "upgrade",
|
|
667
|
+
# "upgrade": "websocket",
|
|
668
|
+
# }
|
|
644
669
|
@pytest.mark.parametrize(
|
|
645
670
|
"headers",
|
|
646
671
|
[
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
672
|
+
CIMultiDict(
|
|
673
|
+
{
|
|
674
|
+
"connection": "Upgrade",
|
|
675
|
+
"Upgrade": "websocket",
|
|
676
|
+
}
|
|
677
|
+
),
|
|
678
|
+
CIMultiDict(
|
|
679
|
+
{
|
|
680
|
+
"connection": "upgrade",
|
|
681
|
+
"upgrade": "websocket",
|
|
682
|
+
}
|
|
683
|
+
),
|
|
655
684
|
],
|
|
656
685
|
ids=["Uppercase header", "Lowercase header"],
|
|
657
686
|
)
|
|
658
|
-
async def
|
|
659
|
-
|
|
687
|
+
async def test_matlab_view_websocket_success(
|
|
688
|
+
mocker,
|
|
689
|
+
mock_request,
|
|
690
|
+
mock_websocket_messages,
|
|
691
|
+
headers,
|
|
692
|
+
patch_authenticate_access_decorator,
|
|
693
|
+
):
|
|
694
|
+
"""Test successful websocket connection and message forwarding"""
|
|
660
695
|
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
""
|
|
696
|
+
# Configure request for WebSocket
|
|
697
|
+
mock_request.headers = headers
|
|
698
|
+
mock_request.method = "GET"
|
|
699
|
+
mock_request.path_qs = "/test"
|
|
664
700
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
701
|
+
# Mock WebSocket setup
|
|
702
|
+
mock_ws_server = mocker.MagicMock(spec=WebSocketResponse)
|
|
703
|
+
mocker.patch(
|
|
704
|
+
"matlab_proxy.app.aiohttp.web.WebSocketResponse", return_value=mock_ws_server
|
|
705
|
+
)
|
|
706
|
+
|
|
707
|
+
# Mock WebSocket client
|
|
708
|
+
mock_ws_client = MockWebSocketClient(messages=mock_websocket_messages)
|
|
709
|
+
mocker.patch(
|
|
710
|
+
"matlab_proxy.app.aiohttp.ClientSession.ws_connect", return_value=mock_ws_client
|
|
670
711
|
)
|
|
671
|
-
|
|
672
|
-
|
|
712
|
+
|
|
713
|
+
# Execute
|
|
714
|
+
result = await matlab_view(mock_request)
|
|
715
|
+
|
|
716
|
+
# Assertions
|
|
717
|
+
assert result == mock_ws_server
|
|
718
|
+
assert mock_ws_server.send_str.call_count == 1
|
|
719
|
+
assert mock_ws_server.send_bytes.call_count == 1
|
|
720
|
+
assert mock_ws_server.ping.call_count == 1
|
|
721
|
+
assert mock_ws_server.pong.call_count == 1
|
|
673
722
|
|
|
674
723
|
|
|
675
724
|
async def test_set_licensing_info_put_mhlm(test_server):
|
|
@@ -992,7 +1041,7 @@ async def test_set_licensing_mhlm_single_entitlement(
|
|
|
992
1041
|
assert resp_json["licensing"]["entitlementId"] == "Entitlement3"
|
|
993
1042
|
|
|
994
1043
|
# validate that MATLAB has started correctly
|
|
995
|
-
await __check_for_matlab_status(test_server, "up")
|
|
1044
|
+
await __check_for_matlab_status(test_server, "up", sleep_interval=2)
|
|
996
1045
|
|
|
997
1046
|
# test-cleanup: unset licensing
|
|
998
1047
|
# without this, we can leave test drool related to cached license file
|