1 /*
2 * Copyright (c) 2023, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <string.h>
30
31 #include "test_util.h"
32 #include "lib/url/url.hpp"
33
34 namespace ot {
35 namespace Url {
36
TestSimple(void)37 void TestSimple(void)
38 {
39 char url[] = "spinel:///dev/ttyUSB0?baudrate=115200";
40 Url args;
41
42 VerifyOrQuit(!args.Init(url));
43
44 VerifyOrQuit(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
45 VerifyOrQuit(!strcmp(args.GetValue("baudrate"), "115200"));
46 VerifyOrQuit(args.GetValue("not-exists") == nullptr);
47 VerifyOrQuit(args.GetValue("last-value-wrong-position", url) == nullptr);
48 VerifyOrQuit(args.GetValue("last-value-before-url", url - 1) == nullptr);
49 VerifyOrQuit(args.GetValue("last-value-after-url", url + sizeof(url)) == nullptr);
50
51 printf("PASS %s\r\n", __func__);
52 }
53
TestSimpleNoQueryString(void)54 void TestSimpleNoQueryString(void)
55 {
56 char url[] = "spinel:///dev/ttyUSB0";
57 Url args;
58
59 VerifyOrQuit(!args.Init(url));
60 VerifyOrQuit(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
61 VerifyOrQuit(args.GetValue("last-value-wrong-position", url) == nullptr);
62 VerifyOrQuit(args.GetValue("last-value-before-url", url - 1) == nullptr);
63 VerifyOrQuit(args.GetValue("last-value-after-url", url + sizeof(url)) == nullptr);
64
65 printf("PASS %s\r\n", __func__);
66 }
67
TestEmptyValue(void)68 void TestEmptyValue(void)
69 {
70 char url[] = "spinel:///dev/ttyUSB0?rtscts&baudrate=115200&verbose&verbose&verbose";
71 Url args;
72 const char *arg = nullptr;
73
74 VerifyOrQuit(!args.Init(url));
75 VerifyOrQuit(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
76 VerifyOrQuit((arg = args.GetValue("rtscts")) != nullptr);
77 VerifyOrQuit(args.GetValue("rtscts", arg) == nullptr);
78 VerifyOrQuit((arg = args.GetValue("verbose", arg)) != nullptr);
79 VerifyOrQuit((arg = args.GetValue("verbose", arg)) != nullptr);
80 VerifyOrQuit((arg = args.GetValue("verbose", arg)) != nullptr);
81 VerifyOrQuit((arg = args.GetValue("verbose", arg)) == nullptr);
82
83 printf("PASS %s\r\n", __func__);
84 }
85
TestMultipleProtocols(void)86 void TestMultipleProtocols(void)
87 {
88 char url[] = "spinel+spi:///dev/ttyUSB0?baudrate=115200";
89 Url args;
90
91 VerifyOrQuit(!args.Init(url));
92 VerifyOrQuit(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
93 VerifyOrQuit(!strcmp(args.GetValue("baudrate"), "115200"));
94
95 printf("PASS %s\r\n", __func__);
96 }
97
TestMultipleProtocolsAndDuplicateParameters(void)98 void TestMultipleProtocolsAndDuplicateParameters(void)
99 {
100 char url[] = "spinel+exec:///path/to/ot-rcp?arg=1&arg=arg2&arg=3";
101 Url args;
102 const char *arg = nullptr;
103
104 VerifyOrQuit(!args.Init(url));
105 VerifyOrQuit(!strcmp(args.GetPath(), "/path/to/ot-rcp"));
106
107 arg = args.GetValue("arg");
108 VerifyOrQuit(!strcmp(arg, "1"));
109
110 arg = args.GetValue("arg", arg);
111 VerifyOrQuit(!strcmp(arg, "arg2"));
112
113 arg = args.GetValue("arg", arg);
114 VerifyOrQuit(!strcmp(arg, "3"));
115
116 VerifyOrQuit(args.GetValue("arg", url) == nullptr);
117 VerifyOrQuit(args.GetValue("arg", url - 1) == nullptr);
118 VerifyOrQuit(args.GetValue("arg", url + sizeof(url)) == nullptr);
119
120 printf("PASS %s\r\n", __func__);
121 }
122
TestIntValue(void)123 void TestIntValue(void)
124 {
125 char int8url[] = "spinel:///dev/ttyUSB0?no-reset&val1=1&val2=0x02&val3=-0X03&val4=-4&val5=+5&val6=128&val7=-129";
126 char int16url[] = "spinel:///dev/ttyUSB0?val1=1&val2=0x02&val3=-0X03&val4=-400&val5=+500&val6=32768&val7=-32769";
127 char int32url[] =
128 "spinel:///dev/ttyUSB0?val1=1&val2=0x02&val3=-0X03&val4=-40000&val5=+50000&val6=2147483648&val7=-2147483649";
129 Url args;
130 int8_t int8val;
131 int16_t int16val;
132 int32_t int32val;
133
134 VerifyOrQuit(!args.Init(int8url));
135 VerifyOrQuit(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
136 VerifyOrQuit(args.HasParam("no-reset"));
137 VerifyOrQuit(!args.HasParam("reset"));
138 SuccessOrQuit(args.ParseInt8("val1", int8val));
139 VerifyOrQuit(int8val == 1);
140 SuccessOrQuit(args.ParseInt8("val2", int8val));
141 VerifyOrQuit(int8val == 2);
142 SuccessOrQuit(args.ParseInt8("val3", int8val));
143 VerifyOrQuit(int8val == -3);
144 SuccessOrQuit(args.ParseInt8("val4", int8val));
145 VerifyOrQuit(int8val == -4);
146 SuccessOrQuit(args.ParseInt8("val5", int8val));
147 VerifyOrQuit(int8val == 5);
148 VerifyOrQuit(args.ParseInt8("val6", int8val) == OT_ERROR_INVALID_ARGS);
149 VerifyOrQuit(int8val == 5);
150 VerifyOrQuit(args.ParseInt8("val7", int8val) == OT_ERROR_INVALID_ARGS);
151 VerifyOrQuit(int8val == 5);
152 VerifyOrQuit(args.ParseInt8("val8", int8val) == OT_ERROR_NOT_FOUND);
153 VerifyOrQuit(int8val == 5);
154
155 VerifyOrQuit(!args.Init(int16url));
156 VerifyOrQuit(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
157 SuccessOrQuit(args.ParseInt16("val1", int16val));
158 VerifyOrQuit(int16val == 1);
159 SuccessOrQuit(args.ParseInt16("val2", int16val));
160 VerifyOrQuit(int16val == 2);
161 SuccessOrQuit(args.ParseInt16("val3", int16val));
162 VerifyOrQuit(int16val == -3);
163 SuccessOrQuit(args.ParseInt16("val4", int16val));
164 VerifyOrQuit(int16val == -400);
165 SuccessOrQuit(args.ParseInt16("val5", int16val));
166 VerifyOrQuit(int16val == 500);
167 VerifyOrQuit(args.ParseInt16("val6", int16val) == OT_ERROR_INVALID_ARGS);
168 VerifyOrQuit(int16val == 500);
169 VerifyOrQuit(args.ParseInt16("val7", int16val) == OT_ERROR_INVALID_ARGS);
170 VerifyOrQuit(int16val == 500);
171 VerifyOrQuit(args.ParseInt16("val8", int16val) == OT_ERROR_NOT_FOUND);
172 VerifyOrQuit(int16val == 500);
173
174 VerifyOrQuit(!args.Init(int32url));
175 VerifyOrQuit(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
176 SuccessOrQuit(args.ParseInt32("val1", int32val));
177 VerifyOrQuit(int32val == 1);
178 SuccessOrQuit(args.ParseInt32("val2", int32val));
179 VerifyOrQuit(int32val == 2);
180 SuccessOrQuit(args.ParseInt32("val3", int32val));
181 VerifyOrQuit(int32val == -3);
182 SuccessOrQuit(args.ParseInt32("val4", int32val));
183 VerifyOrQuit(int32val == -40000);
184 SuccessOrQuit(args.ParseInt32("val5", int32val));
185 VerifyOrQuit(int32val == 50000);
186 VerifyOrQuit(args.ParseInt32("val6", int32val) == OT_ERROR_INVALID_ARGS);
187 VerifyOrQuit(int32val == 50000);
188 VerifyOrQuit(args.ParseInt32("val7", int32val) == OT_ERROR_INVALID_ARGS);
189 VerifyOrQuit(int32val == 50000);
190 VerifyOrQuit(args.ParseInt32("val8", int32val) == OT_ERROR_NOT_FOUND);
191 VerifyOrQuit(int32val == 50000);
192
193 printf("PASS %s\r\n", __func__);
194 }
195
TestUintValue(void)196 void TestUintValue(void)
197 {
198 char uint8url[] = "spinel:///dev/ttyUSB0?no-reset&val1=1&val2=0x02&val3=0X03&val4=-4&val5=+5&val6=256&val7=-1";
199 char uint16url[] = "spinel:///dev/ttyUSB0?val1=1&val2=0x02&val3=0X03&val4=-400&val5=+500&val6=65536&val7=-1";
200 char uint32url[] =
201 "spinel:///dev/ttyUSB0?val1=1&val2=0x02&val3=0X03&val4=-40000&val5=+70000&val6=4294967296&val7=-1";
202 Url args;
203 uint8_t uint8val;
204 uint16_t uint16val;
205 uint32_t uint32val;
206
207 VerifyOrQuit(!args.Init(uint8url));
208 VerifyOrQuit(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
209 SuccessOrQuit(args.ParseUint8("val1", uint8val));
210 VerifyOrQuit(uint8val == 1);
211 SuccessOrQuit(args.ParseUint8("val2", uint8val));
212 VerifyOrQuit(uint8val == 2);
213 SuccessOrQuit(args.ParseUint8("val3", uint8val));
214 VerifyOrQuit(uint8val == 3);
215 VerifyOrQuit(args.ParseUint8("val4", uint8val) == OT_ERROR_INVALID_ARGS);
216 VerifyOrQuit(uint8val == 3);
217 SuccessOrQuit(args.ParseUint8("val5", uint8val));
218 VerifyOrQuit(uint8val == 5);
219 VerifyOrQuit(args.ParseUint8("val6", uint8val) == OT_ERROR_INVALID_ARGS);
220 VerifyOrQuit(uint8val == 5);
221 VerifyOrQuit(args.ParseUint8("val7", uint8val) == OT_ERROR_INVALID_ARGS);
222 VerifyOrQuit(uint8val == 5);
223 VerifyOrQuit(args.ParseUint8("val8", uint8val) == OT_ERROR_NOT_FOUND);
224 VerifyOrQuit(uint8val == 5);
225
226 VerifyOrQuit(!args.Init(uint16url));
227 VerifyOrQuit(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
228 SuccessOrQuit(args.ParseUint16("val1", uint16val));
229 VerifyOrQuit(uint16val == 1);
230 SuccessOrQuit(args.ParseUint16("val2", uint16val));
231 VerifyOrQuit(uint16val == 2);
232 SuccessOrQuit(args.ParseUint16("val3", uint16val));
233 VerifyOrQuit(uint16val == 3);
234 VerifyOrQuit(args.ParseUint16("val4", uint16val) == OT_ERROR_INVALID_ARGS);
235 VerifyOrQuit(uint16val == 3);
236 SuccessOrQuit(args.ParseUint16("val5", uint16val));
237 VerifyOrQuit(uint16val == 500);
238 VerifyOrQuit(args.ParseUint16("val6", uint16val) == OT_ERROR_INVALID_ARGS);
239 VerifyOrQuit(uint16val == 500);
240 VerifyOrQuit(args.ParseUint16("val7", uint16val) == OT_ERROR_INVALID_ARGS);
241 VerifyOrQuit(uint16val == 500);
242 VerifyOrQuit(args.ParseUint16("val8", uint16val) == OT_ERROR_NOT_FOUND);
243 VerifyOrQuit(uint16val == 500);
244
245 VerifyOrQuit(!args.Init(uint32url));
246 VerifyOrQuit(!strcmp(args.GetPath(), "/dev/ttyUSB0"));
247 SuccessOrQuit(args.ParseUint32("val1", uint32val));
248 VerifyOrQuit(uint32val == 1);
249 SuccessOrQuit(args.ParseUint32("val2", uint32val));
250 VerifyOrQuit(uint32val == 2);
251 SuccessOrQuit(args.ParseUint32("val3", uint32val));
252 VerifyOrQuit(uint32val == 3);
253 VerifyOrQuit(args.ParseUint32("val4", uint32val) == OT_ERROR_INVALID_ARGS);
254 VerifyOrQuit(uint32val == 3);
255 SuccessOrQuit(args.ParseUint32("val5", uint32val));
256 VerifyOrQuit(uint32val == 70000);
257 VerifyOrQuit(args.ParseUint32("val6", uint32val) == OT_ERROR_INVALID_ARGS);
258 VerifyOrQuit(uint32val == 70000);
259 VerifyOrQuit(args.ParseUint32("val7", uint32val) == OT_ERROR_INVALID_ARGS);
260 VerifyOrQuit(uint32val == 70000);
261 VerifyOrQuit(args.ParseUint32("val8", uint32val) == OT_ERROR_NOT_FOUND);
262 VerifyOrQuit(uint32val == 70000);
263
264 printf("PASS %s\r\n", __func__);
265 }
266
267 } // namespace Url
268 } // namespace ot
269
main(void)270 int main(void)
271 {
272 ot::Url::TestSimple();
273 ot::Url::TestSimpleNoQueryString();
274 ot::Url::TestEmptyValue();
275 ot::Url::TestMultipleProtocols();
276 ot::Url::TestMultipleProtocolsAndDuplicateParameters();
277 ot::Url::TestIntValue();
278 ot::Url::TestUintValue();
279
280 return 0;
281 }
282