Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@

#### [nidcpower] Unreleased
- Added
- (Common) Added `nitlsconfig[grpc]>=1.0.0a1` to the optional gRPC dependencies.
- (Common) Added `nitlsconfig[grpc]>=1.0.0a2` to the optional gRPC dependencies.
- Changed
- Removed

Expand Down Expand Up @@ -556,7 +556,7 @@

#### [nidigital] Unreleased
- Added
- (Common) Added `nitlsconfig[grpc]>=1.0.0a1` to the optional gRPC dependencies.
- (Common) Added `nitlsconfig[grpc]>=1.0.0a2` to the optional gRPC dependencies.
- Changed
- Removed

Expand Down Expand Up @@ -798,7 +798,7 @@

#### [nidmm] Unreleased
- Added
- (Common) Added `nitlsconfig[grpc]>=1.0.0a1` to the optional gRPC dependencies.
- (Common) Added `nitlsconfig[grpc]>=1.0.0a2` to the optional gRPC dependencies.
- Changed
- Removed

Expand Down Expand Up @@ -1122,7 +1122,7 @@

#### [nifgen] Unreleased
- Added
- (Common) Added `nitlsconfig[grpc]>=1.0.0a1` to the optional gRPC dependencies.
- (Common) Added `nitlsconfig[grpc]>=1.0.0a2` to the optional gRPC dependencies.
- Changed
- Removed

Expand Down Expand Up @@ -1736,7 +1736,7 @@

#### [nirfsa] Unreleased
- Added
- (Common) Added `nitlsconfig[grpc]>=1.0.0a1` to the optional gRPC dependencies.
- (Common) Added `nitlsconfig[grpc]>=1.0.0a2` to the optional gRPC dependencies.
- Changed
- Removed

Expand All @@ -1754,7 +1754,7 @@

#### [nirfsg] Unreleased
- Added
- (Common) Added `nitlsconfig[grpc]>=1.0.0a1` to the optional gRPC dependencies.
- (Common) Added `nitlsconfig[grpc]>=1.0.0a2` to the optional gRPC dependencies.
- Changed
- Removed

Expand Down Expand Up @@ -1893,7 +1893,7 @@

#### [niscope] Unreleased
- Added
- (Common) Added `nitlsconfig[grpc]>=1.0.0a1` to the optional gRPC dependencies.
- (Common) Added `nitlsconfig[grpc]>=1.0.0a2` to the optional gRPC dependencies.
- Changed
- Removed

Expand Down Expand Up @@ -2505,7 +2505,7 @@

#### [niswitch] Unreleased
- Added
- (Common) Added `nitlsconfig[grpc]>=1.0.0a1` to the optional gRPC dependencies.
- (Common) Added `nitlsconfig[grpc]>=1.0.0a2` to the optional gRPC dependencies.
- Changed
- Removed

Expand Down
7 changes: 6 additions & 1 deletion build/templates/_grpc_stub_interpreter.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ are_complex_parameters_used = helper.are_complex_parameters_used(functions)

