Skip to content

Commit

Permalink
Test Server CoAP endpoint based on java-coap in integration tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
sbernard31 committed Oct 19, 2023
1 parent 624ad25 commit 7322032
Show file tree
Hide file tree
Showing 30 changed files with 184 additions and 92 deletions.
4 changes: 4 additions & 0 deletions leshan-integration-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Contributors:
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-server-cf</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-tl-javacoap-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-server-redis</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public class DeleteTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ public class DiscoverTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ public class ExecuteTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ public class QueueModeTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,9 @@
package org.eclipse.leshan.integration.tests;

import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.leshan.core.ResponseCode.CONTENT;
import static org.eclipse.leshan.integration.tests.util.LeshanTestClientBuilder.givenClientUsing;
import static org.eclipse.leshan.integration.tests.util.assertion.Assertions.assertArg;
import static org.eclipse.leshan.integration.tests.util.assertion.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import static org.junit.jupiter.params.provider.Arguments.arguments;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
Expand All @@ -41,7 +38,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

Expand All @@ -56,16 +52,10 @@
import org.eclipse.californium.elements.config.UdpConfig;
import org.eclipse.leshan.core.endpoint.Protocol;
import org.eclipse.leshan.core.link.LinkParseException;
import org.eclipse.leshan.core.node.LwM2mPath;
import org.eclipse.leshan.core.observation.Observation;
import org.eclipse.leshan.core.observation.SingleObservation;
import org.eclipse.leshan.core.request.ContentFormat;
import org.eclipse.leshan.core.request.ObserveRequest;
import org.eclipse.leshan.core.request.ReadRequest;
import org.eclipse.leshan.core.request.exception.RequestCanceledException;
import org.eclipse.leshan.core.request.exception.SendFailedException;
import org.eclipse.leshan.core.response.ErrorCallback;
import org.eclipse.leshan.core.response.ObserveResponse;
import org.eclipse.leshan.core.response.ReadResponse;
import org.eclipse.leshan.core.response.ResponseCallback;
import org.eclipse.leshan.integration.tests.util.LeshanTestClient;
Expand Down Expand Up @@ -98,7 +88,8 @@ public class RegistrationTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down Expand Up @@ -278,54 +269,6 @@ public void register_update_reregister(Protocol protocol, String clientEndpointP
assertThat(client).isRegisteredAt(server);
}

@TestAllTransportLayer
public void register_observe_deregister_observe(Protocol protocol, String clientEndpointProvider,
String serverEndpointProvider) throws NonUniqueSecurityInfoException, InterruptedException {
// TODO java-coap does not raise expected SendFailedException at the end of this tests
// But not sure what should be the right behavior.
// Waiting for https://github.com/open-coap/java-coap/issues/36 before to move forward on this.
assumeTrue(serverEndpointProvider.equals("Californium"));

// Check client is not registered
client = givenClient.build();
assertThat(client).isNotRegisteredAt(server);

// Start it and wait for registration
client.start();
server.waitForNewRegistrationOf(client);
client.waitForRegistrationTo(server);

// Check client is well registered
assertThat(client).isRegisteredAt(server);
Registration registration = server.getRegistrationFor(client);

// observe device timezone
ObserveResponse observeResponse = server.send(registration, new ObserveRequest(3, 0));
assertThat(observeResponse) //
.hasCode(CONTENT) //
.hasValidUnderlyingResponseFor(serverEndpointProvider);

// check observation registry is not null
Set<Observation> observations = server.getObservationService().getObservations(registration);
assertThat(observations) //
.hasSize(1) //
.first().isInstanceOfSatisfying(SingleObservation.class, obs -> {
assertThat(obs.getRegistrationId()).isEqualTo(registration.getId());
assertThat(obs.getPath()).isEqualTo(new LwM2mPath(3, 0));
});

// Check de-registration
client.stop(true);
server.waitForDeregistrationOf(registration, observations);
assertThat(client).isNotRegisteredAt(server);
client.waitForDeregistrationTo(server);
observations = server.getObservationService().getObservations(registration);
assertThat(observations).isEmpty();

// try to send a new observation
assertThrowsExactly(SendFailedException.class, () -> server.send(registration, new ObserveRequest(3, 0), 50));
}

