matlab-proxy 0.15.0__py3-none-any.whl → 0.16.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.

Files changed (41) hide show
  1. matlab_proxy/app.py +13 -7
  2. matlab_proxy/app_state.py +9 -6
  3. matlab_proxy/constants.py +1 -0
  4. matlab_proxy/gui/asset-manifest.json +3 -3
  5. matlab_proxy/gui/index.html +1 -1
  6. matlab_proxy/gui/static/js/{main.14aa7840.js → main.522d83ba.js} +3 -3
  7. matlab_proxy/gui/static/js/main.522d83ba.js.map +1 -0
  8. matlab_proxy/settings.py +7 -4
  9. matlab_proxy/util/__init__.py +8 -1
  10. matlab_proxy/util/mwi/token_auth.py +19 -5
  11. {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/METADATA +1 -1
  12. {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/RECORD +40 -20
  13. tests/integration/integration_tests_with_license/test_http_end_points.py +4 -4
  14. tests/integration/integration_tests_without_license/conftest.py +4 -3
  15. tests/integration/integration_tests_without_license/test_matlab_is_down_if_unlicensed.py +3 -0
  16. tests/unit/__init__.py +1 -0
  17. tests/unit/conftest.py +67 -0
  18. tests/unit/test_app.py +1113 -0
  19. tests/unit/test_app_state.py +586 -0
  20. tests/unit/test_constants.py +6 -0
  21. tests/unit/test_ddux.py +22 -0
  22. tests/unit/test_devel.py +246 -0
  23. tests/unit/test_non_dev_mode.py +169 -0
  24. tests/unit/test_settings.py +460 -0
  25. tests/unit/util/__init__.py +3 -0
  26. tests/unit/util/mwi/__init__.py +1 -0
  27. tests/unit/util/mwi/embedded_connector/__init__.py +1 -0
  28. tests/unit/util/mwi/embedded_connector/test_helpers.py +29 -0
  29. tests/unit/util/mwi/embedded_connector/test_request.py +64 -0
  30. tests/unit/util/mwi/test_custom_http_headers.py +281 -0
  31. tests/unit/util/mwi/test_logger.py +49 -0
  32. tests/unit/util/mwi/test_token_auth.py +303 -0
  33. tests/unit/util/mwi/test_validators.py +331 -0
  34. tests/unit/util/test_mw.py +550 -0
  35. tests/unit/util/test_util.py +135 -0
  36. matlab_proxy/gui/static/js/main.14aa7840.js.map +0 -1
  37. /matlab_proxy/gui/static/js/{main.14aa7840.js.LICENSE.txt → main.522d83ba.js.LICENSE.txt} +0 -0
  38. {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/LICENSE.md +0 -0
  39. {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/WHEEL +0 -0
  40. {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/entry_points.txt +0 -0
  41. {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,331 @@
1
+ # Copyright 2020-2023 The MathWorks, Inc.
2
+
3
+ """Tests for functions in matlab_proxy/util/mwi_validators.py
4
+ """
5
+
6
+ import os
7
+ import random
8
+ import socket
9
+ import tempfile
10
+ from matlab_proxy.util.mwi.validators import validate_matlab_root_path
11
+ from matlab_proxy import constants
12
+ from pathlib import Path
13
+
14
+ import matlab_proxy
15
+ import pytest
16
+ from matlab_proxy.util import system
17
+ from matlab_proxy.util.mwi import environment_variables as mwi_env
18
+ from matlab_proxy.util.mwi import validators
19
+ from matlab_proxy.util.mwi.exceptions import (
20
+ NetworkLicensingError,
21
+ FatalError,
22
+ MatlabInstallError,
23
+ )
24
+
25
+
26
+ @pytest.mark.parametrize(
27
+ "MLM_LICENSE_FILE",
28
+ [
29
+ ("/path/to/a/non-existent/file"),
30
+ ("1234"),
31
+ ("hostname"),
32
+ ("1234hostname"),
33
+ ],
34
+ ids=[
35
+ "Invalid path to a license file",
36
+ "NLM string with just port number",
37
+ "NLM string with just hostname",
38
+ "NLM string with just port number and hostname",
39
+ ],
40
+ )
41
+ def test_validate_mlm_license_file_invalid_value(MLM_LICENSE_FILE, monkeypatch):
42
+ """Check if validator raises expected exception"""
43
+
44
+ env_name = mwi_env.get_env_name_network_license_manager()
45
+
46
+ monkeypatch.setenv(env_name, MLM_LICENSE_FILE)
47
+ nlm_conn_str = os.getenv(env_name)
48
+
49
+ with pytest.raises(NetworkLicensingError) as e_info:
50
+ validators.validate_mlm_license_file(nlm_conn_str)
51
+ assert MLM_LICENSE_FILE in str(e_info.value)
52
+
53
+
54
+ @pytest.fixture(name="temporary_license_file")
55
+ def temporary_license_file_fixture(tmp_path):
56
+ """Pytest fixture which returns a valid path to temporary license file."""
57
+ import time
58
+
59
+ temp_license_file_path = tmp_path / f'{str(time.time()).replace(".", "")}.lic'
60
+ temp_license_file_path.touch()
61
+
62
+ return temp_license_file_path
63
+
64
+
65
+ def test_validate_mlm_license_file_valid_license_file_path(
66
+ temporary_license_file, monkeypatch
67
+ ):
68
+ """Check if a valid license path has been supplied to MLM_LICENSE_FILE env var"""
69
+ env_name = mwi_env.get_env_name_network_license_manager()
70
+ monkeypatch.setenv(env_name, str(temporary_license_file))
71
+
72
+ validated_file_path = validators.validate_mlm_license_file(os.getenv(env_name))
73
+ assert str(temporary_license_file) == validated_file_path
74
+
75
+
76
+ @pytest.mark.parametrize(
77
+ "MLM_LICENSE_FILE",
78
+ [
79
+ (["1234@1.2_any-alphanumeric"]),
80
+ (["1234@1.2_any-alphanumeric", "1234@1.2_any-alphanumeric"]),
81
+ (
82
+ [
83
+ "1234@1.2_any-alphanumeric",
84
+ "1234@1.2_any-alphanumeric",
85
+ "1234@1.2_any-alphanumeric",
86
+ ]
87
+ ),
88
+ [
89
+ "1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric"
90
+ ],
91
+ (
92
+ [
93
+ "1234@1.2_any-alphanumeric",
94
+ "1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric",
95
+ ]
96
+ ),
97
+ (
98
+ [
99
+ "1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric",
100
+ "1234@1.2_any-alphanumeric",
101
+ ]
102
+ ),
103
+ (
104
+ [
105
+ "1234@1.2_any-alphanumeric",
106
+ "1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric",
107
+ "1234@1.2_any-alphanumeric",
108
+ ]
109
+ ),
110
+ ],
111
+ ids=[
112
+ "1 NLM server",
113
+ "2 NLM servers",
114
+ "3 NLM servers",
115
+ "Just a server triad",
116
+ "1 NLM server prefixed to a server triad",
117
+ "1 NLM server suffixed to a server triad",
118
+ "1 NLM server prefixed and another suffixed to a server triad",
119
+ ],
120
+ )
121
+ def test_validate_mlm_license_file_for_valid_nlm_string(MLM_LICENSE_FILE, monkeypatch):
122
+ """Check if port@hostname passes validation"""
123
+
124
+ seperator = system.get_mlm_license_file_seperator()
125
+ MLM_LICENSE_FILE = seperator.join(MLM_LICENSE_FILE)
126
+ env_name = mwi_env.get_env_name_network_license_manager()
127
+ monkeypatch.setenv(env_name, MLM_LICENSE_FILE)
128
+ conn_str = validators.validate_mlm_license_file(os.getenv(env_name))
129
+ assert conn_str == MLM_LICENSE_FILE
130
+
131
+
132
+ def test_validate_mlm_license_file_None():
133
+ """Test to check if validate_mlm_license_file() returns None when nlm_conn_str is None."""
134
+ assert validators.validate_mlm_license_file(None) is None
135
+
136
+
137
+ def test_get_with_environment_variables(monkeypatch):
138
+ """Check if path to license file passes validation"""
139
+ env_name = mwi_env.get_env_name_network_license_manager()
140
+ fd, path = tempfile.mkstemp()
141
+ monkeypatch.setenv(env_name, path)
142
+ try:
143
+ conn_str = validators.validate_mlm_license_file(os.getenv(env_name))
144
+ assert conn_str == str(path)
145
+ finally:
146
+ os.close(fd)
147
+ os.remove(path)
148
+
149
+
150
+ def test_validate_app_port_is_free_false():
151
+ """Test to validate if supplied app port is free"""
152
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
153
+ s.bind(("", 0))
154
+ port = s.getsockname()[1]
155
+ with pytest.raises(FatalError) as e:
156
+ validators.validate_app_port_is_free(port)
157
+ s.close()
158
+
159
+
160
+ def test_validate_app_port_is_free_true():
161
+ """Test to validate if supplied app port is free"""
162
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
163
+ s.bind(("", 0))
164
+ port = s.getsockname()[1]
165
+ s.close()
166
+ assert validators.validate_app_port_is_free(port) == port
167
+
168
+
169
+ def test_validate_app_port_None():
170
+ """Tests if validated app port is None when MWI_APP_PORT env variable is not set.
171
+ If validated app port is None implies a random free port will be used at launch.
172
+ """
173
+ assert validators.validate_app_port_is_free(None) is None
174
+
175
+
176
+ def test_validate_env_config_true():
177
+ """Validate the default config which is used in this package."""
178
+ config = validators.validate_env_config(matlab_proxy.get_default_config_name())
179
+ assert isinstance(config, dict)
180
+
181
+
182
+ def test_validate_env_config_false():
183
+ """Passing a non existent config should raise FatalError exception"""
184
+
185
+ with pytest.raises(FatalError) as e:
186
+ config = validators.validate_env_config(str(random.randint(10, 100)))
187
+
188
+
189
+ def test_get_configs():
190
+ """Test to check if atleast 1 env config is discovered.
191
+ When this package is installed, we will have a default config.
192
+ """
193
+ configs = validators.__get_configs()
194
+
195
+ assert len(configs.keys()) >= 1
196
+
197
+
198
+ @pytest.mark.parametrize(
199
+ "mwi_base_url, validated_base_url",
200
+ [
201
+ ("", ""),
202
+ ("/bla", "/bla"),
203
+ ("/bla/", "/bla"),
204
+ ],
205
+ ids=[
206
+ "Launch integration at root",
207
+ "Launch at custom path",
208
+ "Launch at custom with suffix: /",
209
+ ],
210
+ )
211
+ def test_validate_base_url(mwi_base_url, validated_base_url):
212
+ """Tests multiple base_urls which will beparsed and validated successfully.
213
+
214
+ Args:
215
+ base_url (str): base_url
216
+ validated_base_url (str): validated base_url
217
+ """
218
+ assert validators.validate_base_url(mwi_base_url) == validated_base_url
219
+
220
+
221
+ def test_validate_base_url_no_prefix_error():
222
+ """Test to check base_url will throw error when a prefix / is not present in it.[summary]"""
223
+ with pytest.raises(FatalError) as e:
224
+ validators.validate_base_url("matlab/")
225
+
226
+
227
+ def test_validate_mwi_ssl_key_and_cert_file(monkeypatch):
228
+ """Check if port@hostname passes validation"""
229
+ ssl_cert_file_env_name = mwi_env.get_env_name_ssl_cert_file()
230
+ ssl_key_file_env_name = mwi_env.get_env_name_ssl_key_file()
231
+ fd, path = tempfile.mkstemp()
232
+
233
+ monkeypatch.setenv(ssl_cert_file_env_name, path)
234
+ monkeypatch.setenv(ssl_key_file_env_name, path)
235
+ try:
236
+ # Verify that if KEY and CERT are provided
237
+ key_file, cert_file = validators.validate_ssl_key_and_cert_file(
238
+ os.getenv(ssl_key_file_env_name), os.getenv(ssl_cert_file_env_name)
239
+ )
240
+ assert key_file == str(path)
241
+ assert cert_file == str(path)
242
+
243
+ # Verify that KEY can be None
244
+ key_file, cert_file = validators.validate_ssl_key_and_cert_file(
245
+ None, os.getenv(ssl_cert_file_env_name)
246
+ )
247
+ assert key_file == None
248
+ assert cert_file == str(path)
249
+
250
+ # Verify that if KEY is provided, CERT must also be provided
251
+ with pytest.raises(FatalError) as e:
252
+ validators.validate_ssl_key_and_cert_file(
253
+ os.getenv(ssl_key_file_env_name), None
254
+ )
255
+
256
+ # Verify that KEY is valid file location
257
+ with pytest.raises(FatalError) as e:
258
+ validators.validate_ssl_key_and_cert_file(
259
+ "/file/does/not/exist", os.getenv(ssl_cert_file_env_name)
260
+ )
261
+
262
+ # Verify that KEY is valid file location
263
+ with pytest.raises(FatalError) as e:
264
+ validators.validate_ssl_key_and_cert_file(
265
+ os.getenv(ssl_key_file_env_name), "/file/does/not/exist"
266
+ )
267
+ finally:
268
+ # Need to close the file descriptor in Windows
269
+ # Or else PermissionError is raised.
270
+ os.close(fd)
271
+ os.remove(path)
272
+
273
+
274
+ def test_validate_matlab_root_path(tmp_path):
275
+ """Checks if matlab root is validated without raising exceptions"""
276
+
277
+ # Arrange
278
+ matlab_root = Path(tmp_path) / "MATLAB"
279
+ os.mkdir(matlab_root)
280
+ version_info_file = Path(matlab_root) / constants.VERSION_INFO_FILE_NAME
281
+ version_info_file.touch()
282
+
283
+ # Act
284
+ actual_matlab_root = validate_matlab_root_path(
285
+ matlab_root, is_custom_matlab_root=False
286
+ )
287
+ actual_matlab_root_custom = validate_matlab_root_path(
288
+ matlab_root, is_custom_matlab_root=True
289
+ )
290
+
291
+ # Assert
292
+ assert actual_matlab_root == matlab_root
293
+ assert actual_matlab_root_custom == matlab_root
294
+
295
+
296
+ def test_validate_matlab_root_path_invalid_root_path(tmp_path):
297
+ """Checks if validate_matlab_root_path raises MatlabInstallError when non-existent path is supplied"""
298
+ # Arrange
299
+ matlab_root = Path(tmp_path) / "MATLAB"
300
+
301
+ # Act
302
+ with pytest.raises(MatlabInstallError):
303
+ actual_matlab_root = validate_matlab_root_path(
304
+ matlab_root, is_custom_matlab_root=False
305
+ )
306
+ actual_matlab_root_custom = validate_matlab_root_path(
307
+ matlab_root, is_custom_matlab_root=True
308
+ )
309
+
310
+ # Assert
311
+ assert actual_matlab_root is None
312
+ assert actual_matlab_root_custom is None
313
+
314
+
315
+ def test_validate_matlab_root_path_non_existent_versioninfo_file(tmp_path):
316
+ """Checks if validate_matlab_root_path does not raise any exceptions even if VersionInfo.xml file does not exist"""
317
+ # Arrange
318
+ matlab_root = Path(tmp_path) / "MATLAB"
319
+ os.mkdir(matlab_root)
320
+
321
+ # Act
322
+ actual_matlab_root = validate_matlab_root_path(
323
+ matlab_root, is_custom_matlab_root=False
324
+ )
325
+ actual_matlab_root_custom = validate_matlab_root_path(
326
+ matlab_root, is_custom_matlab_root=True
327
+ )
328
+
329
+ # Assert
330
+ assert actual_matlab_root is None
331
+ assert actual_matlab_root_custom is None