Browse Source

Fixing Mqtt Integration tests

pull/263/head
mp-loki 9 years ago
parent
commit
8a37560b98
  1. 121
      application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java
  2. 4
      application/src/test/java/org/thingsboard/server/mqtt/MqttNoSqlTestSuite.java
  3. 37
      application/src/test/java/org/thingsboard/server/mqtt/MqttSqlTestSuite.java
  4. 40
      application/src/test/java/org/thingsboard/server/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java
  5. 26
      application/src/test/java/org/thingsboard/server/mqtt/rpc/nosql/MqttServerSideRpcNoSqlIntegrationTest.java
  6. 27
      application/src/test/java/org/thingsboard/server/mqtt/rpc/sql/MqttServerSideRpcSqlIntegrationTest.java
  7. 23
      application/src/test/java/org/thingsboard/server/mqtt/telemetry/AbstractMqttTelemetryIntegrationTest.java
  8. 26
      application/src/test/java/org/thingsboard/server/mqtt/telemetry/nosql/MqttTelemetryNoSqlIntegrationTest.java
  9. 27
      application/src/test/java/org/thingsboard/server/mqtt/telemetry/sql/MqttTelemetrySqlIntegrationTest.java

121
application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java

@ -41,6 +41,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.mock.http.MockHttpInputMessage; import org.springframework.mock.http.MockHttpInputMessage;
import org.springframework.mock.http.MockHttpOutputMessage; import org.springframework.mock.http.MockHttpOutputMessage;
@ -51,6 +52,7 @@ import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher; import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
@ -97,28 +99,31 @@ public abstract class AbstractControllerTest {
protected static final String SYS_ADMIN_EMAIL = "sysadmin@thingsboard.org"; protected static final String SYS_ADMIN_EMAIL = "sysadmin@thingsboard.org";
private static final String SYS_ADMIN_PASSWORD = "sysadmin"; private static final String SYS_ADMIN_PASSWORD = "sysadmin";
protected static final String TENANT_ADMIN_EMAIL = "testtenant@thingsboard.org"; protected static final String TENANT_ADMIN_EMAIL = "testtenant@thingsboard.org";
private static final String TENANT_ADMIN_PASSWORD = "tenant"; private static final String TENANT_ADMIN_PASSWORD = "tenant";
protected static final String CUSTOMER_USER_EMAIL = "testcustomer@thingsboard.org"; protected static final String CUSTOMER_USER_EMAIL = "testcustomer@thingsboard.org";
private static final String CUSTOMER_USER_PASSWORD = "customer"; private static final String CUSTOMER_USER_PASSWORD = "customer";
protected MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), protected MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
MediaType.APPLICATION_JSON.getSubtype(), MediaType.APPLICATION_JSON.getSubtype(),
Charset.forName("utf8")); Charset.forName("utf8"));
protected MockMvc mockMvc; protected MockMvc mockMvc;
protected String token; protected String token;
protected String refreshToken; protected String refreshToken;
protected String username; protected String username;
private TenantId tenantId; private TenantId tenantId;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private HttpMessageConverter mappingJackson2HttpMessageConverter; private HttpMessageConverter mappingJackson2HttpMessageConverter;
@SuppressWarnings("rawtypes")
private HttpMessageConverter stringHttpMessageConverter;
@Autowired @Autowired
private WebApplicationContext webApplicationContext; private WebApplicationContext webApplicationContext;
@ -132,7 +137,7 @@ public abstract class AbstractControllerTest {
log.info("Finished test: {}", description.getMethodName()); log.info("Finished test: {}", description.getMethodName());
} }
}; };
@Autowired @Autowired
void setConverters(HttpMessageConverter<?>[] converters) { void setConverters(HttpMessageConverter<?>[] converters) {
@ -141,10 +146,15 @@ public abstract class AbstractControllerTest {
.findAny() .findAny()
.get(); .get();
this.stringHttpMessageConverter = Arrays.stream(converters)
.filter(hmc -> hmc instanceof StringHttpMessageConverter)
.findAny()
.get();
Assert.assertNotNull("the JSON message converter must not be null", Assert.assertNotNull("the JSON message converter must not be null",
this.mappingJackson2HttpMessageConverter); this.mappingJackson2HttpMessageConverter);
} }
@Before @Before
public void setup() throws Exception { public void setup() throws Exception {
log.info("Executing setup"); log.info("Executing setup");
@ -188,7 +198,7 @@ public abstract class AbstractControllerTest {
public void teardown() throws Exception { public void teardown() throws Exception {
log.info("Executing teardown"); log.info("Executing teardown");
loginSysAdmin(); loginSysAdmin();
doDelete("/api/tenant/"+tenantId.getId().toString()) doDelete("/api/tenant/" + tenantId.getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
log.info("Executed teardown"); log.info("Executed teardown");
} }
@ -196,7 +206,7 @@ public abstract class AbstractControllerTest {
protected void loginSysAdmin() throws Exception { protected void loginSysAdmin() throws Exception {
login(SYS_ADMIN_EMAIL, SYS_ADMIN_PASSWORD); login(SYS_ADMIN_EMAIL, SYS_ADMIN_PASSWORD);
} }
protected void loginTenantAdmin() throws Exception { protected void loginTenantAdmin() throws Exception {
login(TENANT_ADMIN_EMAIL, TENANT_ADMIN_PASSWORD); login(TENANT_ADMIN_EMAIL, TENANT_ADMIN_PASSWORD);
} }
@ -204,13 +214,13 @@ public abstract class AbstractControllerTest {
protected void loginCustomerUser() throws Exception { protected void loginCustomerUser() throws Exception {
login(CUSTOMER_USER_EMAIL, CUSTOMER_USER_PASSWORD); login(CUSTOMER_USER_EMAIL, CUSTOMER_USER_PASSWORD);
} }
protected User createUserAndLogin(User user, String password) throws Exception { protected User createUserAndLogin(User user, String password) throws Exception {
User savedUser = doPost("/api/user", user, User.class); User savedUser = doPost("/api/user", user, User.class);
logout(); logout();
doGet("/api/noauth/activate?activateToken={activateToken}", TestMailService.currentActivateToken) doGet("/api/noauth/activate?activateToken={activateToken}", TestMailService.currentActivateToken)
.andExpect(status().isSeeOther()) .andExpect(status().isSeeOther())
.andExpect(header().string(HttpHeaders.LOCATION, "/login/createPassword?activateToken=" + TestMailService.currentActivateToken)); .andExpect(header().string(HttpHeaders.LOCATION, "/login/createPassword?activateToken=" + TestMailService.currentActivateToken));
JsonNode tokenInfo = readResponse(doPost("/api/noauth/activate", "activateToken", TestMailService.currentActivateToken, "password", password).andExpect(status().isOk()), JsonNode.class); JsonNode tokenInfo = readResponse(doPost("/api/noauth/activate", "activateToken", TestMailService.currentActivateToken, "password", password).andExpect(status().isOk()), JsonNode.class);
validateAndSetJwtToken(tokenInfo, user.getEmail()); validateAndSetJwtToken(tokenInfo, user.getEmail());
return savedUser; return savedUser;
@ -247,14 +257,14 @@ public abstract class AbstractControllerTest {
Assert.assertNotNull(token); Assert.assertNotNull(token);
Assert.assertFalse(token.isEmpty()); Assert.assertFalse(token.isEmpty());
int i = token.lastIndexOf('.'); int i = token.lastIndexOf('.');
Assert.assertTrue(i>0); Assert.assertTrue(i > 0);
String withoutSignature = token.substring(0, i+1); String withoutSignature = token.substring(0, i + 1);
Jwt<Header,Claims> jwsClaims = Jwts.parser().parseClaimsJwt(withoutSignature); Jwt<Header, Claims> jwsClaims = Jwts.parser().parseClaimsJwt(withoutSignature);
Claims claims = jwsClaims.getBody(); Claims claims = jwsClaims.getBody();
String subject = claims.getSubject(); String subject = claims.getSubject();
Assert.assertEquals(username, subject); Assert.assertEquals(username, subject);
} }
protected void logout() throws Exception { protected void logout() throws Exception {
this.token = null; this.token = null;
this.refreshToken = null; this.refreshToken = null;
@ -266,24 +276,35 @@ public abstract class AbstractControllerTest {
request.header(ThingsboardSecurityConfiguration.JWT_TOKEN_HEADER_PARAM, "Bearer " + this.token); request.header(ThingsboardSecurityConfiguration.JWT_TOKEN_HEADER_PARAM, "Bearer " + this.token);
} }
} }
protected ResultActions doGet(String urlTemplate, Object... urlVariables) throws Exception { protected ResultActions doGet(String urlTemplate, Object... urlVariables) throws Exception {
MockHttpServletRequestBuilder getRequest = get(urlTemplate, urlVariables); MockHttpServletRequestBuilder getRequest = get(urlTemplate, urlVariables);
setJwtToken(getRequest); setJwtToken(getRequest);
return mockMvc.perform(getRequest); return mockMvc.perform(getRequest);
} }
protected <T> T doGet(String urlTemplate, Class<T> responseClass, Object... urlVariables) throws Exception { protected <T> T doGet(String urlTemplate, Class<T> responseClass, Object... urlVariables) throws Exception {
return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseClass); return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseClass);
} }
protected <T> T doGetAsync(String urlTemplate, Class<T> responseClass, Object... urlVariables) throws Exception {
return readResponse(doGetAsync(urlTemplate, urlVariables).andExpect(status().isOk()), responseClass);
}
protected ResultActions doGetAsync(String urlTemplate, Object... urlVariables) throws Exception {
MockHttpServletRequestBuilder getRequest;
getRequest = get(urlTemplate, urlVariables);
setJwtToken(getRequest);
return mockMvc.perform(asyncDispatch(mockMvc.perform(getRequest).andExpect(request().asyncStarted()).andReturn()));
}
protected <T> T doGetTyped(String urlTemplate, TypeReference<T> responseType, Object... urlVariables) throws Exception { protected <T> T doGetTyped(String urlTemplate, TypeReference<T> responseType, Object... urlVariables) throws Exception {
return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseType); return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseType);
} }
protected <T> T doGetTypedWithPageLink(String urlTemplate, TypeReference<T> responseType, protected <T> T doGetTypedWithPageLink(String urlTemplate, TypeReference<T> responseType,
TextPageLink pageLink, TextPageLink pageLink,
Object... urlVariables) throws Exception { Object... urlVariables) throws Exception {
List<Object> pageLinkVariables = new ArrayList<>(); List<Object> pageLinkVariables = new ArrayList<>();
urlTemplate += "limit={limit}"; urlTemplate += "limit={limit}";
pageLinkVariables.add(pageLink.getLimit()); pageLinkVariables.add(pageLink.getLimit());
@ -299,75 +320,93 @@ public abstract class AbstractControllerTest {
urlTemplate += "&textOffset={textOffset}"; urlTemplate += "&textOffset={textOffset}";
pageLinkVariables.add(pageLink.getTextOffset()); pageLinkVariables.add(pageLink.getTextOffset());
} }
Object[] vars = new Object[urlVariables.length + pageLinkVariables.size()]; Object[] vars = new Object[urlVariables.length + pageLinkVariables.size()];
System.arraycopy(urlVariables, 0, vars, 0, urlVariables.length); System.arraycopy(urlVariables, 0, vars, 0, urlVariables.length);
System.arraycopy(pageLinkVariables.toArray(), 0, vars, urlVariables.length, pageLinkVariables.size()); System.arraycopy(pageLinkVariables.toArray(), 0, vars, urlVariables.length, pageLinkVariables.size());
return readResponse(doGet(urlTemplate, vars).andExpect(status().isOk()), responseType); return readResponse(doGet(urlTemplate, vars).andExpect(status().isOk()), responseType);
} }
protected <T> T doPost(String urlTemplate, Class<T> responseClass, String... params) throws Exception { protected <T> T doPost(String urlTemplate, Class<T> responseClass, String... params) throws Exception {
return readResponse(doPost(urlTemplate, params).andExpect(status().isOk()), responseClass); return readResponse(doPost(urlTemplate, params).andExpect(status().isOk()), responseClass);
} }
protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception {
return readResponse(doPost(urlTemplate, params).andExpect(resultMatcher), responseClass);
}
protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, String... params) throws Exception { protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, String... params) throws Exception {
return readResponse(doPost(urlTemplate, content, params).andExpect(status().isOk()), responseClass); return readResponse(doPost(urlTemplate, content, params).andExpect(status().isOk()), responseClass);
} }
protected <T> T doPostAsync(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception {
return readResponse(doPostAsync(urlTemplate, content, params).andExpect(resultMatcher), responseClass);
}
protected <T> T doDelete(String urlTemplate, Class<T> responseClass, String... params) throws Exception { protected <T> T doDelete(String urlTemplate, Class<T> responseClass, String... params) throws Exception {
return readResponse(doDelete(urlTemplate, params).andExpect(status().isOk()), responseClass); return readResponse(doDelete(urlTemplate, params).andExpect(status().isOk()), responseClass);
} }
protected ResultActions doPost(String urlTemplate, String... params) throws Exception { protected ResultActions doPost(String urlTemplate, String... params) throws Exception {
MockHttpServletRequestBuilder postRequest = post(urlTemplate); MockHttpServletRequestBuilder postRequest = post(urlTemplate);
setJwtToken(postRequest); setJwtToken(postRequest);
populateParams(postRequest, params); populateParams(postRequest, params);
return mockMvc.perform(postRequest); return mockMvc.perform(postRequest);
} }
protected <T> ResultActions doPost(String urlTemplate, T content, String... params) throws Exception { protected <T> ResultActions doPost(String urlTemplate, T content, String... params) throws Exception {
MockHttpServletRequestBuilder postRequest = post(urlTemplate); MockHttpServletRequestBuilder postRequest = post(urlTemplate);
setJwtToken(postRequest); setJwtToken(postRequest);
String json = json(content); String json = json(content);
postRequest.contentType(contentType).content(json); postRequest.contentType(contentType).content(json);
populateParams(postRequest, params);
return mockMvc.perform(postRequest); return mockMvc.perform(postRequest);
} }
protected <T> ResultActions doPostAsync(String urlTemplate, T content, String... params) throws Exception {
MockHttpServletRequestBuilder postRequest = post(urlTemplate);
setJwtToken(postRequest);
String json = json(content);
postRequest.contentType(contentType).content(json);
MvcResult result = mockMvc.perform(postRequest).andReturn();
return mockMvc.perform(asyncDispatch(result));
}
protected ResultActions doDelete(String urlTemplate, String... params) throws Exception { protected ResultActions doDelete(String urlTemplate, String... params) throws Exception {
MockHttpServletRequestBuilder deleteRequest = delete(urlTemplate); MockHttpServletRequestBuilder deleteRequest = delete(urlTemplate);
setJwtToken(deleteRequest); setJwtToken(deleteRequest);
populateParams(deleteRequest, params); populateParams(deleteRequest, params);
return mockMvc.perform(deleteRequest); return mockMvc.perform(deleteRequest);
} }
protected void populateParams(MockHttpServletRequestBuilder request, String... params) { protected void populateParams(MockHttpServletRequestBuilder request, String... params) {
if (params != null && params.length > 0) { if (params != null && params.length > 0) {
Assert.assertEquals(params.length % 2, 0); Assert.assertEquals(params.length % 2, 0);
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<String, String>(); MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<String, String>();
for (int i=0;i<params.length;i+=2) { for (int i = 0; i < params.length; i += 2) {
paramsMap.add(params[i], params[i+1]); paramsMap.add(params[i], params[i + 1]);
} }
request.params(paramsMap); request.params(paramsMap);
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected String json(Object o) throws IOException { protected String json(Object o) throws IOException {
MockHttpOutputMessage mockHttpOutputMessage = new MockHttpOutputMessage(); MockHttpOutputMessage mockHttpOutputMessage = new MockHttpOutputMessage();
this.mappingJackson2HttpMessageConverter.write(
o, MediaType.APPLICATION_JSON, mockHttpOutputMessage); HttpMessageConverter converter = o instanceof String ? stringHttpMessageConverter : mappingJackson2HttpMessageConverter;
converter.write(o, MediaType.APPLICATION_JSON, mockHttpOutputMessage);
return mockHttpOutputMessage.getBodyAsString(); return mockHttpOutputMessage.getBodyAsString();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <T> T readResponse(ResultActions result, Class<T> responseClass) throws Exception { protected <T> T readResponse(ResultActions result, Class<T> responseClass) throws Exception {
byte[] content = result.andReturn().getResponse().getContentAsByteArray(); byte[] content = result.andReturn().getResponse().getContentAsByteArray();
MockHttpInputMessage mockHttpInputMessage = new MockHttpInputMessage(content); MockHttpInputMessage mockHttpInputMessage = new MockHttpInputMessage(content);
return (T) this.mappingJackson2HttpMessageConverter.read(responseClass, mockHttpInputMessage); HttpMessageConverter converter = responseClass.equals(String.class) ? stringHttpMessageConverter : mappingJackson2HttpMessageConverter;
return (T) converter.read(responseClass, mockHttpInputMessage);
} }
protected <T> T readResponse(ResultActions result, TypeReference<T> type) throws Exception { protected <T> T readResponse(ResultActions result, TypeReference<T> type) throws Exception {
byte[] content = result.andReturn().getResponse().getContentAsByteArray(); byte[] content = result.andReturn().getResponse().getContentAsByteArray();
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();

4
application/src/test/java/org/thingsboard/server/mqtt/MqttTestSuite.java → application/src/test/java/org/thingsboard/server/mqtt/MqttNoSqlTestSuite.java

@ -25,8 +25,8 @@ import java.util.Arrays;
@RunWith(ClasspathSuite.class) @RunWith(ClasspathSuite.class)
@ClasspathSuite.ClassnameFilters({ @ClasspathSuite.ClassnameFilters({
"org.thingsboard.server.mqtt.*.*Test"}) "org.thingsboard.server.mqtt.*.nosql.*Test"})
public class MqttTestSuite { public class MqttNoSqlTestSuite {
@ClassRule @ClassRule
public static CustomCassandraCQLUnit cassandraUnit = public static CustomCassandraCQLUnit cassandraUnit =

37
application/src/test/java/org/thingsboard/server/mqtt/MqttSqlTestSuite.java

@ -0,0 +1,37 @@
/**
* Copyright © 2016-2017 The Thingsboard Authors
*
* 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.thingsboard.server.mqtt;
import org.cassandraunit.dataset.cql.ClassPathCQLDataSet;
import org.junit.ClassRule;
import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.runner.RunWith;
import org.thingsboard.server.dao.CustomCassandraCQLUnit;
import org.thingsboard.server.dao.CustomSqlUnit;
import java.util.Arrays;
@RunWith(ClasspathSuite.class)
@ClasspathSuite.ClassnameFilters({
"org.thingsboard.server.mqtt.rpc.sql.*Test", "org.thingsboard.server.mqtt.telemetry.sql.*Test"})
public class MqttSqlTestSuite {
@ClassRule
public static CustomSqlUnit sqlUnit = new CustomSqlUnit(
Arrays.asList("sql/schema.sql", "sql/system-data.sql"),
"sql/drop-all-tables.sql",
"sql-test.properties");
}

40
application/src/test/java/org/thingsboard/server/mqtt/rpc/MqttServerSideRpcIntegrationTest.java → application/src/test/java/org/thingsboard/server/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java

@ -16,6 +16,7 @@
package org.thingsboard.server.mqtt.rpc; package org.thingsboard.server.mqtt.rpc;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.*; import org.eclipse.paho.client.mqttv3.*;
import org.junit.*; import org.junit.*;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
@ -26,6 +27,7 @@ import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.controller.AbstractControllerTest; import org.thingsboard.server.controller.AbstractControllerTest;
import org.thingsboard.server.dao.service.DaoNoSqlTest;
import java.util.UUID; import java.util.UUID;
@ -37,7 +39,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Valerii Sosliuk * @author Valerii Sosliuk
*/ */
@Slf4j @Slf4j
public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractControllerTest {
private static final String MQTT_URL = "tcp://localhost:1883"; private static final String MQTT_URL = "tcp://localhost:1883";
private static final String FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED = "HttpClientErrorException expected, but not encountered"; private static final String FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED = "HttpClientErrorException expected, but not encountered";
@ -67,13 +69,13 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest {
@After @After
public void afterTest() throws Exception { public void afterTest() throws Exception {
loginSysAdmin(); loginSysAdmin();
if (savedTenant != null) {
doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) doDelete("/api/tenant/" + savedTenant.getId().getId().toString())
.andExpect(status().isOk()); .andExpect(status().isOk());
}
} }
@Test @Test
@Ignore
public void testServerMqttOneWayRpc() throws Exception { public void testServerMqttOneWayRpc() throws Exception {
Device device = new Device(); Device device = new Device();
device.setName("Test One-Way Server-Side RPC"); device.setName("Test One-Way Server-Side RPC");
@ -95,12 +97,12 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest {
String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}";
String deviceId = savedDevice.getId().getId().toString(); String deviceId = savedDevice.getId().getId().toString();
String result = doPost("api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class); String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk());
Assert.assertNull(result); Assert.assertTrue(StringUtils.isEmpty(result));
} }
@Test @Test
@Ignore @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 408 but was: 200
public void testServerMqttOneWayRpcDeviceOffline() throws Exception { public void testServerMqttOneWayRpcDeviceOffline() throws Exception {
Device device = new Device(); Device device = new Device();
device.setName("Test One-Way Server-Side RPC Device Offline"); device.setName("Test One-Way Server-Side RPC Device Offline");
@ -114,7 +116,7 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest {
String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}";
String deviceId = savedDevice.getId().getId().toString(); String deviceId = savedDevice.getId().getId().toString();
try { try {
doPost("api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class); doPost("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(408));
Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED);
} catch (HttpClientErrorException e) { } catch (HttpClientErrorException e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
@ -124,12 +126,12 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest {
} }
@Test @Test
@Ignore @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 400 (404?) but was: 401
public void testServerMqttOneWayRpcDeviceDoesNotExist() throws Exception { public void testServerMqttOneWayRpcDeviceDoesNotExist() throws Exception {
String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}";
String nonExistentDeviceId = UUID.randomUUID().toString(); String nonExistentDeviceId = UUID.randomUUID().toString();
try { try {
doPost("api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class); doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, status().is(400));
Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED);
} catch (HttpClientErrorException e) { } catch (HttpClientErrorException e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
@ -139,7 +141,6 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest {
} }
@Test @Test
@Ignore
public void testServerMqttTwoWayRpc() throws Exception { public void testServerMqttTwoWayRpc() throws Exception {
Device device = new Device(); Device device = new Device();
device.setName("Test Two-Way Server-Side RPC"); device.setName("Test Two-Way Server-Side RPC");
@ -161,12 +162,13 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest {
String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}";
String deviceId = savedDevice.getId().getId().toString(); String deviceId = savedDevice.getId().getId().toString();
String result = getStringResult(setGpioRequest, "twoway", deviceId);
String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk());
Assert.assertEquals("{\"value1\":\"A\",\"value2\":\"B\"}", result); Assert.assertEquals("{\"value1\":\"A\",\"value2\":\"B\"}", result);
} }
@Test @Test
@Ignore @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 408 but was: 200
public void testServerMqttTwoWayRpcDeviceOffline() throws Exception { public void testServerMqttTwoWayRpcDeviceOffline() throws Exception {
Device device = new Device(); Device device = new Device();
device.setName("Test Two-Way Server-Side RPC Device Offline"); device.setName("Test Two-Way Server-Side RPC Device Offline");
@ -180,7 +182,7 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest {
String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}";
String deviceId = savedDevice.getId().getId().toString(); String deviceId = savedDevice.getId().getId().toString();
try { try {
doPost("api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class); doPost("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(408));
Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED);
} catch (HttpClientErrorException e) { } catch (HttpClientErrorException e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
@ -190,12 +192,12 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest {
} }
@Test @Test
@Ignore @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 400 (404?) but was: 401
public void testServerMqttTwoWayRpcDeviceDoesNotExist() throws Exception { public void testServerMqttTwoWayRpcDeviceDoesNotExist() throws Exception {
String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}";
String nonExistentDeviceId = UUID.randomUUID().toString(); String nonExistentDeviceId = UUID.randomUUID().toString();
try { try {
doPost("api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class); doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, status().is(400));
Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED);
} catch (HttpClientErrorException e) { } catch (HttpClientErrorException e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
@ -212,10 +214,6 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest {
return doGet("/api/device/" + savedDevice.getId().getId().toString() + "/credentials", DeviceCredentials.class); return doGet("/api/device/" + savedDevice.getId().getId().toString() + "/credentials", DeviceCredentials.class);
} }
private String getStringResult(String requestData, String callType, String deviceId) throws Exception {
return doPost("api/plugins/rpc/" + callType + "/" + deviceId, requestData, String.class);
}
private static class TestMqttCallback implements MqttCallback { private static class TestMqttCallback implements MqttCallback {
private final MqttAsyncClient client; private final MqttAsyncClient client;

26
application/src/test/java/org/thingsboard/server/mqtt/rpc/nosql/MqttServerSideRpcNoSqlIntegrationTest.java

@ -0,0 +1,26 @@
/**
* Copyright © 2016-2017 The Thingsboard Authors
*
* 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.thingsboard.server.mqtt.rpc.nosql;
import org.thingsboard.server.dao.service.DaoNoSqlTest;
import org.thingsboard.server.mqtt.rpc.AbstractMqttServerSideRpcIntegrationTest;
/**
* Created by Valerii Sosliuk on 8/22/2017.
*/
@DaoNoSqlTest
public class MqttServerSideRpcNoSqlIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest {
}

27
application/src/test/java/org/thingsboard/server/mqtt/rpc/sql/MqttServerSideRpcSqlIntegrationTest.java

@ -0,0 +1,27 @@
/**
* Copyright © 2016-2017 The Thingsboard Authors
*
* 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.thingsboard.server.mqtt.rpc.sql;
import org.thingsboard.server.dao.service.DaoNoSqlTest;
import org.thingsboard.server.dao.service.DaoSqlTest;
import org.thingsboard.server.mqtt.rpc.AbstractMqttServerSideRpcIntegrationTest;
/**
* Created by Valerii Sosliuk on 8/22/2017.
*/
@DaoSqlTest
public class MqttServerSideRpcSqlIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest {
}

23
application/src/test/java/org/thingsboard/server/mqtt/telemetry/MqttTelemetryIntegrationTest.java → application/src/test/java/org/thingsboard/server/mqtt/telemetry/AbstractMqttTelemetryIntegrationTest.java

@ -26,11 +26,10 @@ import org.springframework.web.util.UriComponentsBuilder;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.controller.AbstractControllerTest; import org.thingsboard.server.controller.AbstractControllerTest;
import org.thingsboard.server.dao.service.DaoNoSqlTest;
import java.net.URI; import java.net.URI;
import java.util.Arrays; import java.util.*;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -39,7 +38,7 @@ import static org.junit.Assert.assertNotNull;
* @author Valerii Sosliuk * @author Valerii Sosliuk
*/ */
@Slf4j @Slf4j
public class MqttTelemetryIntegrationTest extends AbstractControllerTest { public abstract class AbstractMqttTelemetryIntegrationTest extends AbstractControllerTest {
private static final String MQTT_URL = "tcp://localhost:1883"; private static final String MQTT_URL = "tcp://localhost:1883";
@ -64,7 +63,6 @@ public class MqttTelemetryIntegrationTest extends AbstractControllerTest {
} }
@Test @Test
@Ignore
public void testPushMqttRpcData() throws Exception { public void testPushMqttRpcData() throws Exception {
String clientId = MqttAsyncClient.generateClientId(); String clientId = MqttAsyncClient.generateClientId();
MqttAsyncClient client = new MqttAsyncClient(MQTT_URL, clientId); MqttAsyncClient client = new MqttAsyncClient(MQTT_URL, clientId);
@ -80,13 +78,16 @@ public class MqttTelemetryIntegrationTest extends AbstractControllerTest {
String deviceId = savedDevice.getId().getId().toString(); String deviceId = savedDevice.getId().getId().toString();
Thread.sleep(1000); Thread.sleep(1000);
Object keys = doGet("/api/plugins/telemetry/" + deviceId + "/keys/timeseries", Object.class); List<String> actualKeys = doGetAsync("/api/plugins/telemetry/DEVICE/" + deviceId + "/keys/timeseries", List.class);
assertEquals(Arrays.asList("key1", "key2", "key3", "key4"), keys); Set<String> actualKeySet = new HashSet<>(actualKeys);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("/api/plugins/telemetry/" + deviceId + "/values/timeseries") List<String> expectedKeys = Arrays.asList("key1", "key2", "key3", "key4");
.queryParam("keys", String.join(",", (CharSequence[]) keys)); Set<String> expectedKeySet = new HashSet<>(expectedKeys);
URI uri = builder.build().encode().toUri();
Map<String, List<Map<String, String>>> values = doGet(uri.getPath(), Map.class); assertEquals(expectedKeySet, actualKeySet);
String getTelemetryValuesUrl = "/api/plugins/telemetry/DEVICE/" + deviceId + "/values/timeseries?keys=" + String.join(",", actualKeySet);
Map<String, List<Map<String, String>>> values = doGetAsync(getTelemetryValuesUrl, Map.class);
assertEquals("value1", values.get("key1").get(0).get("value")); assertEquals("value1", values.get("key1").get(0).get("value"));
assertEquals("true", values.get("key2").get(0).get("value")); assertEquals("true", values.get("key2").get(0).get("value"));

26
application/src/test/java/org/thingsboard/server/mqtt/telemetry/nosql/MqttTelemetryNoSqlIntegrationTest.java

@ -0,0 +1,26 @@
/**
* Copyright © 2016-2017 The Thingsboard Authors
*
* 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.thingsboard.server.mqtt.telemetry.nosql;
import org.thingsboard.server.dao.service.DaoNoSqlTest;
import org.thingsboard.server.mqtt.telemetry.AbstractMqttTelemetryIntegrationTest;
/**
* Created by Valerii Sosliuk on 8/22/2017.
*/
@DaoNoSqlTest
public class MqttTelemetryNoSqlIntegrationTest extends AbstractMqttTelemetryIntegrationTest {
}

27
application/src/test/java/org/thingsboard/server/mqtt/telemetry/sql/MqttTelemetrySqlIntegrationTest.java

@ -0,0 +1,27 @@
/**
* Copyright © 2016-2017 The Thingsboard Authors
*
* 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.thingsboard.server.mqtt.telemetry.sql;
import org.thingsboard.server.dao.service.DaoNoSqlTest;
import org.thingsboard.server.dao.service.DaoSqlTest;
import org.thingsboard.server.mqtt.telemetry.AbstractMqttTelemetryIntegrationTest;
/**
* Created by Valerii Sosliuk on 8/22/2017.
*/
@DaoSqlTest
public class MqttTelemetrySqlIntegrationTest extends AbstractMqttTelemetryIntegrationTest {
}
Loading…
Cancel
Save