import grpc
import hightime # noqa: F401
import nitlsconfig
Comment thread
alexdubois-ni marked this conversation as resolved.
import session_pb2 as session_grpc_types
import threading
import warnings
Expand Down Expand Up @@ -69,7 +70,11 @@ class GrpcStubInterpreter(object):
elif grpc_error == grpc.StatusCode.INVALID_ARGUMENT:
raise ValueError(error_message) from None
elif grpc_error == grpc.StatusCode.UNAVAILABLE:
error_message = 'Failed to connect to server'
# gRPC reports a rejected TLS handshake and an unreachable server with the
# same code, so ask NI-TLS whether it built this channel and can say more.
error_message = nitlsconfig.get_tls_connection_error_elaboration(
self._grpc_options.grpc_channel
) or 'Failed to connect to server'
elif grpc_error == grpc.StatusCode.UNIMPLEMENTED:
error_message = (
'This operation is not supported by the NI gRPC Device Server being used. Upgrade NI gRPC Device Server.'
Expand Down
11 changes: 11 additions & 0 deletions build/templates/session.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,18 @@ if grpc_supported:
# if ${init_function['python_name']} fails, the error handler can reference it.
# And then here, once ${init_function['python_name']} succeeds, we call set_session_handle
# with the actual session handle.
% if grpc_supported:
connected = False
try:
self._interpreter.set_session_handle(self.${init_function['python_name']}(${init_call_params}))
connected = True
finally:
if grpc_options:
import nitlsconfig
nitlsconfig.audit_session_connect('${config['driver_name']}', grpc_options.grpc_channel, connected)
% else:
self._interpreter.set_session_handle(self.${init_function['python_name']}(${init_call_params}))
% endif

% if config['uses_nitclk']:
% if grpc_supported:
Expand Down
2 changes: 1 addition & 1 deletion build/templates/setup.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ setup(
'grpcio>=1.59.0,<2.0',
'protobuf>=4.21.6',
'ni.grpcdevice.v1.proto>=1.0.0',
'nitlsconfig[grpc]>=1.0.0a1',
'nitlsconfig[grpc]>=1.0.0a2',
],
},
% endif
Expand Down
7 changes: 6 additions & 1 deletion generated/nidcpower/nidcpower/_grpc_stub_interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import grpc
import hightime # noqa: F401
import nitlsconfig
import session_pb2 as session_grpc_types
import threading
import warnings
Expand Down Expand Up @@ -54,7 +55,11 @@ def _invoke(self, func, request, metadata=None):
elif grpc_error == grpc.StatusCode.INVALID_ARGUMENT:
raise ValueError(error_message) from None
elif grpc_error == grpc.StatusCode.UNAVAILABLE:
error_message = 'Failed to connect to server'
# gRPC reports a rejected TLS handshake and an unreachable server with the
# same code, so ask NI-TLS whether it built this channel and can say more.
error_message = nitlsconfig.get_tls_connection_error_elaboration(
self._grpc_options.grpc_channel
) or 'Failed to connect to server'
elif grpc_error == grpc.StatusCode.UNIMPLEMENTED:
error_message = (
'This operation is not supported by the NI gRPC Device Server being used. Upgrade NI gRPC Device Server.'
Expand Down
9 changes: 8 additions & 1 deletion generated/nidcpower/nidcpower/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -7681,7 +7681,14 @@ def __init__(self, resource_name, channels=None, reset=False, options={}, indepe
# if _fancy_initialize fails, the error handler can reference it.
# And then here, once _fancy_initialize succeeds, we call set_session_handle
# with the actual session handle.
self._interpreter.set_session_handle(self._fancy_initialize(resource_name, channels, reset, options, independent_channels))
connected = False
try:
self._interpreter.set_session_handle(self._fancy_initialize(resource_name, channels, reset, options, independent_channels))
connected = True
finally:
if grpc_options:
import nitlsconfig
nitlsconfig.audit_session_connect('NI-DCPower', grpc_options.grpc_channel, connected)

# Store the parameter list for later printing in __repr__
param_list = []
Expand Down
2 changes: 1 addition & 1 deletion generated/nidcpower/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def read_contents(file_to_read):
'grpcio>=1.59.0,<2.0',
'protobuf>=4.21.6',
'ni.grpcdevice.v1.proto>=1.0.0',
'nitlsconfig[grpc]>=1.0.0a1',
'nitlsconfig[grpc]>=1.0.0a2',
],
},
classifiers=[
Expand Down
7 changes: 6 additions & 1 deletion generated/nidigital/nidigital/_grpc_stub_interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import grpc
import hightime # noqa: F401
import nitlsconfig
import session_pb2 as session_grpc_types
import threading
import warnings
Expand Down Expand Up @@ -52,7 +53,11 @@ def _invoke(self, func, request, metadata=None):
elif grpc_error == grpc.StatusCode.INVALID_ARGUMENT:
raise ValueError(error_message) from None
elif grpc_error == grpc.StatusCode.UNAVAILABLE:
error_message = 'Failed to connect to server'
# gRPC reports a rejected TLS handshake and an unreachable server with the
# same code, so ask NI-TLS whether it built this channel and can say more.
error_message = nitlsconfig.get_tls_connection_error_elaboration(
self._grpc_options.grpc_channel
) or 'Failed to connect to server'
elif grpc_error == grpc.StatusCode.UNIMPLEMENTED:
error_message = (
'This operation is not supported by the NI gRPC Device Server being used. Upgrade NI gRPC Device Server.'
Expand Down
9 changes: 8 additions & 1 deletion generated/nidigital/nidigital/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -3280,7 +3280,14 @@ def __init__(self, resource_name, id_query=False, reset_device=False, options={}
# if _init_with_options fails, the error handler can reference it.
# And then here, once _init_with_options succeeds, we call set_session_handle
# with the actual session handle.
self._interpreter.set_session_handle(self._init_with_options(resource_name, id_query, reset_device, options))
connected = False
try:
self._interpreter.set_session_handle(self._init_with_options(resource_name, id_query, reset_device, options))
connected = True
finally:
if grpc_options:
import nitlsconfig
nitlsconfig.audit_session_connect('NI-Digital Pattern Driver', grpc_options.grpc_channel, connected)

# NI-TClk does not work over NI gRPC Device Server
if not grpc_options:
Expand Down
2 changes: 1 addition & 1 deletion generated/nidigital/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def read_contents(file_to_read):
'grpcio>=1.59.0,<2.0',
'protobuf>=4.21.6',
'ni.grpcdevice.v1.proto>=1.0.0',
'nitlsconfig[grpc]>=1.0.0a1',
'nitlsconfig[grpc]>=1.0.0a2',
],
},
classifiers=[
Expand Down
7 changes: 6 additions & 1 deletion generated/nidmm/nidmm/_grpc_stub_interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import grpc
import hightime # noqa: F401
import nitlsconfig
import session_pb2 as session_grpc_types
import threading
import warnings
Expand Down Expand Up @@ -50,7 +51,11 @@ def _invoke(self, func, request, metadata=None):
elif grpc_error == grpc.StatusCode.INVALID_ARGUMENT:
raise ValueError(error_message) from None
elif grpc_error == grpc.StatusCode.UNAVAILABLE:
error_message = 'Failed to connect to server'
# gRPC reports a rejected TLS handshake and an unreachable server with the
# same code, so ask NI-TLS whether it built this channel and can say more.
error_message = nitlsconfig.get_tls_connection_error_elaboration(
self._grpc_options.grpc_channel
) or 'Failed to connect to server'
elif grpc_error == grpc.StatusCode.UNIMPLEMENTED:
error_message = (
'This operation is not supported by the NI gRPC Device Server being used. Upgrade NI gRPC Device Server.'
Expand Down
9 changes: 8 additions & 1 deletion generated/nidmm/nidmm/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,14 @@ def __init__(self, resource_name, id_query=False, reset_device=False, options={}
# if _init_with_options fails, the error handler can reference it.
# And then here, once _init_with_options succeeds, we call set_session_handle
# with the actual session handle.
self._interpreter.set_session_handle(self._init_with_options(resource_name, id_query, reset_device, options))
connected = False
try:
self._interpreter.set_session_handle(self._init_with_options(resource_name, id_query, reset_device, options))
connected = True
finally:
if grpc_options:
import nitlsconfig
nitlsconfig.audit_session_connect('NI-DMM', grpc_options.grpc_channel, connected)

# Store the parameter list for later printing in __repr__
param_list = []
Expand Down
2 changes: 1 addition & 1 deletion generated/nidmm/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def read_contents(file_to_read):
'grpcio>=1.59.0,<2.0',
'protobuf>=4.21.6',
'ni.grpcdevice.v1.proto>=1.0.0',
'nitlsconfig[grpc]>=1.0.0a1',
'nitlsconfig[grpc]>=1.0.0a2',
],
},
classifiers=[
Expand Down
7 changes: 6 additions & 1 deletion generated/nifake/nifake/_grpc_stub_interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import grpc
import hightime # noqa: F401
import nitlsconfig
import session_pb2 as session_grpc_types
import threading
import warnings
Expand Down Expand Up @@ -57,7 +58,11 @@ def _invoke(self, func, request, metadata=None):
elif grpc_error == grpc.StatusCode.INVALID_ARGUMENT:
raise ValueError(error_message) from None
elif grpc_error == grpc.StatusCode.UNAVAILABLE:
error_message = 'Failed to connect to server'
# gRPC reports a rejected TLS handshake and an unreachable server with the
# same code, so ask NI-TLS whether it built this channel and can say more.
error_message = nitlsconfig.get_tls_connection_error_elaboration(
self._grpc_options.grpc_channel
) or 'Failed to connect to server'
elif grpc_error == grpc.StatusCode.UNIMPLEMENTED:
error_message = (
'This operation is not supported by the NI gRPC Device Server being used. Upgrade NI gRPC Device Server.'
Expand Down
9 changes: 8 additions & 1 deletion generated/nifake/nifake/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,14 @@ def __init__(self, resource_name, options={}, id_query=False, reset_device=False
# if _init_with_options fails, the error handler can reference it.
# And then here, once _init_with_options succeeds, we call set_session_handle
# with the actual session handle.
self._interpreter.set_session_handle(self._init_with_options(resource_name, options, id_query, reset_device))
connected = False
try:
self._interpreter.set_session_handle(self._init_with_options(resource_name, options, id_query, reset_device))
connected = True
finally:
if grpc_options:
import nitlsconfig
nitlsconfig.audit_session_connect('NI-FAKE', grpc_options.grpc_channel, connected)

# NI-TClk does not work over NI gRPC Device Server
if not grpc_options:
Expand Down
19 changes: 19 additions & 0 deletions generated/nifake/nifake/unit_tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import grpc
import nitlsconfig.channel_tag
import pytest


@pytest.fixture
def nitls_tagged_channel():
"""A real gRPC channel tagged the way nitlsconfig.create_grpc_device_channel tags one.

nitlsconfig.create_grpc_device_channel itself requires the nitlsconfig library to be
installed on the system in order to access the CLI. As a result, we are unable to directly
leverage it in our unit tests. But, this can at least allow us to unit-test our code
that relies on channels being created from nitlsconfig.create_grpc_device_channel.
"""
target = 'localhost:31763'
with grpc.insecure_channel(target) as channel:
nitlsconfig.channel_tag.tag_channel_target(channel, target)
assert nitlsconfig.channel_tag.is_nitls_channel(channel), 'nitlsconfig no longer recognizes a channel it tagged'
yield channel
19 changes: 19 additions & 0 deletions generated/nifake/nifake/unit_tests/test_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import math
import nifake
import nifake.errors
import nitlsconfig
import numpy
import pytest
import session_pb2
Expand Down Expand Up @@ -184,6 +185,24 @@ def test_server_unavailable(self):
assert e.description == expected_error_message
assert str(e) == f'StatusCode.UNAVAILABLE: {expected_error_message}'

def test_server_unavailable_with_tls_elaboration(self, nitls_tagged_channel):
library_func = 'InitWithOptions'
grpc_error = grpc.StatusCode.UNAVAILABLE
self._set_side_effect(library_func, side_effect=MyRpcError(None, '', grpc_error=grpc_error))
# The real elaboration, so this fails if nitlsconfig stops recognizing our channel.
expected_error_message = nitlsconfig.get_tls_connection_error_elaboration(nitls_tagged_channel)
assert expected_error_message is not None
assert expected_error_message != 'Failed to connect to server'
grpc_options = nifake.GrpcSessionOptions(nitls_tagged_channel, '', initialization_behavior=nifake.SessionInitializationBehavior.AUTO)
interpreter = nifake._grpc_stub_interpreter.GrpcStubInterpreter(grpc_options)
try:
interpreter.init_with_options('dev1', False, False, '')
assert False
except nifake.Error as e:
assert e.rpc_code == grpc_error
assert e.description == expected_error_message
assert str(e) == f'StatusCode.UNAVAILABLE: {expected_error_message}'

def test_function_not_implemented(self):
library_func = 'PoorlyNamedSimpleFunction'
grpc_error = grpc.StatusCode.UNIMPLEMENTED
Expand Down
19 changes: 19 additions & 0 deletions generated/nifake/nifake/unit_tests/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ def test_init_with_options_nondefault_and_close(self):
session.close()
self.patched_library_interpreter.close.assert_called_once_with()

def test_init_without_grpc_options_does_not_audit(self):
with patch('nitlsconfig.audit_session_connect', autospec=True) as patched_audit:
with nifake.Session('dev1'):
pass
patched_audit.assert_not_called()

def test_close(self):
session = nifake.Session('dev1')
assert session._interpreter._vi == SESSION_NUM_FOR_TEST
Expand Down Expand Up @@ -966,6 +972,19 @@ def test_init_with_options_and_close(self):
session.close()
self.patched_grpc_interpreter.close.assert_called_once_with()

def test_init_audits_successful_connect(self, nitls_tagged_channel):
with patch('nitlsconfig.audit_session_connect', autospec=True) as patched_audit:
with nifake.Session('dev1', grpc_options=nifake.GrpcSessionOptions(nitls_tagged_channel, '')):
pass
patched_audit.assert_called_once_with('NI-FAKE', nitls_tagged_channel, True)

def test_init_audits_failed_connect(self, nitls_tagged_channel):
self.patched_grpc_interpreter.init_with_options.side_effect = nifake.Error('Fake init failure')
with patch('nitlsconfig.audit_session_connect', autospec=True) as patched_audit:
with pytest.raises(nifake.Error):
nifake.Session('dev1', grpc_options=nifake.GrpcSessionOptions(nitls_tagged_channel, ''))
patched_audit.assert_called_once_with('NI-FAKE', nitls_tagged_channel, False)

# Session locking

def test_lock_session_none(self):
Expand Down
2 changes: 1 addition & 1 deletion generated/nifake/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def read_contents(file_to_read):
'grpcio>=1.59.0,<2.0',
'protobuf>=4.21.6',
'ni.grpcdevice.v1.proto>=1.0.0',
'nitlsconfig[grpc]>=1.0.0a1',
'nitlsconfig[grpc]>=1.0.0a2',
],
},
classifiers=[
Expand Down
Loading
Loading