Skip to content

Commit

Permalink
Try to TestFactory to parameterize tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sbernard31 committed Feb 21, 2023
1 parent fdb400e commit 509def6
Show file tree
Hide file tree
Showing 3 changed files with 308 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*******************************************************************************
* Copyright (c) 2023 Sierra Wireless and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.html.
*
* Contributors:
* Sierra Wireless - initial API and implementation
*******************************************************************************/
package org.eclipse.leshan.integration.tests;

import org.eclipse.leshan.core.endpoint.Protocol;
import org.eclipse.leshan.integration.tests.util.LeshanTestServerBuilder;
import org.eclipse.leshan.server.redis.RedisRegistrationStore;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.util.Pool;

public abstract class RedisRegistrationTest4 extends RegistrationTest3 {

public RedisRegistrationTest4(Protocol protocol, String serverProvider, String clientProvider) {
super(protocol, serverProvider, clientProvider);
}

public static class CoAPCaliforniumCalifornium extends RedisRegistrationTest4 {
public CoAPCaliforniumCalifornium() {
super(Protocol.COAP, "Californium", "Californium");
}
}

public static class CoAPCaliforniumJavaCoap extends RedisRegistrationTest4 {
public CoAPCaliforniumJavaCoap() {
super(Protocol.COAP, "Californium", "java-coap");
}
}

@Override
protected LeshanTestServerBuilder givenServerUsing(Protocol givenProtocol) {
LeshanTestServerBuilder builder = super.givenServerUsing(givenProtocol);

// Create redis store
Pool<Jedis> jedis = createJedisPool();
builder.setRegistrationStore(new RedisRegistrationStore(jedis));

return builder;
}

private Pool<Jedis> createJedisPool() {
String redisURI = System.getenv("REDIS_URI");
if (redisURI != null && !redisURI.isEmpty()) {
return new JedisPool(redisURI);
} else {
return new JedisPool();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*******************************************************************************
* Copyright (c) 2013-2015 Sierra Wireless and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.html.
*
* Contributors:
* Zebra Technologies - initial API and implementation
* Achim Kraus (Bosch Software Innovations GmbH) - replace close() with destroy()
* Michał Wadowski (Orange) - Improved compliance with rfc6690
*******************************************************************************/

package org.eclipse.leshan.integration.tests;

import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.leshan.integration.tests.util.IntegrationTestHelper.LIFETIME;
import static org.eclipse.leshan.integration.tests.util.IntegrationTestHelper.linkParser;
import static org.eclipse.leshan.integration.tests.util.LeshanTestClientBuilder.givenClientUsing;
import static org.eclipse.leshan.integration.tests.util.assertion.Assertions.assertThat;
import static org.junit.jupiter.params.provider.Arguments.arguments;

import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

import org.eclipse.leshan.core.endpoint.Protocol;
import org.eclipse.leshan.core.link.LinkParseException;
import org.eclipse.leshan.integration.tests.util.LeshanTestClient;
import org.eclipse.leshan.integration.tests.util.LeshanTestClientBuilder;
import org.eclipse.leshan.integration.tests.util.LeshanTestServer;
import org.eclipse.leshan.integration.tests.util.LeshanTestServerBuilder;
import org.eclipse.leshan.integration.tests.util.junit5.TestingUtils;
import org.eclipse.leshan.server.registration.Registration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DynamicNode;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;

public class RegistrationTest4 {

/*---------------------------------/
* Parameterized Tests
* -------------------------------*/
@TestFactory
Stream<DynamicNode> testRegistrations() throws Exception {
return TestingUtils.parameterizedClassTester("protocol={0} clientProvider={1}, ServerProvider={1}",
InnerRegistrationTest4.class, transports());
}

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", "java-coap") //
);
}

/*---------------------------------/
* Set-up and Tear-down Tests
* -------------------------------*/
public static class InnerRegistrationTest4 {
private final Protocol givenProtocol;
private final String givenServerEndpointProvider;
private final String givenClientEndpointProvider;

public InnerRegistrationTest4(Protocol protocol, String clientProvider, String serverProvider) {
this.givenProtocol = protocol;
this.givenClientEndpointProvider = clientProvider;
this.givenServerEndpointProvider = serverProvider;
}

LeshanTestServer server;
LeshanTestClientBuilder givenClient;
LeshanTestClient client;

@BeforeEach
public void start() {
server = givenServerUsing(givenProtocol).with(givenServerEndpointProvider).build();
server.start();
givenClient = givenClientUsing(givenProtocol).with(givenClientEndpointProvider).connectingTo(server);
}

@AfterEach
public void stop() throws InterruptedException {
if (client != null)
client.destroy(false);
if (server != null)
server.destroy();
}

protected LeshanTestServerBuilder givenServerUsing(Protocol givenProtocol) {
return new LeshanTestServerBuilder(givenProtocol);
}

@Test
public void register_update_deregister() throws LinkParseException {

// 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);
assertThat(registration.getObjectLinks()) //
.isEqualTo(linkParser.parseCoreLinkFormat(
"</>;rt=\"oma.lwm2m\";ct=\"60 110 112 1542 1543 11542 11543\",</1>;ver=1.1,</1/0>,</2>,</3>;ver=1.1,</3/0>,</3442/0>"
.getBytes()));

// Check for update
client.waitForUpdateTo(server, LIFETIME, TimeUnit.SECONDS);
server.waitForUpdateOf(registration);
assertThat(client).isRegisteredAt(server);

// Check deregistration
client.stop(true);
server.waitForDeregistrationOf(registration);
assertThat(client).isNotRegisteredAt(server);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*******************************************************************************
* Copyright (c) 2023 Sierra Wireless and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.html.
*
* Contributors:
*******************************************************************************/

package org.eclipse.leshan.integration.tests.util.junit5;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DynamicContainer;
import org.junit.jupiter.api.DynamicNode;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.engine.discovery.predicates.IsTestMethod;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.platform.commons.util.AnnotationUtils;
import org.junit.platform.commons.util.ReflectionUtils;

public class TestingUtils {

private TestingUtils() {
}

private static interface TestInvoker {

void invoke(Method testMethod) throws Exception;

}

public static Stream<DynamicNode> parameterizedClassTester(String displayName, Class<?> clazz,
Stream<Arguments> streamOfArguments) {

final List<Method> testMethods = ReflectionUtils.findMethods(clazz, new IsTestMethod());
if (testMethods.isEmpty()) {
throw new IllegalStateException(clazz.getName() + " has no supported @Test methods");
}

List<Constructor<?>> candidateConstructors = Arrays.stream(clazz.getDeclaredConstructors())
.filter(ctor -> ctor.getParameterCount() != 0).collect(Collectors.toList());
if (candidateConstructors.size() != 1) {
if (candidateConstructors.isEmpty()) {
throw new IllegalStateException(clazz.getName() + " has no candiate constructors");
}
throw new IllegalStateException(clazz.getName() + " has more than one candiate constructors");
}

final MessageFormat displayNameFormatter = new MessageFormat(displayName);

final Constructor<?> constructor = candidateConstructors.get(0);
constructor.setAccessible(true);

final List<Method> beforeEachMethods = AnnotationUtils.findAnnotatedMethods(clazz, BeforeEach.class,
ReflectionUtils.HierarchyTraversalMode.TOP_DOWN);

final List<Method> afterEachMethods = AnnotationUtils.findAnnotatedMethods(clazz, AfterEach.class,
ReflectionUtils.HierarchyTraversalMode.BOTTOM_UP);

for (List<Method> methods : Arrays.asList(testMethods, beforeEachMethods, afterEachMethods)) {
for (Method method : methods) {
method.setAccessible(true);
}
}

return streamOfArguments.map(arguments -> {
final Object[] arrayOfArguments = arguments.get();

final TestInvoker testInvoker = new TestInvoker() {
private Object instance;

@Override
public void invoke(Method testMethod) throws Exception {
if (instance == null) {
instance = constructor.newInstance(arrayOfArguments);
}

try {
for (Method method : beforeEachMethods) {
method.invoke(instance);
}

testMethod.invoke(instance);

} finally {
for (Method method : afterEachMethods) {
method.invoke(instance);
}
}
}
};

return DynamicContainer.dynamicContainer(displayNameFormatter.format(arrayOfArguments), testMethods.stream()
.map(method -> DynamicTest.dynamicTest(method.getName() + "()", () -> testInvoker.invoke(method))));
});
}

}

0 comments on commit 509def6

Please sign in to comment.