@TestAllTransportLayer
public void register_with_additional_attributes(Protocol protocol, String clientEndpointProvider,
String serverEndpointProvider) throws InterruptedException, LinkParseException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ public class CreateFailedTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ static Stream<Arguments> transports() {

Object[][] transports = new Object[][] {
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
{ Protocol.COAP, "Californium", "Californium" } };
{ Protocol.COAP, "Californium", "Californium" }, //
{ Protocol.COAP, "Californium", "java-coap" } };

Object[] contentFormats = new Object[] { //
ContentFormat.TLV, //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.EnumSet;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
Expand All @@ -46,26 +51,37 @@
import org.eclipse.leshan.core.endpoint.Protocol;
import org.eclipse.leshan.core.link.LinkParser;
import org.eclipse.leshan.core.link.lwm2m.DefaultLwM2mLinkParser;
import org.eclipse.leshan.core.observation.Observation;
import org.eclipse.leshan.core.request.BindingMode;
import org.eclipse.leshan.core.request.ContentFormat;
import org.eclipse.leshan.core.request.DeregisterRequest;
import org.eclipse.leshan.core.request.ObserveRequest;
import org.eclipse.leshan.core.request.ReadRequest;
import org.eclipse.leshan.core.request.RegisterRequest;
import org.eclipse.leshan.core.request.UpdateRequest;
import org.eclipse.leshan.core.request.exception.SendFailedException;
import org.eclipse.leshan.core.request.exception.TimeoutException;
import org.eclipse.leshan.core.response.ErrorCallback;
import org.eclipse.leshan.core.response.ObserveResponse;
import org.eclipse.leshan.core.response.ReadResponse;
import org.eclipse.leshan.core.response.ResponseCallback;
import org.eclipse.leshan.integration.tests.util.LeshanTestServer;
import org.eclipse.leshan.integration.tests.util.LeshanTestServerBuilder;
import org.eclipse.leshan.integration.tests.util.junit5.extensions.BeforeEachParameterizedResolver;
import org.eclipse.leshan.server.californium.endpoint.ServerProtocolProvider;
import org.eclipse.leshan.server.californium.endpoint.coap.CoapServerProtocolProvider;
import org.eclipse.leshan.server.endpoint.LwM2mServerEndpointsProvider;
import org.eclipse.leshan.server.registration.Registration;
import org.eclipse.leshan.transport.javacoap.server.endpoint.JavaCoapServerEndpointsProvider;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

import com.mbed.coap.server.CoapServerBuilder;
import com.mbed.coap.transmission.RetransmissionBackOff;

@ExtendWith(BeforeEachParameterizedResolver.class)
public class LockStepTest {
public static final LinkParser linkParser = new DefaultLwM2mLinkParser();
Expand All @@ -82,7 +98,8 @@ public class LockStepTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// Server Endpoint Provider
arguments("Californium"));
arguments("Californium"), //
arguments("java-coap"));
}

