Showing
9 changed files
with
256 additions
and
75 deletions
... | ... | @@ -41,6 +41,7 @@ import org.springframework.context.annotation.Configuration; |
41 | 41 | import org.springframework.http.HttpHeaders; |
42 | 42 | import org.springframework.http.MediaType; |
43 | 43 | import org.springframework.http.converter.HttpMessageConverter; |
44 | +import org.springframework.http.converter.StringHttpMessageConverter; | |
44 | 45 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; |
45 | 46 | import org.springframework.mock.http.MockHttpInputMessage; |
46 | 47 | import org.springframework.mock.http.MockHttpOutputMessage; |
... | ... | @@ -51,6 +52,7 @@ import org.springframework.test.context.TestPropertySource; |
51 | 52 | import org.springframework.test.context.junit4.SpringRunner; |
52 | 53 | import org.springframework.test.context.web.WebAppConfiguration; |
53 | 54 | import org.springframework.test.web.servlet.MockMvc; |
55 | +import org.springframework.test.web.servlet.MvcResult; | |
54 | 56 | import org.springframework.test.web.servlet.ResultActions; |
55 | 57 | import org.springframework.test.web.servlet.ResultMatcher; |
56 | 58 | import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; |
... | ... | @@ -97,28 +99,31 @@ public abstract class AbstractControllerTest { |
97 | 99 | |
98 | 100 | protected static final String SYS_ADMIN_EMAIL = "sysadmin@thingsboard.org"; |
99 | 101 | private static final String SYS_ADMIN_PASSWORD = "sysadmin"; |
100 | - | |
102 | + | |
101 | 103 | protected static final String TENANT_ADMIN_EMAIL = "testtenant@thingsboard.org"; |
102 | 104 | private static final String TENANT_ADMIN_PASSWORD = "tenant"; |
103 | 105 | |
104 | 106 | protected static final String CUSTOMER_USER_EMAIL = "testcustomer@thingsboard.org"; |
105 | 107 | private static final String CUSTOMER_USER_PASSWORD = "customer"; |
106 | - | |
108 | + | |
107 | 109 | protected MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), |
108 | 110 | MediaType.APPLICATION_JSON.getSubtype(), |
109 | 111 | Charset.forName("utf8")); |
110 | 112 | |
111 | 113 | protected MockMvc mockMvc; |
112 | - | |
114 | + | |
113 | 115 | protected String token; |
114 | 116 | protected String refreshToken; |
115 | 117 | protected String username; |
116 | 118 | |
117 | 119 | private TenantId tenantId; |
118 | - | |
120 | + | |
119 | 121 | @SuppressWarnings("rawtypes") |
120 | 122 | private HttpMessageConverter mappingJackson2HttpMessageConverter; |
121 | - | |
123 | + | |
124 | + @SuppressWarnings("rawtypes") | |
125 | + private HttpMessageConverter stringHttpMessageConverter; | |
126 | + | |
122 | 127 | @Autowired |
123 | 128 | private WebApplicationContext webApplicationContext; |
124 | 129 | |
... | ... | @@ -132,7 +137,7 @@ public abstract class AbstractControllerTest { |
132 | 137 | log.info("Finished test: {}", description.getMethodName()); |
133 | 138 | } |
134 | 139 | }; |
135 | - | |
140 | + | |
136 | 141 | @Autowired |
137 | 142 | void setConverters(HttpMessageConverter<?>[] converters) { |
138 | 143 | |
... | ... | @@ -141,10 +146,15 @@ public abstract class AbstractControllerTest { |
141 | 146 | .findAny() |
142 | 147 | .get(); |
143 | 148 | |
149 | + this.stringHttpMessageConverter = Arrays.stream(converters) | |
150 | + .filter(hmc -> hmc instanceof StringHttpMessageConverter) | |
151 | + .findAny() | |
152 | + .get(); | |
153 | + | |
144 | 154 | Assert.assertNotNull("the JSON message converter must not be null", |
145 | 155 | this.mappingJackson2HttpMessageConverter); |
146 | 156 | } |
147 | - | |
157 | + | |
148 | 158 | @Before |
149 | 159 | public void setup() throws Exception { |
150 | 160 | log.info("Executing setup"); |
... | ... | @@ -188,7 +198,7 @@ public abstract class AbstractControllerTest { |
188 | 198 | public void teardown() throws Exception { |
189 | 199 | log.info("Executing teardown"); |
190 | 200 | loginSysAdmin(); |
191 | - doDelete("/api/tenant/"+tenantId.getId().toString()) | |
201 | + doDelete("/api/tenant/" + tenantId.getId().toString()) | |
192 | 202 | .andExpect(status().isOk()); |
193 | 203 | log.info("Executed teardown"); |
194 | 204 | } |
... | ... | @@ -196,7 +206,7 @@ public abstract class AbstractControllerTest { |
196 | 206 | protected void loginSysAdmin() throws Exception { |
197 | 207 | login(SYS_ADMIN_EMAIL, SYS_ADMIN_PASSWORD); |
198 | 208 | } |
199 | - | |
209 | + | |
200 | 210 | protected void loginTenantAdmin() throws Exception { |
201 | 211 | login(TENANT_ADMIN_EMAIL, TENANT_ADMIN_PASSWORD); |
202 | 212 | } |
... | ... | @@ -204,13 +214,13 @@ public abstract class AbstractControllerTest { |
204 | 214 | protected void loginCustomerUser() throws Exception { |
205 | 215 | login(CUSTOMER_USER_EMAIL, CUSTOMER_USER_PASSWORD); |
206 | 216 | } |
207 | - | |
217 | + | |
208 | 218 | protected User createUserAndLogin(User user, String password) throws Exception { |
209 | 219 | User savedUser = doPost("/api/user", user, User.class); |
210 | 220 | logout(); |
211 | 221 | doGet("/api/noauth/activate?activateToken={activateToken}", TestMailService.currentActivateToken) |
212 | - .andExpect(status().isSeeOther()) | |
213 | - .andExpect(header().string(HttpHeaders.LOCATION, "/login/createPassword?activateToken=" + TestMailService.currentActivateToken)); | |
222 | + .andExpect(status().isSeeOther()) | |
223 | + .andExpect(header().string(HttpHeaders.LOCATION, "/login/createPassword?activateToken=" + TestMailService.currentActivateToken)); | |
214 | 224 | JsonNode tokenInfo = readResponse(doPost("/api/noauth/activate", "activateToken", TestMailService.currentActivateToken, "password", password).andExpect(status().isOk()), JsonNode.class); |
215 | 225 | validateAndSetJwtToken(tokenInfo, user.getEmail()); |
216 | 226 | return savedUser; |
... | ... | @@ -247,14 +257,14 @@ public abstract class AbstractControllerTest { |
247 | 257 | Assert.assertNotNull(token); |
248 | 258 | Assert.assertFalse(token.isEmpty()); |
249 | 259 | int i = token.lastIndexOf('.'); |
250 | - Assert.assertTrue(i>0); | |
251 | - String withoutSignature = token.substring(0, i+1); | |
252 | - Jwt<Header,Claims> jwsClaims = Jwts.parser().parseClaimsJwt(withoutSignature); | |
260 | + Assert.assertTrue(i > 0); | |
261 | + String withoutSignature = token.substring(0, i + 1); | |
262 | + Jwt<Header, Claims> jwsClaims = Jwts.parser().parseClaimsJwt(withoutSignature); | |
253 | 263 | Claims claims = jwsClaims.getBody(); |
254 | 264 | String subject = claims.getSubject(); |
255 | 265 | Assert.assertEquals(username, subject); |
256 | 266 | } |
257 | - | |
267 | + | |
258 | 268 | protected void logout() throws Exception { |
259 | 269 | this.token = null; |
260 | 270 | this.refreshToken = null; |
... | ... | @@ -266,24 +276,35 @@ public abstract class AbstractControllerTest { |
266 | 276 | request.header(ThingsboardSecurityConfiguration.JWT_TOKEN_HEADER_PARAM, "Bearer " + this.token); |
267 | 277 | } |
268 | 278 | } |
269 | - | |
279 | + | |
270 | 280 | protected ResultActions doGet(String urlTemplate, Object... urlVariables) throws Exception { |
271 | 281 | MockHttpServletRequestBuilder getRequest = get(urlTemplate, urlVariables); |
272 | 282 | setJwtToken(getRequest); |
273 | 283 | return mockMvc.perform(getRequest); |
274 | 284 | } |
275 | - | |
285 | + | |
276 | 286 | protected <T> T doGet(String urlTemplate, Class<T> responseClass, Object... urlVariables) throws Exception { |
277 | 287 | return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseClass); |
278 | 288 | } |
279 | - | |
289 | + | |
290 | + protected <T> T doGetAsync(String urlTemplate, Class<T> responseClass, Object... urlVariables) throws Exception { | |
291 | + return readResponse(doGetAsync(urlTemplate, urlVariables).andExpect(status().isOk()), responseClass); | |
292 | + } | |
293 | + | |
294 | + protected ResultActions doGetAsync(String urlTemplate, Object... urlVariables) throws Exception { | |
295 | + MockHttpServletRequestBuilder getRequest; | |
296 | + getRequest = get(urlTemplate, urlVariables); | |
297 | + setJwtToken(getRequest); | |
298 | + return mockMvc.perform(asyncDispatch(mockMvc.perform(getRequest).andExpect(request().asyncStarted()).andReturn())); | |
299 | + } | |
300 | + | |
280 | 301 | protected <T> T doGetTyped(String urlTemplate, TypeReference<T> responseType, Object... urlVariables) throws Exception { |
281 | 302 | return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseType); |
282 | 303 | } |
283 | - | |
304 | + | |
284 | 305 | protected <T> T doGetTypedWithPageLink(String urlTemplate, TypeReference<T> responseType, |
285 | - TextPageLink pageLink, | |
286 | - Object... urlVariables) throws Exception { | |
306 | + TextPageLink pageLink, | |
307 | + Object... urlVariables) throws Exception { | |
287 | 308 | List<Object> pageLinkVariables = new ArrayList<>(); |
288 | 309 | urlTemplate += "limit={limit}"; |
289 | 310 | pageLinkVariables.add(pageLink.getLimit()); |
... | ... | @@ -299,75 +320,93 @@ public abstract class AbstractControllerTest { |
299 | 320 | urlTemplate += "&textOffset={textOffset}"; |
300 | 321 | pageLinkVariables.add(pageLink.getTextOffset()); |
301 | 322 | } |
302 | - | |
303 | - Object[] vars = new Object[urlVariables.length + pageLinkVariables.size()]; | |
323 | + | |
324 | + Object[] vars = new Object[urlVariables.length + pageLinkVariables.size()]; | |
304 | 325 | System.arraycopy(urlVariables, 0, vars, 0, urlVariables.length); |
305 | 326 | System.arraycopy(pageLinkVariables.toArray(), 0, vars, urlVariables.length, pageLinkVariables.size()); |
306 | - | |
327 | + | |
307 | 328 | return readResponse(doGet(urlTemplate, vars).andExpect(status().isOk()), responseType); |
308 | 329 | } |
309 | - | |
330 | + | |
310 | 331 | protected <T> T doPost(String urlTemplate, Class<T> responseClass, String... params) throws Exception { |
311 | 332 | return readResponse(doPost(urlTemplate, params).andExpect(status().isOk()), responseClass); |
312 | 333 | } |
313 | - | |
334 | + | |
335 | + protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception { | |
336 | + return readResponse(doPost(urlTemplate, params).andExpect(resultMatcher), responseClass); | |
337 | + } | |
338 | + | |
314 | 339 | protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, String... params) throws Exception { |
315 | 340 | return readResponse(doPost(urlTemplate, content, params).andExpect(status().isOk()), responseClass); |
316 | 341 | } |
317 | 342 | |
343 | + protected <T> T doPostAsync(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception { | |
344 | + return readResponse(doPostAsync(urlTemplate, content, params).andExpect(resultMatcher), responseClass); | |
345 | + } | |
346 | + | |
318 | 347 | protected <T> T doDelete(String urlTemplate, Class<T> responseClass, String... params) throws Exception { |
319 | 348 | return readResponse(doDelete(urlTemplate, params).andExpect(status().isOk()), responseClass); |
320 | 349 | } |
321 | - | |
350 | + | |
322 | 351 | protected ResultActions doPost(String urlTemplate, String... params) throws Exception { |
323 | 352 | MockHttpServletRequestBuilder postRequest = post(urlTemplate); |
324 | 353 | setJwtToken(postRequest); |
325 | 354 | populateParams(postRequest, params); |
326 | 355 | return mockMvc.perform(postRequest); |
327 | 356 | } |
328 | - | |
329 | - protected <T> ResultActions doPost(String urlTemplate, T content, String... params) throws Exception { | |
357 | + | |
358 | + protected <T> ResultActions doPost(String urlTemplate, T content, String... params) throws Exception { | |
330 | 359 | MockHttpServletRequestBuilder postRequest = post(urlTemplate); |
331 | 360 | setJwtToken(postRequest); |
332 | 361 | String json = json(content); |
333 | 362 | postRequest.contentType(contentType).content(json); |
334 | - populateParams(postRequest, params); | |
335 | 363 | return mockMvc.perform(postRequest); |
336 | 364 | } |
337 | - | |
365 | + | |
366 | + protected <T> ResultActions doPostAsync(String urlTemplate, T content, String... params) throws Exception { | |
367 | + MockHttpServletRequestBuilder postRequest = post(urlTemplate); | |
368 | + setJwtToken(postRequest); | |
369 | + String json = json(content); | |
370 | + postRequest.contentType(contentType).content(json); | |
371 | + MvcResult result = mockMvc.perform(postRequest).andReturn(); | |
372 | + return mockMvc.perform(asyncDispatch(result)); | |
373 | + } | |
374 | + | |
338 | 375 | protected ResultActions doDelete(String urlTemplate, String... params) throws Exception { |
339 | 376 | MockHttpServletRequestBuilder deleteRequest = delete(urlTemplate); |
340 | 377 | setJwtToken(deleteRequest); |
341 | 378 | populateParams(deleteRequest, params); |
342 | 379 | return mockMvc.perform(deleteRequest); |
343 | 380 | } |
344 | - | |
381 | + | |
345 | 382 | protected void populateParams(MockHttpServletRequestBuilder request, String... params) { |
346 | 383 | if (params != null && params.length > 0) { |
347 | 384 | Assert.assertEquals(params.length % 2, 0); |
348 | 385 | MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<String, String>(); |
349 | - for (int i=0;i<params.length;i+=2) { | |
350 | - paramsMap.add(params[i], params[i+1]); | |
386 | + for (int i = 0; i < params.length; i += 2) { | |
387 | + paramsMap.add(params[i], params[i + 1]); | |
351 | 388 | } |
352 | 389 | request.params(paramsMap); |
353 | 390 | } |
354 | 391 | } |
355 | - | |
392 | + | |
356 | 393 | @SuppressWarnings("unchecked") |
357 | 394 | protected String json(Object o) throws IOException { |
358 | 395 | MockHttpOutputMessage mockHttpOutputMessage = new MockHttpOutputMessage(); |
359 | - this.mappingJackson2HttpMessageConverter.write( | |
360 | - o, MediaType.APPLICATION_JSON, mockHttpOutputMessage); | |
396 | + | |
397 | + HttpMessageConverter converter = o instanceof String ? stringHttpMessageConverter : mappingJackson2HttpMessageConverter; | |
398 | + converter.write(o, MediaType.APPLICATION_JSON, mockHttpOutputMessage); | |
361 | 399 | return mockHttpOutputMessage.getBodyAsString(); |
362 | 400 | } |
363 | - | |
401 | + | |
364 | 402 | @SuppressWarnings("unchecked") |
365 | 403 | protected <T> T readResponse(ResultActions result, Class<T> responseClass) throws Exception { |
366 | 404 | byte[] content = result.andReturn().getResponse().getContentAsByteArray(); |
367 | 405 | MockHttpInputMessage mockHttpInputMessage = new MockHttpInputMessage(content); |
368 | - return (T) this.mappingJackson2HttpMessageConverter.read(responseClass, mockHttpInputMessage); | |
406 | + HttpMessageConverter converter = responseClass.equals(String.class) ? stringHttpMessageConverter : mappingJackson2HttpMessageConverter; | |
407 | + return (T) converter.read(responseClass, mockHttpInputMessage); | |
369 | 408 | } |
370 | - | |
409 | + | |
371 | 410 | protected <T> T readResponse(ResultActions result, TypeReference<T> type) throws Exception { |
372 | 411 | byte[] content = result.andReturn().getResponse().getContentAsByteArray(); |
373 | 412 | ObjectMapper mapper = new ObjectMapper(); | ... | ... |
application/src/test/java/org/thingsboard/server/mqtt/MqttNoSqlTestSuite.java
renamed from
application/src/test/java/org/thingsboard/server/mqtt/MqttTestSuite.java
... | ... | @@ -25,8 +25,8 @@ import java.util.Arrays; |
25 | 25 | |
26 | 26 | @RunWith(ClasspathSuite.class) |
27 | 27 | @ClasspathSuite.ClassnameFilters({ |
28 | - "org.thingsboard.server.mqtt.*.*Test"}) | |
29 | -public class MqttTestSuite { | |
28 | + "org.thingsboard.server.mqtt.*.nosql.*Test"}) | |
29 | +public class MqttNoSqlTestSuite { | |
30 | 30 | |
31 | 31 | @ClassRule |
32 | 32 | public static CustomCassandraCQLUnit cassandraUnit = | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2017 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +package org.thingsboard.server.mqtt; | |
17 | + | |
18 | +import org.cassandraunit.dataset.cql.ClassPathCQLDataSet; | |
19 | +import org.junit.ClassRule; | |
20 | +import org.junit.extensions.cpsuite.ClasspathSuite; | |
21 | +import org.junit.runner.RunWith; | |
22 | +import org.thingsboard.server.dao.CustomCassandraCQLUnit; | |
23 | +import org.thingsboard.server.dao.CustomSqlUnit; | |
24 | + | |
25 | +import java.util.Arrays; | |
26 | + | |
27 | +@RunWith(ClasspathSuite.class) | |
28 | +@ClasspathSuite.ClassnameFilters({ | |
29 | + "org.thingsboard.server.mqtt.rpc.sql.*Test", "org.thingsboard.server.mqtt.telemetry.sql.*Test"}) | |
30 | +public class MqttSqlTestSuite { | |
31 | + | |
32 | + @ClassRule | |
33 | + public static CustomSqlUnit sqlUnit = new CustomSqlUnit( | |
34 | + Arrays.asList("sql/schema.sql", "sql/system-data.sql"), | |
35 | + "sql/drop-all-tables.sql", | |
36 | + "sql-test.properties"); | |
37 | +} | ... | ... |
application/src/test/java/org/thingsboard/server/mqtt/rpc/AbstractMqttServerSideRpcIntegrationTest.java
renamed from
application/src/test/java/org/thingsboard/server/mqtt/rpc/MqttServerSideRpcIntegrationTest.java
... | ... | @@ -16,6 +16,7 @@ |
16 | 16 | package org.thingsboard.server.mqtt.rpc; |
17 | 17 | |
18 | 18 | import lombok.extern.slf4j.Slf4j; |
19 | +import org.apache.commons.lang3.StringUtils; | |
19 | 20 | import org.eclipse.paho.client.mqttv3.*; |
20 | 21 | import org.junit.*; |
21 | 22 | import org.springframework.http.HttpStatus; |
... | ... | @@ -26,6 +27,7 @@ import org.thingsboard.server.common.data.User; |
26 | 27 | import org.thingsboard.server.common.data.security.Authority; |
27 | 28 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
28 | 29 | import org.thingsboard.server.controller.AbstractControllerTest; |
30 | +import org.thingsboard.server.dao.service.DaoNoSqlTest; | |
29 | 31 | |
30 | 32 | import java.util.UUID; |
31 | 33 | |
... | ... | @@ -37,7 +39,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. |
37 | 39 | * @author Valerii Sosliuk |
38 | 40 | */ |
39 | 41 | @Slf4j |
40 | -public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { | |
42 | +public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractControllerTest { | |
41 | 43 | |
42 | 44 | private static final String MQTT_URL = "tcp://localhost:1883"; |
43 | 45 | 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 { |
67 | 69 | @After |
68 | 70 | public void afterTest() throws Exception { |
69 | 71 | loginSysAdmin(); |
70 | - | |
71 | - doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) | |
72 | - .andExpect(status().isOk()); | |
72 | + if (savedTenant != null) { | |
73 | + doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) | |
74 | + .andExpect(status().isOk()); | |
75 | + } | |
73 | 76 | } |
74 | 77 | |
75 | 78 | @Test |
76 | - @Ignore | |
77 | 79 | public void testServerMqttOneWayRpc() throws Exception { |
78 | 80 | Device device = new Device(); |
79 | 81 | device.setName("Test One-Way Server-Side RPC"); |
... | ... | @@ -95,12 +97,12 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
95 | 97 | |
96 | 98 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
97 | 99 | String deviceId = savedDevice.getId().getId().toString(); |
98 | - String result = doPost("api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class); | |
99 | - Assert.assertNull(result); | |
100 | + String result = doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
101 | + Assert.assertTrue(StringUtils.isEmpty(result)); | |
100 | 102 | } |
101 | 103 | |
102 | 104 | @Test |
103 | - @Ignore | |
105 | + @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 408 but was: 200 | |
104 | 106 | public void testServerMqttOneWayRpcDeviceOffline() throws Exception { |
105 | 107 | Device device = new Device(); |
106 | 108 | device.setName("Test One-Way Server-Side RPC Device Offline"); |
... | ... | @@ -114,7 +116,7 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
114 | 116 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
115 | 117 | String deviceId = savedDevice.getId().getId().toString(); |
116 | 118 | try { |
117 | - doPost("api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class); | |
119 | + doPost("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(408)); | |
118 | 120 | Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); |
119 | 121 | } catch (HttpClientErrorException e) { |
120 | 122 | log.error(e.getMessage(), e); |
... | ... | @@ -124,12 +126,12 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
124 | 126 | } |
125 | 127 | |
126 | 128 | @Test |
127 | - @Ignore | |
129 | + @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 400 (404?) but was: 401 | |
128 | 130 | public void testServerMqttOneWayRpcDeviceDoesNotExist() throws Exception { |
129 | 131 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
130 | 132 | String nonExistentDeviceId = UUID.randomUUID().toString(); |
131 | 133 | try { |
132 | - doPost("api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class); | |
134 | + doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, status().is(400)); | |
133 | 135 | Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); |
134 | 136 | } catch (HttpClientErrorException e) { |
135 | 137 | log.error(e.getMessage(), e); |
... | ... | @@ -139,7 +141,6 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
139 | 141 | } |
140 | 142 | |
141 | 143 | @Test |
142 | - @Ignore | |
143 | 144 | public void testServerMqttTwoWayRpc() throws Exception { |
144 | 145 | Device device = new Device(); |
145 | 146 | device.setName("Test Two-Way Server-Side RPC"); |
... | ... | @@ -161,12 +162,13 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
161 | 162 | |
162 | 163 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
163 | 164 | String deviceId = savedDevice.getId().getId().toString(); |
164 | - String result = getStringResult(setGpioRequest, "twoway", deviceId); | |
165 | + | |
166 | + String result = doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); | |
165 | 167 | Assert.assertEquals("{\"value1\":\"A\",\"value2\":\"B\"}", result); |
166 | 168 | } |
167 | 169 | |
168 | 170 | @Test |
169 | - @Ignore | |
171 | + @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 408 but was: 200 | |
170 | 172 | public void testServerMqttTwoWayRpcDeviceOffline() throws Exception { |
171 | 173 | Device device = new Device(); |
172 | 174 | device.setName("Test Two-Way Server-Side RPC Device Offline"); |
... | ... | @@ -180,7 +182,7 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
180 | 182 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
181 | 183 | String deviceId = savedDevice.getId().getId().toString(); |
182 | 184 | try { |
183 | - doPost("api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class); | |
185 | + doPost("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(408)); | |
184 | 186 | Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); |
185 | 187 | } catch (HttpClientErrorException e) { |
186 | 188 | log.error(e.getMessage(), e); |
... | ... | @@ -190,12 +192,12 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
190 | 192 | } |
191 | 193 | |
192 | 194 | @Test |
193 | - @Ignore | |
195 | + @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 400 (404?) but was: 401 | |
194 | 196 | public void testServerMqttTwoWayRpcDeviceDoesNotExist() throws Exception { |
195 | 197 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
196 | 198 | String nonExistentDeviceId = UUID.randomUUID().toString(); |
197 | 199 | try { |
198 | - doPost("api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class); | |
200 | + doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, status().is(400)); | |
199 | 201 | Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); |
200 | 202 | } catch (HttpClientErrorException e) { |
201 | 203 | log.error(e.getMessage(), e); |
... | ... | @@ -212,10 +214,6 @@ public class MqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
212 | 214 | return doGet("/api/device/" + savedDevice.getId().getId().toString() + "/credentials", DeviceCredentials.class); |
213 | 215 | } |
214 | 216 | |
215 | - private String getStringResult(String requestData, String callType, String deviceId) throws Exception { | |
216 | - return doPost("api/plugins/rpc/" + callType + "/" + deviceId, requestData, String.class); | |
217 | - } | |
218 | - | |
219 | 217 | private static class TestMqttCallback implements MqttCallback { |
220 | 218 | |
221 | 219 | private final MqttAsyncClient client; | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2017 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +package org.thingsboard.server.mqtt.rpc.nosql; | |
17 | + | |
18 | +import org.thingsboard.server.dao.service.DaoNoSqlTest; | |
19 | +import org.thingsboard.server.mqtt.rpc.AbstractMqttServerSideRpcIntegrationTest; | |
20 | + | |
21 | +/** | |
22 | + * Created by Valerii Sosliuk on 8/22/2017. | |
23 | + */ | |
24 | +@DaoNoSqlTest | |
25 | +public class MqttServerSideRpcNoSqlIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest { | |
26 | +} | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2017 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +package org.thingsboard.server.mqtt.rpc.sql; | |
17 | + | |
18 | +import org.thingsboard.server.dao.service.DaoNoSqlTest; | |
19 | +import org.thingsboard.server.dao.service.DaoSqlTest; | |
20 | +import org.thingsboard.server.mqtt.rpc.AbstractMqttServerSideRpcIntegrationTest; | |
21 | + | |
22 | +/** | |
23 | + * Created by Valerii Sosliuk on 8/22/2017. | |
24 | + */ | |
25 | +@DaoSqlTest | |
26 | +public class MqttServerSideRpcSqlIntegrationTest extends AbstractMqttServerSideRpcIntegrationTest { | |
27 | +} | ... | ... |
application/src/test/java/org/thingsboard/server/mqtt/telemetry/AbstractMqttTelemetryIntegrationTest.java
renamed from
application/src/test/java/org/thingsboard/server/mqtt/telemetry/MqttTelemetryIntegrationTest.java
... | ... | @@ -26,11 +26,10 @@ import org.springframework.web.util.UriComponentsBuilder; |
26 | 26 | import org.thingsboard.server.common.data.Device; |
27 | 27 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
28 | 28 | import org.thingsboard.server.controller.AbstractControllerTest; |
29 | +import org.thingsboard.server.dao.service.DaoNoSqlTest; | |
29 | 30 | |
30 | 31 | import java.net.URI; |
31 | -import java.util.Arrays; | |
32 | -import java.util.List; | |
33 | -import java.util.Map; | |
32 | +import java.util.*; | |
34 | 33 | |
35 | 34 | import static org.junit.Assert.assertEquals; |
36 | 35 | import static org.junit.Assert.assertNotNull; |
... | ... | @@ -39,7 +38,7 @@ import static org.junit.Assert.assertNotNull; |
39 | 38 | * @author Valerii Sosliuk |
40 | 39 | */ |
41 | 40 | @Slf4j |
42 | -public class MqttTelemetryIntegrationTest extends AbstractControllerTest { | |
41 | +public abstract class AbstractMqttTelemetryIntegrationTest extends AbstractControllerTest { | |
43 | 42 | |
44 | 43 | private static final String MQTT_URL = "tcp://localhost:1883"; |
45 | 44 | |
... | ... | @@ -64,7 +63,6 @@ public class MqttTelemetryIntegrationTest extends AbstractControllerTest { |
64 | 63 | } |
65 | 64 | |
66 | 65 | @Test |
67 | - @Ignore | |
68 | 66 | public void testPushMqttRpcData() throws Exception { |
69 | 67 | String clientId = MqttAsyncClient.generateClientId(); |
70 | 68 | MqttAsyncClient client = new MqttAsyncClient(MQTT_URL, clientId); |
... | ... | @@ -80,13 +78,16 @@ public class MqttTelemetryIntegrationTest extends AbstractControllerTest { |
80 | 78 | String deviceId = savedDevice.getId().getId().toString(); |
81 | 79 | |
82 | 80 | Thread.sleep(1000); |
83 | - Object keys = doGet("/api/plugins/telemetry/" + deviceId + "/keys/timeseries", Object.class); | |
84 | - assertEquals(Arrays.asList("key1", "key2", "key3", "key4"), keys); | |
81 | + List<String> actualKeys = doGetAsync("/api/plugins/telemetry/DEVICE/" + deviceId + "/keys/timeseries", List.class); | |
82 | + Set<String> actualKeySet = new HashSet<>(actualKeys); | |
85 | 83 | |
86 | - UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("/api/plugins/telemetry/" + deviceId + "/values/timeseries") | |
87 | - .queryParam("keys", String.join(",", (CharSequence[]) keys)); | |
88 | - URI uri = builder.build().encode().toUri(); | |
89 | - Map<String, List<Map<String, String>>> values = doGet(uri.getPath(), Map.class); | |
84 | + List<String> expectedKeys = Arrays.asList("key1", "key2", "key3", "key4"); | |
85 | + Set<String> expectedKeySet = new HashSet<>(expectedKeys); | |
86 | + | |
87 | + assertEquals(expectedKeySet, actualKeySet); | |
88 | + | |
89 | + String getTelemetryValuesUrl = "/api/plugins/telemetry/DEVICE/" + deviceId + "/values/timeseries?keys=" + String.join(",", actualKeySet); | |
90 | + Map<String, List<Map<String, String>>> values = doGetAsync(getTelemetryValuesUrl, Map.class); | |
90 | 91 | |
91 | 92 | assertEquals("value1", values.get("key1").get(0).get("value")); |
92 | 93 | assertEquals("true", values.get("key2").get(0).get("value")); | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2017 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +package org.thingsboard.server.mqtt.telemetry.nosql; | |
17 | + | |
18 | +import org.thingsboard.server.dao.service.DaoNoSqlTest; | |
19 | +import org.thingsboard.server.mqtt.telemetry.AbstractMqttTelemetryIntegrationTest; | |
20 | + | |
21 | +/** | |
22 | + * Created by Valerii Sosliuk on 8/22/2017. | |
23 | + */ | |
24 | +@DaoNoSqlTest | |
25 | +public class MqttTelemetryNoSqlIntegrationTest extends AbstractMqttTelemetryIntegrationTest { | |
26 | +} | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2017 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +package org.thingsboard.server.mqtt.telemetry.sql; | |
17 | + | |
18 | +import org.thingsboard.server.dao.service.DaoNoSqlTest; | |
19 | +import org.thingsboard.server.dao.service.DaoSqlTest; | |
20 | +import org.thingsboard.server.mqtt.telemetry.AbstractMqttTelemetryIntegrationTest; | |
21 | + | |
22 | +/** | |
23 | + * Created by Valerii Sosliuk on 8/22/2017. | |
24 | + */ | |
25 | +@DaoSqlTest | |
26 | +public class MqttTelemetrySqlIntegrationTest extends AbstractMqttTelemetryIntegrationTest { | |
27 | +} | ... | ... |