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

@@ -1,20 +1,20 @@
1
1
  matlab_proxy/__init__.py,sha256=6cwi8buKCMtw9OeWaOYUHEoqwl5MyJ_s6GxgNuqPuNg,1673
2
- matlab_proxy/app.py,sha256=7BsHSM3PxTjN6eN10HLj74Y1wtu-Gl92g1RLbaTGz9U,34698
3
- matlab_proxy/app_state.py,sha256=KO2aczGbTnIMoXVqHJEriEyeapYHU_sDXifwA5U3kTw,72077
4
- matlab_proxy/constants.py,sha256=L9fhXdcGH7Eu56h0aB_TNm3d6aNFr2nP6-HyQJ96TAA,1175
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=ni-9zNbWF3cy4v0X8vAwAiM5WcC8U_t3a-s7GXIkyBA,26723
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=6SxjZB0znU7vcLRnk4avZIzdOqlFBFt-zaNC8qhxIr0,720
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.Cm14Eqsb.js,sha256=mcaB_Rp1rvj4mdHLEWC3s3dZhDKTBuYOFXSg8e-B68o,280210
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=Rgb1Y3F2pFgByKAaXxWWcYOA2594D7V2HXuyuVmGYjs,653
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,11 +48,11 @@ 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=sOfmL8PjQONgkJdegdotLbsqHsWJDsjS7kak0TJtVKU,7441
52
- matlab_proxy/util/mwi/exceptions.py,sha256=3jklFU6br2_pSSsATCRDY3A5fTzk6ekJ4M69sunwxBk,5114
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
- matlab_proxy/util/mwi/validators.py,sha256=iXPR7b3jtnwx2i15YxKQgmOm2pt3ujJeMGYNxY0oGGw,12633
55
+ matlab_proxy/util/mwi/validators.py,sha256=dg2OXL686vWie_JoTNpFSje2m_UqdpvpTVHJl5tmxSo,13247
56
56
  matlab_proxy/util/mwi/embedded_connector/__init__.py,sha256=Vfl2hNC7V1IwoK9_wrwfENs4BC8P-Mvvqh4BNGi2n48,119
57
57
  matlab_proxy/util/mwi/embedded_connector/helpers.py,sha256=kpIgJN0AqYLeX56UylWgB0t07fg8sh0RhIlUH_8JitM,3654
58
58
  matlab_proxy/util/mwi/embedded_connector/request.py,sha256=RXoVvrm5fibVb2A6EZnkMWwAQkYX3J5kqDTGQDZo9p0,4316
