Commit cb612094 authored by Björn Butzin's avatar Björn Butzin
Browse files

merged BasicResourceTest, InterfaceTest and PlugTest into a single file to...

merged BasicResourceTest, InterfaceTest and PlugTest into a single file to avoid race condition on IP address during parallel testing phase of maven
modified some ToDos
BasicCoapSocketHandler now uses CoAP constants for multicast Socket addresses instead of strings
parent 24dbc06f
......@@ -83,9 +83,9 @@
<url>http://www.ws4d.org/</url>
<name>Web Services for Devices</name>
</organization>
<url>https://gitlab.amd.e-technik.uni-rostock.de/bjoern.konieczek/jcoap-draft18</url>
<url>https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap</url>
<issueManagement>
<url>https://gitlab.amd.e-technik.uni-rostock.de/bjoern.konieczek/jcoap-draft18/issues</url>
<url>https://gitlab.amd.e-technik.uni-rostock.de/ws4d/jcoap/issues</url>
<system>GitLab</system>
</issueManagement>
</project>
\ No newline at end of file
......@@ -62,7 +62,7 @@ public class BasicCoapSocketHandler implements CoapSocketHandler {
private int localPort;
private WorkerThread workerThread = null;
// TODO can b removed MC receive thread can also handle unicast messages
// TODO can be removed MC receive thread can also handle unicast messages
private ReceiveThread receiveThread = null;
private ReceiveThread receiveMCThread = null;
private Map<ChannelKey, CoapClientChannel> clientChannels = new HashMap<ChannelKey, CoapClientChannel>();
......@@ -114,9 +114,9 @@ public class BasicCoapSocketHandler implements CoapSocketHandler {
this.dgramSocket.setSoTimeout(0);
this.dgramSocket.setReceiveBufferSize(CoapConstants.RECEIVE_BUFFER_SIZE);
this.dgramSocket.joinGroup(InetAddress.getByName("ff02::fd"));
this.dgramSocket.joinGroup(InetAddress.getByName("ff05::fd"));
this.dgramSocket.joinGroup(InetAddress.getByName("224.0.1.187"));
this.dgramSocket.joinGroup(InetAddress.getByName(CoapConstants.COAP_ALL_NODES_IPV6_LL_MC_ADDR));
this.dgramSocket.joinGroup(InetAddress.getByName(CoapConstants.COAP_ALL_NODES_IPV6_SL_MC_ADDR));
this.dgramSocket.joinGroup(InetAddress.getByName(CoapConstants.COAP_ALL_NODES_IPV4_MC_ADDR));
this.workerThread = new WorkerThread();
this.workerThread.start();
......@@ -710,7 +710,7 @@ public class BasicCoapSocketHandler implements CoapSocketHandler {
} catch (IOException e) {
logger.warn(e.getLocalizedMessage());
}
/* TODO: wake up thread and kill it */
/* TODO: wake up threads (receive & worker) and kill them */
}
@Override
......
......@@ -76,7 +76,7 @@ public class BasicCoapResource implements CoapResource {
for (String segment : segments) {
if (segment.getBytes().length > 255) {
IllegalArgumentException e = new IllegalArgumentException("Uri-Path too long");
logger.info("Uri-Path too long: " + initPath, e);
logger.warn("Uri-Path too long: " + initPath);
throw e;
}
}
......
......@@ -135,9 +135,11 @@ public class CoapResourceServer implements ResourceServer {
@Override
public void stop() {
this.resources.clear();
addResource(this.coreResource);
this.etags.clear();
this.coreResource.changed();
// FIXME causes java.nio.channels.ClosedChannelException when starting the server again
// FIXME causes NullPointerException when starting the server again
// at org.ws4d.coap.core.connection.BasicCoapChannelManager.createServerChannel(BasicCoapChannelManager.java:61)
// BasicCoapChannelManager.getInstance().removeServerListener(this, this.port);
}
......
/* Copyright 2015 University of Rostock
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*****************************************************************************/
package org.ws4d.coap.core.test;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.ws4d.coap.core.enumerations.CoapMediaType;
import org.ws4d.coap.core.rest.BasicCoapResource;
import org.ws4d.coap.core.rest.CoapResourceServer;
import org.ws4d.coap.core.rest.api.CoapResource;
/**
* @author Bjrn Butzin <bjoern.butzin[at]uni-rostock.de>
*/
public class BasicResourceTest {
private static CoapResourceServer resourceServer;
/*
* ########################################################################
* General Test preparations
* ########################################################################
*/
@BeforeClass
public static void setUpClass() {
// set up server
if (resourceServer != null) {
resourceServer.stop();
}
resourceServer = new CoapResourceServer();
}
@AfterClass
public static void tearDownClass() {
// tear down server
if (resourceServer != null) {
resourceServer.stop();
resourceServer = null;
}
}
@Before
public void setUp() {
try {
resourceServer.start();
} catch (Exception e) {
System.err.println(e.getLocalizedMessage());
System.exit(-1);
}
}
@After
public void tearDown() {
resourceServer.stop();
}
/*
* ########################################################################
* Tests
*
* @Test
* @Test(expected= IndexOutOfBoundsException.class)
* @Test(timeout=1000) - fails after 1000 milliseconds
* org.junit.Assert.* - compare result & expectation
*
* ########################################################################
*/
@Test
public void thisAlwaysPasses() {
// validate test fixtures
}
/*
* test percentage encoding Path separator: (U+002F SOLIDUS "/") First
* Argument led by: (U+003F QUESTION MARK "?") Argument separator: (U+0026
* AMPERSAND "&") An empty path component is equivalent to an absolute path
* of "/" The scheme and host are case insensitive and normally provided in
* lowercase
*
* For example, the following three URIs are equivalent and cause the same
* options and option values to appear in the CoAP messages:
* coap://example.com:5683/~sensors/temp.xml
* coap://EXAMPLE.com/%7Esensors/temp.xml
* coap://EXAMPLE.com:/%7esensors/temp.xml
*/
/*
* ########################################################################
* invalid resources
* ########################################################################
*/
@Test(expected = Exception.class)
public void invalidNameTooLongResource() {
String resourcename = "";
for (int i = 0; i < 256; i++) {
resourcename += 'a';
}
CoapResource res = new BasicCoapResource("/" + resourcename, "", CoapMediaType.text_plain);
resourceServer.createResource(res);
}
@Test(expected = IllegalArgumentException.class)
public void invalidPathTooLongResource() {
String resourcename = "";
for (int i = 0; i < 256; i++) {
resourcename += 'a';
}
CoapResource res = new BasicCoapResource("/1/2/3/4/5/6/7/8/9/0/1/2/3/4/5/6/7/8/9/" + resourcename, "",
CoapMediaType.text_plain);
resourceServer.createResource(res);
}
/*
* ########################################################################
* valid resources
* ########################################################################
*/
@Test
public void validPathShortestResources() {
// An empty path component is equivalent to an absolute path of "/"
CoapResource res = new BasicCoapResource("/test", "", CoapMediaType.text_plain);
resourceServer.createResource(res);
}
@Test
public void validPathRootResources() {
// An empty path component is equivalent to an absolute path of "/"
CoapResource res = new BasicCoapResource("", "", CoapMediaType.text_plain);
resourceServer.createResource(res);
}
@Test
public void validNameLongestResources() {
String resourcename = "";
for (int i = 0; i < 255; i++) {
resourcename += 'a';
}
CoapResource res = new BasicCoapResource("/" + resourcename, "", CoapMediaType.text_plain);
resourceServer.createResource(res);
}
@Test
public void validPathLongestResources() {
CoapResource res = new BasicCoapResource("/1/2/3/4/5", "", CoapMediaType.text_plain);
resourceServer.createResource(res);
}
}
\ No newline at end of file
/* Copyright 2015 University of Rostock
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*****************************************************************************/
package org.ws4d.coap.core.test;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.ws4d.coap.core.CoapClient;
import org.ws4d.coap.core.CoapConstants;
import org.ws4d.coap.core.connection.BasicCoapChannelManager;
import org.ws4d.coap.core.connection.api.CoapClientChannel;
import org.ws4d.coap.core.enumerations.CoapMediaType;
import org.ws4d.coap.core.enumerations.CoapRequestCode;
import org.ws4d.coap.core.messages.api.CoapRequest;
import org.ws4d.coap.core.messages.api.CoapResponse;
import org.ws4d.coap.core.rest.BasicCoapResource;
import org.ws4d.coap.core.rest.CoapResourceServer;
import org.ws4d.coap.core.tools.Encoder;
/**
* @author Bjrn Butzin <bjoern.butzin[at]uni-rostock.de>
*/
public class InterfaceTest {
private static CoapResourceServer resourceServer = null;
private static CoapClientChannel clientChannel = null;
private static ClientDummy client = null;
static CoapResponse receivedResponse = null;
/*
* ########################################################################
* General Test preparations
* ########################################################################
*/
@BeforeClass
public static void setUpClass() {
// empty
}
@AfterClass
public static void tearDownClass() {
// tear down server
if (resourceServer != null) {
resourceServer.stop();
resourceServer = null;
}
if (clientChannel != null) {
clientChannel.close();
clientChannel = null;
}
}
@Before
public void setUp() {
// set up client
receivedResponse = null;
if (null == client) {
client = new ClientDummy();
}
if (null == clientChannel) {
try {
clientChannel = BasicCoapChannelManager.getInstance().connect(client,
InetAddress.getByName("127.0.0.1"), CoapConstants.COAP_DEFAULT_PORT);
} catch (UnknownHostException e) {
System.err.println(e.getLocalizedMessage());
System.exit(-1);
}
}
// set up server
if (resourceServer == null) {
resourceServer = new CoapResourceServer();
try {
resourceServer.start();
} catch (Exception e) {
System.err.println(e.getLocalizedMessage());
System.exit(-1);
}
}
}
@After
public void tearDown() {
// empty
}
/*
* ########################################################################
* Tests
*
* @Test
*
* @Test(expected= IndexOutOfBoundsException.class)
*
* @Test(timeout=1000) - fails after 1000 milliseconds org.junit.Assert.* -
* compare result & expectation
*
* ########################################################################
*
* (/.well-known/core) full query query filter rt - single multiple if -
* single multiple href - single multiple combinations encoding + % GET
* without eTag with eTag matching non matching POST PUT If-Match
* If-Non-Match DELETE
*/
@Test
public void wellKnownFull() throws InterruptedException {
resourceServer.createResource(new BasicCoapResource("/resource1", "content1", CoapMediaType.text_plain)
.setResourceType("resource1Type").setInterfaceDescription("resource1Description"));
CoapRequest request = clientChannel.createRequest(true, CoapRequestCode.GET);
request.setUriPath("/.well-known/core");
clientChannel.sendMessage(request);
while (null == receivedResponse)
Thread.sleep(10);
Assert.assertEquals("</.well-known/core>,</resource1>;rt=\"resource1Type\";if=\"resource1Description\"",
Encoder.ByteToString(receivedResponse.getPayload()));
}
@Test
public void wellKnownRT() throws InterruptedException {
resourceServer.createResource(new BasicCoapResource("/resource1", "content1", CoapMediaType.text_plain)
.setResourceType("resource1Type").setInterfaceDescription("resource1Description"));
resourceServer.createResource(new BasicCoapResource("/resource2", "content2", CoapMediaType.text_plain)
.setResourceType("resource2Type").setInterfaceDescription("resource2Description"));
CoapRequest request = clientChannel.createRequest(true, CoapRequestCode.GET);
request.setUriPath("/.well-known/core");
request.setUriQuery("rt=resource1Type");
clientChannel.sendMessage(request);
while (null == receivedResponse)
Thread.sleep(10);
Assert.assertEquals("</resource1>;rt=\"resource1Type\";if=\"resource1Description\"",
Encoder.ByteToString(receivedResponse.getPayload()));
}
/*
* ########################################################################
* Client Dummy Class
* ########################################################################
*/
private class ClientDummy implements CoapClient {
public ClientDummy() {
// This is intended to be empty
}
public void onMCResponse(CoapClientChannel channel, CoapResponse response, InetAddress srcAddress,
int srcPort) {
// This is intended to be empty
}
public void onConnectionFailed(CoapClientChannel channel, boolean notReachable, boolean resetByServer) {
// This is intended to be empty
}
public void onResponse(CoapClientChannel channel, CoapResponse response) {
receivedResponse = response;
}
}
}
\ No newline at end of file
......@@ -282,8 +282,103 @@ public class PlugTest {
// /.well-known/core
@Test
public void wellKnownFull() throws InterruptedException {
resourceServer.createResource(new BasicCoapResource("/resource1", "content1", CoapMediaType.text_plain)
.setResourceType("resource1Type")
.setInterfaceDescription("resource1Description"));
CoapRequest request = clientChannel.createRequest(true, CoapRequestCode.GET);
request.setUriPath("/.well-known/core");
clientChannel.sendMessage(request);
while (null == receivedResponse)Thread.sleep(10);
Assert.assertEquals("</.well-known/core>,</resource1>;rt=\"resource1Type\";if=\"resource1Description\"",
Encoder.ByteToString(receivedResponse.getPayload()));
}
@Test
public void wellKnownRT() throws InterruptedException {
resourceServer.createResource(new BasicCoapResource("/resource1", "content1", CoapMediaType.text_plain)
.setResourceType("resource1Type")
.setInterfaceDescription("resource1Description"));
resourceServer.createResource(new BasicCoapResource("/resource2", "content2", CoapMediaType.text_plain)
.setResourceType("resource2Type")
.setInterfaceDescription("resource2Description"));
CoapRequest request = clientChannel.createRequest(true, CoapRequestCode.GET);
request.setUriPath("/.well-known/core");
request.setUriQuery("rt=resource1Type");
clientChannel.sendMessage(request);
while (null == receivedResponse)Thread.sleep(10);
Assert.assertEquals("</resource1>;rt=\"resource1Type\";if=\"resource1Description\"",
Encoder.ByteToString(receivedResponse.getPayload()));
}
// URI-query
// Path length
@Test(expected = Exception.class)
public void invalidNameTooLongResource() {
String resourcename = "";
for (int i = 0; i < 256; i++) {
resourcename += 'a';
}
CoapResource res = new BasicCoapResource("/" + resourcename, "", CoapMediaType.text_plain);
resourceServer.createResource(res);
}
@Test(expected = IllegalArgumentException.class)
public void invalidPathTooLongResource() {
String resourcename = "";
for (int i = 0; i < 256; i++) {
resourcename += 'a';
}
CoapResource res = new BasicCoapResource("/1/2/3/4/5/6/7/8/9/0/1/2/3/4/5/6/7/8/9/" + resourcename, "",
CoapMediaType.text_plain);
resourceServer.createResource(res);
}
/*
* ########################################################################
* valid resources
* ########################################################################
*/
@Test
public void validPathShortestResources() {
// An empty path component is equivalent to an absolute path of "/"
CoapResource res = new BasicCoapResource("/test", "", CoapMediaType.text_plain);
resourceServer.createResource(res);
}
@Test
public void validPathRootResources() {
// An empty path component is equivalent to an absolute path of "/"
CoapResource res = new BasicCoapResource("", "", CoapMediaType.text_plain);
resourceServer.createResource(res);
}
@Test
public void validNameLongestResources() {
String resourcename = "";
for (int i = 0; i < 255; i++) {
resourcename += 'a';
}
CoapResource res = new BasicCoapResource("/" + resourcename, "", CoapMediaType.text_plain);
resourceServer.createResource(res);
}
@Test
public void validPathLongestResources() {
CoapResource res = new BasicCoapResource("/1/2/3/4/5", "", CoapMediaType.text_plain);
resourceServer.createResource(res);
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment