Skip to content

Commit d60265f

Browse files
authored
[releases/1.2] Fix pywintypes error during the launch of the discovery service after a fresh install of MeasurementLink (#407)
Fix pywintypes error during the launch of the discovery service after a fresh install of MeasurementLink (#397) * Fix launching of discovery service during fresh install
1 parent 122c556 commit d60265f

2 files changed

Lines changed: 28 additions & 15 deletions

File tree

ni_measurementlink_service/_internal/discovery_client.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,10 @@
2020
from ni_measurementlink_service.measurement.info import MeasurementInfo, ServiceInfo
2121

2222
if sys.platform == "win32":
23-
import errno
2423
import msvcrt
2524

2625
import win32con
2726
import win32file
28-
import winerror
2927

3028
_logger = logging.getLogger(__name__)
3129
# Save Popen object to avoid "ResourceWarning: subprocess N is still running"
@@ -283,7 +281,7 @@ def _start_service(
283281
try:
284282
with _open_key_file(str(key_file_path)) as _:
285283
return discovery_service_subprocess
286-
except IOError:
284+
except OSError:
287285
pass
288286
if time.time() >= timeout_time:
289287
raise TimeoutError("Timed out waiting for discovery service to start")
@@ -293,7 +291,7 @@ def _start_service(
293291
def _service_already_running(key_file_path: pathlib.Path) -> bool:
294292
try:
295293
_delete_existing_key_file(key_file_path)
296-
except IOError:
294+
except OSError:
297295
return True
298296
return False
299297

@@ -344,14 +342,7 @@ def _open_key_file(path: str) -> typing.TextIO:
344342
None,
345343
)
346344
except win32file.error as e:
347-
if e.winerror == winerror.ERROR_FILE_NOT_FOUND:
348-
raise FileNotFoundError(errno.ENOENT, e.strerror, path) from e
349-
elif (
350-
e.winerror == winerror.ERROR_ACCESS_DENIED
351-
or e.winerror == winerror.ERROR_SHARING_VIOLATION
352-
):
353-
raise PermissionError(errno.EACCES, e.strerror, path) from e
354-
raise
345+
raise OSError(None, e.strerror, path, e.winerror) from e
355346

356347
# The CRT file descriptor takes ownership of the Win32 file handle.
357348
# os.O_TEXT is unnecessary because Python handles newline conversion.

tests/unit/test_discovery_client.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from ni_measurementlink_service._internal.discovery_client import (
1313
DiscoveryClient,
1414
_get_discovery_service_address,
15+
_open_key_file,
1516
_start_service,
1617
)
1718
from ni_measurementlink_service._internal.stubs.ni.measurementlink.discovery.v1.discovery_service_pb2_grpc import (
@@ -20,6 +21,9 @@
2021
from ni_measurementlink_service.measurement.info import MeasurementInfo, ServiceInfo
2122
from tests.utilities.fake_discovery_service import FakeDiscoveryServiceStub
2223

24+
if sys.platform == "win32":
25+
import win32file
26+
2327
_PROVIDED_MEASUREMENT_SERVICES = [
2428
"ni.measurementlink.measurement.v1.MeasurementService",
2529
"ni.measurementlink.measurement.v2.MeasurementService",
@@ -129,19 +133,37 @@ def test___get_discovery_service_address___key_file_not_exist___throws_timeouter
129133
"ni_measurementlink_service._internal.discovery_client._START_SERVICE_TIMEOUT", 5.0
130134
)
131135
mocker.patch(
132-
"ni_measurementlink_service._internal.discovery_client._open_key_file", side_effect=IOError
136+
"ni_measurementlink_service._internal.discovery_client._open_key_file", side_effect=OSError
133137
)
134138
mocker.patch(
135139
"ni_measurementlink_service._internal.discovery_client._get_registration_json_file_path",
136140
return_value=temp_registration_json_file_path,
137141
)
138142
mocker.patch("subprocess.Popen")
139143

140-
with pytest.raises(IOError) as exc_info:
144+
with pytest.raises(OSError) as exc_info:
141145
_get_discovery_service_address()
142146
assert exc_info.type is TimeoutError
143147

144148

149+
@pytest.mark.parametrize(
150+
"windows_error_code", [2, 3]
151+
) # ERROR_FILE_NOT_FOUND = 2, ERROR_PATH_NOT_FOUND = 3
152+
def test___key_file_not_exist___open_key_file___raises_file_not_found_error(
153+
mocker: MockerFixture, temp_discovery_key_file_path: pathlib.Path, windows_error_code: int
154+
) -> None:
155+
if sys.platform != "win32":
156+
pytest.skip("Windows-only test")
157+
else:
158+
mocker.patch(
159+
"win32file.CreateFile",
160+
side_effect=win32file.error(windows_error_code, None, None),
161+
)
162+
163+
with pytest.raises(FileNotFoundError):
164+
_open_key_file(str(temp_discovery_key_file_path))
165+
166+
145167
def test___start_discovery_service___key_file_exist_after_poll___service_start_success(
146168
mocker: MockerFixture,
147169
temp_directory: pathlib.Path,
@@ -152,7 +174,7 @@ def test___start_discovery_service___key_file_exist_after_poll___service_start_s
152174

153175
mocker.patch(
154176
"ni_measurementlink_service._internal.discovery_client._open_key_file",
155-
side_effect=[IOError, IOError, IOError, temp_discovery_key_file_path],
177+
side_effect=[OSError, OSError, OSError, temp_discovery_key_file_path],
156178
)
157179
mock_popen = mocker.patch("subprocess.Popen")
158180

0 commit comments

Comments
 (0)