matlab-proxy 0.25.1__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.

Files changed (63) hide show
  1. matlab_proxy/app.py +68 -16
  2. matlab_proxy/app_state.py +8 -2
  3. matlab_proxy/constants.py +1 -0
  4. matlab_proxy/default_configuration.py +2 -2
  5. matlab_proxy/gui/index.html +1 -1
  6. matlab_proxy/gui/static/js/{index.CZgGkMCD.js → index.BcDShXfH.js} +16 -16
  7. matlab_proxy/settings.py +24 -2
  8. matlab_proxy/util/cookie_jar.py +72 -0
  9. matlab_proxy/util/list_servers.py +2 -2
  10. matlab_proxy/util/mwi/environment_variables.py +15 -0
  11. matlab_proxy/util/mwi/session_name.py +28 -0
  12. matlab_proxy/util/mwi/validators.py +2 -4
  13. {matlab_proxy-0.25.1.dist-info → matlab_proxy-0.27.0.dist-info}/METADATA +37 -23
  14. {matlab_proxy-0.25.1.dist-info → matlab_proxy-0.27.0.dist-info}/RECORD +29 -56
  15. {matlab_proxy-0.25.1.dist-info → matlab_proxy-0.27.0.dist-info}/WHEEL +1 -2
  16. matlab_proxy_manager/README.md +85 -0
  17. matlab_proxy_manager/lib/README.md +53 -0
  18. matlab_proxy_manager/lib/api.py +156 -114
  19. matlab_proxy_manager/storage/README.md +54 -0
  20. matlab_proxy_manager/storage/server.py +5 -2
  21. matlab_proxy_manager/utils/constants.py +2 -1
  22. matlab_proxy_manager/utils/environment_variables.py +6 -1
  23. matlab_proxy_manager/utils/exceptions.py +45 -0
  24. matlab_proxy_manager/utils/helpers.py +2 -2
  25. matlab_proxy_manager/utils/logger.py +4 -1
  26. matlab_proxy_manager/web/README.md +37 -0
  27. matlab_proxy_manager/web/app.py +71 -19
  28. matlab_proxy-0.25.1.dist-info/top_level.txt +0 -3
  29. tests/integration/__init__.py +0 -1
  30. tests/integration/integration_tests_with_license/__init__.py +0 -1
  31. tests/integration/integration_tests_with_license/conftest.py +0 -47
  32. tests/integration/integration_tests_with_license/test_http_end_points.py +0 -397
  33. tests/integration/integration_tests_without_license/__init__.py +0 -1
  34. tests/integration/integration_tests_without_license/conftest.py +0 -116
  35. tests/integration/integration_tests_without_license/test_matlab_is_down_if_unlicensed.py +0 -49
  36. tests/integration/utils/__init__.py +0 -1
  37. tests/integration/utils/integration_tests_utils.py +0 -352
  38. tests/integration/utils/licensing.py +0 -152
  39. tests/unit/__init__.py +0 -1
  40. tests/unit/conftest.py +0 -66
  41. tests/unit/test_app.py +0 -1200
  42. tests/unit/test_app_state.py +0 -1094
  43. tests/unit/test_constants.py +0 -7
  44. tests/unit/test_ddux.py +0 -22
  45. tests/unit/test_devel.py +0 -246
  46. tests/unit/test_non_dev_mode.py +0 -169
  47. tests/unit/test_settings.py +0 -659
  48. tests/unit/util/__init__.py +0 -3
  49. tests/unit/util/mwi/__init__.py +0 -1
  50. tests/unit/util/mwi/embedded_connector/__init__.py +0 -1
  51. tests/unit/util/mwi/embedded_connector/test_helpers.py +0 -29
  52. tests/unit/util/mwi/embedded_connector/test_request.py +0 -64
  53. tests/unit/util/mwi/test_custom_http_headers.py +0 -281
  54. tests/unit/util/mwi/test_download.py +0 -152
  55. tests/unit/util/mwi/test_logger.py +0 -82
  56. tests/unit/util/mwi/test_token_auth.py +0 -303
  57. tests/unit/util/mwi/test_validators.py +0 -364
  58. tests/unit/util/test_mw.py +0 -550
  59. tests/unit/util/test_util.py +0 -221
  60. tests/utils/__init__.py +0 -1
  61. tests/utils/logging_util.py +0 -81
  62. {matlab_proxy-0.25.1.dist-info → matlab_proxy-0.27.0.dist-info}/entry_points.txt +0 -0
  63. {matlab_proxy-0.25.1.dist-info → matlab_proxy-0.27.0.dist-info/licenses}/LICENSE.md +0 -0
