1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11 #include <stdio.h>
12 #include <setjmp.h>
13 #include <cmocka.h> /* macros: https://api.cmocka.org/group__cmocka__asserts.html */
14
15 #include "nx_api.h"
16 #include "nx_azure_iot_hub_client.h"
17 #include "nx_azure_iot_cert.h"
18 #include "nx_azure_iot_ciphersuites.h"
19
20
21 #define DEMO_DHCP_DISABLE
22 #define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33)
23 #define DEMO_IPV4_MASK 0xFFFFFF00UL
24 #define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1)
25 #define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1)
26 #define NETWORK_DRIVER _nx_ram_network_driver
27
28 /* Include main.c in the test case since we need to disable DHCP in this test. */
29 #include "main.c"
30
31 #ifndef DEMO_CLOUD_STACK_SIZE
32 #define DEMO_CLOUD_STACK_SIZE 2048
33 #endif /* DEMO_CLOUD_STACK_SIZE */
34
35 #ifndef DEMO_CLOUD_THREAD_PRIORITY
36 #define DEMO_CLOUD_THREAD_PRIORITY (4)
37 #endif /* DEMO_CLOUD_THREAD_PRIORITY */
38
39 #ifndef MAXIMUM_PAYLOAD_LENGTH
40 #define MAXIMUM_PAYLOAD_LENGTH 10240
41 #endif /* MAXIMUM_PAYLOAD_LENGTH */
42
43 typedef VOID (*NX_AZURE_TEST_FN)();
44
45
46 static UCHAR g_hostname[] = "unit-test.iot-azure.com";
47 static UCHAR g_device_id[] = "unit_test_device";
48
49 static const CHAR direct_method_response_topic[] = "$iothub/methods/POST/test_method/?$rid=1";
50 static const CHAR test_method_response_payload[] = "{\"method\" : \"test_method\", \"parameter\": 1}";
51 static const CHAR test_method_name[] = "test_method";
52 static const CHAR test_request_id[] = "1";
53 static const CHAR test_send_payload[] = "{\"return\" : \"OK\"}";
54
55 static UINT g_total_append = 0;
56 static UINT g_failed_append_index = 0;
57 static UINT g_total_allocation = 0;
58 static UINT g_failed_allocation_index = -1;
59 static NX_IP* g_ip_ptr;
60 static NX_PACKET_POOL* g_pool_ptr;
61 static NX_DNS* g_dns_ptr;
62 static ULONG g_available_packet;
63 static CHAR *g_expected_message;
64
65 extern UINT _nxd_mqtt_client_append_message(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, CHAR *message,
66 UINT length, ULONG wait_option);
67 extern UINT _nxd_mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr,
68 UCHAR control_header, UINT length, UINT wait_option);
69
70 static NX_AZURE_IOT iot;
71 static NX_AZURE_IOT_HUB_CLIENT iot_client;
72 static NX_SECURE_X509_CERT root_ca_cert;
73 static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE];
74 static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)];
75 static UCHAR message_payload[MAXIMUM_PAYLOAD_LENGTH];
76 static UCHAR result_buffer[MAXIMUM_PAYLOAD_LENGTH];
77 static VOID (*test_receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count) = NX_NULL;
78
__wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT * nx_azure_iot_ptr)79 UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr)
80 {
81 printf("HIJACKED: %s\n", __func__);
82 return(NX_AZURE_IOT_SUCCESS);
83 }
84
__wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT * nx_azure_iot_ptr)85 UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr)
86 {
87 printf("HIJACKED: %s\n", __func__);
88 return(NX_AZURE_IOT_SUCCESS);
89 }
90
__wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT * client_ptr,VOID (* receive_notify)(NXD_MQTT_CLIENT * client_ptr,UINT message_count))91 UINT __wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr,
92 VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count))
93 {
94 printf("HIJACKED: %s\n", __func__);
95 test_receive_notify = receive_notify;
96 return(NX_AZURE_IOT_SUCCESS);
97 }
98
__wrap__nxde_mqtt_client_subscribe(NXD_MQTT_CLIENT * client_ptr,UINT op,CHAR * topic_name,UINT topic_name_length,USHORT * packet_id_ptr,UINT QoS)99 UINT __wrap__nxde_mqtt_client_subscribe(NXD_MQTT_CLIENT *client_ptr, UINT op,
100 CHAR *topic_name, UINT topic_name_length,
101 USHORT *packet_id_ptr, UINT QoS)
102 {
103 printf("HIJACKED: %s\n", __func__);
104
105 return((UINT)mock());
106 }
107
__wrap__nxde_mqtt_client_unsubscribe(NXD_MQTT_CLIENT * client_ptr,CHAR * topic_name,UINT topic_name_length,UINT QoS)108 UINT __wrap__nxde_mqtt_client_unsubscribe(NXD_MQTT_CLIENT *client_ptr, CHAR *topic_name,
109 UINT topic_name_length, UINT QoS)
110 {
111 printf("HIJACKED: %s\n", __func__);
112 return((UINT)mock());
113 }
114
115 UINT __real__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size,
116 NX_PACKET_POOL *pool_ptr, ULONG wait_option);
__wrap__nx_packet_data_append(NX_PACKET * packet_ptr,VOID * data_start,ULONG data_size,NX_PACKET_POOL * pool_ptr,ULONG wait_option)117 UINT __wrap__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size,
118 NX_PACKET_POOL *pool_ptr, ULONG wait_option)
119 {
120 printf("HIJACKED: %s\n", __func__);
121
122 if (g_failed_append_index == g_total_append)
123 {
124 return(NX_NOT_SUCCESSFUL);
125 }
126
127 g_total_append++;
128 return __real__nx_packet_data_append(packet_ptr, data_start, data_size, pool_ptr, wait_option);
129 }
130
131 UINT __real_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr,
132 UINT *buffer_size, VOID **buffer_context);
__wrap_nx_azure_iot_buffer_allocate(NX_AZURE_IOT * nx_azure_iot_ptr,UCHAR ** buffer_pptr,UINT * buffer_size,VOID ** buffer_context)133 UINT __wrap_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr,
134 UINT *buffer_size, VOID **buffer_context)
135 {
136 printf("HIJACKED: %s\n", __func__);
137
138 if (g_failed_allocation_index == g_total_allocation)
139 {
140 return(NX_NOT_SUCCESSFUL);
141 }
142
143 g_total_allocation++;
144 return __real_nx_azure_iot_buffer_allocate(nx_azure_iot_ptr, buffer_pptr, buffer_size, buffer_context);
145 }
146
__wrap__nxd_mqtt_client_publish_packet_send(NXD_MQTT_CLIENT * client_ptr,NX_PACKET * packet_ptr,USHORT packet_id,UINT QoS,ULONG wait_option)147 UINT __wrap__nxd_mqtt_client_publish_packet_send(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr,
148 USHORT packet_id, UINT QoS, ULONG wait_option)
149 {
150 UINT topic_name_length;
151 UINT message_length;
152 UCHAR *buffer_ptr;
153 UINT status = (UINT)mock();
154
155 printf("HIJACKED: %s\n", __func__);
156 tx_mutex_put(client_ptr -> nxd_mqtt_client_mutex_ptr);
157
158 if (status)
159 {
160 return(status);
161 }
162
163 buffer_ptr = packet_ptr -> nx_packet_prepend_ptr;
164 topic_name_length = (buffer_ptr[5] << 8) | (buffer_ptr[6]);
165 message_length = packet_ptr -> nx_packet_length - (9 + topic_name_length);
166 assert_memory_equal(&buffer_ptr[7 + topic_name_length], g_expected_message, message_length);
167 assert_int_equal(QoS, 0);
168
169 /* packet ownership taken and released */
170 nx_packet_release(packet_ptr);
171
172 return(status);
173 }
174
__wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT * client_ptr,NXD_ADDRESS * server_ip,UINT server_port,UINT (* tls_setup)(NXD_MQTT_CLIENT * client_ptr,NX_SECURE_TLS_SESSION *,NX_SECURE_X509_CERT *,NX_SECURE_X509_CERT *),UINT keepalive,UINT clean_session,ULONG wait_option)175 UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port,
176 UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *,
177 NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *),
178 UINT keepalive, UINT clean_session, ULONG wait_option)
179 {
180 printf("HIJACKED: %s\n", __func__);
181
182 tx_thread_suspend(&(iot.nx_azure_iot_ip_ptr -> nx_ip_thread));
183 client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED;
184 client_ptr -> nxd_mqtt_client_packet_identifier = 1;
185 client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_id = NX_SECURE_TLS_ID;
186 client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_local_session_active = NX_FALSE;
187 client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_tcp_socket = &client_ptr -> nxd_mqtt_client_socket;
188 client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4;
189 client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED;
190
191 return(NXD_MQTT_SUCCESS);
192 }
193
__wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT * client_ptr)194 UINT __wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT *client_ptr)
195 {
196 printf("HIJACKED: %s\n", __func__);
197 client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE;
198 client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_CLOSED;
199 return(NXD_MQTT_SUCCESS);
200 }
201
__wrap__nxde_dns_host_by_name_get(NX_DNS * dns_ptr,UCHAR * host_name,NXD_ADDRESS * host_address_ptr,ULONG wait_option,UINT lookup_type)202 UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr,
203 ULONG wait_option, UINT lookup_type)
204 {
205 printf("HIJACKED: %s\n", __func__);
206 host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1);
207 return(NX_DNS_SUCCESS);
208 }
209
on_receive_callback(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,VOID * arg)210 static VOID on_receive_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *arg)
211 {
212 *((UINT *)arg) = 1;
213 }
214
mqtt_client_set_fixed_header(NXD_MQTT_CLIENT * client_ptr,NX_PACKET * packet_ptr,UCHAR control_header,UINT length,UINT wait_option)215 static UINT mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, UCHAR control_header, UINT length, UINT wait_option)
216 {
217 UCHAR fixed_header[5];
218 UCHAR *byte = fixed_header;
219 UINT count = 0;
220 UINT ret;
221
222 *byte = control_header;
223 byte++;
224
225 do
226 {
227 if (length & 0xFFFFFF80)
228 {
229 *(byte + count) = (UCHAR)((length & 0x7F) | 0x80);
230 }
231 else
232 {
233 *(byte + count) = length & 0x7F;
234 }
235 length = length >> 7;
236
237 count++;
238 } while (length != 0);
239
240 ret = __real__nx_packet_data_append(packet_ptr, fixed_header, count + 1,
241 client_ptr -> nxd_mqtt_client_packet_pool_ptr, wait_option);
242
243 return(ret);
244 }
245
construct_direct_method_response(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,const UCHAR * topic,ULONG topic_len,const UCHAR * message_payload_ptr,ULONG message_payload_length,NX_PACKET ** packet_pptr)246 static VOID construct_direct_method_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
247 const UCHAR *topic, ULONG topic_len,
248 const UCHAR *message_payload_ptr, ULONG message_payload_length,
249 NX_PACKET **packet_pptr)
250 {
251 NX_PACKET *packet_ptr;
252 ULONG total_length;
253 ULONG topic_length = topic_len;
254 UCHAR bytes[2];
255 UINT i;
256
257 assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, 0, NX_NO_WAIT),
258 NX_AZURE_IOT_SUCCESS);
259 total_length = topic_length + 2 + 2 + message_payload_length; /* Two bytes for fixed topic_length field
260 and two bytes for packet id. */
261
262 /* Set fixed header. */
263 assert_int_equal(mqtt_client_set_fixed_header(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt), packet_ptr,
264 (UCHAR)((MQTT_CONTROL_PACKET_TYPE_PUBLISH << 4) | MQTT_PUBLISH_QOS_LEVEL_1),
265 total_length, NX_NO_WAIT),
266 NX_AZURE_IOT_SUCCESS);
267
268 /* Set topic length. */
269 bytes[0] = (topic_length >> 8) & 0xFF;
270 bytes[1] = topic_length & 0xFF;
271 assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes),
272 iot.nx_azure_iot_pool_ptr, NX_NO_WAIT),
273 NX_AZURE_IOT_SUCCESS);
274
275 /* Set topic. */
276 assert_int_equal(__real__nx_packet_data_append(packet_ptr, (VOID *)topic, topic_len,
277 iot.nx_azure_iot_pool_ptr, NX_NO_WAIT),
278 NX_AZURE_IOT_SUCCESS);
279 /* Set packet ID. The value does not matter. */
280 assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes),
281 iot.nx_azure_iot_pool_ptr, NX_NO_WAIT),
282 NX_AZURE_IOT_SUCCESS);
283
284 /* Set message payload. */
285 if (message_payload_length > 0)
286 {
287 assert_int_equal(__real__nx_packet_data_append(packet_ptr, (VOID *)message_payload_ptr, message_payload_length,
288 iot.nx_azure_iot_pool_ptr, NX_NO_WAIT),
289 NX_AZURE_IOT_SUCCESS);
290 }
291
292 *packet_pptr = packet_ptr;
293 }
294
generate_direct_method_response(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr)295 static VOID generate_direct_method_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr)
296 {
297 NX_PACKET *packet_ptr;
298
299 construct_direct_method_response(hub_client_ptr, direct_method_response_topic, sizeof(direct_method_response_topic) - 1,
300 test_method_response_payload, sizeof(test_method_response_payload) - 1,
301 &packet_ptr);
302
303 /* Simulate callback from MQTT layer. */
304 hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt.message_receive_queue_head = packet_ptr;
305 hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt.message_receive_queue_depth = 1;
306 tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, NX_WAIT_FOREVER);
307 test_receive_notify(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt), 1);
308 tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr);
309 }
310
reset_global_state()311 static VOID reset_global_state()
312 {
313 /* reset global state */
314 g_failed_append_index = (UINT)-1;
315 g_total_append = 0;
316 g_failed_allocation_index = (UINT)-1;
317 g_total_allocation = 0;
318 g_expected_message = NX_NULL;
319 }
320
321 /* Hook execute before all tests. */
test_suit_begin()322 static VOID test_suit_begin()
323 {
324
325 /* Initialize root certificate. */
326 assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert,
327 (UCHAR *)_nx_azure_iot_root_cert,
328 (USHORT)_nx_azure_iot_root_cert_size,
329 NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE),
330 NX_AZURE_IOT_SUCCESS);
331
332 /* Initialize azure iot handle. */
333 assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT",
334 g_ip_ptr, g_pool_ptr, g_dns_ptr,
335 (UCHAR *)demo_cloud_thread_stack,
336 sizeof(demo_cloud_thread_stack),
337 DEMO_CLOUD_THREAD_PRIORITY, unix_time_get),
338 NX_AZURE_IOT_SUCCESS);
339
340 /* Record number of available packet before test */
341 g_available_packet = g_pool_ptr -> nx_packet_pool_available;
342
343 /* Initialize azure iot handle. */
344 assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot,
345 g_hostname, sizeof(g_hostname),
346 g_device_id, sizeof(g_device_id),
347 "", 0,
348 _nx_azure_iot_tls_supported_crypto,
349 _nx_azure_iot_tls_supported_crypto_size,
350 _nx_azure_iot_tls_ciphersuite_map,
351 _nx_azure_iot_tls_ciphersuite_map_size,
352 metadata_buffer, sizeof(metadata_buffer),
353 &root_ca_cert),
354 NX_AZURE_IOT_SUCCESS);
355
356 /* Connect IoTHub client */
357 assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_FALSE, NX_WAIT_FOREVER),
358 NX_AZURE_IOT_SUCCESS);
359 }
360
361 /* Hook execute after all tests are executed successfully */
test_suit_end()362 static VOID test_suit_end()
363 {
364
365 /* Disconnect IoTHub client */
366 assert_int_equal(nx_azure_iot_hub_client_disconnect(&iot_client), NX_AZURE_IOT_SUCCESS);
367
368 /* Check if all the packet are released */
369 assert_int_equal(g_pool_ptr -> nx_packet_pool_available, g_available_packet);
370
371 /* Deinitialize IoTHub Client */
372 assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client),
373 NX_AZURE_IOT_SUCCESS);
374
375 /* SUCCESS: iot is deleted. */
376 assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS);
377 }
378
379 /* Hook executed before every test */
test_begin()380 static VOID test_begin()
381 {
382 reset_global_state();
383 }
384
385 /* Hook execute after all tests are executed successfully */
test_end()386 static VOID test_end()
387 {
388 }
389
390 /**
391 * Test direct method enable with invalid argument failed.
392 *
393 **/
test_nx_azure_iot_hub_client_direct_method_enable_invalid_argument_failure()394 static VOID test_nx_azure_iot_hub_client_direct_method_enable_invalid_argument_failure()
395 {
396 printf("test starts =>: %s\n", __func__);
397
398 assert_int_not_equal(nx_azure_iot_hub_client_direct_method_enable(NX_NULL),
399 NX_AZURE_IOT_SUCCESS);
400 }
401
402 /**
403 * Test direct method enable with unsuccessful subscribe failed.
404 *
405 **/
test_nx_azure_iot_hub_client_direct_method_enable_failure()406 static VOID test_nx_azure_iot_hub_client_direct_method_enable_failure()
407 {
408 printf("test starts =>: %s\n", __func__);
409
410 will_return(__wrap__nxde_mqtt_client_subscribe, NX_NOT_SUCCESSFUL);
411 assert_int_not_equal(nx_azure_iot_hub_client_direct_method_enable(&iot_client),
412 NX_AZURE_IOT_SUCCESS);
413 }
414
415 /**
416 * Test direct method enable succeeds.
417 *
418 **/
test_nx_azure_iot_hub_client_direct_method_enable_success()419 static VOID test_nx_azure_iot_hub_client_direct_method_enable_success()
420 {
421 printf("test starts =>: %s\n", __func__);
422
423 will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS);
424 assert_int_equal(nx_azure_iot_hub_client_direct_method_enable(&iot_client),
425 NX_AZURE_IOT_SUCCESS);
426 }
427
428 /**
429 * Test direct method disable with invalid argument failed.
430 *
431 **/
test_nx_azure_iot_hub_client_direct_method_disable_invalid_argument_failure()432 static VOID test_nx_azure_iot_hub_client_direct_method_disable_invalid_argument_failure()
433 {
434 printf("test starts =>: %s\n", __func__);
435
436 assert_int_not_equal(nx_azure_iot_hub_client_direct_method_disable(NX_NULL),
437 NX_AZURE_IOT_SUCCESS);
438 }
439
440 /**
441 * Test direct method disable with unsuccessful un-subscribe failed.
442 *
443 **/
test_nx_azure_iot_hub_client_direct_method_disable_failure()444 static VOID test_nx_azure_iot_hub_client_direct_method_disable_failure()
445 {
446 printf("test starts =>: %s\n", __func__);
447
448 will_return(__wrap__nxde_mqtt_client_unsubscribe, NX_NOT_SUCCESSFUL);
449 assert_int_not_equal(nx_azure_iot_hub_client_direct_method_disable(&iot_client),
450 NX_AZURE_IOT_SUCCESS);
451 }
452
453 /**
454 * Test direct method disable succeeds.
455 *
456 **/
test_nx_azure_iot_hub_client_direct_method_disable_success()457 static VOID test_nx_azure_iot_hub_client_direct_method_disable_success()
458 {
459 printf("test starts =>: %s\n", __func__);
460
461 will_return(__wrap__nxde_mqtt_client_unsubscribe, NX_AZURE_IOT_SUCCESS);
462 assert_int_equal(nx_azure_iot_hub_client_direct_method_disable(&iot_client),
463 NX_AZURE_IOT_SUCCESS);
464 }
465
466 /**
467 * Test direct method receive with invalid argument failed.
468 *
469 **/
test_nx_azure_iot_hub_client_direct_method_message_receive_invalid_argument_failure()470 static VOID test_nx_azure_iot_hub_client_direct_method_message_receive_invalid_argument_failure()
471 {
472 const UCHAR *method_name_ptr;
473 USHORT method_name_length;
474 VOID *context_ptr;
475 USHORT context_length;
476 NX_PACKET *packet_ptr;
477
478 printf("test starts =>: %s\n", __func__);
479
480 assert_int_not_equal(nx_azure_iot_hub_client_direct_method_message_receive(NX_NULL,
481 &method_name_ptr, &method_name_length,
482 &context_ptr, &context_length,
483 &packet_ptr, NX_WAIT_FOREVER),
484 NX_AZURE_IOT_SUCCESS);
485 }
486
487 /**
488 * Test direct method receive succeeds.
489 *
490 **/
test_nx_azure_iot_hub_client_direct_method_message_receive_success()491 static VOID test_nx_azure_iot_hub_client_direct_method_message_receive_success()
492 {
493 const UCHAR *method_name_ptr;
494 USHORT method_name_length;
495 VOID *context_ptr;
496 USHORT context_length;
497 NX_PACKET *packet_ptr;
498 ULONG bytes_copied;
499
500 printf("test starts =>: %s\n", __func__);
501
502 will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS);
503 assert_int_equal(nx_azure_iot_hub_client_direct_method_enable(&iot_client),
504 NX_AZURE_IOT_SUCCESS);
505 generate_direct_method_response(&iot_client);
506
507 assert_int_equal(nx_azure_iot_hub_client_direct_method_message_receive(&iot_client,
508 &method_name_ptr, &method_name_length,
509 &context_ptr, &context_length,
510 &packet_ptr, NX_WAIT_FOREVER),
511 NX_AZURE_IOT_SUCCESS);
512
513 assert_memory_equal(method_name_ptr, test_method_name, sizeof(test_method_name) - 1);
514 assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer,
515 sizeof(result_buffer), &bytes_copied),
516 NX_AZURE_IOT_SUCCESS);
517 assert_memory_equal(result_buffer, test_method_response_payload, sizeof(test_method_response_payload) - 1);
518
519 nx_packet_release(packet_ptr);
520 }
521
522 /**
523 * Test direct method receive succeeds with NX_NO_WAIT.
524 *
525 **/
test_nx_azure_iot_hub_client_direct_method_message_receive_no_blocking_success()526 static VOID test_nx_azure_iot_hub_client_direct_method_message_receive_no_blocking_success()
527 {
528 const UCHAR *method_name_ptr;
529 USHORT method_name_length;
530 VOID *context_ptr;
531 USHORT context_length;
532 NX_PACKET *packet_ptr;
533 ULONG bytes_copied;
534 UINT received = 0;
535
536 printf("test starts =>: %s\n", __func__);
537
538 assert_int_equal(nx_azure_iot_hub_client_receive_callback_set(&iot_client,
539 NX_AZURE_IOT_HUB_DIRECT_METHOD,
540 on_receive_callback,
541 (VOID *)&received),
542 NX_AZURE_IOT_SUCCESS);
543 will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS);
544 assert_int_equal(nx_azure_iot_hub_client_direct_method_enable(&iot_client),
545 NX_AZURE_IOT_SUCCESS);
546 generate_direct_method_response(&iot_client);
547
548 while (!received)
549 {
550 tx_thread_sleep(NX_IP_PERIODIC_RATE / 10);
551 }
552
553 assert_int_equal(nx_azure_iot_hub_client_direct_method_message_receive(&iot_client,
554 &method_name_ptr, &method_name_length,
555 &context_ptr, &context_length,
556 &packet_ptr, NX_NO_WAIT),
557 NX_AZURE_IOT_SUCCESS);
558
559 assert_memory_equal(method_name_ptr, test_method_name, sizeof(test_method_name) - 1);
560 assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer,
561 sizeof(result_buffer), &bytes_copied),
562 NX_AZURE_IOT_SUCCESS);
563 assert_memory_equal(result_buffer, test_method_response_payload, sizeof(test_method_response_payload) - 1);
564
565 nx_packet_release(packet_ptr);
566 }
567
568 /**
569 * Test no one is receiving direct method.
570 *
571 **/
test_nx_azure_iot_hub_client_direct_method_message_no_receive()572 static VOID test_nx_azure_iot_hub_client_direct_method_message_no_receive()
573 {
574 const UCHAR *method_name_ptr;
575 USHORT method_name_length;
576 VOID *context_ptr;
577 USHORT context_length;
578 NX_PACKET *packet_ptr;
579 ULONG bytes_copied;
580
581 printf("test starts =>: %s\n", __func__);
582
583 will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS);
584 assert_int_equal(nx_azure_iot_hub_client_direct_method_enable(&iot_client),
585 NX_AZURE_IOT_SUCCESS);
586 generate_direct_method_response(&iot_client);
587 }
588
589
590 /**
591 * Test direct method response invalid argument fail.
592 *
593 **/
test_nx_azure_iot_hub_client_direct_method_message_response_invalid_argument_fail()594 static VOID test_nx_azure_iot_hub_client_direct_method_message_response_invalid_argument_fail()
595 {
596 printf("test starts =>: %s\n", __func__);
597
598 assert_int_not_equal(nx_azure_iot_hub_client_direct_method_message_response(NX_NULL,
599 200, (VOID *)test_request_id, sizeof(test_request_id) - 1,
600 (UCHAR *)test_send_payload, sizeof(test_send_payload) - 1,
601 NX_WAIT_FOREVER),
602 NX_AZURE_IOT_SUCCESS);
603 assert_int_not_equal(nx_azure_iot_hub_client_direct_method_message_response(&iot_client,
604 200, NX_NULL, 0,
605 (UCHAR *)test_send_payload, sizeof(test_send_payload) - 1,
606 NX_WAIT_FOREVER),
607 NX_AZURE_IOT_SUCCESS);
608 }
609
610
611 /**
612 * Test direct method response send fail.
613 *
614 **/
test_nx_azure_iot_hub_client_direct_method_message_response_send_failure_fail()615 static VOID test_nx_azure_iot_hub_client_direct_method_message_response_send_failure_fail()
616 {
617 printf("test starts =>: %s\n", __func__);
618 will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_NOT_SUCCESSFUL);
619
620 assert_int_not_equal(nx_azure_iot_hub_client_direct_method_message_response(&iot_client,
621 200, (VOID *)test_request_id, sizeof(test_request_id) - 1,
622 (UCHAR *)test_send_payload, sizeof(test_send_payload) - 1,
623 NX_WAIT_FOREVER),
624 NX_AZURE_IOT_SUCCESS);
625 }
626
627 /**
628 * Test direct method response succeeds.
629 *
630 **/
test_nx_azure_iot_hub_client_direct_method_message_response_success()631 static VOID test_nx_azure_iot_hub_client_direct_method_message_response_success()
632 {
633 printf("test starts =>: %s\n", __func__);
634 will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS);
635 g_expected_message = (CHAR *)test_send_payload;
636
637 assert_int_equal(nx_azure_iot_hub_client_direct_method_message_response(&iot_client,
638 200, (VOID *)test_request_id, sizeof(test_request_id) - 1,
639 (UCHAR *)test_send_payload, sizeof(test_send_payload) - 1,
640 NX_WAIT_FOREVER),
641 NX_AZURE_IOT_SUCCESS);
642 }
643
644 /**
645 * Test direct method response empty json succeeds.
646 *
647 **/
test_nx_azure_iot_hub_client_direct_method_message_response_empty_success()648 static VOID test_nx_azure_iot_hub_client_direct_method_message_response_empty_success()
649 {
650 printf("test starts =>: %s\n", __func__);
651 will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS);
652 g_expected_message = (CHAR *)"{}";
653
654 assert_int_equal(nx_azure_iot_hub_client_direct_method_message_response(&iot_client,
655 200, (VOID *)test_request_id, sizeof(test_request_id) - 1,
656 NX_NULL, 0,
657 NX_WAIT_FOREVER),
658 NX_AZURE_IOT_SUCCESS);
659 }
660
demo_entry(NX_IP * ip_ptr,NX_PACKET_POOL * pool_ptr,NX_DNS * dns_ptr,UINT (* unix_time_callback)(ULONG * unix_time))661 VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time))
662 {
663 NX_AZURE_TEST_FN tests[] = { test_nx_azure_iot_hub_client_direct_method_enable_invalid_argument_failure,
664 test_nx_azure_iot_hub_client_direct_method_enable_failure,
665 test_nx_azure_iot_hub_client_direct_method_enable_success,
666 test_nx_azure_iot_hub_client_direct_method_disable_invalid_argument_failure,
667 test_nx_azure_iot_hub_client_direct_method_disable_failure,
668 test_nx_azure_iot_hub_client_direct_method_disable_success,
669 test_nx_azure_iot_hub_client_direct_method_message_receive_invalid_argument_failure,
670 test_nx_azure_iot_hub_client_direct_method_message_receive_success,
671 test_nx_azure_iot_hub_client_direct_method_message_receive_no_blocking_success,
672 test_nx_azure_iot_hub_client_direct_method_message_no_receive,
673 test_nx_azure_iot_hub_client_direct_method_message_response_invalid_argument_fail,
674 test_nx_azure_iot_hub_client_direct_method_message_response_send_failure_fail,
675 test_nx_azure_iot_hub_client_direct_method_message_response_success,
676 test_nx_azure_iot_hub_client_direct_method_message_response_empty_success };
677 INT number_of_tests = sizeof(tests)/sizeof(tests[0]);
678 g_ip_ptr = ip_ptr;
679 g_pool_ptr = pool_ptr;
680 g_dns_ptr = dns_ptr;
681
682 test_suit_begin();
683
684 printf("Number of tests %d\r\n", number_of_tests);
685 for (INT index = 0; index < number_of_tests; index++)
686 {
687 test_begin();
688 tests[index]();
689 test_end();
690 }
691
692 test_suit_end();
693 }
694