Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/update_protos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ jobs:
client = <Name>ServiceStub(channel)
await client.Method(request, timeout=1.82)
cast(AsyncMock, <name>.method_name).assert_called_once_with(
value1, timeout=loose_approx(1.82), extra={"a": "b"}, metadata={}
value1, timeout=expected_grpc_timeout(1.82), extra={"a": "b"}, metadata={}
)

class TestClient:
Expand Down
11 changes: 9 additions & 2 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import pytest


def loose_approx(val):
return pytest.approx(val, rel=1e-2)
def expected_grpc_timeout(val):
"""Approximate comparison accounting for grpclib timeout encoding precision loss and time_remaining jitter.

grpclib.encode_timeout truncates to integer seconds (>10s) or integer milliseconds (<=10s).
time_remaining introduces up to ~10ms of jitter from async processing.
"""
if val > 10:
return pytest.approx(val, abs=1.01)
return pytest.approx(val, abs=0.011)
6 changes: 3 additions & 3 deletions tests/test_arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from viam.resource.manager import ResourceManager
from viam.utils import dict_to_struct, struct_to_dict

from . import loose_approx
from . import expected_grpc_timeout
from .mocks.components import GEOMETRIES, MockArm


Expand Down Expand Up @@ -130,7 +130,7 @@ async def test_stop(self):
request = StopRequest(name=self.name)
await client.Stop(request, timeout=4.4)
assert self.arm.is_stopped is True
assert self.arm.timeout == loose_approx(4.4)
assert self.arm.timeout == expected_grpc_timeout(4.4)

async def test_is_moving(self):
async with ChannelFor([self.service]) as channel:
Expand Down Expand Up @@ -215,7 +215,7 @@ async def test_stop(self):
client = ArmClient(self.name, channel)
await client.stop(timeout=1.82)
assert self.arm.is_stopped is True
assert self.arm.timeout == loose_approx(1.82)
assert self.arm.timeout == expected_grpc_timeout(1.82)

async def test_is_moving(self):
async with ChannelFor([self.service]) as channel:
Expand Down
6 changes: 3 additions & 3 deletions tests/test_audio_in.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from viam.resource.manager import ResourceManager
from viam.utils import dict_to_struct, struct_to_dict

from . import loose_approx
from . import expected_grpc_timeout
from .mocks.components import GEOMETRIES, MockAudioIn