@@ -1,303 +0,0 @@
1
- # Copyright 2023-2025 The MathWorks, Inc.
2
-
3
- import pytest
4
- from aiohttp import web
5
- from aiohttp_session import setup as aiohttp_session_setup
6
- from aiohttp_session.cookie_storage import EncryptedCookieStorage
7
- from cryptography import fernet
8
-
9
- from matlab_proxy.constants import MWI_AUTH_TOKEN_NAME_FOR_HTTP
10
- from matlab_proxy.util.mwi import environment_variables as mwi_env
11
- from matlab_proxy.util.mwi import token_auth
12
-
13
- ## APIs to test:
14
- # 1. generate_mwi_auth_token (auth enabled, auth enabled+custom token, custom token, auth disabled)
15
- # 2. authenticate_access_decorator (headers & url_string, and session storage)
16
-
17
- ## Testing generate_mwi_auth_token :
18
-
19
- test_data = [
20
- pytest.param(
21
- "False",
22
- "CustomTokenStr123_-Test1",
23
- None,
24
- id="token isn't generated when MWI_ENABLE_AUTH_TOKEN is explicitly disabled & has custom token set",
25
- ),
26
- pytest.param(
27
- "",
28
- "CustomTokenStr123_-Test2",
29
- "CustomTokenStr123_-Test2",
30
- id="token is generated when MWI_ENABLE_AUTH_TOKEN is not set & has custom token set",
31
- ),
32
- pytest.param(
33
- "True",
34
- "CustomTokenStr123_-Test3",
35
- "CustomTokenStr123_-Test3",
36
- id="token is generated when MWI_ENABLE_AUTH_TOKEN is set & has custom token set",
37
- ),
38
- ]
39
-
40
-
41
- @pytest.mark.parametrize(
42
- "expected_auth_enablement, auth_token, expected_auth_token",
43
- test_data,
44
- )
45
- def test_generate_mwi_auth_token(
46
- monkeypatch, expected_auth_enablement, auth_token, expected_auth_token
47
- ):
48
- monkeypatch.setenv(
49
- mwi_env.get_env_name_enable_mwi_auth_token(), str(expected_auth_enablement)
50
- )
51
- monkeypatch.setenv(mwi_env.get_env_name_mwi_auth_token(), str(auth_token))
52
-
53
- generated_token = token_auth.generate_mwi_auth_token_and_hash()["token"]
54
- assert generated_token == expected_auth_token
55
-
56
-
57
- def test_auto_token_generation_with_enable_flag_set(monkeypatch):
58
- # Test if token is auto-generated when MWI_ENABLE_AUTH_TOKEN is True
59
- expected_auth_enablement = "True"
60
- monkeypatch.setenv(
61
- mwi_env.get_env_name_enable_mwi_auth_token(), str(expected_auth_enablement)
62
- )
63
-
64
- generated_token = token_auth.generate_mwi_auth_token_and_hash()["token"]
65
- assert generated_token is not None
66
-
67
-
68
- def test_auto_token_generation_with_enable_flag_unset():
69
- # Test if token is generated by default when MWI_ENABLE_AUTH_TOKEN and MWI_AUTH_TOKEN are not set
70
- generated_token = token_auth.generate_mwi_auth_token_and_hash()["token"]
71
- assert generated_token is not None
72
-
73
-
74
- ## Testing authenticate_access_decorator :
75
- # This in turn, also tests authenticate_request
76
-
77
-
78
- @pytest.fixture
79
- def get_custom_auth_token_str():
80
- return "CustomTokenStr123_-TestOtherAPIS"
81
-
82
-
83
- @token_auth.authenticate_access_decorator
84
- async def fake_endpoint(request):
85
- if request.method == "POST":
86
- request.app["value"] = (await request.post())["value"]
87
- return web.Response(body=b"thanks for the data")
88
- return web.Response(body="value: {}".format(request.app["value"]).encode("utf-8"))
89
-
90
-
91
- @pytest.fixture
92
- def fake_server_with_auth_enabled(
93
- event_loop, aiohttp_client, monkeypatch, get_custom_auth_token_str
94
- ):
95
- auth_token = get_custom_auth_token_str
96
- auth_enablement = "True"
97
- monkeypatch.setenv(
98
- mwi_env.get_env_name_enable_mwi_auth_token(), str(auth_enablement)
99
- )
100
- monkeypatch.setenv(mwi_env.get_env_name_mwi_auth_token(), str(auth_token))
101
-
102
- (
103
- mwi_auth_token,
104
- mwi_auth_token_hash,
105
- ) = token_auth.generate_mwi_auth_token_and_hash().values()
106
-
107
- app = web.Application()
108
- app["settings"] = {
109
- "mwi_is_token_auth_enabled": mwi_auth_token is not None,
110
- "mwi_auth_token": mwi_auth_token,
111
- "mwi_auth_token_hash": mwi_auth_token_hash,
112
- "mwi_auth_token_name_for_http": MWI_AUTH_TOKEN_NAME_FOR_HTTP,
113
- "mwi_auth_token_name_for_env": mwi_env.get_env_name_mwi_auth_token().lower(),
114
- }
115
- app.router.add_get("/", fake_endpoint)
116
- app.router.add_post("/", fake_endpoint)
117
- # Setup the session storage
118
- fernet_key = fernet.Fernet.generate_key()
119
- f = fernet.Fernet(fernet_key)
120
- aiohttp_session_setup(
121
- app, EncryptedCookieStorage(f, cookie_name="matlab-proxy-session")
122
- )
123
- return event_loop.run_until_complete(aiohttp_client(app))
124
-
125
-
126
- async def test_set_value_with_token(
127
- fake_server_with_auth_enabled, get_custom_auth_token_str
128
- ):
129
- resp = await fake_server_with_auth_enabled.post(
130
- "/",
131
- data={"value": "foo"},
132
- headers={MWI_AUTH_TOKEN_NAME_FOR_HTTP: get_custom_auth_token_str},
133
- )
134
- assert resp.status == web.HTTPOk.status_code
135
- assert await resp.text() == "thanks for the data"
136
- assert fake_server_with_auth_enabled.server.app["value"] == "foo"
137
-
138
- # Test subsequent requests do not need token authentication
139
- resp2 = await fake_server_with_auth_enabled.post(
140
- "/",
141
- data={"value": "foobar"},
142
- )
143
- assert resp2.status == web.HTTPOk.status_code
144
- assert fake_server_with_auth_enabled.server.app["value"] == "foobar"
145
-
146
- # Test request which accepts cookies from previous request
147
- resp3 = await fake_server_with_auth_enabled.post(
148
- "/",
149
- data={"value": "foobar1"},
150
- cookies=resp.cookies,
151
- )
152
- assert resp3.status == web.HTTPOk.status_code
153
- assert fake_server_with_auth_enabled.server.app["value"] == "foobar1"
154
-
155
-
156
- async def test_set_value_with_token_hash(
157
- fake_server_with_auth_enabled, get_custom_auth_token_str
158
- ):
159
- resp = await fake_server_with_auth_enabled.post(
160
- "/",
161
- data={"value": "foo"},
162
- headers={
163
- MWI_AUTH_TOKEN_NAME_FOR_HTTP: token_auth._generate_hash(
164
- get_custom_auth_token_str
165
- )
166
- },
167
- )
168
- assert resp.status == web.HTTPOk.status_code
169
- assert await resp.text() == "thanks for the data"
170
- assert fake_server_with_auth_enabled.server.app["value"] == "foo"
171
-
172
- # Test subsequent requests do not need token authentication
173
- resp2 = await fake_server_with_auth_enabled.post(
174
- "/",
175
- data={"value": "foobar"},
176
- )
177
- assert resp2.status == web.HTTPOk.status_code
178
- assert fake_server_with_auth_enabled.server.app["value"] == "foobar"
179
-
180
- # Test request which accepts cookies from previous request
181
- resp3 = await fake_server_with_auth_enabled.post(
182
- "/",
183
- data={"value": "foobar1"},
184
- cookies=resp.cookies,
185
- )
186
- assert resp3.status == web.HTTPOk.status_code
187
- assert fake_server_with_auth_enabled.server.app["value"] == "foobar1"
188
-
189
-
190
- async def test_set_value_without_token(fake_server_with_auth_enabled):
191
- resp2 = await fake_server_with_auth_enabled.post(
192
- "/",
193
- data={"value": "foobar"},
194
- )
195
- assert resp2.status == web.HTTPForbidden.status_code
196
-
197
-
198
- async def test_set_value_with_invalid_token(fake_server_with_auth_enabled):
199
- resp2 = await fake_server_with_auth_enabled.post(
200
- "/",
201
- data={"value": "foobar"},
202
- headers={MWI_AUTH_TOKEN_NAME_FOR_HTTP: "invalid-token"},
203
- )
204
- assert resp2.status == web.HTTPForbidden.status_code
205
-
206
-
207
- async def test_set_value_with_token_in_params(
208
- fake_server_with_auth_enabled, get_custom_auth_token_str
209
- ):
210
- fake_server_with_auth_enabled.server.app["value"] = "foo"
211
- resp = await fake_server_with_auth_enabled.post(
212
- "/",
213
- data={"value": "foofoo"},
214
- params={
215
- MWI_AUTH_TOKEN_NAME_FOR_HTTP: token_auth._generate_hash(
216
- get_custom_auth_token_str
217
- )
218
- },
219
- )
220
- assert resp.status == web.HTTPOk.status_code
221
- assert await resp.text() == "thanks for the data"
222
- assert fake_server_with_auth_enabled.server.app["value"] == "foofoo"
223
-
224
- # Test subsequent requests do not need token authentication
225
- resp2 = await fake_server_with_auth_enabled.post(
226
- "/",
227
- data={"value": "foobar"},
228
- )
229
- assert resp2.status == web.HTTPForbidden.status_code
230
- # assert server_with_auth_enabled.server.app["value"] == "foobar"
231
-
232
-
233
- async def test_get_value_without_token(fake_server_with_auth_enabled):
234
- fake_server_with_auth_enabled.server.app["value"] = "bar"
235
- resp = await fake_server_with_auth_enabled.get("/")
236
- assert resp.status == web.HTTPForbidden.status_code
237
-
238
-
239
- async def test_get_value_with_token_in_query_params(
240
- fake_server_with_auth_enabled, get_custom_auth_token_str
241
- ):
242
- fake_server_with_auth_enabled.server.app["value"] = "bar"
243
- resp = await fake_server_with_auth_enabled.get(
244
- "/",
245
- params={
246
- MWI_AUTH_TOKEN_NAME_FOR_HTTP: token_auth._generate_hash(
247
- get_custom_auth_token_str
248
- )
249
- },
250
- )
251
- assert resp.status == web.HTTPOk.status_code
252
- assert await resp.text() == "value: bar"
253
-
254
-
255
- ## Create a fake_server without authentication enabled, and test that you can access data.
256
-
257
-
258
- @pytest.fixture
259
- def fake_server_without_auth_enabled(event_loop, aiohttp_client, monkeypatch):
260
- auth_enablement = "False"
261
- monkeypatch.setenv(
262
- mwi_env.get_env_name_enable_mwi_auth_token(), str(auth_enablement)
263
- )
264
- (
265
- mwi_auth_token,
266
- mwi_auth_token_hash,
267
- ) = token_auth.generate_mwi_auth_token_and_hash().values()
268
-
269
- app = web.Application()
270
- app["settings"] = {
271
- "mwi_is_token_auth_enabled": mwi_auth_token != None,
272
- "mwi_auth_token": mwi_auth_token,
273
- "mwi_auth_token_hash": mwi_auth_token_hash,
274
- "mwi_auth_token_name_for_env": mwi_env.get_env_name_mwi_auth_token().lower(),
275
- }
276
- app.router.add_get("/", fake_endpoint)
277
- app.router.add_post("/", fake_endpoint)
278
- # Setup the session storage
279
- fernet_key = fernet.Fernet.generate_key()
280
- f = fernet.Fernet(fernet_key)
281
- aiohttp_session_setup(
282
- app, EncryptedCookieStorage(f, cookie_name="matlab-proxy-session")
283
- )
284
- return event_loop.run_until_complete(aiohttp_client(app))
285
-
286
-
287
- async def test_get_value(fake_server_without_auth_enabled):
288
- fake_server_without_auth_enabled.server.app["value"] = "bar1"
289
- resp = await fake_server_without_auth_enabled.get("/")
290
- assert resp.status == web.HTTPOk.status_code
291
- assert await resp.text() == "value: bar1"
292
-
293
-
294
- async def test_get_value_in_query_params(
295
- fake_server_without_auth_enabled, get_custom_auth_token_str
296
- ):
297
- # Server should respond even if token is provided when not needed.
298
- fake_server_without_auth_enabled.server.app["value"] = "bar2"
299
- resp = await fake_server_without_auth_enabled.get(
300
- "/", params={"mwi-auth-token": get_custom_auth_token_str}
301
- )
302
- assert resp.status == web.HTTPOk.status_code
303
- assert await resp.text() == "value: bar2"
@@ -1,364 +0,0 @@
1
- # Copyright 2020-2025 The MathWorks, Inc.
2
-
3
- """Tests for functions in matlab_proxy/util/mwi_validators.py"""
4
-
5
- import os
6
- import random
7
- import socket
8
- import tempfile
9
- from matlab_proxy.util.mwi.validators import (
10
- validate_idle_timeout,
11
- validate_matlab_root_path,
12
- )
13
- from matlab_proxy import constants
14
- from pathlib import Path
15
-
16
- import matlab_proxy
17
- import pytest
18
- from matlab_proxy.util import system
19
- from matlab_proxy.util.mwi import environment_variables as mwi_env
20
- from matlab_proxy.util.mwi import validators
21
- from matlab_proxy.util.mwi.exceptions import (
22
- NetworkLicensingError,
23
- FatalError,
24
- MatlabInstallError,
25
- )
26
-
27
-
28
- @pytest.mark.parametrize(
29
- "MLM_LICENSE_FILE",
30
- [
31
- ("/path/to/a/non-existent/file"),
32
- ("1234"),
33
- ("hostname"),
34
- ("1234hostname"),
35
- ],
36
- ids=[
37
- "Invalid path to a license file",
38
- "NLM string with just port number",
39
- "NLM string with just hostname",
40
- "NLM string with just port number and hostname",
41
- ],
42
- )
43
- def test_validate_mlm_license_file_invalid_value(MLM_LICENSE_FILE, monkeypatch):
44
- """Check if validator raises expected exception"""
45
-
46
- env_name = mwi_env.get_env_name_network_license_manager()
47
-
48
- monkeypatch.setenv(env_name, MLM_LICENSE_FILE)
49
- nlm_conn_str = os.getenv(env_name)
50
-
51
- with pytest.raises(NetworkLicensingError) as e_info:
52
- validators.validate_mlm_license_file(nlm_conn_str)
53
- assert MLM_LICENSE_FILE in str(e_info.value)
54
-
55
-
56
- @pytest.fixture(name="temporary_license_file")
57
- def temporary_license_file_fixture(tmp_path):
58
- """Pytest fixture which returns a valid path to temporary license file."""
59
- import time
60
-
61
- temp_license_file_path = tmp_path / f'{str(time.time()).replace(".", "")}.lic'
62
- temp_license_file_path.touch()
63
-
64
- return temp_license_file_path
65
-
66
-
67
- def test_validate_mlm_license_file_valid_license_file_path(
68
- temporary_license_file, monkeypatch
69
- ):
70
- """Check if a valid license path has been supplied to MLM_LICENSE_FILE env var"""
71
- env_name = mwi_env.get_env_name_network_license_manager()
72
- monkeypatch.setenv(env_name, str(temporary_license_file))
73
-
74
- validated_file_path = validators.validate_mlm_license_file(os.getenv(env_name))
75
- assert str(temporary_license_file) == validated_file_path
76
-
77
-
78
- @pytest.mark.parametrize(
79
- "MLM_LICENSE_FILE",
80
- [
81
- (["1234@1.2_any-alphanumeric"]),
82
- (["1234@1.2_any-alphanumeric", "1234@1.2_any-alphanumeric"]),
83
- (
84
- [
85
- "1234@1.2_any-alphanumeric",
86
- "1234@1.2_any-alphanumeric",
87
- "1234@1.2_any-alphanumeric",
88
- ]
89
- ),
90
- [
91
- "1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric"
92
- ],
93
- (
94
- [
95
- "1234@1.2_any-alphanumeric",
96
- "1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric",
97
- ]
98
- ),
99
- (
100
- [
101
- "1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric",
102
- "1234@1.2_any-alphanumeric",
103
- ]
104
- ),
105
- (
106
- [
107
- "1234@1.2_any-alphanumeric",
108
- "1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric,1234@1.2_any-alphanumeric",
109
- "1234@1.2_any-alphanumeric",
110
- ]
111
- ),
112
- ],
113
- ids=[
114
- "1 NLM server",
115
- "2 NLM servers",
116
- "3 NLM servers",
117
- "Just a server triad",
118
- "1 NLM server prefixed to a server triad",
119
- "1 NLM server suffixed to a server triad",
120
- "1 NLM server prefixed and another suffixed to a server triad",
121
- ],
122
- )
123
- def test_validate_mlm_license_file_for_valid_nlm_string(MLM_LICENSE_FILE, monkeypatch):
124
- """Check if port@hostname passes validation"""
125
-
126
- seperator = system.get_mlm_license_file_seperator()
127
- MLM_LICENSE_FILE = seperator.join(MLM_LICENSE_FILE)
128
- env_name = mwi_env.get_env_name_network_license_manager()
129
- monkeypatch.setenv(env_name, MLM_LICENSE_FILE)
130
- conn_str = validators.validate_mlm_license_file(os.getenv(env_name))
131
- assert conn_str == MLM_LICENSE_FILE
132
-
133
-
134
- def test_validate_mlm_license_file_None():
135
- """Test to check if validate_mlm_license_file() returns None when nlm_conn_str is None."""
136
- assert validators.validate_mlm_license_file(None) is None
137
-
138
-
139
- def test_get_with_environment_variables(monkeypatch):
140
- """Check if path to license file passes validation"""
141
- env_name = mwi_env.get_env_name_network_license_manager()
142
- fd, path = tempfile.mkstemp()
143
- monkeypatch.setenv(env_name, path)
144
- try:
145
- conn_str = validators.validate_mlm_license_file(os.getenv(env_name))
146
- assert conn_str == str(path)
147
- finally:
148
- os.close(fd)
149
- os.remove(path)
150
-
151
-
152
- def test_validate_app_port_is_free_false():
153
- """Test to validate if supplied app port is free"""
154
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
155
- s.bind(("", 0))
156
- port = s.getsockname()[1]
157
- with pytest.raises(FatalError) as e:
158
- validators.validate_app_port_is_free(port)
159
- s.close()
160
-
161
-
162
- def test_validate_app_port_is_free_true():
163
- """Test to validate if supplied app port is free"""
164
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
165
- s.bind(("", 0))
166
- port = s.getsockname()[1]
167
- s.close()
168
- assert validators.validate_app_port_is_free(port) == port
169
-
170
-
171
- def test_validate_app_port_None():
172
- """Tests if validated app port is None when MWI_APP_PORT env variable is not set.
173
- If validated app port is None implies a random free port will be used at launch.
174
- """
175
- assert validators.validate_app_port_is_free(None) is None
176
-
177
-
178
- def test_validate_env_config_true():
179
- """Validate the default config which is used in this package."""
180
- config = validators.validate_env_config(matlab_proxy.get_default_config_name())
181
- assert isinstance(config, dict)
182
-
183
-
184
- def test_validate_env_config_false():
185
- """Passing a non existent config should raise FatalError exception"""
186
-
187
- with pytest.raises(FatalError):
188
- validators.validate_env_config(str(random.randint(10, 100)))
189
-
190
-
191
- def test_get_configs():
192
- """Test to check if atleast 1 env config is discovered.
193
- When this package is installed, we will have a default config.
194
- """
195
- configs = validators.__get_configs()
196
-
197
- assert len(configs.keys()) >= 1
198
-
199
-
200
- @pytest.mark.parametrize(
201
- "mwi_base_url, validated_base_url",
202
- [
203
- ("", ""),
204
- ("/bla", "/bla"),
205
- ("/bla/", "/bla"),
206
- ],
207
- ids=[
208
- "Launch integration at root",
209
- "Launch at custom path",
210
- "Launch at custom with suffix: /",
211
- ],
212
- )
213
- def test_validate_base_url(mwi_base_url, validated_base_url):
214
- """Tests multiple base_urls which will beparsed and validated successfully.
215
-
216
- Args:
217
- base_url (str): base_url
218
- validated_base_url (str): validated base_url
219
- """
220
- assert validators.validate_base_url(mwi_base_url) == validated_base_url
221
-
222
-
223
- def test_validate_base_url_no_prefix_error():
224
- """Test to check base_url will throw error when a prefix / is not present in it.[summary]"""
225
- with pytest.raises(FatalError) as e:
226
- validators.validate_base_url("matlab/")
227
-
228
-
229
- def test_validate_mwi_ssl_key_and_cert_file(monkeypatch):
230
- """Check if port@hostname passes validation"""
231
- ssl_cert_file_env_name = mwi_env.get_env_name_ssl_cert_file()
232
- ssl_key_file_env_name = mwi_env.get_env_name_ssl_key_file()
233
- fd, path = tempfile.mkstemp()
234
-
235
- monkeypatch.setenv(ssl_cert_file_env_name, path)
236
- monkeypatch.setenv(ssl_key_file_env_name, path)
237
- try:
238
- # Verify that if KEY and CERT are provided
239
- key_file, cert_file = validators.validate_ssl_key_and_cert_file(
240
- os.getenv(ssl_key_file_env_name), os.getenv(ssl_cert_file_env_name)
241
- )
242
- assert key_file == str(path)
243
- assert cert_file == str(path)
244
-
245
- # Verify that KEY can be None
246
- key_file, cert_file = validators.validate_ssl_key_and_cert_file(
247
- None, os.getenv(ssl_cert_file_env_name)
248
- )
249
- assert key_file == None
250
- assert cert_file == str(path)
251
-
252
- # Verify that if KEY is provided, CERT must also be provided
253
- with pytest.raises(FatalError) as e:
254
- validators.validate_ssl_key_and_cert_file(
255
- os.getenv(ssl_key_file_env_name), None
256
- )
257
-
258
- # Verify that KEY is valid file location
259
- with pytest.raises(FatalError) as e:
260
- validators.validate_ssl_key_and_cert_file(
261
- "/file/does/not/exist", os.getenv(ssl_cert_file_env_name)
262
- )
263
-
264
- # Verify that KEY is valid file location
265
- with pytest.raises(FatalError) as e:
266
- validators.validate_ssl_key_and_cert_file(
267
- os.getenv(ssl_key_file_env_name), "/file/does/not/exist"
268
- )
269
- finally:
270
- # Need to close the file descriptor in Windows
271
- # Or else PermissionError is raised.
272
- os.close(fd)
273
- os.remove(path)
274
-
275
-
276
- def test_validate_matlab_root_path(tmp_path):
277
- """Checks if matlab root is validated without raising exceptions"""
278
-
279
- # Arrange
280
- matlab_root = Path(tmp_path) / "MATLAB"
281
- os.mkdir(matlab_root)
282
- version_info_file = Path(matlab_root) / constants.VERSION_INFO_FILE_NAME
283
- version_info_file.touch()
284
-
285
- # Act
286
- actual_matlab_root = validate_matlab_root_path(
287
- matlab_root, is_custom_matlab_root=False
288
- )
289
- actual_matlab_root_custom = validate_matlab_root_path(
290
- matlab_root, is_custom_matlab_root=True
291
- )
292
-
293
- # Assert
294
- assert actual_matlab_root == matlab_root
295
- assert actual_matlab_root_custom == matlab_root
296
-
297
-
298
- def test_validate_matlab_root_path_non_existent_root_path(tmp_path):
299
- """Checks if validate_matlab_root_path raises MatlabInstallError when non-existent path is supplied"""
300
- # Arrange
301
- matlab_root = Path(tmp_path) / "MATLAB"
302
-
303
- # Act
304
- with pytest.raises(MatlabInstallError):
305
- actual_matlab_root = validate_matlab_root_path(
306
- matlab_root, is_custom_matlab_root=False
307
- )
308
- actual_matlab_root_custom = validate_matlab_root_path(
309
- matlab_root, is_custom_matlab_root=True
310
- )
311
-
312
- # Assert
313
- assert actual_matlab_root is None
314
- assert actual_matlab_root_custom is None
315
-
316
-
317
- def test_validate_matlab_root_path_non_existent_versioninfo_file(tmp_path):
318
- """Checks if validate_matlab_root_path does not raise any exceptions even if VersionInfo.xml file does not exist
319
- when matlab wrapper is used and raises an exception when custom matlab root is used.
320
- """
321
- # Arrange
322
- matlab_root = Path(tmp_path) / "MATLAB"
323
- os.mkdir(matlab_root)
324
-
325
- # Act
326
- # Location of VersionInfo.xml can't be determined with matlab wrapper script
327
- # and error should not be raised
328
- actual_matlab_root = validate_matlab_root_path(
329
- matlab_root, is_custom_matlab_root=False
330
- )
331
-
332
- # Location of VersionInfo.xml must be determinable when custom MATLAB root is supplied.
333
- # If not, an exception must be raised
334
- with pytest.raises(MatlabInstallError):
335
- validate_matlab_root_path(matlab_root, is_custom_matlab_root=True)
336
-
337
- # Assert
338
- assert actual_matlab_root is None
339
-
340
-
341
- @pytest.mark.parametrize(
342
- "timeout, validated_timeout",
343
- [
344
- (None, None),
345
- ("abc", None),
346
- (-10, None),
347
- (123, 60 * 123),
348
- ],
349
- ids=[
350
- "No IDLE timeout specified",
351
- "Invalid IDLE timeout specified",
352
- "Negative number supplied as IDLE timeout",
353
- "Valid IDLE timeout specified",
354
- ],
355
- )
356
- def test_validate_idle_timeout(timeout, validated_timeout):
357
- # Arrange
358
- # Nothing to arrange
359
-
360
- # Act
361
- actual_timeout = validate_idle_timeout(timeout)
362
-
363
- # Assert
364
- assert actual_timeout == validated_timeout