Skip to content

Commit a295c1a

Browse files
Avinash2Sureshjayaseelan-jamesbkeryan
authored
tests: Add integration and acceptance tests for NI-DMM and NI-DAQmx drivers session management APIs (#504)
* tests: add acceptance and integration tests for nidaqmx session management apis * tests: add acceptance and integration tests for nidmm session management apis * fix: use approximate value for float assertion * tests: round expected DMM resolution --------- Co-authored-by: Jayaseelan James <jayaseelan.james@ni.com> Co-authored-by: Brad Keryan <brad.keryan@ni.com>
1 parent f26fb49 commit a295c1a

25 files changed

Lines changed: 982 additions & 1 deletion

File tree

ni_measurementlink_service/session_management/_reservation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ def create_nidaqmx_task(
622622
def create_nidaqmx_tasks(
623623
self,
624624
initialization_behavior: SessionInitializationBehavior = SessionInitializationBehavior.AUTO,
625-
) -> ContextManager[Sequence[TypedSessionInformation[nidcpower.Session]]]:
625+
) -> ContextManager[Sequence[TypedSessionInformation[nidaqmx.Task]]]:
626626
"""Create multiple NI-DAQmx tasks.
627627
628628
Args:
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import pathlib
2+
from typing import Generator, Iterable, NamedTuple
3+
4+
import pytest
5+
6+
from ni_measurementlink_service._internal.stubs.ni.measurementlink.measurement.v2.measurement_service_pb2 import (
7+
MeasureRequest,
8+
)
9+
from ni_measurementlink_service._internal.stubs.ni.measurementlink.measurement.v2.measurement_service_pb2_grpc import (
10+
MeasurementServiceStub,
11+
)
12+
from ni_measurementlink_service._internal.stubs.ni.measurementlink.pin_map_context_pb2 import (
13+
PinMapContext,
14+
)
15+
from ni_measurementlink_service.measurement.service import MeasurementService
16+
from tests.assets.stubs.nidaqmx_measurement.types_pb2 import (
17+
Configurations,
18+
Outputs,
19+
)
20+
from tests.utilities import nidaqmx_measurement
21+
from tests.utilities.pin_map_client import PinMapClient
22+
23+
_SITE = 0
24+
25+
26+
def test___single_session___measure___returns_measured_values(
27+
pin_map_context: PinMapContext,
28+
stub_v2: MeasurementServiceStub,
29+
) -> None:
30+
pin_names = ["Pin1"]
31+
min_value = -10.5
32+
max_value = 10.5
33+
configurations = Configurations(pin_names=pin_names, multi_session=False)
34+
35+
outputs = _measure(stub_v2, pin_map_context, configurations)
36+
37+
assert min_value <= outputs.voltage_values[0] <= max_value
38+
39+
40+
def test___single_session___measure___creates_single_session(
41+
pin_map_context: PinMapContext,
42+
stub_v2: MeasurementServiceStub,
43+
) -> None:
44+
pin_names = ["Pin1"]
45+
configurations = Configurations(pin_names=pin_names, multi_session=False)
46+
47+
outputs = _measure(stub_v2, pin_map_context, configurations)
48+
49+
assert _get_output(outputs) == [_MeasurementOutput("Dev1", "Dev1", "Dev1/ai0", "Dev1/ai0")]
50+
51+
52+
def test___multiple_sessions___measure___creates_multiple_sessions(
53+
pin_map_context: PinMapContext,
54+
stub_v2: MeasurementServiceStub,
55+
) -> None:
56+
pin_names = ["Pin1", "Pin2"]
57+
configurations = Configurations(pin_names=pin_names, multi_session=True)
58+
59+
outputs = _measure(stub_v2, pin_map_context, configurations)
60+
61+
assert _get_output(outputs) == [
62+
_MeasurementOutput("Dev1", "Dev1", "Dev1/ai0", "Dev1/ai0"),
63+
_MeasurementOutput("Dev2", "Dev2", "Dev2/ai0", "Dev2/ai0"),
64+
]
65+
66+
67+
def _measure(
68+
stub_v2: MeasurementServiceStub,
69+
pin_map_context: PinMapContext,
70+
configurations: Configurations,
71+
) -> Outputs:
72+
request = MeasureRequest(pin_map_context=pin_map_context)
73+
request.configuration_parameters.Pack(configurations)
74+
response_iterator = stub_v2.Measure(request)
75+
responses = list(response_iterator)
76+
assert len(responses) == 1
77+
outputs = Outputs.FromString(responses[0].outputs.value)
78+
return outputs
79+
80+
81+
@pytest.fixture(scope="module")
82+
def measurement_service() -> Generator[MeasurementService, None, None]:
83+
"""Test fixture that creates and hosts a measurement service."""
84+
with nidaqmx_measurement.measurement_service.host_service() as service:
85+
yield service
86+
87+
88+
@pytest.fixture
89+
def pin_map_context(pin_map_client: PinMapClient, pin_map_directory: pathlib.Path) -> PinMapContext:
90+
pin_map_name = "2Mio2Pin1Site.pinmap"
91+
pin_map_id = pin_map_client.update_pin_map(pin_map_directory / pin_map_name)
92+
93+
return PinMapContext(pin_map_id=pin_map_id, sites=[_SITE])
94+
95+
96+
class _MeasurementOutput(NamedTuple):
97+
session_name: str
98+
resource_name: str
99+
channel_list: str
100+
connected_channels: str
101+
102+
103+
def _get_output(outputs: Outputs) -> Iterable[_MeasurementOutput]:
104+
return [
105+
_MeasurementOutput(session_name, resource_name, channel_list, connected_channels)
106+
for session_name, resource_name, channel_list, connected_channels in zip(
107+
outputs.session_names,
108+
outputs.resource_names,
109+
outputs.channel_lists,
110+
outputs.connected_channels,
111+
)
112+
]
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import pathlib
2+
from typing import Generator, Iterable, NamedTuple
3+
4+
import pytest
5+
6+
from ni_measurementlink_service._internal.stubs.ni.measurementlink.measurement.v2.measurement_service_pb2 import (
7+
MeasureRequest,
8+
)
9+
from ni_measurementlink_service._internal.stubs.ni.measurementlink.measurement.v2.measurement_service_pb2_grpc import (
10+
MeasurementServiceStub,
11+
)
12+
from ni_measurementlink_service._internal.stubs.ni.measurementlink.pin_map_context_pb2 import (
13+
PinMapContext,
14+
)
15+
from ni_measurementlink_service.measurement.service import MeasurementService
16+
from tests.assets.stubs.nidmm_measurement.types_pb2 import (
17+
Configurations,
18+
Outputs,
19+
)
20+
from tests.utilities import nidmm_measurement
21+
from tests.utilities.pin_map_client import PinMapClient
22+
23+
_SITE = 0
24+
25+
26+
def test___single_session___measure___returns_measured_values(
27+
pin_map_context: PinMapContext,
28+
stub_v2: MeasurementServiceStub,
29+
) -> None:
30+
pin_names = ["Pin1"]
31+
configurations = Configurations(pin_names=pin_names, multi_session=False)
32+
33+
outputs = _measure(stub_v2, pin_map_context, configurations)
34+
35+
assert outputs.signals_out_of_range == [False]
36+
assert outputs.absolute_resolutions == pytest.approx([5.0e-05])
37+
38+
39+
def test___single_session___measure___creates_single_session(
40+
pin_map_context: PinMapContext,
41+
stub_v2: MeasurementServiceStub,
42+
) -> None:
43+
pin_names = ["Pin1"]
44+
configurations = Configurations(pin_names=pin_names, multi_session=False)
45+
46+
outputs = _measure(stub_v2, pin_map_context, configurations)
47+
48+
assert _get_output(outputs) == [_MeasurementOutput("DMM1", "DMM1", "0", "0")]
49+
50+
51+
def test___multiple_sessions___measure___creates_multiple_sessions(
52+
pin_map_context: PinMapContext,
53+
stub_v2: MeasurementServiceStub,
54+
) -> None:
55+
pin_names = ["Pin1", "Pin2"]
56+
configurations = Configurations(pin_names=pin_names, multi_session=True)
57+
58+
outputs = _measure(stub_v2, pin_map_context, configurations)
59+
60+
assert _get_output(outputs) == [
61+
_MeasurementOutput("DMM1", "DMM1", "0", "0"),
62+
_MeasurementOutput("DMM2", "DMM2", "0", "0"),
63+
]
64+
65+
66+
def _measure(
67+
stub_v2: MeasurementServiceStub,
68+
pin_map_context: PinMapContext,
69+
configurations: Configurations,
70+
) -> Outputs:
71+
request = MeasureRequest(pin_map_context=pin_map_context)
72+
request.configuration_parameters.Pack(configurations)
73+
response_iterator = stub_v2.Measure(request)
74+
responses = list(response_iterator)
75+
assert len(responses) == 1
76+
outputs = Outputs.FromString(responses[0].outputs.value)
77+
return outputs
78+
79+
80+
@pytest.fixture(scope="module")
81+
def measurement_service() -> Generator[MeasurementService, None, None]:
82+
"""Test fixture that creates and hosts a measurement service."""
83+
with nidmm_measurement.measurement_service.host_service() as service:
84+
yield service
85+
86+
87+
@pytest.fixture
88+
def pin_map_context(pin_map_client: PinMapClient, pin_map_directory: pathlib.Path) -> PinMapContext:
89+
pin_map_name = "2Dmm2Pin1Site.pinmap"
90+
pin_map_id = pin_map_client.update_pin_map(pin_map_directory / pin_map_name)
91+
92+
return PinMapContext(pin_map_id=pin_map_id, sites=[_SITE])
93+
94+
95+
class _MeasurementOutput(NamedTuple):
96+
session_name: str
97+
resource_name: str
98+
channel_list: str
99+
connected_channels: str
100+
101+
102+
def _get_output(outputs: Outputs) -> Iterable[_MeasurementOutput]:
103+
return [
104+
_MeasurementOutput(session_name, resource_name, channel_list, connected_channels)
105+
for session_name, resource_name, channel_list, connected_channels in zip(
106+
outputs.session_names,
107+
outputs.resource_names,
108+
outputs.channel_lists,
109+
outputs.connected_channels,
110+
)
111+
]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<PinMap xmlns="http://www.ni.com/TestStand/SemiconductorModule/PinMap.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" schemaVersion="1.6">
3+
<Instruments>
4+
<NIDmmInstrument name="DMM1" />
5+
<NIDmmInstrument name="DMM2" />
6+
</Instruments>
7+
<Pins>
8+
<DUTPin name="Pin1" />
9+
<DUTPin name="Pin2" />
10+
</Pins>
11+
<PinGroups></PinGroups>
12+
<Sites>
13+
<Site siteNumber="0" />
14+
</Sites>
15+
<Connections>
16+
<Connection pin="Pin1" siteNumber="0" instrument="DMM1" channel="0" />
17+
<Connection pin="Pin2" siteNumber="0" instrument="DMM2" channel="0" />
18+
</Connections>
19+
</PinMap>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<PinMap xmlns="http://www.ni.com/TestStand/SemiconductorModule/PinMap.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" schemaVersion="1.1">
3+
<Instruments>
4+
<NIDAQmxTask name="Dev1" taskType="AnalogInput" channelList="Dev1/ai0" />
5+
<NIDAQmxTask name="Dev2" taskType="AnalogInput" channelList="Dev2/ai0" />
6+
</Instruments>
7+
<Pins>
8+
<DUTPin name="Pin1" />
9+
<DUTPin name="Pin2" />
10+
</Pins>
11+
<PinGroups></PinGroups>
12+
<Sites>
13+
<Site siteNumber="0" />
14+
</Sites>
15+
<Connections>
16+
<Connection pin="Pin1" siteNumber="0" instrument="Dev1" channel="Dev1/ai0" />
17+
<Connection pin="Pin2" siteNumber="0" instrument="Dev2" channel="Dev2/ai0" />
18+
</Connections>
19+
</PinMap>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<PinMap xmlns="http://www.ni.com/TestStand/SemiconductorModule/PinMap.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" schemaVersion="1.6">
3+
<Instruments>
4+
<NIDmmInstrument name="DMM1" />
5+
<NIDmmInstrument name="DMM2" />
6+
</Instruments>
7+
<Pins>
8+
<DUTPin name="Pin1" />
9+
<DUTPin name="Pin2" />
10+
</Pins>
11+
<PinGroups></PinGroups>
12+
<Sites>
13+
<Site siteNumber="0" />
14+
</Sites>
15+
<Connections>
16+
<Connection pin="Pin1" siteNumber="0" instrument="DMM1" channel="0" />
17+
<Connection pin="Pin2" siteNumber="0" instrument="DMM2" channel="0" />
18+
</Connections>
19+
</PinMap>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<PinMap xmlns="http://www.ni.com/TestStand/SemiconductorModule/PinMap.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" schemaVersion="1.1">
3+
<Instruments>
4+
<NIDAQmxTask name="Dev1" taskType="AnalogInput" channelList="Dev1/ai0" />
5+
<NIDAQmxTask name="Dev2" taskType="AnalogInput" channelList="Dev2/ai0" />
6+
</Instruments>
7+
<Pins>
8+
<DUTPin name="Pin1" />
9+
<DUTPin name="Pin2" />
10+
</Pins>
11+
<PinGroups></PinGroups>
12+
<Sites>
13+
<Site siteNumber="0" />
14+
</Sites>
15+
<Connections>
16+
<Connection pin="Pin1" siteNumber="0" instrument="Dev1" channel="Dev1/ai0" />
17+
<Connection pin="Pin2" siteNumber="0" instrument="Dev2" channel="Dev2/ai0" />
18+
</Connections>
19+
</PinMap>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Auto generated gRPC files for nidaqmx test measurement."""
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
syntax = "proto3";
2+
package ni.measurementlink.measurement.tests.nidaqmx_measurement;
3+
4+
message Configurations {
5+
repeated string pin_names = 1;
6+
bool multi_session = 2;
7+
}
8+
9+
message Outputs {
10+
repeated string session_names = 1;
11+
repeated string resource_names = 2;
12+
repeated string channel_lists = 3;
13+
repeated string connected_channels = 4;
14+
repeated double voltage_values = 5;
15+
}

tests/assets/stubs/nidaqmx_measurement/types_pb2.py

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)