@@ -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=51r3foIshg80NLgvsxaQUxlnnZiKs0O6gLvdF3Y7sWk,14448
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=pM8zVyXWLx8nP8RePusXH4admEBYKc5JC8eE2t8xIQE,38487
89
- tests/unit/test_app_state.py,sha256=HuRs4ofCviS_N8Nj71_KkB3OrEf8aqHsA0SZlUreQPc,37110
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=0v27y27SLOWvw6jf_GhLLNg-RMsZS_OyGAnqoQYPpSA,5515
94
- tests/unit/test_settings.py,sha256=eBlV-ME_O8oLoOjJqqYTDTXJs-0smnM0oIMwHZEjUbo,17727
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=YC4mjn6G6_XuHELt8uW9F6g2K0_fWtQl1R0kWFvWbAo,18565
97
- tests/unit/util/test_util.py,sha256=gecUFSVIg4a9s3Ljl0A7eSSY5jN4vH668CbjnTpi198,7431
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=-eBsaQ5JC7pyd9PXt48Rqs4cWjg6I-eOkp_gFVEwYhk,10538
103
- tests/unit/util/mwi/test_validators.py,sha256=lJy9rEXCULRrp9wxv9KXUjtlTFbchqTefxGLUg_n3S8,11452
102
+ tests/unit/util/mwi/test_token_auth.py,sha256=0gp41Y7zZFqeFDCA0V3Arv_CqnQKo5RZqijIccvezYM,10562
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.24.1.dist-info/LICENSE.md,sha256=oF0h3UdSF-rlUiMGYwi086ZHqelzz7yOOk9HFDv9ELo,2344
110
- matlab_proxy-0.24.1.dist-info/METADATA,sha256=4MRz3xe4BjJtlDV-2KJ07wl-lP-QsE-o64F2u5FZk4U,10199
111
- matlab_proxy-0.24.1.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
112
- matlab_proxy-0.24.1.dist-info/entry_points.txt,sha256=ZAlCUsgKzGcAeQaMZOq31FrTB5tQ8Ypq8Op_8U600-A,305
113
- matlab_proxy-0.24.1.dist-info/top_level.txt,sha256=KF-347aoRGsfHTpiSqfIPUZ95bzK5-oMIu8S_TUcu-w,40
114
- matlab_proxy-0.24.1.dist-info/RECORD,,
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,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.45.1)
2
+ Generator: setuptools (75.3.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -5,4 +5,3 @@ matlab-proxy-manager-app = matlab_proxy_manager.web.app:main
5
5
 
6
6
  [matlab_proxy_configs]
7
7
  default_configuration_matlab_proxy = matlab_proxy.default_configuration:config
8
-
@@ -1,4 +1,4 @@
1
- # Copyright 2023-2024 The MathWorks, Inc.
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
- loop,
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
- loop (Event event_loop): The built-in event event_loop provided by pytest.
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(loop) as matlab_proxy_app:
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-2024 The MathWorks, Inc.
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
- import tests.unit.test_constants as test_constants
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(loop):
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
- loop.run_until_complete(test_server["state"].stop_server_tasks())
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
- loop,
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(loop, aiohttp_client) as test_server:
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(0.5)
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
- "connection": "Upgrade",
649
- "Upgrade": "websocket",
650
- },
651
- {
652
- "connection": "upgrade",
653
- "upgrade": "websocket",
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 test_matlab_proxy_web_socket(test_server, headers):
659
- """Test to check if test_server proxies web socket request to fake matlab server
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
- Args:
662
- test_server (aiohttp_client): Test Server to send HTTP Requests.
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
- await wait_for_matlab_to_be_up(test_server, test_constants.ONE_SECOND_DELAY)
666
- resp = await test_server.ws_connect("/http_ws_request.html/", headers=headers)
667
- text = await resp.receive()
668
- websocket_response_string = (
669
- "Hello world" # This string is set by the web_socket_handler in devel.py
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
- assert text.type == aiohttp.WSMsgType.TEXT
672
- assert text.data == websocket_response_string
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
@@ -1,4 +1,4 @@
1
- # Copyright 2023-2024 The MathWorks, Inc.
1
+ # Copyright 2023-2025 The MathWorks, Inc.
2
2
 
3
3
  import asyncio
4
4
  import json
@@ -13,7 +13,11 @@ from matlab_proxy import settings
13
13
  from matlab_proxy import settings
14
14
  from matlab_proxy.app_state import AppState
15
15
  from matlab_proxy.constants import MWI_AUTH_TOKEN_NAME_FOR_HTTP
16
- from matlab_proxy.util.mwi.exceptions import LicensingError, MatlabError
16
+ from matlab_proxy.util.mwi.exceptions import (
17
+ LicensingError,
18
+ MatlabError,
19
+ MatlabInstallError,
20
+ )
17
21
  from matlab_proxy.constants import (
18
22
  CONNECTOR_SECUREPORT_FILENAME,
19
23
  USER_CODE_OUTPUT_FILE_NAME,
@@ -39,6 +43,7 @@ def sample_settings_fixture(tmp_path):
39
43
  "warnings": [],
40
44
  "matlab_config_file": tmp_file,
41
45
  "is_xvfb_available": True,
46
+ "is_windowmanager_available": True,
42
47
  "mwi_server_url": "dummy",
43
48
  "mwi_logs_root_dir": Path(settings.get_mwi_config_folder(dev=True)),
44
49
  "app_port": 12345,
@@ -51,12 +56,12 @@ def sample_settings_fixture(tmp_path):
51
56
 
52
57
 
53
58
  @pytest.fixture
54
- def app_state_fixture(sample_settings_fixture, loop):
59
+ def app_state_fixture(sample_settings_fixture, event_loop):
55
60
  """A pytest fixture which returns an instance of AppState class with no errors.
56
61
 
57
62
  Args:
58
63
  sample_settings_fixture (dict): A dictionary of sample settings to be used by
59
- loop : A pytest builtin fixture
64
+ event_loop : A pytest builtin fixture
60
65
 
61
66
  Returns:
62
67
  AppState: An object of the AppState class
@@ -67,7 +72,7 @@ def app_state_fixture(sample_settings_fixture, loop):
67
72
 
68
73
  yield app_state
69
74
 
70
- loop.run_until_complete(app_state.stop_server_tasks())
75
+ event_loop.run_until_complete(app_state.stop_server_tasks())
71
76
 
72
77
 
73
78
  @pytest.fixture
@@ -104,13 +109,13 @@ def app_state_with_token_auth_fixture(
104
109
 
105
110
 
106
111
  @pytest.fixture
107
- def mocker_os_patching_fixture(mocker, platform, loop):
112
+ def mocker_os_patching_fixture(mocker, platform, event_loop):
108
113
  """A pytest fixture which patches the is_* functions in system.py module
109
114
 
110
115
  Args:
111
116
  mocker : Built in pytest fixture
112
117
  platform (str): A string representing "windows", "linux" or "mac"
113
- loop : A pytest builtin fixture
118
+ event_loop : A pytest builtin fixture
114
119
 
115
120
  Returns:
116
121
  mocker: Built in pytest fixture with patched calls to system.py module.
@@ -119,7 +124,7 @@ def mocker_os_patching_fixture(mocker, platform, loop):
119
124
  mocker.patch("matlab_proxy.app_state.system.is_windows", return_value=False)
120
125
  mocker.patch("matlab_proxy.app_state.system.is_mac", return_value=False)
121
126
  mocker.patch("matlab_proxy.app_state.system.is_posix", return_value=False)
122
- mocker.patch("matlab_proxy.app_state.util.get_event_loop", return_value=loop)
127
+ mocker.patch("matlab_proxy.app_state.util.get_event_loop", return_value=event_loop)
123
128
 
124
129
  if platform == "linux":
125
130
  mocker.patch("matlab_proxy.app_state.system.is_linux", return_value=True)
@@ -611,6 +616,29 @@ async def test_start_matlab_without_xvfb(app_state_fixture, mocker):
611
616
  assert app_state_fixture.processes["matlab"] is mock_matlab
612
617
 
613
618
 
619
+ async def test_start_matlab_without_xvfb_and_matlab(app_state_fixture):
620
+ """Test to check if MATLAB doesn't start and sets the error variable to MatlabInstallError when
621
+ there is not MATLAB on system PATH
622
+
623
+ Args:
624
+ app_state_fixture (AppState): Object of AppState class with defaults set
625
+ """
626
+ # Arrange
627
+ app_state_fixture.settings["is_xvfb_available"] = False
628
+ app_state_fixture.settings["matlab_cmd"] = None
629
+
630
+ # Act
631
+ await app_state_fixture.start_matlab()
632
+
633
+ # Assert
634
+ # Check if Xvfb has not started
635
+ assert app_state_fixture.processes["xvfb"] is None
636
+ # Check if Matlab has not started
637
+ assert app_state_fixture.processes["matlab"] is None
638
+ # Check if MatlabInstallError is set as the error
639
+ assert isinstance(app_state_fixture.error, MatlabInstallError)
640
+
641
+
614
642
  @pytest.mark.parametrize(
615
643
  "is_desktop, client_id, is_client_id_present, expected_is_active_client",
616
644
  [
@@ -793,7 +821,7 @@ async def test_decrement_timer_runs_out(sample_settings_fixture, mocker):
793
821
  app_state.processes = {"matlab": None, "xvfb": None}
794
822
  app_state.licensing = {"type": "existing_license"}
795
823
 
796
- # mock util.get_event_loop() to return a new loop for the test to assert
824
+ # mock util.get_event_loop() to return a new event_loop for the test to assert
797
825
  mock_loop = asyncio.new_event_loop()
798
826
  mocker.patch("matlab_proxy.app_state.util.get_event_loop", return_value=mock_loop)
799
827
 
@@ -1,4 +1,4 @@
1
- # Copyright 2020-2022 The MathWorks, Inc.
1
+ # Copyright 2020-2025 The MathWorks, Inc.
2
2
 
3
3
  import os
4
4
  import shutil
@@ -126,7 +126,7 @@ def mock_settings_get_fixture(mocker):
126
126
 
127
127
  @pytest.fixture(name="test_server")
128
128
  def test_server_fixture(
129
- loop,
129
+ event_loop,
130
130
  aiohttp_client,
131
131
  build_frontend,
132
132
  matlab_port_setup,
@@ -140,7 +140,7 @@ def test_server_fixture(
140
140
  This fixture 'initializes' the test server with different constraints from the test server in test_app.py
141
141
 
142
142
  Args:
143
- loop : Event Loop
143
+ event_loop : Event loop
144
144
  aiohttp_client : A built-in pytest fixture
145
145
  build_frontend: Pytest fixture which generates the directory structure of static files with some placeholder content
146
146
  matlab_port_setup: Pytest fixture which monkeypatches 'MWI_DEV' env to False. This is required for the test_server to add static content
@@ -150,7 +150,7 @@ def test_server_fixture(
150
150
  [aiohttp_client]: A aiohttp_client to send HTTP requests.
151
151
  """
152
152
 
153
- with FakeServer(loop, aiohttp_client) as test_server:
153
+ with FakeServer(event_loop, aiohttp_client) as test_server:
154
154
  yield test_server
155
155
 
156
156