Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
724a7ae
tests: add nidcpower specific test measurement
jayaseelan-james Oct 30, 2023
7a82994
tests: add proto file and stubs
jayaseelan-james Oct 30, 2023
f65225c
tests: add sample nidcpower integration test
jayaseelan-james Oct 30, 2023
f2399a3
tests: add sample nidcpower acceptance test
jayaseelan-james Oct 30, 2023
68d39e8
refactor: remove parameterization
jayaseelan-james Oct 30, 2023
7b4fd7e
rename test files
jayaseelan-james Oct 30, 2023
ab94562
tests: simplify nidcpower integration test
jayaseelan-james Oct 30, 2023
c350285
fix: lint errors
jayaseelan-james Oct 30, 2023
4fe566a
Merge branch 'main' into users/jay/tests-for-nidcpower
jayaseelan-james Oct 30, 2023
da45daf
tests: add more acceptance tests
jayaseelan-james Oct 31, 2023
fa9421d
tests: add more integration tests
jayaseelan-james Oct 31, 2023
8ac26ca
tests: return connected channels from nidcpower measurment.
jayaseelan-james Oct 31, 2023
eb32a12
tests: update acceptance tests to verify connected channels
jayaseelan-james Oct 31, 2023
27350d3
fix: lint errors
jayaseelan-james Oct 31, 2023
11dcbd3
fix: add actual measurement to nidcpower measurement
jayaseelan-james Nov 1, 2023
0f43cb0
fix: refactor nidcpower session apis integration tests
jayaseelan-james Nov 1, 2023
7d9de37
fix: refactor nidcpower session apis acceptance tests
jayaseelan-james Nov 1, 2023
04db9b5
chore: add a new line before return
jayaseelan-james Nov 1, 2023
e887bf8
refactor: move utils to utility folder
jayaseelan-james Nov 1, 2023
b484b46
fix: lint errors
jayaseelan-james Nov 1, 2023
43e4e98
fix: mypy error
jayaseelan-james Nov 1, 2023
8b9c2ec
fix: typo
jayaseelan-james Nov 1, 2023
702d3b2
chore: update acceptance & integration tests folder structure
jayaseelan-james Nov 2, 2023
77fa3bc
chore: move nidcpower test meas stubs to sub dir
jayaseelan-james Nov 2, 2023
cda1d31
refactor: update test names to present tense
jayaseelan-james Nov 2, 2023
9d1d374
fix: PR comments
jayaseelan-james Nov 2, 2023
7adb457
fix: typo and lint errors
jayaseelan-james Nov 2, 2023
a6d7e3f
fix: update proto package name
jayaseelan-james Nov 2, 2023
ec1d674
tests: proto and stub changes
jayaseelan-james Nov 3, 2023
c0ac0ab
Merge branch 'main' into users/jay/tests-for-nidcpower
jayaseelan-james Nov 3, 2023
57f472b
fix: update to pin_names for consistency
jayaseelan-james Nov 3, 2023
0fd1300
refactor: acceptance tests
jayaseelan-james Nov 3, 2023
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
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ module = [
# https://github.com/briancurtin/deprecation/issues/56 - Add type information (PEP 561)
"deprecation.*",
"grpc.framework.foundation.*",
# https://github.com/ni/hightime/issues/4 - Add type annotations
"hightime.*",
# https://github.com/microsoft/tracelogging/issues/57 - Python traceloggingdynamic package is missing py.typed marker file
"traceloggingdynamic",
# https://github.com/ni/nidaqmx-python/issues/209 - Support type annotations
Expand Down
10 changes: 10 additions & 0 deletions tests/acceptance/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Pytest configuration file for acceptance tests."""
import pathlib

import pytest


@pytest.fixture(scope="module")
def pin_map_directory(test_assets_directory: pathlib.Path) -> pathlib.Path:
"""Test fixture that returns the pin map directory."""
return test_assets_directory / "acceptance" / "session_management"
110 changes: 110 additions & 0 deletions tests/acceptance/test_nidcpower_measurement.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import pathlib
from typing import Generator, Iterable, NamedTuple

import pytest

from ni_measurementlink_service._internal.stubs.ni.measurementlink.measurement.v2.measurement_service_pb2 import (
MeasureRequest,
)
from ni_measurementlink_service._internal.stubs.ni.measurementlink.measurement.v2.measurement_service_pb2_grpc import (
MeasurementServiceStub,
)
from ni_measurementlink_service._internal.stubs.ni.measurementlink.pin_map_context_pb2 import (
PinMapContext,
)
from ni_measurementlink_service.measurement.service import MeasurementService
from tests.assets.stubs.nidcpower_measurement.types_pb2 import (
Configurations,
Outputs,
)
from tests.utilities import nidcpower_measurement
from tests.utilities.pin_map_client import PinMapClient

_SITE = 0


def test___single_session___measure___returns_measured_values(
pin_map_context: PinMapContext,
stub_v2: MeasurementServiceStub,
) -> None:
configurations = Configurations(pin_names=["Pin1"], multi_session=False)

outputs = _measure(stub_v2, pin_map_context, configurations)

assert outputs.voltage_measurements == [5]
assert outputs.current_measurements == [0.0001]


def test___single_session___measure___creates_single_session(
pin_map_context: PinMapContext,
stub_v2: MeasurementServiceStub,
) -> None:
configurations = Configurations(pin_names=["Pin1"], multi_session=False)

outputs = _measure(stub_v2, pin_map_context, configurations)

assert _get_output(outputs) == [
_MeasurementOutput("DCPower1/0", "DCPower1/0", "DCPower1/0", "DCPower1/0")
]


def test___multiple_sessions___measure___creates_multiple_sessions(
pin_map_context: PinMapContext,
stub_v2: MeasurementServiceStub,
) -> None:
configurations = Configurations(pin_names=["Pin1", "Pin2"], multi_session=True)

outputs = _measure(stub_v2, pin_map_context, configurations)

assert _get_output(outputs) == [
_MeasurementOutput("DCPower1/0", "DCPower1/0", "DCPower1/0", "DCPower1/0"),
_MeasurementOutput("DCPower1/2", "DCPower1/2", "DCPower1/2", "DCPower1/2"),
]


def _measure(
stub_v2: MeasurementServiceStub,
pin_map_context: PinMapContext,
configurations: Configurations,
) -> Outputs:
request = MeasureRequest(pin_map_context=pin_map_context)
request.configuration_parameters.Pack(configurations)
response_iterator = stub_v2.Measure(request)
responses = list(response_iterator)
assert len(responses) == 1
outputs = Outputs.FromString(responses[0].outputs.value)
return outputs


@pytest.fixture(scope="module")
def measurement_service() -> Generator[MeasurementService, None, None]:
"""Test fixture that creates and hosts a measurement service."""
with nidcpower_measurement.measurement_service.host_service() as service:
yield service


@pytest.fixture
def pin_map_context(pin_map_client: PinMapClient, pin_map_directory: pathlib.Path) -> PinMapContext:
pin_map_name = "1Smu2ChannelGroup2Pin1Site.pinmap"
pin_map_id = pin_map_client.update_pin_map(pin_map_directory / pin_map_name)

return PinMapContext(pin_map_id=pin_map_id, sites=[_SITE])


class _MeasurementOutput(NamedTuple):
session_name: str
resource_name: str
channel_list: str
connected_channels: str


def _get_output(outputs: Outputs) -> Iterable[_MeasurementOutput]:
return [
_MeasurementOutput(session_name, resource_name, channel_list, connected_channels)
for session_name, resource_name, channel_list, connected_channels in zip(
outputs.session_names,
outputs.resource_names,
outputs.channel_lists,
outputs.connected_channels,
)
]
6 changes: 0 additions & 6 deletions tests/acceptance/test_session_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,3 @@ def measurement_service(
"""Test fixture that creates and hosts a measurement service."""
with pin_aware_measurement.measurement_service.host_service() as service:
yield service


@pytest.fixture
def pin_map_directory(test_assets_directory: pathlib.Path) -> pathlib.Path:
"""Test fixture that returns the pin map directory."""
return test_assets_directory / "acceptance" / "session_management"
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<PinMap xmlns="http://www.ni.com/TestStand/SemiconductorModule/PinMap.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" schemaVersion="1.6">
<Instruments>
<NIDCPowerInstrument name="DCPower1" numberOfChannels="4">
<ChannelGroup name="DCPowerChannelGroup0" channels="0,1" />
<ChannelGroup name="DCPowerChannelGroup1" channels="2,3" />
</NIDCPowerInstrument>
</Instruments>
<Pins>
<DUTPin name="Pin1" />
<DUTPin name="Pin2" />
</Pins>
<PinGroups></PinGroups>
<Sites>
<Site siteNumber="0" />
</Sites>
<Connections>
<Connection pin="Pin1" siteNumber="0" instrument="DCPower1" channel="0" />
<Connection pin="Pin2" siteNumber="0" instrument="DCPower1" channel="2" />
</Connections>
</PinMap>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<PinMap xmlns="http://www.ni.com/TestStand/SemiconductorModule/PinMap.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" schemaVersion="1.6">
<Instruments>
<NIDCPowerInstrument name="DCPower1" numberOfChannels="4">
<ChannelGroup name="DCPowerChannelGroup0" channels="0,1" />
<ChannelGroup name="DCPowerChannelGroup1" channels="2,3" />
</NIDCPowerInstrument>
</Instruments>
<Pins>
<DUTPin name="Pin1" />
<DUTPin name="Pin2" />
</Pins>
<PinGroups></PinGroups>
<Sites>
<Site siteNumber="0" />
</Sites>
<Connections>
<Connection pin="Pin1" siteNumber="0" instrument="DCPower1" channel="0" />
<Connection pin="Pin2" siteNumber="0" instrument="DCPower1" channel="2" />
</Connections>
</PinMap>
1 change: 1 addition & 0 deletions tests/assets/stubs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Auto generated gRPC files."""
1 change: 1 addition & 0 deletions tests/assets/stubs/nidcpower_measurement/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Auto generated gRPC files for nidcpower test measurement."""
16 changes: 16 additions & 0 deletions tests/assets/stubs/nidcpower_measurement/types.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
syntax = "proto3";
package ni.measurementlink.measurement.tests.nidcpower_measurement;

message Configurations {
repeated string pin_names = 1;
bool multi_session = 2;
}

message Outputs {
repeated string session_names = 1;
repeated string resource_names = 2;
repeated string channel_lists = 3;
repeated string connected_channels = 4;
repeated double voltage_measurements = 5;
repeated double current_measurements = 6;
}
27 changes: 27 additions & 0 deletions tests/assets/stubs/nidcpower_measurement/types_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 72 additions & 0 deletions tests/assets/stubs/nidcpower_measurement/types_pb2.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
"""
import builtins
import collections.abc
import google.protobuf.descriptor
import google.protobuf.internal.containers
import google.protobuf.message
import sys

if sys.version_info >= (3, 8):
import typing as typing_extensions
else:
import typing_extensions

DESCRIPTOR: google.protobuf.descriptor.FileDescriptor

@typing_extensions.final
class Configurations(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor

PIN_NAMES_FIELD_NUMBER: builtins.int
MULTI_SESSION_FIELD_NUMBER: builtins.int
@property
def pin_names(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ...
multi_session: builtins.bool
def __init__(
self,
*,
pin_names: collections.abc.Iterable[builtins.str] | None = ...,
multi_session: builtins.bool = ...,
) -> None: ...
def ClearField(self, field_name: typing_extensions.Literal["multi_session", b"multi_session", "pin_names", b"pin_names"]) -> None: ...

global___Configurations = Configurations

@typing_extensions.final
class Outputs(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor

SESSION_NAMES_FIELD_NUMBER: builtins.int
RESOURCE_NAMES_FIELD_NUMBER: builtins.int
CHANNEL_LISTS_FIELD_NUMBER: builtins.int
CONNECTED_CHANNELS_FIELD_NUMBER: builtins.int
VOLTAGE_MEASUREMENTS_FIELD_NUMBER: builtins.int
CURRENT_MEASUREMENTS_FIELD_NUMBER: builtins.int
@property
def session_names(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ...
@property
def resource_names(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ...
@property
def channel_lists(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ...
@property
def connected_channels(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ...
@property
def voltage_measurements(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: ...
@property
def current_measurements(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: ...
def __init__(
self,
*,
session_names: collections.abc.Iterable[builtins.str] | None = ...,
resource_names: collections.abc.Iterable[builtins.str] | None = ...,
channel_lists: collections.abc.Iterable[builtins.str] | None = ...,
connected_channels: collections.abc.Iterable[builtins.str] | None = ...,
voltage_measurements: collections.abc.Iterable[builtins.float] | None = ...,
current_measurements: collections.abc.Iterable[builtins.float] | None = ...,
) -> None: ...
def ClearField(self, field_name: typing_extensions.Literal["channel_lists", b"channel_lists", "connected_channels", b"connected_channels", "current_measurements", b"current_measurements", "resource_names", b"resource_names", "session_names", b"session_names", "voltage_measurements", b"voltage_measurements"]) -> None: ...

global___Outputs = Outputs
4 changes: 4 additions & 0 deletions tests/assets/stubs/nidcpower_measurement/types_pb2_grpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc

17 changes: 17 additions & 0 deletions tests/assets/stubs/nidcpower_measurement/types_pb2_grpc.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
"""
import abc
import collections.abc
import grpc
import grpc.aio
import typing

_T = typing.TypeVar('_T')

class _MaybeAsyncIterator(collections.abc.AsyncIterator[_T], collections.abc.Iterator[_T], metaclass=abc.ABCMeta):
...

class _ServicerContext(grpc.ServicerContext, grpc.aio.ServicerContext): # type: ignore
...
1 change: 1 addition & 0 deletions tests/integration/session_management/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Integration tests for driver-specific session management APIs."""
10 changes: 10 additions & 0 deletions tests/integration/session_management/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Pytest configuration file for integration tests."""
import pathlib

import pytest


@pytest.fixture(scope="module")
def pin_map_directory(test_assets_directory: pathlib.Path) -> pathlib.Path:
"""Test fixture that returns the pin map directory."""
return test_assets_directory / "integration" / "session_management"
Loading