Skip to content

Commit

Permalink
Add proto and tests for NI-Digital (#1840)
Browse files Browse the repository at this point in the history
* Put system tests into a class

* Add proto and tests for NI-Digital

* Give the server time to start up

* Force regen of niswitch

* Update test to use GrpcSessionOptions

* Regen after rebase

* Update _interpreter comment to not reference _library_interpreter

* Update metadata; regen

* Regen

* Add TODO about removing Popen, sleep, etc.

* Regen after merge

* Regen after merge

* Make get/set_session_handle public

* Fix tests to not mock get/set_session_handle

* Restore use of session_handle_parameter_name for nimodinst and nitclk

* Update test + regen after merge

* Regen after merge

* Clean up comment
  • Loading branch information
DavidCurtiss authored Nov 10, 2022
1 parent c58a6bb commit 28f446e
Show file tree
Hide file tree
Showing 55 changed files with 9,397 additions and 1,497 deletions.
7 changes: 4 additions & 3 deletions build/defines.mak
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ METADATA_DIR := $(DRIVER_DIR)/metadata
METADATA_FILES := $(wildcard $(METADATA_DIR)/*.py)
SHARED_PROTOS_DIR := $(ROOT_DIR)/src/shared_protos
PROTO_DIRS := $(METADATA_DIR) $(SHARED_PROTOS_DIR)
PROTO_FILE ?= $(METADATA_DIR)/$(DRIVER).proto

BUILD_HELPER_SCRIPTS := $(wildcard $(BUILD_HELPER_DIR)/*.py $(BUILD_HELPER_DIR)/helper/*.py)

Expand All @@ -26,7 +27,7 @@ VPATH = $(TEMPLATE_DIR)

true := T
false :=
GRPC_SUPPORTED := $(if $(wildcard $(METADATA_DIR)/$(DRIVER).proto),$(true))
GRPC_SUPPORTED := $(if $(wildcard $(PROTO_FILE)),$(true))

PYTHON_CMD ?= python
GRPC_SUPPORT_PARAM := $(if $(GRPC_SUPPORTED),--include-grpc-support)
Expand Down Expand Up @@ -62,8 +63,8 @@ DEFAULT_PY_FILES_TO_GENERATE := \
$(if $(GRPC_SUPPORTED), \
_grpc_stub_interpreter.py \
grpc_session_options.py \
$(DRIVER)_pb2.py \
$(DRIVER)_pb2_grpc.py \
$(basename $(notdir $(PROTO_FILE)))_pb2.py \
$(basename $(notdir $(PROTO_FILE)))_pb2_grpc.py \
nidevice_pb2.py \
nidevice_pb2_grpc.py \
session_pb2.py \
Expand Down
1 change: 0 additions & 1 deletion build/rules.mak
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ $(MODULE_DIR)/%: %.mako $(BUILD_HELPER_SCRIPTS) $(METADATA_FILES)

$(MODULE_DIR)/%_pb2.py: %.proto
$(call trace_to_console, "Generating",$@ and $(notdir $*)_pb2_grpc.py)
$(_hide_cmds)$(call log_command,mkdir -p $(OUTPUT_DIR)/build/proto/$(dir $*))
$(_hide_cmds)$(call log_command,python -m grpc_tools.protoc $(addprefix -I=,$(PROTO_DIRS)) --python_out=$(MODULE_DIR) --grpc_python_out=$(MODULE_DIR) $*.proto)
$(_hide_cmds)$(call log_command,sed -i 's/^import session_pb2/from . import session_pb2/' $(MODULE_DIR)/$*_pb2*.py)
$(_hide_cmds)$(call log_command,sed -i 's/^import nidevice_pb2/from . import nidevice_pb2/' $(MODULE_DIR)/$*_pb2*.py)
Expand Down
16 changes: 12 additions & 4 deletions build/templates/_grpc_stub_interpreter.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import build.helper as helper
config = template_parameters['metadata'].config
module_name = config['module_name']
proto_name = config.get('proto_name', module_name)
service_class_prefix = config['grpc_service_class_prefix']
functions = helper.filter_library_functions(config['functions'])
functions = helper.filter_codegen_functions(config['functions'])
%>\

import grpc
Expand All @@ -18,8 +19,9 @@ import warnings
from . import enums as enums # noqa: F401
% endif
from . import errors as errors
from . import ${module_name}_pb2 as grpc_types
from . import ${module_name}_pb2_grpc as ${module_name}_grpc
from . import ${proto_name}_pb2 as grpc_types
from . import ${proto_name}_pb2_grpc as ${module_name}_grpc
from . import session_pb2 as session_grpc_types
% for c in config['custom_types']:

from . import ${c['file_name']} as ${c['file_name']} # noqa: F401
Expand All @@ -33,7 +35,13 @@ class GrpcStubInterpreter(object):
self._grpc_options = grpc_options
self._lock = threading.RLock()
self._client = ${module_name}_grpc.${service_class_prefix}Stub(grpc_options.grpc_channel)
self._${config['session_handle_parameter_name']} = 0
self.set_session_handle()

def set_session_handle(self, value=session_grpc_types.Session()):
self._${config['session_handle_parameter_name']} = value

def get_session_handle(self):
return self._${config['session_handle_parameter_name']}

def _invoke(self, func, request):
try:
Expand Down
8 changes: 7 additions & 1 deletion build/templates/_library_interpreter.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,13 @@ class LibraryInterpreter(object):
# Initialize _${config['session_handle_parameter_name']} to 0 for now.
# Session will directly update it once the driver runtime init function has been called and
# we have a valid session handle.
self._${config['session_handle_parameter_name']} = 0
self.set_session_handle()

def set_session_handle(self, value=0):
self._${config['session_handle_parameter_name']} = value

def get_session_handle(self):
return self._${config['session_handle_parameter_name']}

<%include file="/_library_interpreter.py/_get_error_description.py.mako" args="config=config" />\
% for func_name in sorted(functions):
Expand Down
16 changes: 8 additions & 8 deletions build/templates/session.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -272,19 +272,19 @@ if grpc_supported:
% endfor

# Call specified init function
# Note that _library_interpreter sets _${config['session_handle_parameter_name']} to 0 in its constructor, so that if
# Note that _interpreter clears the session handle in its constructor, so that if
# ${init_function['python_name']} fails, the error handler can reference it.
# And then once ${init_function['python_name']} succeeds, we can update _library_interpreter._${config['session_handle_parameter_name']}
# And then once ${init_function['python_name']} succeeds, we can call set_session_handle
# with the actual session handle.
self._interpreter._${config['session_handle_parameter_name']} = self.${init_function['python_name']}(${init_call_params})
self._interpreter.set_session_handle(self.${init_function['python_name']}(${init_call_params}))

% if config['uses_nitclk']:
% if grpc_supported:
# NI-TClk does not work over NI gRPC Device Server
if not _grpc_options:
self.tclk = nitclk.SessionReference(self._interpreter._${config['session_handle_parameter_name']})
self.tclk = nitclk.SessionReference(self._interpreter.get_session_handle())
% else:
self.tclk = nitclk.SessionReference(self._interpreter._${config['session_handle_parameter_name']})
self.tclk = nitclk.SessionReference(self._interpreter.get_session_handle())
% endif

% endif
Expand All @@ -298,7 +298,7 @@ if grpc_supported:
# Store the list of channels in the Session which is needed by some nimi-python modules.
# Use try/except because not all the modules support channels.
# self.get_channel_names() and self.channel_count can only be called after the session
# handle `self._interpreter._${config['session_handle_parameter_name']}` is set
# handle is set
try:
self._all_channels_in_session = self.get_channel_names(range(self.channel_count))
except AttributeError:
Expand Down Expand Up @@ -336,9 +336,9 @@ if grpc_supported:
try:
self._${close_function_name}()
except errors.DriverError:
self._interpreter._${config['session_handle_parameter_name']} = 0
self._interpreter.set_session_handle()
raise
self._interpreter._${config['session_handle_parameter_name']} = 0
self._interpreter.set_session_handle()

''' These are code-generated '''
% for func_name in sorted({k: v for k, v in functions.items() if not v['render_in_session_base']}):
Expand Down
9 changes: 8 additions & 1 deletion generated/nidcpower/nidcpower/_grpc_stub_interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from . import errors as errors
from . import nidcpower_pb2 as grpc_types
from . import nidcpower_pb2_grpc as nidcpower_grpc
from . import session_pb2 as session_grpc_types

from . import lcr_load_compensation_spot as lcr_load_compensation_spot # noqa: F401

Expand All @@ -23,7 +24,13 @@ def __init__(self, grpc_options):
self._grpc_options = grpc_options
self._lock = threading.RLock()
self._client = nidcpower_grpc.NiDCPowerStub(grpc_options.grpc_channel)
self._vi = 0
self.set_session_handle()

def set_session_handle(self, value=session_grpc_types.Session()):
self._vi = value

def get_session_handle(self):
return self._vi

def _invoke(self, func, request):
try:
Expand Down
8 changes: 7 additions & 1 deletion generated/nidcpower/nidcpower/_library_interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,13 @@ def __init__(self, encoding):
# Initialize _vi to 0 for now.
# Session will directly update it once the driver runtime init function has been called and
# we have a valid session handle.
self._vi = 0
self.set_session_handle()

def set_session_handle(self, value=0):
self._vi = value

def get_session_handle(self):
return self._vi

def get_error_description(self, error_code):
'''get_error_description
Expand Down
12 changes: 6 additions & 6 deletions generated/nidcpower/nidcpower/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -6911,11 +6911,11 @@ def __init__(self, resource_name, channels=None, reset=False, options={}, indepe
options = _converters.convert_init_with_options_dictionary(options)

# Call specified init function
# Note that _library_interpreter sets _vi to 0 in its constructor, so that if
# Note that _interpreter clears the session handle in its constructor, so that if
# _fancy_initialize fails, the error handler can reference it.
# And then once _fancy_initialize succeeds, we can update _library_interpreter._vi
# And then once _fancy_initialize succeeds, we can call set_session_handle
# with the actual session handle.
self._interpreter._vi = self._fancy_initialize(resource_name, channels, reset, options, independent_channels)
self._interpreter.set_session_handle(self._fancy_initialize(resource_name, channels, reset, options, independent_channels))

# Store the parameter list for later printing in __repr__
param_list = []
Expand All @@ -6929,7 +6929,7 @@ def __init__(self, resource_name, channels=None, reset=False, options={}, indepe
# Store the list of channels in the Session which is needed by some nimi-python modules.
# Use try/except because not all the modules support channels.
# self.get_channel_names() and self.channel_count can only be called after the session
# handle `self._interpreter._vi` is set
# handle is set
try:
self._all_channels_in_session = self.get_channel_names(range(self.channel_count))
except AttributeError:
Expand Down Expand Up @@ -6970,9 +6970,9 @@ def close(self):
try:
self._close()
except errors.DriverError:
self._interpreter._vi = 0
self._interpreter.set_session_handle()
raise
self._interpreter._vi = 0
self._interpreter.set_session_handle()

''' These are code-generated '''

Expand Down
1 change: 1 addition & 0 deletions generated/nidigital/nidigital/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from nidigital.enums import * # noqa: F403,F401,H303
from nidigital.errors import DriverWarning # noqa: F401
from nidigital.errors import Error # noqa: F401
from nidigital.grpc_session_options import * # noqa: F403,F401,H303
from nidigital.session import Session # noqa: F401

from nidigital.history_ram_cycle_information import HistoryRAMCycleInformation # noqa: F401
Expand Down
Loading

0 comments on commit 28f446e

Please sign in to comment.