1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/ztest.h>
8 #include <zephyr/net_buf.h>
9 #include <string.h>
10 #include <zephyr/mgmt/mcumgr/smp/smp_client.h>
11 #include <zephyr/mgmt/mcumgr/mgmt/mgmt.h>
12 #include <zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h>
13 #include <zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h>
14 #include <zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_client.h>
15 /* Include stubbed test helpers */
16 #include "smp_stub.h"
17 #include "img_gr_stub.h"
18 #include "os_gr_stub.h"
19 
20 /* IMG group data */
21 static uint8_t image_hash[32];
22 static struct mcumgr_image_data image_info[2];
23 static uint8_t image_dummy[1024];
24 
25 static const char os_echo_test[] = "TestString";
26 static struct smp_client_object smp_client;
27 static struct img_mgmt_client img_client;
28 static struct os_mgmt_client os_client;
29 
ZTEST(mcumgr_client,test_img_upload)30 ZTEST(mcumgr_client, test_img_upload)
31 {
32 	int rc;
33 	struct mcumgr_image_upload response;
34 
35 	smp_stub_set_rx_data_verify(NULL);
36 	img_upload_stub_init();
37 
38 	img_mgmt_client_init(&img_client, &smp_client, 2, image_info);
39 
40 	rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, image_hash);
41 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
42 	/* Start upload  and test Timeout */
43 	rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response);
44 	zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d",
45 		      MGMT_ERR_ETIMEOUT, rc);
46 	zassert_equal(MGMT_ERR_ETIMEOUT, response.status, "Expected to receive %d response %d\n",
47 		      MGMT_ERR_ETIMEOUT, response.status);
48 	rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, image_hash);
49 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
50 	rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, image_hash);
51 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
52 	/* Start upload  and test Timeout */
53 	rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response);
54 	zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d",
55 		      MGMT_ERR_ETIMEOUT, rc);
56 	zassert_equal(MGMT_ERR_ETIMEOUT, response.status, "Expected to receive %d response %d",
57 		      MGMT_ERR_ETIMEOUT, response.status);
58 
59 	smp_client_send_status_stub(MGMT_ERR_EOK);
60 
61 	/* Allocate response buf */
62 	img_upload_response(0, MGMT_ERR_EINVAL);
63 	rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response);
64 	zassert_equal(MGMT_ERR_EINVAL, rc, "Expected to receive %d response %d", MGMT_ERR_EINVAL,
65 		      rc);
66 	zassert_equal(MGMT_ERR_EINVAL, response.status, "Expected to receive %d response %d",
67 		      MGMT_ERR_EINVAL, response.status);
68 	rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, image_hash);
69 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d\n", MGMT_ERR_EOK, rc);
70 	img_upload_response(1024, MGMT_ERR_EOK);
71 
72 	smp_stub_set_rx_data_verify(img_upload_init_verify);
73 	img_upload_stub_init();
74 	rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response);
75 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
76 	zassert_equal(MGMT_ERR_EOK, response.status, "Expected to receive %d response %d",
77 		      MGMT_ERR_EOK, response.status);
78 	zassert_equal(1024, response.image_upload_offset,
79 		      "Expected to receive offset %d response %d", 1024,
80 		      response.image_upload_offset);
81 	/* Send last frame from image */
82 	rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response);
83 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
84 	zassert_equal(MGMT_ERR_EOK, response.status, "Expected to receive %d response %d",
85 		      MGMT_ERR_EOK, response.status);
86 	zassert_equal(TEST_IMAGE_SIZE, response.image_upload_offset,
87 		      "Expected to receive offset %d response %d", TEST_IMAGE_SIZE,
88 		      response.image_upload_offset);
89 
90 	/* Test without hash */
91 	rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, NULL);
92 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
93 	img_upload_stub_init();
94 	rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response);
95 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
96 	zassert_equal(MGMT_ERR_EOK, response.status, "Expected to receive %d response %d",
97 		      MGMT_ERR_EOK, response.status);
98 	zassert_equal(1024, response.image_upload_offset,
99 		      "Expected to receive offset %d response %d", 1024,
100 		      response.image_upload_offset);
101 	/* Send last frame from image */
102 	rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response);
103 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
104 	zassert_equal(MGMT_ERR_EOK, response.status, "Expected to receive %d response %d",
105 		      MGMT_ERR_EOK, response.status);
106 	zassert_equal(TEST_IMAGE_SIZE, response.image_upload_offset,
107 		      "Expected to receive offset %d response %d", TEST_IMAGE_SIZE,
108 		      response.image_upload_offset);
109 }
110 
ZTEST(mcumgr_client,test_img_erase)111 ZTEST(mcumgr_client, test_img_erase)
112 {
113 	int rc;
114 
115 	smp_client_send_status_stub(MGMT_ERR_EOK);
116 
117 	/* Test timeout */
118 	rc = img_mgmt_client_erase(&img_client, TEST_SLOT_NUMBER);
119 	zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d",
120 		      MGMT_ERR_ETIMEOUT, rc);
121 
122 	/* Test erase fail */
123 	img_erase_response(MGMT_ERR_EINVAL);
124 	rc = img_mgmt_client_erase(&img_client, TEST_SLOT_NUMBER);
125 	zassert_equal(MGMT_ERR_EINVAL, rc, "Expected to receive %d response %d", MGMT_ERR_EINVAL,
126 		      rc);
127 	/* Tesk ok */
128 	img_erase_response(MGMT_ERR_EOK);
129 	rc = img_mgmt_client_erase(&img_client, TEST_SLOT_NUMBER);
130 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
131 }
132 
ZTEST(mcumgr_client,test_image_state_read)133 ZTEST(mcumgr_client, test_image_state_read)
134 {
135 	int rc;
136 	struct mcumgr_image_state res_buf;
137 
138 	smp_client_send_status_stub(MGMT_ERR_EOK);
139 	/* Test timeout */
140 	rc = img_mgmt_client_state_read(&img_client, &res_buf);
141 	zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d",
142 		      MGMT_ERR_ETIMEOUT, rc);
143 	/* Testing read successfully 1 image info and print that */
144 	img_read_response(1);
145 	rc = img_mgmt_client_state_read(&img_client, &res_buf);
146 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
147 	zassert_equal(1, res_buf.image_list_length, "Expected to receive %d response %d", 1,
148 		      res_buf.image_list_length);
149 	img_read_response(2);
150 	rc = img_mgmt_client_state_read(&img_client, &res_buf);
151 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
152 	zassert_equal(2, res_buf.image_list_length, "Expected to receive %d response %d", 2,
153 		      res_buf.image_list_length);
154 }
155 
ZTEST(mcumgr_client,test_image_state_set)156 ZTEST(mcumgr_client, test_image_state_set)
157 {
158 	int rc;
159 	char hash[32];
160 	struct mcumgr_image_state res_buf;
161 
162 	smp_client_response_buf_clean();
163 	smp_stub_set_rx_data_verify(NULL);
164 	smp_client_send_status_stub(MGMT_ERR_EOK);
165 	/* Test timeout */
166 	rc = img_mgmt_client_state_write(&img_client, NULL, false, &res_buf);
167 	zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d",
168 		      MGMT_ERR_ETIMEOUT, rc);
169 
170 	printf("Timeout OK\r\n");
171 	/* Read secondary image hash for testing */
172 	img_read_response(2);
173 	rc = img_mgmt_client_state_read(&img_client, &res_buf);
174 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
175 	zassert_equal(2, res_buf.image_list_length, "Expected to receive %d response %d", 2,
176 		      res_buf.image_list_length);
177 	zassert_equal(false, image_info[1].flags.pending, "Expected to receive %d response %d",
178 		      false, image_info[1].flags.pending);
179 	/* Copy hash for set pending flag */
180 	memcpy(hash, image_info[1].hash, 32);
181 	printf("Read OK\r\n");
182 
183 	/* Read secondary image hash for testing */
184 	smp_stub_set_rx_data_verify(img_state_write_verify);
185 	rc = img_mgmt_client_state_write(&img_client, hash, false, &res_buf);
186 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
187 	zassert_equal(2, res_buf.image_list_length, "Expected to receive %d response %d", 2,
188 		      res_buf.image_list_length);
189 	zassert_equal(true, image_info[1].flags.pending, "Expected to receive %d response %d",
190 		      true, image_info[1].flags.pending);
191 	/* Test to set confirmed bit  */
192 	image_info[0].flags.confirmed = false;
193 	smp_stub_set_rx_data_verify(img_state_write_verify);
194 	rc = img_mgmt_client_state_write(&img_client, NULL, true, &res_buf);
195 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
196 	zassert_equal(2, res_buf.image_list_length, "Expected to receive %d response %d", 2,
197 		      res_buf.image_list_length);
198 	zassert_equal(true, image_info[0].flags.confirmed, "Expected to receive %d response %d",
199 		      true, image_info[0].flags.confirmed);
200 }
201 
ZTEST(mcumgr_client,test_os_reset)202 ZTEST(mcumgr_client, test_os_reset)
203 {
204 	int rc;
205 
206 	smp_client_response_buf_clean();
207 	smp_stub_set_rx_data_verify(NULL);
208 
209 	smp_client_send_status_stub(MGMT_ERR_EOK);
210 	/* Test timeout */
211 	rc = os_mgmt_client_reset(&os_client);
212 	zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d",
213 		      MGMT_ERR_ETIMEOUT, rc);
214 	/* Testing reset successfully handling */
215 	os_reset_response();
216 	rc = os_mgmt_client_reset(&os_client);
217 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
218 }
219 
ZTEST(mcumgr_client,test_os_echo)220 ZTEST(mcumgr_client, test_os_echo)
221 {
222 	int rc;
223 
224 	smp_client_response_buf_clean();
225 	smp_stub_set_rx_data_verify(NULL);
226 	smp_client_send_status_stub(MGMT_ERR_EOK);
227 	/* Test timeout */
228 	rc = os_mgmt_client_echo(&os_client, os_echo_test, sizeof(os_echo_test));
229 	zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d",
230 		      MGMT_ERR_ETIMEOUT, rc);
231 	/* Test successfully operation */
232 	smp_stub_set_rx_data_verify(os_echo_verify);
233 	rc = os_mgmt_client_echo(&os_client, os_echo_test, sizeof(os_echo_test));
234 	zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc);
235 }
236 
setup_custom_os(void)237 static void *setup_custom_os(void)
238 {
239 	stub_smp_client_transport_register();
240 	smp_client_object_init(&smp_client, SMP_SERIAL_TRANSPORT);
241 	os_mgmt_client_init(&os_client, &smp_client);
242 	img_mgmt_client_init(&img_client, &smp_client, 2, image_info);
243 
244 	img_gr_stub_data_init(image_hash);
245 	os_stub_init(os_echo_test);
246 	return NULL;
247 }
248 
cleanup_test(void * p)249 static void cleanup_test(void *p)
250 {
251 	smp_client_response_buf_clean();
252 	smp_stub_set_rx_data_verify(NULL);
253 }
254 
255 /* Main test set */
256 ZTEST_SUITE(mcumgr_client, NULL, setup_custom_os, NULL, cleanup_test, NULL);
257