diff --git a/pom.xml b/pom.xml index 9c4f38e..57fe133 100644 --- a/pom.xml +++ b/pom.xml @@ -377,23 +377,14 @@ + org/eclipse/uprotocol/Uoptions.* + org/eclipse/uprotocol/UServiceTopic* org/eclipse/uprotocol/core/** org/eclipse/uprotocol/v1/** - - - **/client/** - **/cloudevent/** - **/communication/** - **/transport/** - **/uri/** - **/uuid/** - **/validation/** - - org.sonatype.central diff --git a/src/main/java/org/eclipse/uprotocol/transport/builder/UMessageBuilder.java b/src/main/java/org/eclipse/uprotocol/transport/builder/UMessageBuilder.java index 8136be6..d8c038f 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/builder/UMessageBuilder.java +++ b/src/main/java/org/eclipse/uprotocol/transport/builder/UMessageBuilder.java @@ -55,7 +55,7 @@ public final class UMessageBuilder { /** * Gets a builder for a publish message. - * + *

* A publish message is used to notify all interested consumers of an event that has occurred. * Consumers usually indicate their interest by subscribing to a particular topic. * @@ -75,7 +75,7 @@ public static UMessageBuilder publish(UUri source) { /** * Gets a builder for a notification message. - * + *

* A notification is used to inform a specific consumer about an event that has occurred. * * @param source The component that the notification originates from. @@ -135,13 +135,6 @@ public static UMessageBuilder request(UUri source, UUri sink, int ttl) { *

* The builder will be initialized with {@link UPriority#UPRIORITY_CS4}. * - * # Arguments - * - * * `reply_to_address` - The URI that the sender of the request expects to receive the response message at. - * * `request_id` - The identifier of the request that this is the response to. - * * `invoked_method` - The URI identifying the method that has been invoked and which the created message is - * the outcome of. - * * @param source The URI identifying the method that has been invoked and which the created message is * the outcome of. * @param sink The URI that the sender of the request expects to receive the response message at. @@ -169,16 +162,9 @@ public static UMessageBuilder response(UUri source, UUri sink, UUID reqid) { *

* A response message is used to send the outcome of processing a request message * to the original sender of the request message. - *

- * The builder will be initialized with values from the given request attributes. * - * # Arguments - * - * * `request_attributes` - The attributes from the request message. The response message - * builder will be initialized with the corresponding attribute values. - * * @param request The attributes from the request message. The response message - * builder will be initialized with the corresponding attribute values. + * builder will be initialized with the corresponding attribute values. * @return The builder. * @throws NullPointerException if request is {@code null}. * @throws IllegalArgumentException if the request does not contain valid request attributes. @@ -219,7 +205,7 @@ private UMessageBuilder(UUri source, UUID id, UMessageType type) { /** * Sets the message's identifier. - * + *

* Every message must have an identifier. If this method is not used, an identifier will be * generated and set on the message when one of the build methods is invoked. * @@ -241,14 +227,11 @@ public UMessageBuilder withMessageId(UUID id) { /** * Sets the message's time-to-live. * - * @param ttl The time-to-live in milliseconds. + * @param ttl The time-to-live in milliseconds. Note that the value is interpreted as an + * unsigned integer. A value of 0 indicates that the message never expires. * @return The builder with the configured ttl. - * @throws IllegalArgumentException if the ttl is negative. */ public UMessageBuilder withTtl(int ttl) { - if (ttl < 0) { - throw new IllegalArgumentException("TTL must be a non-negative integer."); - } this.ttl = ttl; return this; } @@ -296,16 +279,12 @@ public UMessageBuilder withPriority(UPriority priority) { /** * Sets the message's permission level. * - * @param plevel The level. + * @param plevel The level. Note that the value is interpreted as an unsigned integer. * @return The builder with the configured permission level. - * @throws IllegalArgumentException if the permission level is less than 0. * @throws IllegalStateException if the message is not an RPC request message. */ public UMessageBuilder withPermissionLevel(int plevel) { // [impl->dsn~up-attributes-permission-level~1] - if (plevel < 0) { - throw new IllegalArgumentException("Permission level must be greater than or equal to 0."); - } if (this.type != UMessageType.UMESSAGE_TYPE_REQUEST) { throw new IllegalStateException("Permission level can only be set for RPC request messages."); } @@ -372,11 +351,6 @@ public UMessage build(UPayload payload) { /** * Creates the message based on the builder's state. * - * # Errors - * - * If the properties set on the builder do not represent a consistent set of [`UAttributes`], - * a [`UMessageError::AttributesValidationError`] is returned. - * * @return A message ready to be sent using a transport implementation. * @throws ValidationException if the properties set on the builder do not represent a * consistent set of attributes as determined by {@link UAttributesValidator#validate(UAttributes)}. diff --git a/src/main/java/org/eclipse/uprotocol/transport/validator/UAttributesValidator.java b/src/main/java/org/eclipse/uprotocol/transport/validator/UAttributesValidator.java index 3adecd3..df0e5ef 100644 --- a/src/main/java/org/eclipse/uprotocol/transport/validator/UAttributesValidator.java +++ b/src/main/java/org/eclipse/uprotocol/transport/validator/UAttributesValidator.java @@ -129,19 +129,42 @@ public final void validateRpcPriority(UAttributes attributes) { } } + /** + * Validates the time-to-live configuration of RPC messages. + * + * @param attributes The attributes to check. + * @throws IllegalArgumentException if the attributes do not represent an RPC message. + * @throws ValidationException if the attributes do not contain a TTL or if its value is 0. + */ + public final void validateRpcTtl(UAttributes attributes) { + if (attributes.getType() != UMessageType.UMESSAGE_TYPE_REQUEST + && attributes.getType() != UMessageType.UMESSAGE_TYPE_RESPONSE) { + throw new IllegalArgumentException("Attributes do not represent an RPC message"); + } + if (!attributes.hasTtl()) { + throw new ValidationException("RPC messages must contain a TTL"); + } + int ttl = attributes.getTtl(); + // TTL is interpreted as an unsigned integer, so negative values are not possible + if (ttl == 0) { + throw new ValidationException("RPC message's TTL must not be 0"); + } + } + /** * Checks if a given set of attributes belong to a message that has expired. *

* The message is considered expired if the message's creation time plus the * duration indicated by the ttl attribute is before the current - * instant in time. + * instant in (system) time. * * @param attributes The attributes to check. * @return {@code true} if the given attributes should be considered expired. */ public final boolean isExpired(UAttributes attributes) { final int ttl = attributes.getTtl(); - return ttl > 0 && UuidUtils.isExpired(attributes.getId(), ttl, Instant.now()); + // TTL is interpreted as an unsigned integer, so negative values are not possible + return Integer.compareUnsigned(ttl, 0) > 0 && UuidUtils.isExpired(attributes.getId(), ttl, Instant.now()); } /* @@ -178,43 +201,6 @@ public final boolean isExpired(UAttributes attributes) { */ public abstract void validate(UAttributes attributes); - /** - * Validates the time-to-live configuration. - *

- * If the UAttributes does not contain a time to live then the ValidationResult is ok. - * - * @param attributes The attributes to check. - * @throws ValidationException if the attributes contain a negative TTL. - */ - public void validateTtl(UAttributes attributes) { - if (!attributes.hasTtl()) { - return; - } - int ttl = attributes.getTtl(); - if (ttl < 0) { - throw new ValidationException(String.format("TTL must be a non-negative integer [%s]", ttl)); - } - } - - /** - * Validate the permissionLevel for the default case. If the UAttributes does - * not contain a permission level then - * the ValidationResult is ok. - * - * @param attributes The attributes to check. - * @throws ValidationException if the attributes contain a negative permission level. - */ - public final void validatePermissionLevel(UAttributes attributes) { - if (!attributes.hasPermissionLevel()) { - return; - } - final var level = attributes.getPermissionLevel(); - if (level < 0) { - throw new ValidationException( - String.format("Permission level must be a non-negative integer [%d]", level)); - } - } - /** * Validators for the message types defined by uProtocol. */ @@ -294,7 +280,6 @@ public void validate(UAttributes attributes) { this::validateId, this::validateSource, this::validateSink, - this::validateTtl, this::validatePriority ); if (!errors.isEmpty()) { @@ -366,7 +351,6 @@ public void validate(UAttributes attributes) { this::validateId, this::validateSource, this::validateSink, - this::validateTtl, this::validatePriority ); if (!errors.isEmpty()) { @@ -435,27 +419,6 @@ public void validateSink(UAttributes attributes) { } } - /** - * Verifies that a set of attributes representing an RPC request contain a valid time-to-live. - * - * @param attributes The attributes to check. - * @throws ValidationException if the attributes do not contain a time-to-live, - * or if the time-to-live is <= 0. - */ - @Override - public void validateTtl(UAttributes attributes) { - // [impl->dsn~up-attributes-request-ttl~1] - if (!attributes.hasTtl()) { - throw new ValidationException("RPC request message must contain a TTL"); - } - int ttl = attributes.getTtl(); - if (ttl <= 0) { - throw new ValidationException(String.format( - "RPC request message's TTL must be a positive integer [%d]", - ttl)); - } - } - @Override public void validate(UAttributes attributes) { final var errors = ValidationUtils.collectErrors(attributes, @@ -463,9 +426,8 @@ public void validate(UAttributes attributes) { this::validateId, this::validateSource, this::validateSink, - this::validateTtl, - this::validateRpcPriority, - this::validatePermissionLevel + this::validateRpcTtl, + this::validateRpcPriority ); if (!errors.isEmpty()) { throw new ValidationException(errors); @@ -575,7 +537,7 @@ public void validate(UAttributes attributes) { this::validateSource, this::validateSink, this::validateReqId, - this::validateTtl, + this::validateRpcTtl, this::validateRpcPriority, this::validateCommstatus ); diff --git a/src/main/java/org/eclipse/uprotocol/uuid/factory/UuidUtils.java b/src/main/java/org/eclipse/uprotocol/uuid/factory/UuidUtils.java index 33b40f6..9b7d174 100644 --- a/src/main/java/org/eclipse/uprotocol/uuid/factory/UuidUtils.java +++ b/src/main/java/org/eclipse/uprotocol/uuid/factory/UuidUtils.java @@ -76,7 +76,7 @@ public static boolean isUProtocol(UUID uuid) { * @throws NullPointerException if the UUID is {@code null}. * @throws IllegalArgumentException if the UUID is not a uProtocol UUID. */ - public static long getTime(UUID uuid) { + public static long getTimestamp(UUID uuid) { Objects.requireNonNull(uuid); if (!isUProtocol(uuid)) { throw new IllegalArgumentException("UUID is not a uProtocol UUID"); @@ -101,7 +101,7 @@ public static long getElapsedTime(UUID id, Instant now) { if (!isUProtocol(id)) { throw new IllegalArgumentException("UUID is not a uProtocol UUID"); } - final var creationTime = getTime(id); + final var creationTime = getTimestamp(id); final var referenceTime = now != null ? now.toEpochMilli() : Instant.now().toEpochMilli(); return referenceTime - creationTime; } @@ -118,21 +118,16 @@ public static long getElapsedTime(UUID id, Instant now) { * has already expired. * @throws NullPointerException if the UUID is {@code null}. * @throws IllegalArgumentException if the UUID is not a uProtocol UUID. - * @throws IllegalArgumentException if the TTL is non-positive. + * @throws IllegalArgumentException if the TTL is 0. */ public static long getRemainingTime(UUID id, int ttl, Instant now) { Objects.requireNonNull(id); - if (!isUProtocol(id)) { - throw new IllegalArgumentException("UUID is not a uProtocol UUID"); - } - if (ttl <= 0) { - throw new IllegalArgumentException("TTL must be positive"); + if (ttl == 0) { + throw new IllegalArgumentException("TTL must not be 0"); } - final var creationTime = getTime(id); - final var referenceTime = now != null ? now.toEpochMilli() : Instant.now().toEpochMilli(); - final var elapsedTime = referenceTime - creationTime; - if (elapsedTime >= ttl) { - return 0; + final long elapsedTime = getElapsedTime(id, now); + if (Long.compareUnsigned(elapsedTime, ttl) > 0) { + return 0; // Expired } else { return ttl - elapsedTime; } @@ -142,22 +137,19 @@ public static long getRemainingTime(UUID id, int ttl, Instant now) { * Checks if an object identified by a given UUID should be considered expired. * * @param id The UUID. - * @param ttl The object's time-to-live (TTL) in milliseconds. + * @param ttl The object's time-to-live (TTL) in milliseconds. Note that the TTL is + * interpreted as an unsigned integer. * @param now The reference point in time that the calculation should be based on, given * as the number of milliseconds since the Unix epoch, or {@code null} to use the current point in time. * @return {@code true} if the object's TTL has already expired. * @throws NullPointerException if the UUID is {@code null}. * @throws IllegalArgumentException if the UUID is not a uProtocol UUID. - * @throws IllegalArgumentException if the TTL is negative. */ public static boolean isExpired(UUID id, int ttl, Instant now) { Objects.requireNonNull(id); if (!isUProtocol(id)) { throw new IllegalArgumentException("UUID is not a uProtocol UUID"); } - if (ttl < 0) { - throw new IllegalArgumentException("TTL must be non-negative"); - } - return ttl > 0 && getRemainingTime(id, ttl, now) == 0; + return Integer.compareUnsigned(ttl, 0) > 0 && getRemainingTime(id, ttl, now) == 0; } } diff --git a/src/test/java/org/eclipse/uprotocol/communication/InMemoryRpcClientTest.java b/src/test/java/org/eclipse/uprotocol/communication/InMemoryRpcClientTest.java index bed348e..80fe153 100644 --- a/src/test/java/org/eclipse/uprotocol/communication/InMemoryRpcClientTest.java +++ b/src/test/java/org/eclipse/uprotocol/communication/InMemoryRpcClientTest.java @@ -187,6 +187,7 @@ void testHandleUnexpectedResponse(Consumer unexpectedMessageHandler) { METHOD_URI, TRANSPORT_SOURCE, reqId) + .withTtl(54321) .build(); responseListener.getValue().onReceive(responseMessage); diff --git a/src/test/java/org/eclipse/uprotocol/transport/builder/UMessageBuilderTest.java b/src/test/java/org/eclipse/uprotocol/transport/builder/UMessageBuilderTest.java index b22187d..4c2d390 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/builder/UMessageBuilderTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/builder/UMessageBuilderTest.java @@ -27,7 +27,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; -import org.junit.jupiter.params.provider.ValueSource; import com.google.protobuf.ByteString; @@ -130,45 +129,36 @@ void assertBuilderPanics( } } - @ParameterizedTest - @ValueSource(ints = { -1, 0 }) - void testRequestRejectsInvalidTtl(int ttl) { + @Test + void testRequestRejectsInvalidTtl() { assertThrows( IllegalArgumentException.class, - () -> UMessageBuilder.request(UURI_DEFAULT, UURI_METHOD, ttl) + () -> UMessageBuilder.request(UURI_DEFAULT, UURI_METHOD, 0) ); } @ParameterizedTest @CsvSource(useHeadersInDisplayName = true, textBlock = """ - permLevel, commStatus, priority - # // [utest->dsn~up-attributes-permission-level~1] - -1, , - , NOT_FOUND, + commStatus, priority + NOT_FOUND, # // [utest->dsn~up-attributes-request-priority~1] - , , UPRIORITY_UNSPECIFIED + , UPRIORITY_UNSPECIFIED # // [utest->dsn~up-attributes-request-priority~1] - , , UPRIORITY_CS0 + , UPRIORITY_CS0 # // [utest->dsn~up-attributes-request-priority~1] - , , UPRIORITY_CS1 + , UPRIORITY_CS1 # // [utest->dsn~up-attributes-request-priority~1] - , , UPRIORITY_CS2 + , UPRIORITY_CS2 # // [utest->dsn~up-attributes-request-priority~1] - , , UPRIORITY_CS3 + , UPRIORITY_CS3 """) void testRequestMessageBuilderRejectsInvalidAttributes( - Integer permLevel, UCode commStatus, UPriority priority ) { var builder = UMessageBuilder.request(UURI_DEFAULT, UURI_METHOD, 5000); - if (permLevel != null) { - assertThrows( - IllegalArgumentException.class, - () -> builder.withPermissionLevel(permLevel) - ); - } else if (commStatus != null) { + if (commStatus != null) { assertThrows( IllegalStateException.class, () -> builder.withCommStatus(commStatus) @@ -183,25 +173,23 @@ void testRequestMessageBuilderRejectsInvalidAttributes( @ParameterizedTest @CsvSource(useHeadersInDisplayName = true, textBlock = """ - ttl, permLevel, token, priority + permLevel, token, priority # // [utest->dsn~up-attributes-permission-level~1] - -1, , , - , 5, , + 5, , # // [utest->dsn~up-attributes-request-token~1] - , , my-token, + , my-token, # // [utest->dsn~up-attributes-request-priority~1] - , , , UPRIORITY_UNSPECIFIED + , , UPRIORITY_UNSPECIFIED # // [utest->dsn~up-attributes-request-priority~1] - , , , UPRIORITY_CS0 + , , UPRIORITY_CS0 # // [utest->dsn~up-attributes-request-priority~1] - , , , UPRIORITY_CS1 + , , UPRIORITY_CS1 # // [utest->dsn~up-attributes-request-priority~1] - , , , UPRIORITY_CS2 + , , UPRIORITY_CS2 # // [utest->dsn~up-attributes-request-priority~1] - , , , UPRIORITY_CS3 + , , UPRIORITY_CS3 """) void testResponseMessageBuilderRejectsInvalidAttributes( - Integer ttl, Integer permLevel, String token, UPriority priority @@ -211,12 +199,7 @@ void testResponseMessageBuilderRejectsInvalidAttributes( UURI_DEFAULT, UuidFactory.create()); - if (ttl != null) { - assertThrows( - IllegalArgumentException.class, - () -> builder.withTtl(ttl) - ); - } else if (permLevel != null) { + if (permLevel != null) { assertThrows( IllegalStateException.class, () -> builder.withPermissionLevel(permLevel) @@ -312,7 +295,7 @@ void testBuildRetainsAllNotificationAttributes() { UMessage message = UMessageBuilder.notification(origin, destination) .withMessageId(messageId) .withPriority(UPriority.UPRIORITY_CS2) - .withTtl(5000) + .withTtl(0xFF00_FFFF) // test unsigned integer .withTraceparent(traceparent) .build(UPayload.pack(ByteString.copyFromUtf8("locked"), UPayloadFormat.UPAYLOAD_FORMAT_TEXT)); @@ -321,7 +304,7 @@ void testBuildRetainsAllNotificationAttributes() { assertEquals(UPriority.UPRIORITY_CS2, message.getAttributes().getPriority()); assertEquals(origin, message.getAttributes().getSource()); assertEquals(destination, message.getAttributes().getSink()); - assertEquals(5000, message.getAttributes().getTtl()); + assertEquals(0xFF00_FFFF, message.getAttributes().getTtl()); // [utest->dsn~up-attributes-traceparent~1] assertEquals(traceparent, message.getAttributes().getTraceparent()); // [utest->dsn~up-attributes-notification-type~1] @@ -349,7 +332,7 @@ void testBuildRetainsAllRequestAttributes() { var replyToAddress = UURI_DEFAULT; UMessage message = UMessageBuilder.request(replyToAddress, methodToInvoke, 5000) .withMessageId(messageId) - .withPermissionLevel(5) + .withPermissionLevel(0xFF00_FFFF) // test unsigned integer .withPriority(UPriority.UPRIORITY_CS4) .withToken(token) .withTraceparent(traceparent) @@ -358,7 +341,7 @@ void testBuildRetainsAllRequestAttributes() { // [utest->dsn~up-attributes-id~1] assertEquals(messageId, message.getAttributes().getId()); // [utest->dsn~up-attributes-permission-level~1] - assertEquals(5, message.getAttributes().getPermissionLevel()); + assertEquals(0xFF00_FFFF, message.getAttributes().getPermissionLevel()); assertEquals(UPriority.UPRIORITY_CS4, message.getAttributes().getPriority()); assertEquals(replyToAddress, message.getAttributes().getSource()); assertEquals(methodToInvoke, message.getAttributes().getSink()); diff --git a/src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java b/src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java index 24554e5..c2bbb14 100644 --- a/src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java +++ b/src/test/java/org/eclipse/uprotocol/transport/validator/UAttributesValidatorTest.java @@ -563,16 +563,6 @@ static Stream requestMessageArgProvider() { OptionalInt.of(0), OptionalInt.of(UPriority.UPRIORITY_CS4_VALUE), Optional.empty(), - false), - // fails for invalid (negative) permission level - Arguments.of( - Optional.of(UuidFactory.create()), - Optional.of(UURI_METHOD), - Optional.of(UURI_DEFAULT), - OptionalInt.of(-1), - OptionalInt.of(2000), - OptionalInt.of(UPriority.UPRIORITY_CS4_VALUE), - Optional.empty(), false) ); } @@ -629,7 +619,7 @@ static Stream responseMessageArgProvider() { Optional.of(UURI_METHOD), Optional.of(UuidFactory.create()), OptionalInt.empty(), - OptionalInt.empty(), + OptionalInt.of(100), Optional.of(UPriority.UPRIORITY_CS4), true), // succeeds for valid attributes @@ -661,7 +651,7 @@ static Stream responseMessageArgProvider() { Optional.of(UURI_METHOD), Optional.of(UuidFactory.create()), OptionalInt.empty(), - OptionalInt.empty(), + OptionalInt.of(100), Optional.of(UPriority.UPRIORITY_CS4), false), // fails for missing reply-to-address @@ -672,7 +662,7 @@ static Stream responseMessageArgProvider() { Optional.of(UURI_METHOD), Optional.of(UuidFactory.create()), OptionalInt.empty(), - OptionalInt.empty(), + OptionalInt.of(100), Optional.of(UPriority.UPRIORITY_CS4), false), // fails for invalid reply-to-address @@ -683,7 +673,7 @@ static Stream responseMessageArgProvider() { Optional.of(UURI_METHOD), Optional.of(UuidFactory.create()), OptionalInt.empty(), - OptionalInt.empty(), + OptionalInt.of(100), Optional.of(UPriority.UPRIORITY_CS4), false), // fails for reply-to-address with wildcard @@ -694,7 +684,7 @@ static Stream responseMessageArgProvider() { Optional.of(UURI_METHOD), Optional.of(UuidFactory.create()), OptionalInt.empty(), - OptionalInt.empty(), + OptionalInt.of(100), Optional.of(UPriority.UPRIORITY_CS4), false), // fails for missing invoked-method @@ -705,7 +695,7 @@ static Stream responseMessageArgProvider() { Optional.empty(), Optional.of(UuidFactory.create()), OptionalInt.empty(), - OptionalInt.empty(), + OptionalInt.of(100), Optional.of(UPriority.UPRIORITY_CS4), false), // fails for invalid invoked-method @@ -716,7 +706,7 @@ static Stream responseMessageArgProvider() { Optional.of(UURI_TOPIC), Optional.of(UuidFactory.create()), OptionalInt.empty(), - OptionalInt.empty(), + OptionalInt.of(100), Optional.of(UPriority.UPRIORITY_CS4), false), // fails for invoked-method with wildcard @@ -727,7 +717,7 @@ static Stream responseMessageArgProvider() { Optional.of(UURI_WILDCARD_RESOURCE), Optional.of(UuidFactory.create()), OptionalInt.empty(), - OptionalInt.empty(), + OptionalInt.of(100), Optional.of(UPriority.UPRIORITY_CS4), false), // fails for invalid commstatus @@ -737,20 +727,10 @@ static Stream responseMessageArgProvider() { Optional.of(UURI_METHOD), Optional.of(UuidFactory.create()), OptionalInt.of(-189), - OptionalInt.empty(), - Optional.of(UPriority.UPRIORITY_CS4), - false), - // succeeds for ttl > 0 - Arguments.of( - Optional.of(UuidFactory.create()), - Optional.of(UURI_DEFAULT), - Optional.of(UURI_METHOD), - Optional.of(UuidFactory.create()), - OptionalInt.empty(), OptionalInt.of(100), Optional.of(UPriority.UPRIORITY_CS4), - true), - // succeeds for ttl = 0 + false), + // fails for ttl = 0 Arguments.of( Optional.of(UuidFactory.create()), Optional.of(UURI_DEFAULT), @@ -759,7 +739,7 @@ static Stream responseMessageArgProvider() { OptionalInt.empty(), OptionalInt.of(0), Optional.of(UPriority.UPRIORITY_CS4), - true), + false), // fails for missing priority Arguments.of( Optional.of(UuidFactory.create()), diff --git a/src/test/java/org/eclipse/uprotocol/uuid/factory/UuidUtilsTest.java b/src/test/java/org/eclipse/uprotocol/uuid/factory/UuidUtilsTest.java index 82c2ce3..cd3f458 100644 --- a/src/test/java/org/eclipse/uprotocol/uuid/factory/UuidUtilsTest.java +++ b/src/test/java/org/eclipse/uprotocol/uuid/factory/UuidUtilsTest.java @@ -75,14 +75,14 @@ private static Stream provideCreationTimestamps() { @MethodSource("provideCreationTimestamps") void testGetTime(Instant timestamp) { final UUID uuid = UuidFactory.create(timestamp); - final var time = UuidUtils.getTime(uuid); + final var time = UuidUtils.getTimestamp(uuid); assertEquals(timestamp.toEpochMilli(), time); } @Test void testGetTimeRejectsInvalidArgs() { - assertThrows(NullPointerException.class, () -> UuidUtils.getTime(null)); - assertThrows(IllegalArgumentException.class, () -> UuidUtils.getTime(invalidUuid())); + assertThrows(NullPointerException.class, () -> UuidUtils.getTimestamp(null)); + assertThrows(IllegalArgumentException.class, () -> UuidUtils.getTimestamp(invalidUuid())); } private static Stream provideElapsedTimeTestCases() { @@ -123,15 +123,16 @@ private static Stream provideRemainingTimeTestCases() { Arguments.of(now.minusSeconds(60), 40_000, now, 0), Arguments.of(now.minusSeconds(60), 60_000, now, 0), Arguments.of(now.minusSeconds(60), 80_000, now, 20_000), - Arguments.of(now.plusSeconds(10), 70_000, now.plusSeconds(79), 1_000) + Arguments.of(now.plusSeconds(10), 70_000, now.plusSeconds(79), 1_000), + Arguments.of(now, 0xFFFF_FFFF, now.plusMillis(0x00FF_FFFF), 0xFF00_0000) ); } @ParameterizedTest(name = "Test getting remaining time for UUID {index} - {arguments}") @MethodSource("provideRemainingTimeTestCases") - void testGetRemainingTime(Instant creationTime, int ttl, Instant referenceTime, long expectedRemaining) { + void testGetRemainingTime(Instant creationTime, int ttl, Instant referenceTime, long expectedRemainingMillis) { final UUID id = UuidFactory.create(creationTime); - assertEquals(expectedRemaining, UuidUtils.getRemainingTime(id, ttl, referenceTime)); + assertEquals(expectedRemainingMillis, UuidUtils.getRemainingTime(id, ttl, referenceTime)); } @Test @@ -154,10 +155,6 @@ void testGetRemainingTimeRejectsInvalidArgs() { IllegalArgumentException.class, () -> UuidUtils.getRemainingTime(UuidFactory.create(), 0, Instant.now().plusSeconds(10)) ); - assertThrows( - IllegalArgumentException.class, - () -> UuidUtils.getRemainingTime(UuidFactory.create(), -1, Instant.now().plusSeconds(10)) - ); } private static Stream provideIsExpiredTestCases() { @@ -167,7 +164,9 @@ private static Stream provideIsExpiredTestCases() { Arguments.of(now.minusSeconds(60), 40_000, now, true), Arguments.of(now.minusSeconds(60), 60_000, now, true), Arguments.of(now.minusSeconds(60), 80_000, now, false), - Arguments.of(now.plusSeconds(10), 70_000, now.plusSeconds(79), false) + Arguments.of(now.plusSeconds(10), 70_000, now.plusSeconds(79), false), + Arguments.of(now, 0xFFFF_FF00, now.plusMillis(0xFFFF_FEFF), false), + Arguments.of(now, 0xFFFF_FF00, now.plusMillis(0xFFFF_FF00), true) ); } @@ -182,9 +181,5 @@ void testIsExpired(Instant creationTime, int ttl, Instant referenceTime, boolean void testIsExpiredRejectsInvalidArgs() { assertThrows(NullPointerException.class, () -> UuidUtils.isExpired(null, TTL, Instant.now())); assertThrows(IllegalArgumentException.class, () -> UuidUtils.isExpired(invalidUuid(), TTL, Instant.now())); - assertThrows( - IllegalArgumentException.class, - () -> UuidUtils.isExpired(UuidFactory.create(), -3, Instant.now()) - ); } } diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index f26aace..253a798 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -8,5 +8,5 @@ - +