# Test properties for the mock AudioIn
Expand Down Expand Up @@ -116,7 +116,7 @@ async def test_get_properties(self, audio_in: MockAudioIn, service: AudioInRPCSe
assert response.supported_codecs == PROPERTIES.supported_codecs
assert response.sample_rate_hz == PROPERTIES.sample_rate_hz
assert response.num_channels == PROPERTIES.num_channels
assert audio_in.timeout == loose_approx(1.82)
assert audio_in.timeout == expected_grpc_timeout(1.82)

async def test_do_command(self, audio_in: MockAudioIn, service: AudioInRPCService):
async with ChannelFor([service]) as channel:
Expand Down Expand Up @@ -165,7 +165,7 @@ async def test_get_properties(self, audio_in: MockAudioIn, service: AudioInRPCSe
assert properties.supported_codecs == PROPERTIES.supported_codecs
assert properties.sample_rate_hz == PROPERTIES.sample_rate_hz
assert properties.num_channels == PROPERTIES.num_channels
assert audio_in.timeout == loose_approx(4.4)
assert audio_in.timeout == expected_grpc_timeout(4.4)

async def test_do_command(self, audio_in: AudioIn, service: AudioInRPCService):
async with ChannelFor([service]) as channel:
Expand Down
6 changes: 3 additions & 3 deletions tests/test_audio_out.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from viam.resource.manager import ResourceManager
from viam.utils import dict_to_struct, struct_to_dict

from . import loose_approx
from . import expected_grpc_timeout
from .mocks.components import GEOMETRIES, MockAudioOut

# Test properties for the mock AudioIn
Expand Down Expand Up @@ -121,7 +121,7 @@ async def test_get_properties(self, audio_out: MockAudioOut, service: AudioOutRP
assert response.supported_codecs == PROPERTIES.supported_codecs
assert response.sample_rate_hz == PROPERTIES.sample_rate_hz
assert response.num_channels == PROPERTIES.num_channels
assert audio_out.timeout == loose_approx(1.82)
assert audio_out.timeout == expected_grpc_timeout(1.82)

@pytest.mark.asyncio
async def test_do_command(self, audio_out: MockAudioOut, service: AudioOutRPCService):
Expand Down Expand Up @@ -183,7 +183,7 @@ async def test_get_properties(self, audio_out: MockAudioOut, service: AudioOutRP
assert properties.supported_codecs == PROPERTIES.supported_codecs
assert properties.sample_rate_hz == PROPERTIES.sample_rate_hz
assert properties.num_channels == PROPERTIES.num_channels
assert audio_out.timeout == loose_approx(4.4)
assert audio_out.timeout == expected_grpc_timeout(4.4)

@pytest.mark.asyncio
async def test_do_command(self, audio_out: MockAudioOut, service: AudioOutRPCService):
Expand Down
6 changes: 3 additions & 3 deletions tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from viam.resource.manager import ResourceManager
from viam.utils import dict_to_struct, struct_to_dict

from . import loose_approx
from . import expected_grpc_timeout
from .mocks.components import GEOMETRIES, MockBase


Expand Down Expand Up @@ -194,7 +194,7 @@ async def test_stop(self, base: MockBase, service: BaseRPCService):
assert base.stopped is False
await client.Stop(StopRequest(name=base.name), timeout=1.82)
assert base.stopped is True
assert base.timeout == loose_approx(1.82)
assert base.timeout == expected_grpc_timeout(1.82)

request = MoveStraightRequest(
name=base.name,
Expand Down Expand Up @@ -315,7 +315,7 @@ async def test_stop(self, base: MockBase, service: BaseRPCService):
assert base.stopped is False
await client.stop(timeout=4.4)
assert base.stopped is True
assert base.timeout == loose_approx(4.4)
assert base.timeout == expected_grpc_timeout(4.4)

await client.move_straight(1, 1)
assert base.stopped is False
Expand Down
31 changes: 15 additions & 16 deletions tests/test_board.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from viam.resource.manager import ResourceManager
from viam.utils import dict_to_struct, struct_to_dict

from . import loose_approx
from . import expected_grpc_timeout
from .mocks.components import GEOMETRIES, MockAnalog, MockBoard, MockDigitalInterrupt, MockGPIOPin


Expand Down Expand Up @@ -122,7 +122,7 @@ async def test_set_power_mode(self, board: MockBoard):
pm_mode = PowerMode.POWER_MODE_OFFLINE_DEEP
pm_duration = timedelta(minutes=1)
await board.set_power_mode(mode=pm_mode, duration=pm_duration, timeout=1.11)
assert board.timeout == loose_approx(1.11)
assert board.timeout == expected_grpc_timeout(1.11)
assert board.power_mode == pm_mode
assert board.power_mode_duration == pm_duration

Expand Down Expand Up @@ -157,7 +157,7 @@ async def test_read_analog(self, board: MockBoard, service: BoardRPCService):

reader = cast(MockAnalog, board.analogs["analog1"])
assert reader.extra == extra
assert reader.timeout == loose_approx(4.4)
assert reader.timeout == expected_grpc_timeout(4.4)

async def test_get_digital_interrupt_value(self, board: MockBoard, service: BoardRPCService, interrupt: MockDigitalInterrupt):
async with ChannelFor([service]) as channel:
Expand All @@ -182,7 +182,7 @@ async def test_set_gpio(self, board: MockBoard, service: BoardRPCService):
pin = cast(MockGPIOPin, board.gpios["pin1"])
assert pin.high is True
assert pin.extra == extra
assert pin.timeout == loose_approx(4.1)
assert pin.timeout == expected_grpc_timeout(4.1)

async def test_get_gpio(self, board: MockBoard, service: BoardRPCService):
async with ChannelFor([service]) as channel:
Expand All @@ -199,7 +199,7 @@ async def test_get_gpio(self, board: MockBoard, service: BoardRPCService):

pin = cast(MockGPIOPin, board.gpios["pin1"])
assert pin.extra == extra
assert pin.timeout == loose_approx(1.82)
assert pin.timeout == expected_grpc_timeout(1.82)

async def test_pwm(self, board: MockBoard, service: BoardRPCService):
async with ChannelFor([service]) as channel:
Expand All @@ -212,7 +212,7 @@ async def test_pwm(self, board: MockBoard, service: BoardRPCService):

pin = cast(MockGPIOPin, board.gpios["pin1"])
assert pin.extra == extra
assert pin.timeout == loose_approx(7.86)
assert pin.timeout == expected_grpc_timeout(7.86)

async def test_set_pwm(self, board: MockBoard, service: BoardRPCService):
async with ChannelFor([service]) as channel:
Expand All @@ -225,7 +225,7 @@ async def test_set_pwm(self, board: MockBoard, service: BoardRPCService):
pin = cast(MockGPIOPin, board.gpios["pin1"])
assert pin.pwm == 12.3
assert pin.extra == extra
assert pin.timeout == loose_approx(1.213)
assert pin.timeout == expected_grpc_timeout(1.213)

async def test_pwm_frequency(self, board: MockBoard, service: BoardRPCService):
async with ChannelFor([service]) as channel:
Expand All @@ -238,7 +238,7 @@ async def test_pwm_frequency(self, board: MockBoard, service: BoardRPCService):

pin = cast(MockGPIOPin, board.gpios["pin1"])
assert pin.extra == extra
assert pin.timeout == loose_approx(182)
assert pin.timeout == expected_grpc_timeout(182)

async def test_set_pwm_freq(self, board: MockBoard, service: BoardRPCService):
async with ChannelFor([service]) as channel:
Expand Down Expand Up @@ -279,7 +279,7 @@ async def test_set_power_mode(self, board: MockBoard, service: BoardRPCService):
request = SetPowerModeRequest(name=board.name, power_mode=pm_mode, duration=pm_duration, extra=dict_to_struct(extra))
response: SetPowerModeResponse = await client.SetPowerMode(request, timeout=6.66)
assert response == SetPowerModeResponse()
assert board.timeout == loose_approx(6.66)
assert board.timeout == expected_grpc_timeout(6.66)
assert board.power_mode == PowerMode.POWER_MODE_OFFLINE_DEEP
assert board.power_mode_duration == pm_duration.ToTimedelta()
assert board.extra == extra
Expand All @@ -293,7 +293,7 @@ async def test_write_analog(self, board: MockBoard, service: BoardRPCService):
response: WriteAnalogResponse = await client.WriteAnalog(request, timeout=6.66)
assert response == WriteAnalogResponse()
mock_analog = cast(MockAnalog, board.analogs["analog1"])
assert mock_analog.timeout == loose_approx(6.66)
assert mock_analog.timeout == expected_grpc_timeout(6.66)
assert mock_analog.value.value == value
assert mock_analog.name == pin

Expand Down Expand Up @@ -364,8 +364,7 @@ async def test_set_power_mode(self, board: MockBoard, service: BoardRPCService):
pm_mode = PowerMode.POWER_MODE_OFFLINE_DEEP
pm_timedelta = timedelta(minutes=1)
await client.set_power_mode(mode=pm_mode, duration=pm_timedelta, timeout=9.83)
print("timeout is", board.timeout)
assert board.timeout == loose_approx(9.83)
assert board.timeout == expected_grpc_timeout(9.83)
assert board.power_mode == pm_mode
pm_duration = Duration()
pm_duration.FromTimedelta(pm_timedelta)
Expand Down Expand Up @@ -426,7 +425,7 @@ async def test_set(self, board: MockBoard, service: BoardRPCService):
mock_pin = cast(MockGPIOPin, board.gpios["pin1"])
assert mock_pin.high is True
assert mock_pin.extra == extra
assert mock_pin.timeout == loose_approx(1.82)
assert mock_pin.timeout == expected_grpc_timeout(1.82)

async def test_get(self, board: MockBoard, service: BoardRPCService):
async with ChannelFor([service]) as channel:
Expand All @@ -448,7 +447,7 @@ async def test_set_pwm(self, board: MockBoard, service: BoardRPCService):
mock_pin = cast(MockGPIOPin, board.gpios["pin1"])
assert mock_pin.pwm == 12.3
assert mock_pin.extra == extra
assert mock_pin.timeout == loose_approx(3.23)
assert mock_pin.timeout == expected_grpc_timeout(3.23)

async def test_get_pwm(self, board: MockBoard, service: BoardRPCService):
async with ChannelFor([service]) as channel:
Expand All @@ -459,7 +458,7 @@ async def test_get_pwm(self, board: MockBoard, service: BoardRPCService):
assert pwm == 0.0
mock_pin = cast(MockGPIOPin, board.gpios["pin1"])
assert mock_pin.extra == extra
assert mock_pin.timeout == loose_approx(1.2345)
assert mock_pin.timeout == expected_grpc_timeout(1.2345)

async def test_set_pwm_frequency(self, board: MockBoard, service: BoardRPCService):
async with ChannelFor([service]) as channel:
Expand All @@ -470,7 +469,7 @@ async def test_set_pwm_frequency(self, board: MockBoard, service: BoardRPCServic
mock_pin = cast(MockGPIOPin, board.gpios["pin1"])
assert mock_pin.pwm_freq == 123
assert mock_pin.extra == extra
assert mock_pin.timeout == loose_approx(4.341)
assert mock_pin.timeout == expected_grpc_timeout(4.341)

async def test_get_pwm_freq(self, board: MockBoard, service: BoardRPCService):
async with ChannelFor([service]) as channel:
Expand Down
8 changes: 4 additions & 4 deletions tests/test_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from viam.resource.manager import ResourceManager
from viam.utils import dict_to_struct, struct_to_dict

from . import loose_approx
from . import expected_grpc_timeout
from .mocks.components import MockButton

EXTRA_PARAMS = {"foo": "bar", "baz": [1, 2, 3]}
Expand All @@ -27,7 +27,7 @@ class TestButton:
async def test_push(self, button):
await button.push(timeout=1.23, extra=EXTRA_PARAMS)
assert button.pushed is True
assert button.timeout == loose_approx(1.23)
assert button.timeout == expected_grpc_timeout(1.23)
assert button.extra == EXTRA_PARAMS

async def test_do(self, button):
Expand Down Expand Up @@ -55,7 +55,7 @@ async def test_push(self, button, service):
await client.Push(request, timeout=1.23)
assert button.pushed is True
assert button.extra == EXTRA_PARAMS
assert button.timeout == loose_approx(1.23)
assert button.timeout == expected_grpc_timeout(1.23)

async def test_do(self, button: MockButton, service: ButtonRPCService):
async with ChannelFor([service]) as channel:
Expand All @@ -75,7 +75,7 @@ async def test_push(self, button, service):
await client.push(timeout=3.45, extra=EXTRA_PARAMS)
assert button.pushed is True
assert button.extra == EXTRA_PARAMS
assert button.timeout == loose_approx(3.45)
assert button.timeout == expected_grpc_timeout(3.45)

async def test_do(self, button, manager, service):
async with ChannelFor([service]) as channel:
Expand Down
18 changes: 9 additions & 9 deletions tests/test_camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from viam.resource.manager import ResourceManager
from viam.utils import dict_to_struct, struct_to_dict

from . import loose_approx
from . import expected_grpc_timeout
from .mocks.components import GEOMETRIES, MockCamera

# ################################ NB ################################# #
Expand Down Expand Up @@ -107,10 +107,10 @@ async def test_timeout(self, camera: MockCamera):
assert camera.timeout is None

await camera.get_point_cloud(timeout=4.4)
assert camera.timeout == loose_approx(4.4)
assert camera.timeout == expected_grpc_timeout(4.4)

await camera.get_properties(timeout=7.86)
assert camera.timeout == loose_approx(7.86)
assert camera.timeout == expected_grpc_timeout(7.86)

async def test_get_geometries(self, camera: MockCamera):
geometries = await camera.get_geometries()
Expand All @@ -129,7 +129,7 @@ async def test_get_images(self, camera: MockCamera, service: CameraRPCService, m
assert raw_img.mime_type == CameraMimeType.PNG
assert raw_img.source_name == camera.name
assert response.response_metadata == metadata
assert camera.timeout == loose_approx(18.1)
assert camera.timeout == expected_grpc_timeout(18.1)

async def test_get_images_uses_source_name_not_resource_name(self):
class MockCameraWithCustomSource(MockCamera):
Expand Down Expand Up @@ -158,7 +158,7 @@ async def test_get_point_cloud(self, camera: MockCamera, service: CameraRPCServi
request = GetPointCloudRequest(name="camera", mime_type=CameraMimeType.PCD)
response: GetPointCloudResponse = await client.GetPointCloud(request, timeout=7.86)
assert response.point_cloud == point_cloud
assert camera.timeout == loose_approx(7.86)
assert camera.timeout == expected_grpc_timeout(7.86)

async def test_get_properties(self, camera: MockCamera, service: CameraRPCService, properties: Camera.Properties):
assert camera.timeout is None
Expand All @@ -170,7 +170,7 @@ async def test_get_properties(self, camera: MockCamera, service: CameraRPCServic
assert response.intrinsic_parameters == properties.intrinsic_parameters
assert response.mime_types == properties.mime_types
assert response.frame_rate == properties.frame_rate
assert camera.timeout == loose_approx(5.43)
assert camera.timeout == expected_grpc_timeout(5.43)

async def test_do(self, camera: MockCamera, service: CameraRPCService):
async with ChannelFor([service]) as channel:
Expand Down Expand Up @@ -200,23 +200,23 @@ async def test_get_images(self, camera: MockCamera, service: CameraRPCService, i
assert imgs[0].name == camera.name
assert imgs[0].data == image.data
assert md == metadata
assert camera.timeout == loose_approx(1.82)
assert camera.timeout == expected_grpc_timeout(1.82)

async def test_get_point_cloud(self, camera: MockCamera, service: CameraRPCService, point_cloud: bytes):
assert camera.timeout is None
async with ChannelFor([service]) as channel:
client = CameraClient("camera", channel)
pc, _ = await client.get_point_cloud(timeout=4.4)
assert pc == point_cloud
assert camera.timeout == loose_approx(4.4)
assert camera.timeout == expected_grpc_timeout(4.4)

async def test_get_properties(self, camera: MockCamera, service: CameraRPCService, properties: Camera.Properties):
assert camera.timeout is None
async with ChannelFor([service]) as channel:
client = CameraClient("camera", channel)
props = await client.get_properties(timeout=7.86)
assert props == properties
assert camera.timeout == loose_approx(7.86)
assert camera.timeout == expected_grpc_timeout(7.86)

async def test_do(self, service: CameraRPCService):
async with ChannelFor([service]) as channel:
Expand Down
Loading
Loading