From ef77c7a8ab7f1ba5ca98c7fafad2b08261ea4755 Mon Sep 17 00:00:00 2001 From: Naveed Jooma Date: Thu, 27 Jun 2024 14:50:02 -0400 Subject: [PATCH] Add default extra methods to board (#44) --- .../viam/sdk/core/component/board/Board.kt | 145 ++++++++-- .../core/component/board/BoardRPCClient.kt | 109 +++----- .../core/component/board/BoardRPCService.kt | 60 ++--- .../sdk/core/component/ComponentTest.java | 10 +- .../component/board/BoardRPCClientTest.kt | 145 +++++----- .../component/board/BoardRPCServiceTest.kt | 155 ++++++----- .../sdk/core/component/board/BoardTest.kt | 250 ++++++------------ .../com/viam/sdk/core/util/MediaTest.kt | 2 +- .../com/viam/sdk/core/util/test_jpeg.jpg | Bin .../com/viam/sdk/core/util/test_png.png | Bin .../com/viam/sdk/core/util/test_viam_rgba | Bin 11 files changed, 417 insertions(+), 459 deletions(-) rename core/sdk/src/test/{java => kotlin}/com/viam/sdk/core/util/MediaTest.kt (97%) rename core/sdk/src/test/{java => kotlin}/com/viam/sdk/core/util/test_jpeg.jpg (100%) rename core/sdk/src/test/{java => kotlin}/com/viam/sdk/core/util/test_png.png (100%) rename core/sdk/src/test/{java => kotlin}/com/viam/sdk/core/util/test_viam_rgba (100%) diff --git a/core/sdk/src/main/kotlin/com/viam/sdk/core/component/board/Board.kt b/core/sdk/src/main/kotlin/com/viam/sdk/core/component/board/Board.kt index 252546551..a3c1a3c50 100644 --- a/core/sdk/src/main/kotlin/com/viam/sdk/core/component/board/Board.kt +++ b/core/sdk/src/main/kotlin/com/viam/sdk/core/component/board/Board.kt @@ -21,8 +21,7 @@ typealias Tick = StreamTicksResponse abstract class Board(name: String) : Component(SUBTYPE, named(name)) { companion object { @JvmField - val SUBTYPE = - Subtype(Subtype.NAMESPACE_RDK, Subtype.RESOURCE_TYPE_COMPONENT, "board") + val SUBTYPE = Subtype(Subtype.NAMESPACE_RDK, Subtype.RESOURCE_TYPE_COMPONENT, "board") /** * Get the ResourceName of the component @@ -51,94 +50,190 @@ abstract class Board(name: String) : Component(SUBTYPE, named(name)) { * @param pin the name of the GPIO pin * @param high when true, sets the pin to high. When false, sets the pin to low. */ - abstract fun setGpioState(pin: String, high: Boolean, extra: Optional) + abstract fun setGpioState(pin: String, high: Boolean, extra: Struct) + + /** + * Set the high/low state of the given pin of a board. + * @param pin the name of the GPIO pin + * @param high when true, sets the pin to high. When false, sets the pin to low. + */ + fun setGpioState(pin: String, high: Boolean) { + return setGpioState(pin, high, Struct.getDefaultInstance()) + } /** * Get the high/low state of the given pin of a board. * @param pin the name of the GPIO pin * @return the state of the pin: true if high, false otherwise. */ - abstract fun getGpioState(pin: String, extra: Optional): Boolean + abstract fun getGpioState(pin: String, extra: Struct): Boolean + + /** + * Get the high/low state of the given pin of a board. + * @param pin the name of the GPIO pin + * @return the state of the pin: true if high, false otherwise. + */ + fun getGpioState(pin: String): Boolean { + return getGpioState(pin, Struct.getDefaultInstance()) + } + + /** + * Set the duty cycle of the given pin of a board. + * @param pin the name of the GPIO pin + * @param dutyCyclePct the duty cycle percent + */ + abstract fun setPwm(pin: String, dutyCyclePct: Double, extra: Struct) /** * Set the duty cycle of the given pin of a board. * @param pin the name of the GPIO pin * @param dutyCyclePct the duty cycle percent */ - abstract fun setPwm(pin: String, dutyCyclePct: Double, extra: Optional) + fun setPwm(pin: String, dutyCyclePct: Double) { + return setPwm(pin, dutyCyclePct, Struct.getDefaultInstance()) + } + + /** + * Get the duty cycle of the given pin of a board. + * @param pin the name of the pin + * @returns the duty cycle percent + */ + abstract fun getPwm(pin: String, extra: Struct): Double /** * Get the duty cycle of the given pin of a board. * @param pin the name of the pin * @returns the duty cycle percent */ - abstract fun getPwm(pin: String, extra: Optional): Double + fun getPwm(pin: String): Double { + return getPwm(pin, Struct.getDefaultInstance()) + } /** * Set the PWM frequency of the given pin of a board. * @param pin the name of the pin * @param frequencyHz the frequency to set */ - abstract fun setPwmFrequency(pin: String, frequencyHz: Int, extra: Optional) + abstract fun setPwmFrequency(pin: String, frequencyHz: Int, extra: Struct) + + /** + * Set the PWM frequency of the given pin of a board. + * @param pin the name of the pin + * @param frequencyHz the frequency to set + */ + fun setPwmFrequency(pin: String, frequencyHz: Int) { + return setPwmFrequency(pin, frequencyHz, Struct.getDefaultInstance()) + } + + /** + * Get the PWM frequency of the given pin of a board. + * @param pin the name of the pin + * @returns the frequency of the pin in Hz + */ + abstract fun getPwmFrequency(pin: String, extra: Struct): Int /** * Get the PWM frequency of the given pin of a board. * @param pin the name of the pin * @returns the frequency of the pin in Hz */ - abstract fun getPwmFrequency(pin: String, extra: Optional): Int + fun getPwmFrequency(pin: String): Int { + return getPwmFrequency(pin, Struct.getDefaultInstance()) + } /** * Write analog value to pin. * @param pin the name of the pin * @param value the value to set */ - abstract fun writeAnalog(pin: String, value: Int, extra: Optional) + abstract fun writeAnalog(pin: String, value: Int, extra: Struct) + + /** + * Write analog value to pin. + * @param pin the name of the pin + * @param value the value to set + */ + fun writeAnalog(pin: String, value: Int) { + return writeAnalog(pin, value, Struct.getDefaultInstance()) + } /** * Read the current value of an analog reader of a board. * @param analogReader the name of the analog reader * @returns the current value of the analog reader */ - abstract fun getAnalogReaderValue(analogReader: String, extra: Optional): Int + abstract fun getAnalogReaderValue(analogReader: String, extra: Struct): Int + + /** + * Read the current value of an analog reader of a board. + * @param analogReader the name of the analog reader + * @returns the current value of the analog reader + */ + fun getAnalogReaderValue(analogReader: String): Int { + return getAnalogReaderValue(analogReader, Struct.getDefaultInstance()) + } + + /** + * Return the current value of the interrupt which is based on the type of Interrupt. + * @param digitalInterrupt the name of the digital interrupt + * @returns the current value of the digital reader + */ + abstract fun getDigitalInterruptValue(digitalInterrupt: String, extra: Struct): Int /** * Return the current value of the interrupt which is based on the type of Interrupt. * @param digitalInterrupt the name of the digital interrupt * @returns the current value of the digital reader */ - abstract fun getDigitalInterruptValue( - digitalInterrupt: String, - extra: Optional - ): Int + fun getDigitalInterruptValue(digitalInterrupt: String): Int { + return getDigitalInterruptValue(digitalInterrupt, Struct.getDefaultInstance()) + } /** * Stream digital interrupts ticks. * @param interrupts the list of digital interrupts names from which to receive ticks * @returns a [Stream] of [Tick] objects */ - abstract fun streamTicks(interrupts: List, extra: Optional): Iterator + abstract fun streamTicks(interrupts: List, extra: Struct): Iterator + + /** + * Stream digital interrupts ticks. + * @param interrupts the list of digital interrupts names from which to receive ticks + * @returns a [Stream] of [Tick] objects + */ + fun streamTicks(interrupts: List): Iterator { + return streamTicks(interrupts, Struct.getDefaultInstance()) + } + + /** + * Add a listener for the digital interrupts. + * @param interrupts the list of digital interrupts names from which to receive ticks + * @param tickQueue an object to receive values from the callback + */ + abstract fun addCallbacks(interrupts: List, tickQueue: Queue, extra: Struct) /** * Add a listener for the digital interrupts. * @param interrupts the list of digital interrupts names from which to receive ticks * @param tickQueue an object to receive values from the callback */ - abstract fun addCallbacks( - interrupts: List, - tickQueue: Queue, - extra: Optional - ) + fun addCallbacks(interrupts: List, tickQueue: Queue) { + return addCallbacks(interrupts, tickQueue, Struct.getDefaultInstance()) + } /** * Set the board to the indicated power mode. * @param powerMode the power mode to set * @param duration if provided, the board will exit the given power mode after this duration */ - abstract fun setPowerMode( - powerMode: PowerMode, - duration: Duration, - extra: Optional - ) + abstract fun setPowerMode(powerMode: PowerMode, duration: Duration, extra: Struct) + /** + * Set the board to the indicated power mode. + * @param powerMode the power mode to set + * @param duration if provided, the board will exit the given power mode after this duration + */ + fun setPowerMode(powerMode: PowerMode, duration: Duration) { + return setPowerMode(powerMode, duration, Struct.getDefaultInstance()) + } } diff --git a/core/sdk/src/main/kotlin/com/viam/sdk/core/component/board/BoardRPCClient.kt b/core/sdk/src/main/kotlin/com/viam/sdk/core/component/board/BoardRPCClient.kt index 319e2c0d8..545a3a9c9 100644 --- a/core/sdk/src/main/kotlin/com/viam/sdk/core/component/board/BoardRPCClient.kt +++ b/core/sdk/src/main/kotlin/com/viam/sdk/core/component/board/BoardRPCClient.kt @@ -29,118 +29,77 @@ class BoardRPCClient(name: String, channel: Channel) : Board(name) { } } - override fun setGpioState(pin: String, high: Boolean, extra: Optional) { - val request = SetGPIORequest.newBuilder() - .setName(this.name.name) - .setPin(pin).setHigh(high) - .setExtra(extra.getOrDefault(Struct.getDefaultInstance())) - .build() + override fun setGpioState(pin: String, high: Boolean, extra: Struct) { + val request = + SetGPIORequest.newBuilder().setName(this.name.name).setPin(pin).setHigh(high).setExtra(extra).build() this.client.setGPIO(request) } - override fun getGpioState(pin: String, extra: Optional): Boolean { - val request = GetGPIORequest.newBuilder() - .setName(this.name.name) - .setPin(pin) - .setExtra(extra.getOrDefault(Struct.getDefaultInstance())) - .build() + override fun getGpioState(pin: String, extra: Struct): Boolean { + val request = GetGPIORequest.newBuilder().setName(this.name.name).setPin(pin).setExtra(extra).build() return this.client.getGPIO(request).high } - override fun setPwm(pin: String, dutyCyclePct: Double, extra: Optional) { - val request = SetPWMRequest.newBuilder() - .setName(this.name.name) - .setPin(pin) - .setDutyCyclePct(dutyCyclePct) - .setExtra(extra.getOrDefault(Struct.getDefaultInstance())) - .build() + override fun setPwm(pin: String, dutyCyclePct: Double, extra: Struct) { + val request = + SetPWMRequest.newBuilder().setName(this.name.name).setPin(pin).setDutyCyclePct(dutyCyclePct).setExtra(extra) + .build() this.client.setPWM(request) } - override fun getPwm(pin: String, extra: Optional): Double { - val request = PWMRequest.newBuilder() - .setName(this.name.name) - .setPin(pin) - .setExtra(extra.getOrDefault(Struct.getDefaultInstance())) - .build() + override fun getPwm(pin: String, extra: Struct): Double { + val request = PWMRequest.newBuilder().setName(this.name.name).setPin(pin).setExtra(extra).build() return this.client.pWM(request).dutyCyclePct } - override fun setPwmFrequency(pin: String, frequencyHz: Int, extra: Optional) { - val request = SetPWMFrequencyRequest.newBuilder() - .setName(this.name.name) - .setPin(pin) - .setFrequencyHz(frequencyHz.toLong()) - .setExtra(extra.getOrDefault(Struct.getDefaultInstance())) - .build() + override fun setPwmFrequency(pin: String, frequencyHz: Int, extra: Struct) { + val request = + SetPWMFrequencyRequest.newBuilder().setName(this.name.name).setPin(pin).setFrequencyHz(frequencyHz.toLong()) + .setExtra(extra).build() this.client.setPWMFrequency(request) } - override fun getPwmFrequency(pin: String, extra: Optional): Int { - val request = PWMFrequencyRequest.newBuilder() - .setName(this.name.name) - .setPin(pin) - .setExtra(extra.getOrDefault(Struct.getDefaultInstance())) - .build() + override fun getPwmFrequency(pin: String, extra: Struct): Int { + val request = PWMFrequencyRequest.newBuilder().setName(this.name.name).setPin(pin).setExtra(extra).build() return this.client.pWMFrequency(request).frequencyHz.toInt() } - override fun writeAnalog(pin: String, value: Int, extra: Optional) { - val request = WriteAnalogRequest.newBuilder() - .setName(this.name.name) - .setPin(pin) - .setValue(value) - .setExtra(extra.getOrDefault(Struct.getDefaultInstance())) - .build() + override fun writeAnalog(pin: String, value: Int, extra: Struct) { + val request = + WriteAnalogRequest.newBuilder().setName(this.name.name).setPin(pin).setValue(value).setExtra(extra).build() this.client.writeAnalog(request) } - override fun getAnalogReaderValue(analogReader: String, extra: Optional): Int { - val request = ReadAnalogReaderRequest.newBuilder() - .setBoardName(this.name.name) - .setAnalogReaderName(analogReader) - .setExtra(extra.getOrDefault(Struct.getDefaultInstance())) - .build() + override fun getAnalogReaderValue(analogReader: String, extra: Struct): Int { + val request = + ReadAnalogReaderRequest.newBuilder().setBoardName(this.name.name).setAnalogReaderName(analogReader) + .setExtra(extra).build() return this.client.readAnalogReader(request).value } - override fun getDigitalInterruptValue(digitalInterrupt: String, extra: Optional): Int { - val request = GetDigitalInterruptValueRequest.newBuilder() - .setBoardName(this.name.name) - .setDigitalInterruptName(digitalInterrupt) - .setExtra(extra.getOrDefault(Struct.getDefaultInstance())) - .build() + override fun getDigitalInterruptValue(digitalInterrupt: String, extra: Struct): Int { + val request = GetDigitalInterruptValueRequest.newBuilder().setBoardName(this.name.name) + .setDigitalInterruptName(digitalInterrupt).setExtra(extra).build() return this.client.getDigitalInterruptValue(request).value.toInt() } - override fun streamTicks(interrupts: List, extra: Optional): Iterator { - val request = StreamTicksRequest.newBuilder() - .setName(this.name.name) - .addAllPinNames(interrupts) - .setExtra(extra.getOrDefault(Struct.getDefaultInstance())) - .build() + override fun streamTicks(interrupts: List, extra: Struct): Iterator { + val request = + StreamTicksRequest.newBuilder().setName(this.name.name).addAllPinNames(interrupts).setExtra(extra).build() return this.client.streamTicks(request) } override fun addCallbacks( - interrupts: List, - tickQueue: Queue, - extra: Optional + interrupts: List, tickQueue: Queue, extra: Struct ) { throw MethodNotImplementedException("BoardRPCClient.addCallbacks") } override fun setPowerMode( - powerMode: PowerMode, - duration: Duration, - extra: Optional + powerMode: PowerMode, duration: Duration, extra: Struct ) { - val request = SetPowerModeRequest.newBuilder() - .setName(this.name.name) - .setPowerMode(powerMode) - .setDuration(Durations.fromNanos(duration.inWholeNanoseconds)) - .setExtra(extra.getOrDefault(Struct.getDefaultInstance())) - .build() + val request = SetPowerModeRequest.newBuilder().setName(this.name.name).setPowerMode(powerMode) + .setDuration(Durations.fromNanos(duration.inWholeNanoseconds)).setExtra(extra).build() this.client.setPowerMode(request) } diff --git a/core/sdk/src/main/kotlin/com/viam/sdk/core/component/board/BoardRPCService.kt b/core/sdk/src/main/kotlin/com/viam/sdk/core/component/board/BoardRPCService.kt index 4f3581a19..768df0516 100644 --- a/core/sdk/src/main/kotlin/com/viam/sdk/core/component/board/BoardRPCService.kt +++ b/core/sdk/src/main/kotlin/com/viam/sdk/core/component/board/BoardRPCService.kt @@ -17,11 +17,10 @@ internal class BoardRPCService(private val manager: ResourceManager) : BoardServ ResourceRPCService { override fun setGPIO( - request: SetGPIORequest, - responseObserver: StreamObserver + request: SetGPIORequest, responseObserver: StreamObserver ) { val board = getResource(Board.named(request.name)) - board.setGpioState(request.pin, request.high, Optional.of(request.extra)) + board.setGpioState(request.pin, request.high, request.extra) responseObserver.onNext( SetGPIOResponse.newBuilder().build() ) @@ -29,11 +28,10 @@ internal class BoardRPCService(private val manager: ResourceManager) : BoardServ } override fun getGPIO( - request: GetGPIORequest, - responseObserver: StreamObserver + request: GetGPIORequest, responseObserver: StreamObserver ) { val board = getResource(Board.named(request.name)) - val state = board.getGpioState(request.pin, Optional.of(request.extra)) + val state = board.getGpioState(request.pin, request.extra) responseObserver.onNext( GetGPIOResponse.newBuilder().setHigh(state).build() ) @@ -41,11 +39,10 @@ internal class BoardRPCService(private val manager: ResourceManager) : BoardServ } override fun setPWM( - request: SetPWMRequest, - responseObserver: StreamObserver + request: SetPWMRequest, responseObserver: StreamObserver ) { val board = getResource(Board.named(request.name)) - board.setPwm(request.pin, request.dutyCyclePct, Optional.of(request.extra)) + board.setPwm(request.pin, request.dutyCyclePct, request.extra) responseObserver.onNext( SetPWMResponse.newBuilder().build() ) @@ -53,11 +50,10 @@ internal class BoardRPCService(private val manager: ResourceManager) : BoardServ } override fun pWM( - request: PWMRequest, - responseObserver: StreamObserver + request: PWMRequest, responseObserver: StreamObserver ) { val board = getResource(Board.named(request.name)) - val pwm = board.getPwm(request.pin, Optional.of(request.extra)) + val pwm = board.getPwm(request.pin, request.extra) responseObserver.onNext( PWMResponse.newBuilder().setDutyCyclePct(pwm).build() ) @@ -65,11 +61,10 @@ internal class BoardRPCService(private val manager: ResourceManager) : BoardServ } override fun setPWMFrequency( - request: SetPWMFrequencyRequest, - responseObserver: StreamObserver + request: SetPWMFrequencyRequest, responseObserver: StreamObserver ) { val board = getResource(Board.named(request.name)) - board.setPwmFrequency(request.pin, request.frequencyHz.toInt(), Optional.of(request.extra)) + board.setPwmFrequency(request.pin, request.frequencyHz.toInt(), request.extra) responseObserver.onNext( SetPWMFrequencyResponse.newBuilder().build() ) @@ -77,11 +72,10 @@ internal class BoardRPCService(private val manager: ResourceManager) : BoardServ } override fun pWMFrequency( - request: PWMFrequencyRequest, - responseObserver: StreamObserver + request: PWMFrequencyRequest, responseObserver: StreamObserver ) { val board = getResource(Board.named(request.name)) - val freq = board.getPwmFrequency(request.pin, Optional.of(request.extra)) + val freq = board.getPwmFrequency(request.pin, request.extra) responseObserver.onNext( PWMFrequencyResponse.newBuilder().setFrequencyHz(freq.toLong()).build() ) @@ -89,11 +83,10 @@ internal class BoardRPCService(private val manager: ResourceManager) : BoardServ } override fun writeAnalog( - request: WriteAnalogRequest, - responseObserver: StreamObserver + request: WriteAnalogRequest, responseObserver: StreamObserver ) { val board = getResource(Board.named(request.name)) - board.writeAnalog(request.pin, request.value, Optional.of(request.extra)) + board.writeAnalog(request.pin, request.value, request.extra) responseObserver.onNext( WriteAnalogResponse.newBuilder().build() ) @@ -101,11 +94,10 @@ internal class BoardRPCService(private val manager: ResourceManager) : BoardServ } override fun readAnalogReader( - request: ReadAnalogReaderRequest, - responseObserver: StreamObserver + request: ReadAnalogReaderRequest, responseObserver: StreamObserver ) { val board = getResource(Board.named(request.boardName)) - val value = board.getAnalogReaderValue(request.analogReaderName, Optional.of(request.extra)) + val value = board.getAnalogReaderValue(request.analogReaderName, request.extra) responseObserver.onNext( ReadAnalogReaderResponse.newBuilder().setValue(value).build() ) @@ -113,11 +105,10 @@ internal class BoardRPCService(private val manager: ResourceManager) : BoardServ } override fun streamTicks( - request: StreamTicksRequest, - responseObserver: StreamObserver + request: StreamTicksRequest, responseObserver: StreamObserver ) { val board = getResource(Board.named(request.name)) - val ticksStream = board.streamTicks(request.pinNamesList, Optional.of(request.extra)) + val ticksStream = board.streamTicks(request.pinNamesList, request.extra) for (tick in ticksStream) { responseObserver.onNext(tick) } @@ -125,14 +116,11 @@ internal class BoardRPCService(private val manager: ResourceManager) : BoardServ } override fun setPowerMode( - request: SetPowerModeRequest, - responseObserver: StreamObserver + request: SetPowerModeRequest, responseObserver: StreamObserver ) { val board = getResource(Board.named(request.name)) board.setPowerMode( - request.powerMode, - Durations.toNanos(request.duration).toDuration(DurationUnit.NANOSECONDS), - Optional.of(request.extra) + request.powerMode, Durations.toNanos(request.duration).toDuration(DurationUnit.NANOSECONDS), request.extra ) responseObserver.onNext( SetPowerModeResponse.newBuilder().build() @@ -141,14 +129,12 @@ internal class BoardRPCService(private val manager: ResourceManager) : BoardServ } override fun getDigitalInterruptValue( - request: GetDigitalInterruptValueRequest, - responseObserver: StreamObserver + request: GetDigitalInterruptValueRequest, responseObserver: StreamObserver ) { val board = getResource(Board.named(request.boardName)) - val value = board.getDigitalInterruptValue(request.digitalInterruptName, Optional.of(request.extra)) + val value = board.getDigitalInterruptValue(request.digitalInterruptName, request.extra) responseObserver.onNext( - GetDigitalInterruptValueResponse.newBuilder().setValue(value.toLong()) - .build() + GetDigitalInterruptValueResponse.newBuilder().setValue(value.toLong()).build() ) responseObserver.onCompleted() } diff --git a/core/sdk/src/test/java/com/viam/sdk/core/component/ComponentTest.java b/core/sdk/src/test/java/com/viam/sdk/core/component/ComponentTest.java index 4bc92b3ec..3e647dd17 100644 --- a/core/sdk/src/test/java/com/viam/sdk/core/component/ComponentTest.java +++ b/core/sdk/src/test/java/com/viam/sdk/core/component/ComponentTest.java @@ -10,7 +10,8 @@ import java.util.List; import java.util.Optional; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; class ComponentTest { @@ -19,12 +20,7 @@ class ComponentTest { @BeforeEach void setup() { Subtype subtype = new Subtype("testNamespace", "testType", "testSubtype"); - Common.ResourceName resourceName = Common.ResourceName.newBuilder(). - setNamespace(subtype.getNamespace()). - setType(subtype.getResourceType()). - setSubtype(subtype.getResourceSubtype()). - setName("testComponent"). - build(); + Common.ResourceName resourceName = Common.ResourceName.newBuilder().setNamespace(subtype.getNamespace()).setType(subtype.getResourceType()).setSubtype(subtype.getResourceSubtype()).setName("testComponent").build(); component = new Component(subtype, resourceName) { @Override public List getGeometries(Optional extra) { diff --git a/core/sdk/src/test/kotlin/com/viam/sdk/core/component/board/BoardRPCClientTest.kt b/core/sdk/src/test/kotlin/com/viam/sdk/core/component/board/BoardRPCClientTest.kt index f1ba9ed6e..cfe13d7a3 100644 --- a/core/sdk/src/test/kotlin/com/viam/sdk/core/component/board/BoardRPCClientTest.kt +++ b/core/sdk/src/test/kotlin/com/viam/sdk/core/component/board/BoardRPCClientTest.kt @@ -1,26 +1,30 @@ package com.viam.sdk.core.component.board +import com.google.protobuf.Struct import com.google.protobuf.Value +import com.viam.common.v1.Common.Geometry import com.viam.component.board.v1.Board.PowerMode import com.viam.sdk.core.exception.MethodNotImplementedException import com.viam.sdk.core.resource.ResourceManager import com.viam.sdk.core.rpc.BasicManagedChannel -import io.grpc.StatusRuntimeException import io.grpc.inprocess.InProcessChannelBuilder import io.grpc.inprocess.InProcessServerBuilder import io.grpc.testing.GrpcCleanupRule import org.junit.Rule -import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows +import org.mockito.Mockito.* +import java.time.Instant import java.util.* import kotlin.random.Random import kotlin.time.DurationUnit import kotlin.time.toDuration class BoardRPCClientTest { - private lateinit var board: MockBoard + private lateinit var board: Board private lateinit var client: BoardRPCClient @JvmField @@ -29,7 +33,7 @@ class BoardRPCClientTest { @BeforeEach fun setup() { - board = MockBoard("testBoard") + board = mock(Board::class.java, withSettings().useConstructor("mock-board").defaultAnswer(CALLS_REAL_METHODS)) val resourceManager = ResourceManager(listOf(board)) val service = BoardRPCService(resourceManager) @@ -40,29 +44,28 @@ class BoardRPCClientTest { val channel = grpcCleanup.register( InProcessChannelBuilder.forName(serviceName).directExecutor().build() ) - client = BoardRPCClient("testBoard", BasicManagedChannel(channel)) + client = BoardRPCClient("mock-board", BasicManagedChannel(channel)) } - @Test fun setGpioState() { val pinName = "test-pin" - val funName = "setGpioState" - client.setGpioState(pinName, false, getExtra(funName)) - assertFalse(board.gpios.getValue(pinName)) - assertEquals(board.extra?.fieldsMap?.getValue(EXTRA_KEY)?.stringValue, funName) + val extra = + Struct.newBuilder().putAllFields(mapOf("foo" to Value.newBuilder().setStringValue("bar").build())).build() + client.setGpioState(pinName, false, extra) + verify(board).setGpioState(pinName, false, extra) } @Test fun getGpioState() { val pinName = "test-pin" - - assertThrows { - client.getGpioState(pinName, Optional.empty()) - } - - board.setGpioState(pinName, true, Optional.empty()) - val high = client.getGpioState(pinName, Optional.empty()) + `when`( + board.getGpioState( + eq(pinName) ?: pinName, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(true) + val high = client.getGpioState(pinName) + verify(board).getGpioState(pinName, Struct.getDefaultInstance()) assertTrue(high) } @@ -70,21 +73,19 @@ class BoardRPCClientTest { fun setPwm() { val pinName = "test-pin" val dutyCyclePct = Random.nextDouble() - client.setPwm(pinName, dutyCyclePct, Optional.empty()) - assertEquals(board.pwms.getValue(pinName), dutyCyclePct) + client.setPwm(pinName, dutyCyclePct) + verify(board).setPwm(pinName, dutyCyclePct, Struct.getDefaultInstance()) } @Test fun getPwm() { val pinName = "test-pin" val dutyCyclePct = Random.nextDouble() - - assertThrows { - client.getPwm(pinName, Optional.empty()) - } - - board.setPwm(pinName, dutyCyclePct, Optional.empty()) - val result = client.getPwm(pinName, Optional.empty()) + `when`(board.getPwm(eq(pinName) ?: pinName, any(Struct::class.java) ?: Struct.getDefaultInstance())).thenReturn( + dutyCyclePct + ) + val result = client.getPwm(pinName) + verify(board).getPwm(pinName, Struct.getDefaultInstance()) assertEquals(result, dutyCyclePct) } @@ -92,21 +93,21 @@ class BoardRPCClientTest { fun setPwmFrequency() { val pinName = "test-pin" val frequencyHz = Random.nextInt() - client.setPwmFrequency(pinName, frequencyHz, Optional.empty()) - assertEquals(board.freqs.getValue(pinName), frequencyHz) + client.setPwmFrequency(pinName, frequencyHz) + verify(board).setPwmFrequency(pinName, frequencyHz, Struct.getDefaultInstance()) } @Test fun getPwmFrequency() { val pinName = "test-pin" val frequencyHz = Random.nextInt() - - assertThrows { - client.getPwmFrequency(pinName, Optional.empty()) - } - - board.setPwmFrequency(pinName, frequencyHz, Optional.empty()) - val result = client.getPwmFrequency(pinName, Optional.empty()) + `when`( + board.getPwmFrequency( + eq(pinName) ?: pinName, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(frequencyHz) + val result = client.getPwmFrequency(pinName) + verify(board).getPwmFrequency(pinName, Struct.getDefaultInstance()) assertEquals(result, frequencyHz) } @@ -114,21 +115,21 @@ class BoardRPCClientTest { fun writeAnalog() { val readerName = "reader-name" val value = Random.nextInt() - client.writeAnalog(readerName, value, Optional.empty()) - assertEquals(board.analogs.getValue(readerName), value) + client.writeAnalog(readerName, value) + verify(board).writeAnalog(readerName, value, Struct.getDefaultInstance()) } @Test fun getAnalogReaderValue() { val readerName = "reader-name" val value = Random.nextInt() - - assertThrows { - client.getAnalogReaderValue(readerName, Optional.empty()) - } - - board.writeAnalog(readerName, value, Optional.empty()) - val result = client.getAnalogReaderValue(readerName, Optional.empty()) + `when`( + board.getAnalogReaderValue( + eq(readerName) ?: readerName, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(value) + val result = client.getAnalogReaderValue(readerName) + verify(board).getAnalogReaderValue(readerName, Struct.getDefaultInstance()) assertEquals(result, value) } @@ -136,20 +137,38 @@ class BoardRPCClientTest { fun getDigitalInterruptValue() { val interruptName = "interrupt-name" val value = Random.nextInt() - - assertThrows { - client.getDigitalInterruptValue(interruptName, Optional.empty()) - } - - board.interrupts[interruptName] = value - val result = client.getDigitalInterruptValue(interruptName, Optional.empty()) + `when`( + board.getDigitalInterruptValue( + eq(interruptName) ?: interruptName, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(value) + val result = client.getDigitalInterruptValue(interruptName) + verify(board).getDigitalInterruptValue(interruptName, Struct.getDefaultInstance()) assertEquals(result, value) } @Test fun streamTicks() { + fun createTicks(interrupts: List): Iterator { + val ticks: MutableList = mutableListOf() + for (i in 0..(interrupts.size * 5)) { + val idx = i % interrupts.size + val interrupt = interrupts[idx] + val value = Random.nextBoolean() + val time = Instant.now().epochSecond + ticks.add(Tick.newBuilder().setPinName(interrupt).setHigh(value).setTime(time).build()) + } + return ticks.iterator() + } + val interruptNames = listOf("interrupt-1", "interrupt-2", "interrupt-3") - val ticks = client.streamTicks(interruptNames, Optional.empty()) + `when`( + board.streamTicks( + eq(interruptNames) ?: interruptNames, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(createTicks(interruptNames)) + val ticks = client.streamTicks(interruptNames) + verify(board).streamTicks(interruptNames, Struct.getDefaultInstance()) for (tick in ticks) { assertTrue(interruptNames.contains(tick.pinName)) } @@ -158,7 +177,7 @@ class BoardRPCClientTest { @Test fun addCallback() { assertThrows { - client.addCallbacks(listOf(), PriorityQueue(), Optional.empty()) + client.addCallbacks(listOf(), PriorityQueue()) } } @@ -166,27 +185,23 @@ class BoardRPCClientTest { fun setPowerMode() { val powerMode = PowerMode.POWER_MODE_OFFLINE_DEEP val powerModeDuration = Random.nextInt().toDuration(DurationUnit.NANOSECONDS) - - assertNotEquals(board.powerMode, powerMode) - assertNotEquals(board.powerModeDuration, powerModeDuration) - - client.setPowerMode(powerMode, powerModeDuration, Optional.empty()) - - assertEquals(board.powerMode, powerMode) - assertEquals(board.powerModeDuration, powerModeDuration) + client.setPowerMode(powerMode, powerModeDuration) + verify(board).setPowerMode(powerMode, powerModeDuration, Struct.getDefaultInstance()) } @Test fun doCommand() { val command = mapOf("foo" to Value.newBuilder().setStringValue("bar").build()) + doReturn(Struct.newBuilder().putAllFields(command).build()).`when`(board).doCommand(anyMap()) val response = client.doCommand(command) - assertEquals(response.fieldsMap, command) + verify(board).doCommand(command) + assertEquals(command, response.fieldsMap) } @Test fun getGeometries() { - val funName = "getGeometries" - client.getGeometries(getExtra(funName)) - assertEquals(board.extra?.fieldsMap?.getValue(EXTRA_KEY)?.stringValue, funName) + doReturn(listOf()).`when`(board).getGeometries(any()) + client.getGeometries(Optional.empty()) + verify(board).getGeometries(any()) } } diff --git a/core/sdk/src/test/kotlin/com/viam/sdk/core/component/board/BoardRPCServiceTest.kt b/core/sdk/src/test/kotlin/com/viam/sdk/core/component/board/BoardRPCServiceTest.kt index 402c13d09..7dc6e6cc5 100644 --- a/core/sdk/src/test/kotlin/com/viam/sdk/core/component/board/BoardRPCServiceTest.kt +++ b/core/sdk/src/test/kotlin/com/viam/sdk/core/component/board/BoardRPCServiceTest.kt @@ -3,20 +3,22 @@ package com.viam.sdk.core.component.board import com.google.protobuf.Struct import com.google.protobuf.Value import com.viam.common.v1.Common +import com.viam.common.v1.Common.Geometry import com.viam.component.board.v1.Board.* import com.viam.component.board.v1.BoardServiceGrpc import com.viam.component.board.v1.BoardServiceGrpc.BoardServiceBlockingStub import com.viam.sdk.core.resource.ResourceManager import com.viam.sdk.core.util.Durations -import io.grpc.StatusRuntimeException import io.grpc.inprocess.InProcessChannelBuilder import io.grpc.inprocess.InProcessServerBuilder import io.grpc.testing.GrpcCleanupRule import org.junit.Rule -import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows +import org.mockito.Mockito.* +import java.time.Instant import java.util.* import kotlin.random.Random import kotlin.time.DurationUnit @@ -25,7 +27,7 @@ import kotlin.time.toDuration class BoardRPCServiceTest { - private lateinit var board: MockBoard + private lateinit var board: Board private lateinit var client: BoardServiceBlockingStub @JvmField @@ -34,7 +36,7 @@ class BoardRPCServiceTest { @BeforeEach fun setup() { - board = MockBoard("testBoard") + board = mock(Board::class.java, withSettings().useConstructor("mock-board").defaultAnswer(CALLS_REAL_METHODS)) val resourceManager = ResourceManager(listOf(board)) val service = BoardRPCService(resourceManager) @@ -49,31 +51,29 @@ class BoardRPCServiceTest { ) } + @Test fun setGpioState() { val pinName = "test-pin" - val funName = "setGpioState" - - val request = SetGPIORequest.newBuilder().setName(board.name.name).setPin(pinName).setHigh(false).setExtra( - getExtra(funName).get() - ).build() + val extra = + Struct.newBuilder().putAllFields(mapOf("foo" to Value.newBuilder().setStringValue("bar").build())).build() + val request = + SetGPIORequest.newBuilder().setName(board.name.name).setPin(pinName).setHigh(false).setExtra(extra).build() client.setGPIO(request) - - assertFalse(board.gpios.getValue(pinName)) - assertEquals(board.extra?.fieldsMap?.getValue(EXTRA_KEY)?.stringValue, funName) + verify(board).setGpioState(pinName, false, extra) } @Test fun getGpioState() { val pinName = "test-pin" - + `when`( + board.getGpioState( + eq(pinName) ?: pinName, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(true) val request = GetGPIORequest.newBuilder().setName(board.name.name).setPin(pinName).build() - assertThrows { - client.getGPIO(request) - } - - board.setGpioState(pinName, true, Optional.empty()) val response = client.getGPIO(request) + verify(board).getGpioState(pinName, Struct.getDefaultInstance()) assertTrue(response.high) } @@ -81,27 +81,23 @@ class BoardRPCServiceTest { fun setPwm() { val pinName = "test-pin" val dutyCyclePct = Random.nextDouble() - val request = SetPWMRequest.newBuilder().setName(board.name.name).setPin(pinName).setDutyCyclePct(dutyCyclePct).build() client.setPWM(request) - - assertEquals(board.pwms.getValue(pinName), dutyCyclePct) + verify(board).setPwm(pinName, dutyCyclePct, Struct.getDefaultInstance()) } @Test fun getPwm() { val pinName = "test-pin" val dutyCyclePct = Random.nextDouble() - + `when`(board.getPwm(eq(pinName) ?: pinName, any(Struct::class.java) ?: Struct.getDefaultInstance())).thenReturn( + dutyCyclePct + ) val request = PWMRequest.newBuilder().setName(board.name.name).setPin(pinName).build() - assertThrows { - client.pWM(request) - } - - board.setPwm(pinName, dutyCyclePct, Optional.empty()) - val response = client.pWM(request) - assertEquals(response.dutyCyclePct, dutyCyclePct) + val result = client.pWM(request) + verify(board).getPwm(pinName, Struct.getDefaultInstance()) + assertEquals(result.dutyCyclePct, dutyCyclePct) } @Test @@ -111,22 +107,22 @@ class BoardRPCServiceTest { val request = SetPWMFrequencyRequest.newBuilder().setName(board.name.name).setPin(pinName) .setFrequencyHz(frequencyHz.toLong()).build() client.setPWMFrequency(request) - assertEquals(board.freqs.getValue(pinName), frequencyHz) + verify(board).setPwmFrequency(pinName, frequencyHz, Struct.getDefaultInstance()) } @Test fun getPwmFrequency() { val pinName = "test-pin" val frequencyHz = Random.nextInt() - + `when`( + board.getPwmFrequency( + eq(pinName) ?: pinName, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(frequencyHz) val request = PWMFrequencyRequest.newBuilder().setName(board.name.name).setPin(pinName).build() - assertThrows { - client.pWMFrequency(request) - } - - board.setPwmFrequency(pinName, frequencyHz, Optional.empty()) - val response = client.pWMFrequency(request) - assertEquals(response.frequencyHz, frequencyHz.toLong()) + val result = client.pWMFrequency(request) + verify(board).getPwmFrequency(pinName, Struct.getDefaultInstance()) + assertEquals(result.frequencyHz.toInt(), frequencyHz) } @Test @@ -136,47 +132,65 @@ class BoardRPCServiceTest { val request = WriteAnalogRequest.newBuilder().setName(board.name.name).setPin(readerName).setValue(value).build() client.writeAnalog(request) - assertEquals(board.analogs.getValue(readerName), value) + verify(board).writeAnalog(readerName, value, Struct.getDefaultInstance()) } @Test fun getAnalogReaderValue() { val readerName = "reader-name" val value = Random.nextInt() - + `when`( + board.getAnalogReaderValue( + eq(readerName) ?: readerName, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(value) val request = ReadAnalogReaderRequest.newBuilder().setBoardName(board.name.name).setAnalogReaderName(readerName).build() - assertThrows { - client.readAnalogReader(request) - } - - board.writeAnalog(readerName, value, Optional.empty()) - val response = client.readAnalogReader(request) - assertEquals(response.value, value) + val result = client.readAnalogReader(request) + verify(board).getAnalogReaderValue(readerName, Struct.getDefaultInstance()) + assertEquals(result.value, value) } @Test fun getDigitalInterruptValue() { val interruptName = "interrupt-name" val value = Random.nextInt() - + `when`( + board.getDigitalInterruptValue( + eq(interruptName) ?: interruptName, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(value) val request = GetDigitalInterruptValueRequest.newBuilder().setBoardName(board.name.name) .setDigitalInterruptName(interruptName).build() - assertThrows { - client.getDigitalInterruptValue(request) - } - - board.interrupts[interruptName] = value - val response = client.getDigitalInterruptValue(request) - assertEquals(response.value, value.toLong()) + val result = client.getDigitalInterruptValue(request) + verify(board).getDigitalInterruptValue(interruptName, Struct.getDefaultInstance()) + assertEquals(result.value.toInt(), value) } @Test fun streamTicks() { + fun createTicks(interrupts: List): Iterator { + val ticks: MutableList = mutableListOf() + for (i in 0..(interrupts.size * 5)) { + val idx = i % interrupts.size + val interrupt = interrupts[idx] + val value = Random.nextBoolean() + val time = Instant.now().epochSecond + ticks.add(Tick.newBuilder().setPinName(interrupt).setHigh(value).setTime(time).build()) + } + return ticks.iterator() + } + val interruptNames = listOf("interrupt-1", "interrupt-2", "interrupt-3") + `when`( + board.streamTicks( + eq(interruptNames) ?: interruptNames, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(createTicks(interruptNames)) val request = StreamTicksRequest.newBuilder().setName(board.name.name).addAllPinNames(interruptNames).build() - val ticks = client.streamTicks(request) - for (tick in ticks) { + val response = client.streamTicks(request) + verify(board).streamTicks(interruptNames, Struct.getDefaultInstance()) + for (tick in response) { assertTrue(interruptNames.contains(tick.pinName)) } } @@ -185,33 +199,28 @@ class BoardRPCServiceTest { fun setPowerMode() { val powerMode = PowerMode.POWER_MODE_OFFLINE_DEEP val powerModeDuration = Random.nextInt().toDuration(DurationUnit.NANOSECONDS) - - assertNotEquals(board.powerMode, powerMode) - assertNotEquals(board.powerModeDuration, powerModeDuration) - val request = SetPowerModeRequest.newBuilder().setName(board.name.name).setPowerMode(powerMode) .setDuration(Durations.fromNanos(powerModeDuration.inWholeNanoseconds)).build() client.setPowerMode(request) - - assertEquals(board.powerMode, powerMode) - assertEquals(board.powerModeDuration, powerModeDuration) + verify(board).setPowerMode(powerMode, powerModeDuration, Struct.getDefaultInstance()) } @Test fun doCommand() { - val command = mapOf("foo" to Value.newBuilder().setStringValue("bar").build()) - val commandStruct = Struct.newBuilder().putAllFields(command).build() - val request = Common.DoCommandRequest.newBuilder().setName(board.name.name).setCommand(commandStruct).build() + val command = + Struct.newBuilder().putAllFields(mapOf("foo" to Value.newBuilder().setStringValue("bar").build())).build() + doReturn(command).`when`(board).doCommand(anyMap()) + val request = Common.DoCommandRequest.newBuilder().setName(board.name.name).setCommand(command).build() val response = client.doCommand(request) - assertEquals(response.result, commandStruct) + verify(board).doCommand(command.fieldsMap) + assertEquals(command, response.result) } @Test fun getGeometries() { - val funName = "getGeometries" - val request = - Common.GetGeometriesRequest.newBuilder().setName(board.name.name).setExtra(getExtra(funName).get()).build() + doReturn(listOf()).`when`(board).getGeometries(any()) + val request = Common.GetGeometriesRequest.newBuilder().setName(board.name.name).build() client.getGeometries(request) - assertEquals(board.extra?.fieldsMap?.getValue(EXTRA_KEY)?.stringValue, funName) + verify(board).getGeometries(Optional.of(Struct.getDefaultInstance())) } } diff --git a/core/sdk/src/test/kotlin/com/viam/sdk/core/component/board/BoardTest.kt b/core/sdk/src/test/kotlin/com/viam/sdk/core/component/board/BoardTest.kt index 95c94990e..7d73824a8 100644 --- a/core/sdk/src/test/kotlin/com/viam/sdk/core/component/board/BoardTest.kt +++ b/core/sdk/src/test/kotlin/com/viam/sdk/core/component/board/BoardTest.kt @@ -2,145 +2,46 @@ package com.viam.sdk.core.component.board import com.google.protobuf.Struct import com.google.protobuf.Value -import com.viam.common.v1.Common import com.viam.component.board.v1.Board.PowerMode -import com.viam.sdk.core.exception.MethodNotImplementedException -import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows +import org.mockito.Answers +import org.mockito.Mockito.* import java.time.Instant import java.util.* import kotlin.random.Random -import kotlin.time.Duration import kotlin.time.DurationUnit import kotlin.time.toDuration -class MockBoard(name: String) : Board(name) { - var gpios: MutableMap = mutableMapOf() - var pwms: MutableMap = mutableMapOf() - var freqs: MutableMap = mutableMapOf() - var analogs: MutableMap = mutableMapOf() - var interrupts: MutableMap = mutableMapOf() - var powerMode: PowerMode = PowerMode.POWER_MODE_UNSPECIFIED - var powerModeDuration: Duration = Duration.ZERO - var extra: Struct? = null - - override fun setGpioState(pin: String, high: Boolean, extra: Optional) { - gpios[pin] = high - this.extra = extra.orElse(null) - } - - override fun getGpioState(pin: String, extra: Optional): Boolean { - this.extra = extra.orElse(null) - return gpios.getValue(pin) - } - - override fun setPwm(pin: String, dutyCyclePct: Double, extra: Optional) { - pwms[pin] = dutyCyclePct - this.extra = extra.orElse(null) - } - - override fun getPwm(pin: String, extra: Optional): Double { - this.extra = extra.orElse(null) - return pwms.getValue(pin) - } - - override fun setPwmFrequency(pin: String, frequencyHz: Int, extra: Optional) { - freqs[pin] = frequencyHz - this.extra = extra.orElse(null) - } - - override fun getPwmFrequency(pin: String, extra: Optional): Int { - this.extra = extra.orElse(null) - return freqs.getValue(pin) - } - - override fun writeAnalog(pin: String, value: Int, extra: Optional) { - analogs[pin] = value - this.extra = extra.orElse(null) - } - - override fun getAnalogReaderValue(analogReader: String, extra: Optional): Int { - this.extra = extra.orElse(null) - return analogs.getValue(analogReader) - } - - override fun getDigitalInterruptValue(digitalInterrupt: String, extra: Optional): Int { - this.extra = extra.orElse(null) - return interrupts.getValue(digitalInterrupt) - } - - override fun streamTicks(interrupts: List, extra: Optional): Iterator { - this.extra = extra.orElse(null) - val ticks: MutableList = mutableListOf() - for (i in 0..(interrupts.size * 5)) { - val idx = i % interrupts.size - val interrupt = interrupts[idx] - val value = Random.nextBoolean() - val time = Instant.now().epochSecond - ticks.add(Tick.newBuilder().setPinName(interrupt).setHigh(value).setTime(time).build()) - } - return ticks.iterator() - } - - override fun addCallbacks(interrupts: List, tickQueue: Queue, extra: Optional) { - throw MethodNotImplementedException("MockBoard.addCallbacks") - } - - override fun setPowerMode( - powerMode: PowerMode, duration: Duration, extra: Optional - ) { - this.powerMode = powerMode - powerModeDuration = duration - this.extra = extra.orElse(null) - } - - override fun doCommand(command: Map): Struct { - return Struct.newBuilder().putAllFields(command).build() - } - - override fun getGeometries(extra: Optional): List { - this.extra = extra.orElse(null) - return listOf() - } -} - - -internal const val EXTRA_KEY = "funName" -internal fun getExtra(funName: String): Optional { - return Optional.of( - Struct.newBuilder().putAllFields(mapOf(EXTRA_KEY to Value.newBuilder().setStringValue(funName).build())).build() - ) -} - class BoardTest { - private lateinit var board: MockBoard + private lateinit var board: Board @BeforeEach fun setup() { - board = MockBoard("testBoard") + board = mock(Board::class.java, Answers.CALLS_REAL_METHODS) } @Test fun setGpioState() { val pinName = "test-pin" - val funName = "setGpioState" - board.setGpioState(pinName, false, getExtra(funName)) - assertFalse(board.gpios.getValue(pinName)) - assertEquals(board.extra?.fieldsMap?.getValue(EXTRA_KEY)?.stringValue, funName) + val extra = + Struct.newBuilder().putAllFields(mapOf("foo" to Value.newBuilder().setStringValue("bar").build())).build() + board.setGpioState(pinName, false, extra) + verify(board).setGpioState(pinName, false, extra) } @Test fun getGpioState() { val pinName = "test-pin" - - assertThrows { - board.getGpioState(pinName, Optional.empty()) - } - - board.setGpioState(pinName, true, Optional.empty()) - val high = board.getGpioState(pinName, Optional.empty()) + `when`( + board.getGpioState( + eq(pinName) ?: pinName, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(true) + val high = board.getGpioState(pinName) + verify(board).getGpioState(pinName, Struct.getDefaultInstance()) assertTrue(high) } @@ -148,21 +49,19 @@ class BoardTest { fun setPwm() { val pinName = "test-pin" val dutyCyclePct = Random.nextDouble() - board.setPwm(pinName, dutyCyclePct, Optional.empty()) - assertEquals(board.pwms.getValue(pinName), dutyCyclePct) + board.setPwm(pinName, dutyCyclePct) + verify(board).setPwm(pinName, dutyCyclePct) } @Test fun getPwm() { val pinName = "test-pin" val dutyCyclePct = Random.nextDouble() - - assertThrows { - board.getPwm(pinName, Optional.empty()) - } - - board.setPwm(pinName, dutyCyclePct, Optional.empty()) - val result = board.getPwm(pinName, Optional.empty()) + `when`(board.getPwm(eq(pinName) ?: pinName, any(Struct::class.java) ?: Struct.getDefaultInstance())).thenReturn( + dutyCyclePct + ) + val result = board.getPwm(pinName) + verify(board).getPwm(pinName, Struct.getDefaultInstance()) assertEquals(result, dutyCyclePct) } @@ -170,21 +69,21 @@ class BoardTest { fun setPwmFrequency() { val pinName = "test-pin" val frequencyHz = Random.nextInt() - board.setPwmFrequency(pinName, frequencyHz, Optional.empty()) - assertEquals(board.freqs.getValue(pinName), frequencyHz) + board.setPwmFrequency(pinName, frequencyHz) + verify(board).setPwmFrequency(pinName, frequencyHz) } @Test fun getPwmFrequency() { val pinName = "test-pin" val frequencyHz = Random.nextInt() - - assertThrows { - board.getPwmFrequency(pinName, Optional.empty()) - } - - board.setPwmFrequency(pinName, frequencyHz, Optional.empty()) - val result = board.getPwmFrequency(pinName, Optional.empty()) + `when`( + board.getPwmFrequency( + eq(pinName) ?: pinName, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(frequencyHz) + val result = board.getPwmFrequency(pinName) + verify(board).getPwmFrequency(pinName, Struct.getDefaultInstance()) assertEquals(result, frequencyHz) } @@ -192,21 +91,21 @@ class BoardTest { fun writeAnalog() { val readerName = "reader-name" val value = Random.nextInt() - board.writeAnalog(readerName, value, Optional.empty()) - assertEquals(board.analogs.getValue(readerName), value) + board.writeAnalog(readerName, value) + verify(board).writeAnalog(readerName, value) } @Test fun getAnalogReaderValue() { val readerName = "reader-name" val value = Random.nextInt() - - assertThrows { - board.getAnalogReaderValue(readerName, Optional.empty()) - } - - board.writeAnalog(readerName, value, Optional.empty()) - val result = board.getAnalogReaderValue(readerName, Optional.empty()) + `when`( + board.getAnalogReaderValue( + eq(readerName) ?: readerName, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(value) + val result = board.getAnalogReaderValue(readerName) + verify(board).getAnalogReaderValue(readerName, Struct.getDefaultInstance()) assertEquals(result, value) } @@ -214,20 +113,38 @@ class BoardTest { fun getDigitalInterruptValue() { val interruptName = "interrupt-name" val value = Random.nextInt() - - assertThrows { - board.getDigitalInterruptValue(interruptName, Optional.empty()) - } - - board.interrupts[interruptName] = value - val result = board.getDigitalInterruptValue(interruptName, Optional.empty()) + `when`( + board.getDigitalInterruptValue( + eq(interruptName) ?: interruptName, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(value) + val result = board.getDigitalInterruptValue(interruptName) + verify(board).getDigitalInterruptValue(interruptName, Struct.getDefaultInstance()) assertEquals(result, value) } @Test fun streamTicks() { + fun createTicks(interrupts: List): Iterator { + val ticks: MutableList = mutableListOf() + for (i in 0..(interrupts.size * 5)) { + val idx = i % interrupts.size + val interrupt = interrupts[idx] + val value = Random.nextBoolean() + val time = Instant.now().epochSecond + ticks.add(Tick.newBuilder().setPinName(interrupt).setHigh(value).setTime(time).build()) + } + return ticks.iterator() + } + val interruptNames = listOf("interrupt-1", "interrupt-2", "interrupt-3") - val ticks = board.streamTicks(interruptNames, Optional.empty()) + `when`( + board.streamTicks( + eq(interruptNames) ?: interruptNames, any(Struct::class.java) ?: Struct.getDefaultInstance() + ) + ).thenReturn(createTicks(interruptNames)) + val ticks = board.streamTicks(interruptNames) + verify(board).streamTicks(interruptNames, Struct.getDefaultInstance()) for (tick in ticks) { assertTrue(interruptNames.contains(tick.pinName)) } @@ -235,36 +152,17 @@ class BoardTest { @Test fun addCallback() { - assertThrows { - board.addCallbacks(listOf(), PriorityQueue(), Optional.empty()) - } + val list = listOf() + val queue = PriorityQueue() + board.addCallbacks(list, queue) + verify(board).addCallbacks(list, queue, Struct.getDefaultInstance()) } @Test fun setPowerMode() { val powerMode = PowerMode.POWER_MODE_OFFLINE_DEEP val powerModeDuration = Random.nextInt().toDuration(DurationUnit.NANOSECONDS) - - assertNotEquals(board.powerMode, powerMode) - assertNotEquals(board.powerModeDuration, powerModeDuration) - - board.setPowerMode(powerMode, powerModeDuration, Optional.empty()) - - assertEquals(board.powerMode, powerMode) - assertEquals(board.powerModeDuration, powerModeDuration) - } - - @Test - fun doCommand() { - val command = mapOf("foo" to Value.newBuilder().setStringValue("bar").build()) - val response = board.doCommand(command) - assertEquals(response.fieldsMap, command) - } - - @Test - fun getGeometries() { - val funName = "getGeometries" - board.getGeometries(getExtra(funName)) - assertEquals(board.extra?.fieldsMap?.getValue(EXTRA_KEY)?.stringValue, funName) + board.setPowerMode(powerMode, powerModeDuration) + verify(board).setPowerMode(powerMode, powerModeDuration) } } diff --git a/core/sdk/src/test/java/com/viam/sdk/core/util/MediaTest.kt b/core/sdk/src/test/kotlin/com/viam/sdk/core/util/MediaTest.kt similarity index 97% rename from core/sdk/src/test/java/com/viam/sdk/core/util/MediaTest.kt rename to core/sdk/src/test/kotlin/com/viam/sdk/core/util/MediaTest.kt index ab1041be6..888dd3190 100644 --- a/core/sdk/src/test/java/com/viam/sdk/core/util/MediaTest.kt +++ b/core/sdk/src/test/kotlin/com/viam/sdk/core/util/MediaTest.kt @@ -5,7 +5,7 @@ import org.junit.jupiter.api.Test import java.io.File class MediaTest { - private val testDir = "${System.getProperty("user.dir")}/src/test/java/com/viam/sdk/core/util/" + private val testDir = "${System.getProperty("user.dir")}/src/test/kotlin/com/viam/sdk/core/util/" private val testJPEG = File("$testDir/test_jpeg.jpg").readBytes().toList() private val jpegWidth = 190 diff --git a/core/sdk/src/test/java/com/viam/sdk/core/util/test_jpeg.jpg b/core/sdk/src/test/kotlin/com/viam/sdk/core/util/test_jpeg.jpg similarity index 100% rename from core/sdk/src/test/java/com/viam/sdk/core/util/test_jpeg.jpg rename to core/sdk/src/test/kotlin/com/viam/sdk/core/util/test_jpeg.jpg diff --git a/core/sdk/src/test/java/com/viam/sdk/core/util/test_png.png b/core/sdk/src/test/kotlin/com/viam/sdk/core/util/test_png.png similarity index 100% rename from core/sdk/src/test/java/com/viam/sdk/core/util/test_png.png rename to core/sdk/src/test/kotlin/com/viam/sdk/core/util/test_png.png diff --git a/core/sdk/src/test/java/com/viam/sdk/core/util/test_viam_rgba b/core/sdk/src/test/kotlin/com/viam/sdk/core/util/test_viam_rgba similarity index 100% rename from core/sdk/src/test/java/com/viam/sdk/core/util/test_viam_rgba rename to core/sdk/src/test/kotlin/com/viam/sdk/core/util/test_viam_rgba