check_utils.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. #include <stdlib.h>
  5. #include "ua_types.h"
  6. #include "ua_client.h"
  7. #include "ua_util.h"
  8. #include "ua_util_internal.h"
  9. #include "check.h"
  10. START_TEST(EndpointUrl_split) {
  11. UA_String hostname = UA_STRING_NULL;
  12. UA_String path = UA_STRING_NULL;
  13. UA_UInt16 port = 0;
  14. // check for too short url
  15. UA_String endPointUrl = UA_STRING("inv.ali:/");
  16. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path),
  17. UA_STATUSCODE_BADTCPENDPOINTURLINVALID);
  18. // check for opc.tcp:// protocol
  19. endPointUrl = UA_STRING("inv.ali://");
  20. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path),
  21. UA_STATUSCODE_BADTCPENDPOINTURLINVALID);
  22. // empty url
  23. endPointUrl = UA_STRING("opc.tcp://");
  24. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path),
  25. UA_STATUSCODE_BADTCPENDPOINTURLINVALID);
  26. ck_assert(UA_String_equal(&hostname, &UA_STRING_NULL));
  27. ck_assert_uint_eq(port, 0);
  28. ck_assert(UA_String_equal(&path, &UA_STRING_NULL));
  29. // only hostname
  30. endPointUrl = UA_STRING("opc.tcp://hostname");
  31. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path), UA_STATUSCODE_GOOD);
  32. UA_String expected = UA_STRING("hostname");
  33. ck_assert(UA_String_equal(&hostname, &expected));
  34. ck_assert_uint_eq(port, 0);
  35. ck_assert(UA_String_equal(&path, &UA_STRING_NULL));
  36. // empty port
  37. endPointUrl = UA_STRING("opc.tcp://hostname:");
  38. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path),
  39. UA_STATUSCODE_BADTCPENDPOINTURLINVALID);
  40. ck_assert(UA_String_equal(&hostname, &expected));
  41. ck_assert_uint_eq(port, 0);
  42. ck_assert(UA_String_equal(&path, &UA_STRING_NULL));
  43. // specific port
  44. endPointUrl = UA_STRING("opc.tcp://hostname:1234");
  45. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path),
  46. UA_STATUSCODE_GOOD);
  47. ck_assert(UA_String_equal(&hostname, &expected));
  48. ck_assert_uint_eq(port, 1234);
  49. ck_assert(UA_String_equal(&path, &UA_STRING_NULL));
  50. // IPv6
  51. endPointUrl = UA_STRING("opc.tcp://[2001:0db8:85a3::8a2e:0370:7334]:1234/path");
  52. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path), UA_STATUSCODE_GOOD);
  53. expected = UA_STRING("[2001:0db8:85a3::8a2e:0370:7334]");
  54. UA_String expectedPath = UA_STRING("path");
  55. ck_assert(UA_String_equal(&hostname, &expected));
  56. ck_assert_uint_eq(port, 1234);
  57. ck_assert(UA_String_equal(&path, &expectedPath));
  58. // invalid IPv6: missing ]
  59. endPointUrl = UA_STRING("opc.tcp://[2001:0db8:85a3::8a2e:0370:7334");
  60. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path), UA_STATUSCODE_BADTCPENDPOINTURLINVALID);
  61. // empty hostname
  62. endPointUrl = UA_STRING("opc.tcp://:");
  63. port = 0;
  64. path = UA_STRING_NULL;
  65. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path),
  66. UA_STATUSCODE_BADTCPENDPOINTURLINVALID);
  67. ck_assert(UA_String_equal(&hostname, &UA_STRING_NULL));
  68. ck_assert_uint_eq(port, 0);
  69. ck_assert(UA_String_equal(&path, &UA_STRING_NULL));
  70. // empty hostname and no port
  71. endPointUrl = UA_STRING("opc.tcp:///");
  72. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path), UA_STATUSCODE_GOOD);
  73. ck_assert(UA_String_equal(&hostname, &UA_STRING_NULL));
  74. ck_assert_uint_eq(port, 0);
  75. ck_assert(UA_String_equal(&path, &UA_STRING_NULL));
  76. // overlength port
  77. endPointUrl = UA_STRING("opc.tcp://hostname:12345678");
  78. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path),
  79. UA_STATUSCODE_BADTCPENDPOINTURLINVALID);
  80. // port not a number
  81. endPointUrl = UA_STRING("opc.tcp://hostname:6x6");
  82. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path),
  83. UA_STATUSCODE_BADTCPENDPOINTURLINVALID);
  84. expected = UA_STRING("hostname");
  85. ck_assert(UA_String_equal(&hostname, &expected));
  86. ck_assert_uint_eq(port, 0);
  87. ck_assert(UA_String_equal(&path, &UA_STRING_NULL));
  88. // no port but path
  89. endPointUrl = UA_STRING("opc.tcp://hostname/");
  90. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path), UA_STATUSCODE_GOOD);
  91. ck_assert(UA_String_equal(&hostname, &expected));
  92. ck_assert_uint_eq(port, 0);
  93. ck_assert(UA_String_equal(&path, &UA_STRING_NULL));
  94. // port and path
  95. endPointUrl = UA_STRING("opc.tcp://hostname:1234/path");
  96. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path), UA_STATUSCODE_GOOD);
  97. ck_assert(UA_String_equal(&hostname, &expected));
  98. ck_assert_uint_eq(port, 1234);
  99. ck_assert(UA_String_equal(&path, &expectedPath));
  100. // port and path with a slash
  101. endPointUrl = UA_STRING("opc.tcp://hostname:1234/path/");
  102. ck_assert_uint_eq(UA_parseEndpointUrl(&endPointUrl, &hostname, &port, &path), UA_STATUSCODE_GOOD);
  103. ck_assert(UA_String_equal(&hostname, &expected));
  104. ck_assert_uint_eq(port, 1234);
  105. ck_assert(UA_String_equal(&path, &expectedPath));
  106. }
  107. END_TEST
  108. START_TEST(EndpointUrl_ethernet) {
  109. UA_String target;
  110. UA_UInt16 vid = 0;
  111. UA_Byte pcp = 0;
  112. UA_String expected;
  113. // check for too short url
  114. UA_String endPointUrl = UA_STRING("inv.ali:/");
  115. ck_assert_uint_eq(UA_parseEndpointUrlEthernet(&endPointUrl, &target, &vid, &pcp),
  116. UA_STATUSCODE_BADINTERNALERROR);
  117. ck_assert_uint_eq(vid, 0);
  118. ck_assert_uint_eq(pcp, 0);
  119. // long enough, but malformed
  120. endPointUrl = UA_STRING("opc.eth.//target:");
  121. ck_assert_uint_eq(UA_parseEndpointUrlEthernet(&endPointUrl, &target, &vid, &pcp),
  122. UA_STATUSCODE_BADINTERNALERROR);
  123. // valid without vid and pcp but leading ':'
  124. endPointUrl = UA_STRING("opc.eth://target:");
  125. ck_assert_uint_eq(UA_parseEndpointUrlEthernet(&endPointUrl, &target, &vid, &pcp),
  126. UA_STATUSCODE_BADINTERNALERROR);
  127. ck_assert_uint_eq(vid, 0);
  128. ck_assert_uint_eq(pcp, 0);
  129. // without pcp and vid as non decimal
  130. endPointUrl = UA_STRING("opc.eth://target:abc");
  131. ck_assert_uint_eq(UA_parseEndpointUrlEthernet(&endPointUrl, &target, &vid, &pcp),
  132. UA_STATUSCODE_BADINTERNALERROR);
  133. ck_assert_uint_eq(vid, 0);
  134. ck_assert_uint_eq(pcp, 0);
  135. // pcp as non decimal
  136. endPointUrl = UA_STRING("opc.eth://target:100.abc");
  137. ck_assert_uint_eq(UA_parseEndpointUrlEthernet(&endPointUrl, &target, &vid, &pcp),
  138. UA_STATUSCODE_BADINTERNALERROR);
  139. ck_assert_uint_eq(vid, 100);
  140. ck_assert_uint_eq(pcp, 0);
  141. // valid without pcp but leading '.'
  142. endPointUrl = UA_STRING("opc.eth://target:100.");
  143. ck_assert_uint_eq(UA_parseEndpointUrlEthernet(&endPointUrl, &target, &vid, &pcp),
  144. UA_STATUSCODE_BADINTERNALERROR);
  145. ck_assert_uint_eq(vid, 100);
  146. ck_assert_uint_eq(pcp, 0);
  147. // valid without pcp
  148. endPointUrl = UA_STRING("opc.eth://target:100");
  149. ck_assert_uint_eq(UA_parseEndpointUrlEthernet(&endPointUrl, &target, &vid, &pcp),
  150. UA_STATUSCODE_GOOD);
  151. expected = UA_STRING("target");
  152. ck_assert(UA_String_equal(&target, &expected));
  153. ck_assert_uint_eq(vid, 100);
  154. ck_assert_uint_eq(pcp, 0);
  155. // valid
  156. endPointUrl = UA_STRING("opc.eth://target:100.7");
  157. ck_assert_uint_eq(UA_parseEndpointUrlEthernet(&endPointUrl, &target, &vid, &pcp),
  158. UA_STATUSCODE_GOOD);
  159. expected = UA_STRING("target");
  160. ck_assert(UA_String_equal(&target, &expected));
  161. ck_assert_uint_eq(vid, 100);
  162. ck_assert_uint_eq(pcp, 7);
  163. }
  164. END_TEST
  165. START_TEST(readNumber) {
  166. UA_UInt32 result;
  167. ck_assert_uint_eq(UA_readNumber((UA_Byte*)"x", 1, &result), 0);
  168. ck_assert_uint_eq(UA_readNumber((UA_Byte*)"1x", 2, &result), 1);
  169. ck_assert_uint_eq(result, 1);
  170. ck_assert_uint_eq(UA_readNumber((UA_Byte*)"123456789", 9, &result), 9);
  171. ck_assert_uint_eq(result, 123456789);
  172. }
  173. END_TEST
  174. START_TEST(readNumberWithBase) {
  175. UA_UInt32 result;
  176. ck_assert_uint_eq(UA_readNumberWithBase((UA_Byte*)"g", 1, &result, 16), 0);
  177. ck_assert_uint_eq(UA_readNumberWithBase((UA_Byte*)"f", 1, &result, 16), 1);
  178. ck_assert_uint_eq(result, 15);
  179. ck_assert_uint_eq(UA_readNumberWithBase((UA_Byte*)"F", 1, &result, 16), 1);
  180. ck_assert_uint_eq(result, 15);
  181. ck_assert_uint_eq(UA_readNumberWithBase((UA_Byte*)"1x", 2, &result, 16), 1);
  182. ck_assert_uint_eq(result, 1);
  183. ck_assert_uint_eq(UA_readNumberWithBase((UA_Byte*)"12345678", 9, &result, 16), 8);
  184. ck_assert_uint_eq(result, 0x12345678);
  185. ck_assert_uint_eq(UA_readNumberWithBase((UA_Byte*)"123456789", 9, &result, 8), 7);
  186. ck_assert_uint_eq(result, 01234567);
  187. }
  188. END_TEST
  189. START_TEST(StatusCode_msg) {
  190. #ifndef UA_ENABLE_STATUSCODE_DESCRIPTIONS
  191. return;
  192. #endif
  193. // first element in table
  194. ck_assert_str_eq(UA_StatusCode_name(UA_STATUSCODE_GOOD), "Good");
  195. // just some randomly picked status codes
  196. ck_assert_str_eq(UA_StatusCode_name(UA_STATUSCODE_BADNOCOMMUNICATION),
  197. "BadNoCommunication");
  198. ck_assert_str_eq(UA_StatusCode_name(UA_STATUSCODE_GOODNODATA), "GoodNoData");
  199. // last element in table
  200. ck_assert_str_eq(UA_StatusCode_name(UA_STATUSCODE_BADMAXCONNECTIONSREACHED),
  201. "BadMaxConnectionsReached");
  202. // an invalid status code
  203. ck_assert_str_eq(UA_StatusCode_name(0x80123456), "Unknown StatusCode");
  204. }
  205. END_TEST
  206. static void assertNodeIdString(const UA_String *gotStr, const char* expectedStr) {
  207. size_t expectedStringLength = strlen(expectedStr);
  208. ck_assert_uint_eq(gotStr->length, expectedStringLength);
  209. char *gotChars = (char*)UA_malloc(gotStr->length+1);
  210. memcpy(gotChars, gotStr->data, gotStr->length);
  211. gotChars[gotStr->length] = 0;
  212. ck_assert_str_eq(gotChars, expectedStr);
  213. UA_free(gotChars);
  214. }
  215. START_TEST(idToStringNull) {
  216. UA_String str = UA_STRING_NULL;
  217. ck_assert_int_eq(UA_NodeId_toString(NULL, &str), UA_STATUSCODE_GOOD);
  218. } END_TEST
  219. START_TEST(idToStringNumeric) {
  220. UA_NodeId n;
  221. UA_String str = UA_STRING_NULL;
  222. n = UA_NODEID_NUMERIC(0,0);
  223. UA_NodeId_toString(&n, &str);
  224. assertNodeIdString(&str, "i=0");
  225. n = UA_NODEID_NUMERIC(12345,1234567890);
  226. UA_NodeId_toString(&n, &str);
  227. assertNodeIdString(&str, "ns=12345;i=1234567890");
  228. n = UA_NODEID_NUMERIC(0xFFFF,0xFFFFFFFF);
  229. UA_NodeId_toString(&n, &str);
  230. assertNodeIdString(&str, "ns=65535;i=4294967295");
  231. UA_String_deleteMembers(&str);
  232. } END_TEST
  233. START_TEST(idToStringString) {
  234. UA_NodeId n;
  235. UA_String str = UA_STRING_NULL;
  236. n = UA_NODEID_STRING(0,"");
  237. UA_NodeId_toString(&n, &str);
  238. assertNodeIdString(&str, "s=");
  239. n = UA_NODEID_STRING(54321,"Some String");
  240. UA_NodeId_toString(&n, &str);
  241. assertNodeIdString(&str, "ns=54321;s=Some String");
  242. n = UA_NODEID_STRING(0,"Some String");
  243. UA_NodeId_toString(&n, &str);
  244. assertNodeIdString(&str, "s=Some String");
  245. UA_String_deleteMembers(&str);
  246. } END_TEST
  247. START_TEST(idToStringGuid) {
  248. UA_NodeId n;
  249. UA_String str = UA_STRING_NULL;
  250. UA_Guid g = UA_GUID_NULL;
  251. n = UA_NODEID_GUID(0,UA_GUID_NULL);
  252. UA_NodeId_toString(&n, &str);
  253. assertNodeIdString(&str, "g=00000000-0000-0000-0000-000000000000");
  254. g.data1 = 0xA123456C;
  255. g.data2 = 0x0ABC;
  256. g.data3 = 0x1A2B;
  257. g.data4[0] = 0x81;
  258. g.data4[1] = 0x5F;
  259. g.data4[2] = 0x68;
  260. g.data4[3] = 0x72;
  261. g.data4[4] = 0x12;
  262. g.data4[5] = 0xAA;
  263. g.data4[6] = 0xEE;
  264. g.data4[7] = 0x1B;
  265. n = UA_NODEID_GUID(65535,g);
  266. UA_NodeId_toString(&n, &str);
  267. assertNodeIdString(&str, "ns=65535;g=a123456c-0abc-1a2b-815f-687212aaee1b");
  268. g.data1 = 0xFFFFFFFF;
  269. g.data2 = 0xFFFF;
  270. g.data3 = 0xFFFF;
  271. g.data4[0] = 0xFF;
  272. g.data4[1] = 0xFF;
  273. g.data4[2] = 0xFF;
  274. g.data4[3] = 0xFF;
  275. g.data4[4] = 0xFF;
  276. g.data4[5] = 0xFF;
  277. g.data4[6] = 0xFF;
  278. g.data4[7] = 0xFF;
  279. n = UA_NODEID_GUID(65535,g);
  280. UA_NodeId_toString(&n, &str);
  281. assertNodeIdString(&str, "ns=65535;g=ffffffff-ffff-ffff-ffff-ffffffffffff");
  282. UA_String_deleteMembers(&str);
  283. } END_TEST
  284. START_TEST(idToStringByte) {
  285. UA_NodeId n;
  286. UA_String str = UA_STRING_NULL;
  287. n.namespaceIndex = 0;
  288. n.identifierType = UA_NODEIDTYPE_BYTESTRING;
  289. n.identifier.byteString.data = NULL;
  290. n.identifier.byteString.length = 0;
  291. UA_NodeId_toString(&n, &str);
  292. assertNodeIdString(&str, "b=");
  293. UA_ByteString bs = UA_BYTESTRING_NULL;
  294. bs.length = 1;
  295. bs.data = (UA_Byte*)UA_malloc(bs.length);
  296. bs.data[0] = 0x00;
  297. n.identifier.byteString = bs;
  298. n.namespaceIndex = 123;
  299. UA_NodeId_toString(&n, &str);
  300. assertNodeIdString(&str, "ns=123;b=AA==");
  301. UA_free(bs.data);
  302. bs.length = 1;
  303. bs.data = (UA_Byte*)UA_malloc(bs.length);
  304. bs.data[0] = 0x2C;
  305. n.identifier.byteString = bs;
  306. n.namespaceIndex = 123;
  307. UA_NodeId_toString(&n, &str);
  308. assertNodeIdString(&str, "ns=123;b=LA==");
  309. UA_free(bs.data);
  310. bs.length = 5;
  311. bs.data = (UA_Byte*)UA_malloc(bs.length);
  312. bs.data[0] = 0x21;
  313. bs.data[1] = 0x83;
  314. bs.data[2] = 0xE0;
  315. bs.data[3] = 0x54;
  316. bs.data[4] = 0x78;
  317. n.identifier.byteString = bs;
  318. n.namespaceIndex = 599;
  319. UA_NodeId_toString(&n, &str);
  320. assertNodeIdString(&str, "ns=599;b=IYPgVHg=");
  321. UA_free(bs.data);
  322. UA_String_deleteMembers(&str);
  323. } END_TEST
  324. static Suite* testSuite_Utils(void) {
  325. Suite *s = suite_create("Utils");
  326. TCase *tc_endpointUrl_split = tcase_create("EndpointUrl_split");
  327. tcase_add_test(tc_endpointUrl_split, EndpointUrl_split);
  328. suite_add_tcase(s,tc_endpointUrl_split);
  329. TCase *tc_endpointUrl_ethernet = tcase_create("EndpointUrl_ethernet");
  330. tcase_add_test(tc_endpointUrl_ethernet, EndpointUrl_ethernet);
  331. suite_add_tcase(s,tc_endpointUrl_ethernet);
  332. TCase *tc_utils = tcase_create("Utils");
  333. tcase_add_test(tc_utils, readNumber);
  334. tcase_add_test(tc_utils, readNumberWithBase);
  335. tcase_add_test(tc_utils, StatusCode_msg);
  336. suite_add_tcase(s,tc_utils);
  337. TCase *tc1 = tcase_create("test nodeid string");
  338. tcase_add_test(tc1, idToStringNull);
  339. tcase_add_test(tc1, idToStringNumeric);
  340. tcase_add_test(tc1, idToStringString);
  341. tcase_add_test(tc1, idToStringGuid);
  342. tcase_add_test(tc1, idToStringByte);
  343. suite_add_tcase(s, tc1);
  344. return s;
  345. }
  346. int main(void) {
  347. Suite *s = testSuite_Utils();
  348. SRunner *sr = srunner_create(s);
  349. srunner_set_fork_status(sr, CK_NOFORK);
  350. srunner_run_all(sr,CK_NORMAL);
  351. int number_failed = srunner_ntests_failed(sr);
  352. srunner_free(sr);
  353. return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
  354. }