matlab-proxy 0.14.0__py3-none-any.whl → 0.15.1__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 (50) hide show
  1. matlab_proxy/app.py +52 -10
  2. matlab_proxy/constants.py +1 -0
  3. matlab_proxy/gui/asset-manifest.json +3 -3
  4. matlab_proxy/gui/index.html +1 -1
  5. matlab_proxy/gui/static/js/{main.14aa7840.js → main.ff1bfd69.js} +3 -3
  6. matlab_proxy/gui/static/js/main.ff1bfd69.js.map +1 -0
  7. matlab_proxy/util/__init__.py +8 -1
  8. matlab_proxy/util/mwi/download.py +145 -0
  9. matlab_proxy/util/mwi/embedded_connector/helpers.py +1 -1
  10. matlab_proxy/util/mwi/embedded_connector/request.py +1 -1
  11. {matlab_proxy-0.14.0.dist-info → matlab_proxy-0.15.1.dist-info}/METADATA +1 -1
  12. {matlab_proxy-0.14.0.dist-info → matlab_proxy-0.15.1.dist-info}/RECORD +49 -16
  13. {matlab_proxy-0.14.0.dist-info → matlab_proxy-0.15.1.dist-info}/top_level.txt +1 -0
  14. tests/integration/__init__.py +1 -0
  15. tests/integration/integration_tests_with_license/__init__.py +1 -0
  16. tests/integration/integration_tests_with_license/conftest.py +47 -0
  17. tests/integration/integration_tests_with_license/test_http_end_points.py +223 -0
  18. tests/integration/integration_tests_without_license/__init__.py +1 -0
  19. tests/integration/integration_tests_without_license/conftest.py +115 -0
  20. tests/integration/integration_tests_without_license/test_matlab_is_down_if_unlicensed.py +49 -0
  21. tests/integration/utils/__init__.py +1 -0
  22. tests/integration/utils/integration_tests_utils.py +352 -0
  23. tests/integration/utils/licensing.py +152 -0
  24. tests/unit/__init__.py +1 -0
  25. tests/unit/conftest.py +67 -0
  26. tests/unit/test_app.py +1113 -0
  27. tests/unit/test_app_state.py +582 -0
  28. tests/unit/test_constants.py +5 -0
  29. tests/unit/test_ddux.py +22 -0
  30. tests/unit/test_devel.py +246 -0
  31. tests/unit/test_non_dev_mode.py +169 -0
  32. tests/unit/test_settings.py +460 -0
  33. tests/unit/util/__init__.py +3 -0
  34. tests/unit/util/mwi/__init__.py +1 -0
  35. tests/unit/util/mwi/embedded_connector/__init__.py +1 -0
  36. tests/unit/util/mwi/embedded_connector/test_helpers.py +29 -0
  37. tests/unit/util/mwi/embedded_connector/test_request.py +64 -0
  38. tests/unit/util/mwi/test_custom_http_headers.py +281 -0
  39. tests/unit/util/mwi/test_logger.py +49 -0
  40. tests/unit/util/mwi/test_token_auth.py +289 -0
  41. tests/unit/util/mwi/test_validators.py +331 -0
  42. tests/unit/util/test_mw.py +550 -0
  43. tests/unit/util/test_util.py +135 -0
  44. tests/utils/__init__.py +1 -0
  45. tests/utils/logging_util.py +81 -0
  46. matlab_proxy/gui/static/js/main.14aa7840.js.map +0 -1
  47. /matlab_proxy/gui/static/js/{main.14aa7840.js.LICENSE.txt → main.ff1bfd69.js.LICENSE.txt} +0 -0
  48. {matlab_proxy-0.14.0.dist-info → matlab_proxy-0.15.1.dist-info}/LICENSE.md +0 -0
  49. {matlab_proxy-0.14.0.dist-info → matlab_proxy-0.15.1.dist-info}/WHEEL +0 -0
  50. {matlab_proxy-0.14.0.dist-info → matlab_proxy-0.15.1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,582 @@
1
+ # Copyright 2023 The MathWorks, Inc.
2
+
3
+ import json
4
+ import os
5
+ from dataclasses import dataclass
6
+ from pathlib import Path
7
+ from typing import Optional
8
+
9
+ import pytest
10
+ from matlab_proxy import settings
11
+
12
+ from matlab_proxy.app_state import AppState
13
+ from matlab_proxy.util.mwi.exceptions import LicensingError, MatlabError
14
+ from tests.unit.util import MockResponse
15
+
16
+
17
+ @pytest.fixture
18
+ def sample_settings_fixture(tmp_path):
19
+ """A pytest fixture which returns a dict containing sample settings for the AppState class.
20
+
21
+ Args:
22
+ tmp_path : Builtin pytest fixture
23
+
24
+ Returns:
25
+ dict: A dictionary of sample settings
26
+ """
27
+ tmp_file = tmp_path / "parent_1" / "parent_2" / "tmp_file.json"
28
+ return {
29
+ "error": None,
30
+ "warnings": [],
31
+ "matlab_config_file": tmp_file,
32
+ "is_xvfb_available": True,
33
+ "mwi_server_url": "dummy",
34
+ "mwi_logs_root_dir": Path(settings.get_mwi_config_folder(dev=True)),
35
+ "app_port": 12345,
36
+ "mwapikey": "asdf",
37
+ }
38
+
39
+
40
+ @pytest.fixture
41
+ def app_state_fixture(sample_settings_fixture):
42
+ """A pytest fixture which returns an instance of AppState class with no errors.
43
+
44
+ Args:
45
+ sample_settings_fixture (dict): A dictionary of sample settings to be used by
46
+
47
+ Returns:
48
+ AppState: An object of the AppState class
49
+ """
50
+ app_state = AppState(settings=sample_settings_fixture)
51
+ app_state.processes = {"matlab": None, "xvfb": None}
52
+ app_state.licensing = {"type": "existing_license"}
53
+ return app_state
54
+
55
+
56
+ @pytest.fixture
57
+ def sample_token_headers_fixture():
58
+ return {"mwi_auth_token_name": "asdf"}
59
+
60
+
61
+ @pytest.fixture
62
+ def app_state_with_token_auth_fixture(
63
+ app_state_fixture, sample_token_headers_fixture, tmp_path
64
+ ):
65
+ """Pytest fixture which returns AppState instance with token authentication enabled.
66
+
67
+ Args:
68
+ app_state_fixture (AppState): Pytest fixture
69
+ tmp_path (str): Built-in pytest fixture
70
+
71
+ Returns:
72
+ (AppState, dict): Instance of the AppState class with token authentication enabled and token headers
73
+ """
74
+ tmp_matlab_ready_file = Path(tmp_path) / "tmp_file.txt"
75
+ tmp_matlab_ready_file.touch()
76
+ ((mwi_auth_token_name, mwi_auth_token_hash),) = sample_token_headers_fixture.items()
77
+ app_state_fixture.matlab_session_files["matlab_ready_file"] = tmp_matlab_ready_file
78
+ app_state_fixture.settings["mwi_is_token_auth_enabled"] = True
79
+ app_state_fixture.settings["mwi_auth_token_name"] = mwi_auth_token_name
80
+ app_state_fixture.settings["mwi_auth_token_hash"] = mwi_auth_token_hash
81
+ app_state_fixture.settings["mwi_server_url"] = "http://localhost:8888"
82
+
83
+ return app_state_fixture
84
+
85
+
86
+ @pytest.fixture
87
+ def mocker_os_patching_fixture(mocker, platform):
88
+ """A pytest fixture which patches the is_* functions in system.py module
89
+
90
+ Args:
91
+ mocker : Built in pytest fixture
92
+ platform (str): A string representing "windows", "linux" or "mac"
93
+
94
+ Returns:
95
+ mocker: Built in pytest fixture with patched calls to system.py module.
96
+ """
97
+ mocker.patch("matlab_proxy.app_state.system.is_linux", return_value=False)
98
+ mocker.patch("matlab_proxy.app_state.system.is_windows", return_value=False)
99
+ mocker.patch("matlab_proxy.app_state.system.is_mac", return_value=False)
100
+ mocker.patch("matlab_proxy.app_state.system.is_posix", return_value=False)
101
+
102
+ if platform == "linux":
103
+ mocker.patch("matlab_proxy.app_state.system.is_linux", return_value=True)
104
+ mocker.patch("matlab_proxy.app_state.system.is_posix", return_value=True)
105
+
106
+ elif platform == "windows":
107
+ mocker.patch("matlab_proxy.app_state.system.is_windows", return_value=True)
108
+ mocker.patch("matlab_proxy.app_state.system.is_posix", return_value=False)
109
+
110
+ else:
111
+ mocker.patch("matlab_proxy.app_state.system.is_mac", return_value=True)
112
+ mocker.patch("matlab_proxy.app_state.system.is_posix", return_value=True)
113
+
114
+ return mocker
115
+
116
+
117
+ @dataclass(frozen=True)
118
+ class Mock_xvfb:
119
+ """An immutable dataclass representing a mocked Xvfb process"""
120
+
121
+ returncode: Optional[int]
122
+ pid: Optional[int]
123
+
124
+
125
+ @dataclass(frozen=True)
126
+ class Mock_matlab:
127
+ """An immutable dataclass representing a mocked MATLAB process"""
128
+
129
+ returncode: Optional[int]
130
+ pid: Optional[int]
131
+
132
+
133
+ @pytest.mark.parametrize(
134
+ "licensing, expected",
135
+ [
136
+ (None, False),
137
+ ({"type": "nlm", "conn_str": "123@host"}, True),
138
+ ({"type": "nlm"}, False),
139
+ ({"type": "mhlm", "identity_token": "random_token"}, False),
140
+ (
141
+ {
142
+ "type": "mhlm",
143
+ "identity_token": "random_token",
144
+ "source_id": "dummy_id",
145
+ "expiry": "Jan 1, 1970",
146
+ "entitlement_id": "123456",
147
+ },
148
+ True,
149
+ ),
150
+ ({"type": "existing_license"}, True),
151
+ ({"type": "invalid_type"}, False),
152
+ ],
153
+ ids=[
154
+ "None licensing",
155
+ "happy path-nlm",
156
+ "incomplete nlm data",
157
+ "incomplete mhlm data",
158
+ "happy path-mhlm",
159
+ "happy path-existing license",
160
+ "invalid license",
161
+ ],
162
+ )
163
+ def test_is_licensed(app_state_fixture, licensing, expected):
164
+ """Test to check is_licensed()
165
+
166
+ Args:
167
+ app_state_fixture (AppState): Object of AppState class with defaults set
168
+ licensing (dict): Represents licensing information
169
+ expected (bool): Expected return value.
170
+ """
171
+ # Arrange
172
+ # Nothing to arrange
173
+
174
+ # Act
175
+ app_state_fixture.licensing = licensing
176
+
177
+ # Assert
178
+ assert app_state_fixture.is_licensed() == expected
179
+
180
+
181
+ @pytest.mark.parametrize(
182
+ "err, expected_err",
183
+ [
184
+ (MatlabError(message="dummy error"), MatlabError(message="dummy")),
185
+ (LicensingError(message="license issue"), None),
186
+ ],
187
+ ids=["Any error except licensing error", "licensing error"],
188
+ )
189
+ def test_unset_licensing(err, app_state_fixture, expected_err):
190
+ """Test to check unset_liecnsing removes licensing from the AppState object
191
+
192
+ Args:
193
+ err (Exception): Custom exceptions defined in exceptions.py
194
+ licensing (bool): Whether licensing info is removed
195
+ expected_err (Exception): Expected exception
196
+ """
197
+ # Arrange
198
+ app_state_fixture.error = err
199
+
200
+ # Act
201
+ app_state_fixture.unset_licensing()
202
+
203
+ # Assert
204
+ assert app_state_fixture.licensing == None
205
+ assert type(app_state_fixture.error) is type(expected_err)
206
+
207
+
208
+ # config file is deleted when licensing info is not set i.e. set to None
209
+ def test_persist_licensing_when_licensing_info_is_not_set(app_state_fixture):
210
+ """Test to check if data is not persisted to a file if licensing info is not present
211
+
212
+ Args:
213
+ tmp_path (Path): Built in pytest fixture
214
+ """
215
+ # Arrange
216
+ # Nothing to arrange
217
+ app_state_fixture.licensing = None
218
+
219
+ # Act
220
+ app_state_fixture.persist_config_data()
221
+
222
+ # Assert
223
+ assert os.path.exists(app_state_fixture.settings["matlab_config_file"]) is False
224
+
225
+
226
+ @pytest.mark.parametrize(
227
+ "licensing_data",
228
+ [
229
+ ({"type": "nlm", "conn_str": "123@host"}),
230
+ (
231
+ {
232
+ "type": "mhlm",
233
+ "identity_token": "random_token",
234
+ "source_id": "dummy_id",
235
+ "expiry": "Jan 1, 1970",
236
+ "entitlement_id": "123456",
237
+ }
238
+ ),
239
+ ({"type": "existing_license"}),
240
+ ],
241
+ ids=["nlm type", "mhlm type", "existing license type"],
242
+ )
243
+ def test_persist_config_data(licensing_data: dict, tmp_path):
244
+ """Test to check if persist_licensing() writes data to the file system
245
+
246
+ Args:
247
+ data (dict): Represents matlab-proxy licensing data
248
+ tmp_path : Built-in pytest fixture.
249
+ """
250
+ # Arrange
251
+ tmp_file = tmp_path / "parent_1" / "parent_2" / "tmp_file.json"
252
+ settings = {
253
+ "matlab_config_file": tmp_file,
254
+ "error": None,
255
+ "matlab_version": None,
256
+ "warnings": [],
257
+ }
258
+ app_state = AppState(settings=settings)
259
+ app_state.licensing = licensing_data
260
+
261
+ cached_data = {"licensing": licensing_data, "matlab": {"version": None}}
262
+
263
+ # Act
264
+ app_state.persist_config_data()
265
+ with open(tmp_file, "r") as file:
266
+ got = file.read()
267
+
268
+ # Assert
269
+ assert json.loads(got) == cached_data
270
+
271
+
272
+ validate_required_processes_test_data = [
273
+ (None, None, "linux", False), # xvfb is None == True
274
+ (None, Mock_xvfb(None, 1), "linux", False), # matlab is None == True
275
+ (
276
+ Mock_matlab(None, 1),
277
+ Mock_xvfb(None, 1),
278
+ "linux",
279
+ True,
280
+ ), # All branches are skipped and nothing returned
281
+ (
282
+ Mock_matlab(None, 1),
283
+ Mock_xvfb(123, 2),
284
+ "linux",
285
+ False,
286
+ ), # xvfb.returncode is not None == True
287
+ (
288
+ Mock_matlab(123, 1),
289
+ Mock_xvfb(None, 2),
290
+ "linux",
291
+ False,
292
+ ), # matlab.returncode is not None == True
293
+ (
294
+ Mock_matlab(None, 1),
295
+ None,
296
+ "linux",
297
+ True,
298
+ ), # Xvfb not found on path
299
+ ]
300
+
301
+
302
+ @pytest.mark.parametrize(
303
+ "matlab, xvfb, platform, expected",
304
+ validate_required_processes_test_data,
305
+ ids=[
306
+ "processes_not_running",
307
+ "matlab_not_running",
308
+ "All_required_processes_running",
309
+ "All_processes_running_with_xvfb_returning_non_zero_code",
310
+ "All_processes_running_with_matlab_returning_non_zero_code",
311
+ "xvfb_is_optional_matlab_starts_without_it",
312
+ ],
313
+ )
314
+ def test_are_required_processes_ready(
315
+ app_state_fixture, mocker_os_patching_fixture, matlab, xvfb, expected
316
+ ):
317
+ """Test to check if required processes are ready
318
+
319
+ Args:
320
+ app_state_fixture (AppState): Object of AppState class with defaults set
321
+ mocker_os_patching_fixture (mocker): Custom pytest fixture for mocking
322
+ matlab (Mock_matlab): Represents a mocked MATLAB process
323
+ xvfb (Mock_xvfb): Represents a mocked Xvfb process
324
+ expected (bool): Expected return value based on process return code
325
+ """
326
+ # Arrange
327
+ app_state_fixture.processes = {"matlab": matlab, "xvfb": xvfb}
328
+ if not xvfb:
329
+ app_state_fixture.settings["is_xvfb_available"] = False
330
+
331
+ # Act
332
+ actual = app_state_fixture._are_required_processes_ready()
333
+
334
+ # Assert
335
+ assert actual == expected
336
+
337
+
338
+ get_matlab_status_based_on_connector_status_test_data = [
339
+ ("up", True, "up"),
340
+ ("down", True, "starting"),
341
+ ("up", False, "starting"),
342
+ ]
343
+
344
+
345
+ @pytest.mark.parametrize(
346
+ "connector_status, ready_file_present, matlab_status",
347
+ get_matlab_status_based_on_connector_status_test_data,
348
+ ids=["connector_up", "connector_down", "connector_up_ready_file_not_present"],
349
+ )
350
+ async def test_get_matlab_status_based_on_connector_status(
351
+ mocker, app_state_fixture, connector_status, ready_file_present, matlab_status
352
+ ):
353
+ """Test to check matlab status based on connector status
354
+
355
+ Args:
356
+ mocker : Built in pytest fixture.
357
+ connector_status (str): Status of Embedded Connector.
358
+ ready_file_present (bool): Represents if the ready file has been created or not.
359
+ matlab_status (str): Represents the status of MATLAB process.
360
+ """
361
+ # Arrange
362
+ mocker.patch(
363
+ "matlab_proxy.app_state.mwi.embedded_connector.request.get_state",
364
+ return_value=connector_status,
365
+ )
366
+ mocker.patch.object(Path, "exists", return_value=ready_file_present)
367
+ app_state_fixture.settings["mwi_is_token_auth_enabled"] = False
368
+ app_state_fixture.matlab_session_files["matlab_ready_file"] = Path("dummy")
369
+
370
+ # Act
371
+ actual_matlab_status = await app_state_fixture._get_matlab_connector_status()
372
+
373
+ # Assert
374
+ assert actual_matlab_status == matlab_status
375
+
376
+
377
+ @pytest.mark.parametrize(
378
+ "valid_processes, connector_status, expected",
379
+ [
380
+ (True, "up", "up"),
381
+ (False, "up", "down"),
382
+ (True, "down", "down"),
383
+ ],
384
+ ids=[
385
+ "valid_processes_connector_up",
386
+ "invalid_processes_connector_up",
387
+ "valid_processes_connector_down",
388
+ ],
389
+ )
390
+ async def test_get_matlab_state(
391
+ app_state_fixture, mocker, valid_processes, connector_status, expected
392
+ ):
393
+ """Test to check get_matlab_state returns the correct MATLAB state based on the connector status
394
+
395
+ Args:
396
+ app_state_fixture (AppState): Object of AppState class with defaults set
397
+ mocker : Built in pytest fixture
398
+ valid_processes (bool): Represents if the processes are valid or not
399
+ connector_status (str): Status of Embedded Connector.
400
+ expected (str): Expected status of MATLAB process.
401
+ """
402
+ # Arrange
403
+ mocker.patch.object(
404
+ AppState,
405
+ "_are_required_processes_ready",
406
+ return_value=valid_processes,
407
+ )
408
+ mocker.patch.object(
409
+ AppState,
410
+ "_get_matlab_connector_status",
411
+ return_value=connector_status,
412
+ )
413
+
414
+ # Act
415
+ actual_state = await app_state_fixture.get_matlab_state()
416
+
417
+ # Assert
418
+ assert actual_state == expected
419
+
420
+
421
+ @pytest.mark.parametrize("platform", [("linux"), ("windows"), ("mac")])
422
+ async def test_track_embedded_connector(mocker_os_patching_fixture, app_state_fixture):
423
+ """Test to check track_embedded_connector task
424
+
425
+ Args:
426
+ mocker_os_patching_fixture (mocker): Custom pytest fixture for mocking
427
+ app_state_fixture (AppState): Object of AppState class with defaults set
428
+ """
429
+
430
+ # Arrange
431
+ # patching embedded_connector_start_time to EPOCH+1 seconds and state to be "down"
432
+ mocker_os_patching_fixture.patch.object(
433
+ app_state_fixture, "embedded_connector_start_time", new=float(1.0)
434
+ )
435
+ mocker_os_patching_fixture.patch.object(
436
+ app_state_fixture, "embedded_connector_state", return_value="down"
437
+ )
438
+
439
+ # verify that stop_matlab() is called once
440
+ spy = mocker_os_patching_fixture.spy(app_state_fixture, "stop_matlab")
441
+
442
+ # Act
443
+ await app_state_fixture._AppState__track_embedded_connector_state()
444
+
445
+ # Assert
446
+ spy.assert_called_once()
447
+
448
+
449
+ @pytest.mark.parametrize(
450
+ "env_var_name, filter_prefix, is_filtered",
451
+ [("MWI_AUTH_TOKEN", "MWI_", None), ("MWIFOO_AUTH_TOKEN", "MWI_", "foo")],
452
+ ids=["env_var_is_filtered", "env_var_is_not_filtered"],
453
+ )
454
+ def test_env_variables_filtration_for_xvfb_process(
455
+ monkeypatch, env_var_name, filter_prefix, is_filtered
456
+ ):
457
+ """Test to check if __filter_env_variables filters environment variables with a certain prefix correctly.
458
+
459
+ Args:
460
+ monkeypatch (Object): Built-in pytest fixture for monkeypatching
461
+ env_var_name (str): Name of the environment variable
462
+ filter_prefix (str): Prefix to check for filtering
463
+ is_filtered (bool): To check if the env variable with specified prefix is filtered.
464
+ """
465
+ # Arrange
466
+ env_var = env_var_name
467
+ monkeypatch.setenv(env_var, "foo")
468
+
469
+ # Act
470
+ filtered_env_vars: dict = AppState._AppState__filter_env_variables(
471
+ os.environ, filter_prefix
472
+ )
473
+
474
+ # Assert
475
+ assert filtered_env_vars.get(env_var) == is_filtered
476
+
477
+
478
+ @pytest.mark.parametrize(
479
+ "platform, expected_output",
480
+ [("linux", "stdout"), ("windows", "file"), ("mac", "stdout")],
481
+ )
482
+ async def test_setup_env_for_matlab(
483
+ mocker_os_patching_fixture, platform, expected_output, app_state_fixture, tmp_path
484
+ ):
485
+ """Test to check MW_DIAGNOSTIC_DEST is set appropriately for posix and non-posix systems
486
+
487
+ Args:
488
+ mocker_os_patching_fixture (mocker): Custom pytest fixture for mocking
489
+ platform (str): string describing a platform
490
+ app_state_fixture (AppState): Object of AppState class with defaults set
491
+ tmp_path (Path): Built-in pytest fixture for temporary paths
492
+ """
493
+
494
+ # Arrange
495
+ app_state_fixture.licensing = {"type": "existing_license"}
496
+ app_state_fixture.settings = {"mwapikey": None, "matlab_display": ":1"}
497
+ app_state_fixture.mwi_logs_dir = tmp_path
498
+ mocker_os_patching_fixture.patch(
499
+ "matlab_proxy.app_state.logger.isEnabledFor", return_value=True
500
+ )
501
+
502
+ # Act
503
+ matlab_env = await app_state_fixture._AppState__setup_env_for_matlab()
504
+
505
+ # Assert
506
+ assert expected_output in matlab_env["MW_DIAGNOSTIC_DEST"]
507
+
508
+
509
+ @pytest.mark.parametrize(
510
+ "function_to_call ,mock_response",
511
+ [
512
+ ("_get_matlab_connector_status", MockResponse(ok=True)),
513
+ (
514
+ "_AppState__send_stop_request_to_matlab",
515
+ MockResponse(
516
+ ok=True, payload={"messages": {"EvalResponse": [{"isError": None}]}}
517
+ ),
518
+ ),
519
+ ],
520
+ ids=["request matlab connector status", "send request to stop matlab"],
521
+ )
522
+ async def test_requests_sent_by_matlab_proxy_have_headers(
523
+ app_state_with_token_auth_fixture,
524
+ function_to_call,
525
+ mock_response,
526
+ mocker,
527
+ sample_token_headers_fixture,
528
+ ):
529
+ """Test to check if token headers are included in requests sent by matlab-proxy when authentication is enabled
530
+
531
+ Args:
532
+ app_state_fixture_with_token_auth (AppState): Instance of AppState class with token authentication enabled
533
+ mocker : Built-in pytest fixture
534
+ """
535
+ # Arrange
536
+ mocked_request = mocker.patch(
537
+ "aiohttp.ClientSession.request", return_value=mock_response
538
+ )
539
+
540
+ # Act
541
+ # Call the function passed as a string
542
+ method = getattr(app_state_with_token_auth_fixture, function_to_call)
543
+ _ = await method()
544
+
545
+ # Assert
546
+ connector_status_request_headers = list(mocked_request.call_args_list)[0].kwargs[
547
+ "headers"
548
+ ]
549
+ assert sample_token_headers_fixture == connector_status_request_headers
550
+
551
+
552
+ async def test_start_matlab_without_xvfb(app_state_fixture, mocker):
553
+ """Test to check if Matlab process starts without throwing errors when Xvfb is not present
554
+
555
+ Args:
556
+ app_state_fixture (AppState): Object of AppState class with defaults set
557
+ mocker : Built-in pytest fixture
558
+ """
559
+ # Arrange
560
+ app_state_fixture.settings["is_xvfb_available"] = False
561
+ mock_matlab = Mock_matlab(None, 1)
562
+
563
+ # Starting asyncio tasks related to matlab is not required here as only Xvfb check is required.
564
+ mocker.patch.object(
565
+ AppState, "_AppState__start_matlab_process", return_value=mock_matlab
566
+ )
567
+ mocker.patch.object(
568
+ AppState, "_AppState__matlab_stderr_reader_posix", return_value=None
569
+ )
570
+ mocker.patch.object(
571
+ AppState, "_AppState__track_embedded_connector_state", return_value=None
572
+ )
573
+ mocker.patch.object(AppState, "_AppState__update_matlab_port", return_value=None)
574
+
575
+ # Act
576
+ await app_state_fixture.start_matlab()
577
+
578
+ # Assert
579
+ # Check if Xvfb has not started
580
+ assert app_state_fixture.processes["xvfb"] is None
581
+ # Check if Matlab started
582
+ assert app_state_fixture.processes["matlab"] is mock_matlab
@@ -0,0 +1,5 @@
1
+ # Copyright 2020-2023 The MathWorks, Inc.
2
+ TWO_MAX_TRIES = 2
3
+ FIVE_MAX_TRIES = 5
4
+ HALF_SECOND_DELAY = 0.5
5
+ ONE_SECOND_DELAY = 1
@@ -0,0 +1,22 @@
1
+ # Copyright 2020-2022 The MathWorks, Inc.
2
+
3
+ import matlab_proxy
4
+ from matlab_proxy import util
5
+
6
+
7
+ def test_get_mwi_ddux_value():
8
+ """Tests ddux value for matlab-proxy with different extension names"""
9
+ expected_result = matlab_proxy.__get_matlab_proxy_base_ddux_value()
10
+ actual_result = matlab_proxy.get_mwi_ddux_value(
11
+ matlab_proxy.get_default_config_name()
12
+ )
13
+
14
+ assert expected_result == actual_result
15
+
16
+ expected_result = f"MATLAB_PROXY:HELLO_WORLD:V1"
17
+ actual_result = matlab_proxy.get_mwi_ddux_value("hello world")
18
+
19
+ assert expected_result == actual_result
20
+
21
+ actual_result = matlab_proxy.get_mwi_ddux_value(" \n \t hello-world \n")
22
+ assert expected_result == actual_result