/*---------------------------------/
Expand All @@ -97,14 +114,28 @@ protected ServerProtocolProvider getCaliforniumProtocolProvider(Protocol protoco
public void applyDefaultValue(Configuration configuration) {
super.applyDefaultValue(configuration);
// configure retransmission, with this configuration a request without ACK should timeout in
// ~200*5ms
// ~200*5ms = 1s
configuration.set(CoapConfig.ACK_TIMEOUT, 200, TimeUnit.MILLISECONDS) //
.set(CoapConfig.ACK_INIT_RANDOM, 1f) //
.set(CoapConfig.ACK_TIMEOUT_SCALE, 1f) //
.set(CoapConfig.MAX_RETRANSMIT, 4);
}
};
}

@Override
protected LwM2mServerEndpointsProvider getJavaCoapProtocolProvider(Protocol protocol) {
return new JavaCoapServerEndpointsProvider(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)) {
@Override
protected CoapServerBuilder createCoapServer() {
return super.createCoapServer()
// configure retransmission, with this configuration a request without ACK should
// timeout in
// 140 + 2*140 + 4*140 = ~1s
.retransmission(RetransmissionBackOff.ofExponential(Duration.ofMillis(140), 2, 1));
}
};
}
};
}

Expand Down Expand Up @@ -329,4 +360,50 @@ public void async_send_with_acknowleged_request_without_response(String givenSer
}));
verify(responseCallback, never()).onResponse(any());
}

@TestAllTransportLayer
public void register_deregister_observe(String givenServerEndpointProvider) throws Exception {
// register client
LockStepLwM2mClient client = new LockStepLwM2mClient(server.getEndpoint(Protocol.COAP).getURI());
Token token = client
.sendLwM2mRequest(new RegisterRequest(client.getEndpointName(), 60l, "1.1", EnumSet.of(BindingMode.U),
null, null, linkParser.parseCoreLinkFormat("</1>,</2>,</3>".getBytes()), null));
client.expectResponse().token(token).go();
server.waitForNewRegistrationOf(client.getEndpointName());
Registration registration = server.getRegistrationService().getByEndpoint(client.getEndpointName());

// deregister client
token = client.sendLwM2mRequest(new DeregisterRequest("rd/" + registration.getId()));
client.expectResponse().token(token).go();
server.waitForDeregistrationOf(registration);

// send read
@SuppressWarnings("unchecked")
ResponseCallback<ObserveResponse> responseCallback = mock(ResponseCallback.class);
ErrorCallback errorCallback = mock(ErrorCallback.class);

server.send(registration, new ObserveRequest(ContentFormat.TEXT_CODE, 3, 0), 500l, responseCallback,
errorCallback);

if (givenServerEndpointProvider.equals("Californium")) {
// with californium endpoint provider "SendFailedException" is raised because,
// we try to add the relation in store before to send the request and registration doesn't exist anymorev
verify(errorCallback, timeout(200).times(1)) //
.onError(assertArg(e -> {
assertThat(e).isInstanceOf(SendFailedException.class);
}));
} else {
// with java-coap it failed transparently at response reception.
// TODO I don't know if this is the right behavior.
client.expectRequest().storeMID("R").storeToken("T").go();
client.sendResponse(Type.ACK, ResponseCode.CONTENT).payload("aaa").observe(2).loadMID("R").loadToken("T")
.go();
}

// ensure we don't get answer and there is no observation in store.
verifyNoMoreInteractions(responseCallback, errorCallback);
assertThat(server.getRegistrationService().getAllRegistrations().hasNext() == false);
Set<Observation> observations = server.getObservationService().getObservations(registration);
assertThat(observations).isEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ public class DynamicIPObserveTest {
static Stream<Arguments> noTlsTransports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"),
arguments(Protocol.COAP, "Californium", "java-coap"));
}

@ParameterizedTest(name = "{0} - Client using {1} - Server using {2}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ public class ObserveCompositeTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ public class ObserveServerOnlyTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// Server Endpoint Provider
arguments("Californium"));
arguments("Californium"), //
arguments("java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ public class ObserveTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ static Stream<Arguments> transports() {

Object[][] transports = new Object[][] {
// Server Endpoint Provider
{ "Californium" } };
{ "Californium" }, //
{ "java-coap" } };

Object[] contentFormats = new Object[] { //
ContentFormat.JSON, //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ public class ReadCompositeTest {

static Stream<Arguments> transports() {

Object[][] transports = new Object[][]
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
{ { Protocol.COAP, "Californium", "Californium" } };
Object[][] transports = new Object[][] {
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
{ Protocol.COAP, "Californium", "Californium" }, //
{ Protocol.COAP, "Californium", "java-coap" } };

Object[][] contentFormats = new Object[][] { //
// {request content format, response content format}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ public class ReadFailedTest {
static Stream<org.junit.jupiter.params.provider.Arguments> transports() {
return Stream.of(//
// ProtocolUsed - Client Endpoint Provider - Server Endpoint Provider
arguments(Protocol.COAP, "Californium", "Californium"));
arguments(Protocol.COAP, "Californium", "Californium"), //
arguments(Protocol.COAP, "Californium", "java-coap"));
}

/*---------------------------------/
Expand Down
Loading

0 comments on commit 7322032

Please sign in to comment.