check_services_view.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  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 <open62541/client.h>
  5. #include <open62541/client_config_default.h>
  6. #include <open62541/server.h>
  7. #include <open62541/server_config_default.h>
  8. #include "server/ua_server_internal.h"
  9. #include <check.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include "thread_wrapper.h"
  13. UA_Server *server_translate_browse;
  14. UA_Boolean *running_translate_browse;
  15. THREAD_HANDLE server_thread_translate_browse;
  16. THREAD_CALLBACK(serverloop_register) {
  17. while (*running_translate_browse)
  18. UA_Server_run_iterate(server_translate_browse, true);
  19. return 0;
  20. }
  21. static void setup_server(void) {
  22. // start server
  23. running_translate_browse = UA_Boolean_new();
  24. *running_translate_browse = true;
  25. server_translate_browse = UA_Server_new();
  26. UA_ServerConfig *server_translate_config = UA_Server_getConfig(server_translate_browse);
  27. UA_ServerConfig_setDefault(server_translate_config);
  28. UA_String_deleteMembers(&server_translate_config->applicationDescription.applicationUri);
  29. server_translate_config->applicationDescription.applicationUri =
  30. UA_String_fromChars("urn:open62541.test.server_translate_browse");
  31. UA_Server_run_startup(server_translate_browse);
  32. THREAD_CREATE(server_thread_translate_browse, serverloop_register);
  33. }
  34. static void teardown_server(void) {
  35. *running_translate_browse = false;
  36. THREAD_JOIN(server_thread_translate_browse);
  37. UA_Server_run_shutdown(server_translate_browse);
  38. UA_Boolean_delete(running_translate_browse);
  39. UA_Server_delete(server_translate_browse);
  40. }
  41. static size_t
  42. browseWithMaxResults(UA_Server *server, UA_NodeId nodeId, UA_UInt32 maxResults) {
  43. UA_BrowseDescription bd;
  44. UA_BrowseDescription_init(&bd);
  45. bd.nodeId = nodeId;
  46. bd.resultMask = UA_BROWSERESULTMASK_ALL;
  47. bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;
  48. UA_BrowseResult br = UA_Server_browse(server, maxResults, &bd);
  49. ck_assert_int_eq(br.statusCode, UA_STATUSCODE_GOOD);
  50. ck_assert(br.referencesSize > 0);
  51. ck_assert(br.referencesSize <= maxResults);
  52. size_t total = br.referencesSize;
  53. UA_ByteString cp = br.continuationPoint;
  54. br.continuationPoint = UA_BYTESTRING_NULL;
  55. UA_BrowseResult_deleteMembers(&br);
  56. while(cp.length > 0) {
  57. br = UA_Server_browseNext(server, false, &cp);
  58. ck_assert(br.referencesSize > 0);
  59. ck_assert(br.referencesSize <= maxResults);
  60. UA_ByteString_deleteMembers(&cp);
  61. cp = br.continuationPoint;
  62. br.continuationPoint = UA_BYTESTRING_NULL;
  63. total += br.referencesSize;
  64. UA_BrowseResult_deleteMembers(&br);
  65. }
  66. return total;
  67. }
  68. START_TEST(Service_Browse_WithMaxResults) {
  69. UA_Server *server = UA_Server_new();
  70. UA_ServerConfig_setDefault(UA_Server_getConfig(server));
  71. UA_BrowseDescription bd;
  72. UA_BrowseDescription_init(&bd);
  73. bd.resultMask = UA_BROWSERESULTMASK_ALL;
  74. bd.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER);
  75. bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;
  76. UA_BrowseResult br = UA_Server_browse(server, 0, &bd);
  77. ck_assert_int_eq(br.statusCode, UA_STATUSCODE_GOOD);
  78. ck_assert(br.referencesSize > 0);
  79. size_t total = br.referencesSize;
  80. UA_BrowseResult_deleteMembers(&br);
  81. for(UA_UInt32 i = 1; i <= total; i++) {
  82. size_t sum_total =
  83. browseWithMaxResults(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER), i);
  84. ck_assert_int_eq(total, sum_total);
  85. }
  86. UA_Server_delete(server);
  87. }
  88. END_TEST
  89. START_TEST(Service_Browse_WithBrowseName) {
  90. UA_Server *server = UA_Server_new();
  91. UA_ServerConfig_setDefault(UA_Server_getConfig(server));
  92. UA_BrowseDescription bd;
  93. UA_BrowseDescription_init(&bd);
  94. bd.resultMask = UA_BROWSERESULTMASK_BROWSENAME;
  95. bd.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
  96. bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
  97. bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;
  98. UA_BrowseResult br = UA_Server_browse(server, 0, &bd);
  99. ck_assert_int_eq(br.statusCode, UA_STATUSCODE_GOOD);
  100. ck_assert(br.referencesSize > 0);
  101. ck_assert(!UA_String_equal(&br.references[0].browseName.name, &UA_STRING_NULL));
  102. UA_BrowseResult_deleteMembers(&br);
  103. UA_Server_delete(server);
  104. }
  105. END_TEST
  106. START_TEST(Service_Browse_Recursive) {
  107. UA_Server *server = UA_Server_new();
  108. UA_ServerConfig_setDefault(UA_Server_getConfig(server));
  109. size_t resultSize = 0;
  110. UA_ExpandedNodeId *result = NULL;
  111. UA_BrowseDescription bd;
  112. UA_BrowseDescription_init(&bd);
  113. bd.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_NAMESPACEARRAY);
  114. bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HIERARCHICALREFERENCES);
  115. bd.includeSubtypes = true;
  116. bd.browseDirection = UA_BROWSEDIRECTION_INVERSE;
  117. UA_StatusCode retval = UA_Server_browseRecursive(server, &bd, &resultSize, &result);
  118. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  119. ck_assert_uint_eq(resultSize, 3);
  120. UA_NodeId expected[3];
  121. expected[0] = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER);
  122. expected[1] = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
  123. expected[2] = UA_NODEID_NUMERIC(0, UA_NS0ID_ROOTFOLDER);
  124. for(size_t i = 0; i < resultSize; i++) {
  125. ck_assert(UA_NodeId_equal(&expected[i], &result[i].nodeId));
  126. }
  127. UA_Array_delete(result, resultSize, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
  128. UA_Server_delete(server);
  129. }
  130. END_TEST
  131. START_TEST(Service_TranslateBrowsePathsToNodeIds) {
  132. UA_Client *client = UA_Client_new();
  133. UA_ClientConfig_setDefault(UA_Client_getConfig(client));
  134. UA_StatusCode retVal = UA_Client_connect(client, "opc.tcp://localhost:4840");
  135. ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD);
  136. // Just for testing we want to translate the following path to its corresponding node id
  137. // /Objects/Server/ServerStatus/State
  138. // Equals the following node IDs:
  139. // /85/2253/2256/2259
  140. #define BROWSE_PATHS_SIZE 3
  141. char *paths[BROWSE_PATHS_SIZE] = {"Server", "ServerStatus", "State"};
  142. UA_UInt32 ids[BROWSE_PATHS_SIZE] = {UA_NS0ID_ORGANIZES, UA_NS0ID_HASCOMPONENT, UA_NS0ID_HASCOMPONENT};
  143. UA_BrowsePath browsePath;
  144. UA_BrowsePath_init(&browsePath);
  145. browsePath.startingNode = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
  146. browsePath.relativePath.elements = (UA_RelativePathElement*)UA_Array_new(BROWSE_PATHS_SIZE, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]);
  147. browsePath.relativePath.elementsSize = BROWSE_PATHS_SIZE;
  148. for(size_t i = 0; i < BROWSE_PATHS_SIZE; i++) {
  149. UA_RelativePathElement *elem = &browsePath.relativePath.elements[i];
  150. elem->referenceTypeId = UA_NODEID_NUMERIC(0, ids[i]);
  151. elem->targetName = UA_QUALIFIEDNAME_ALLOC(0, paths[i]);
  152. }
  153. UA_TranslateBrowsePathsToNodeIdsRequest request;
  154. UA_TranslateBrowsePathsToNodeIdsRequest_init(&request);
  155. request.browsePaths = &browsePath;
  156. request.browsePathsSize = 1;
  157. UA_TranslateBrowsePathsToNodeIdsResponse response = UA_Client_Service_translateBrowsePathsToNodeIds(client, request);
  158. ck_assert_int_eq(response.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  159. ck_assert_int_eq(response.resultsSize, 1);
  160. ck_assert_int_eq(response.results[0].targetsSize, 1);
  161. ck_assert_int_eq(response.results[0].targets[0].targetId.nodeId.identifierType, UA_NODEIDTYPE_NUMERIC);
  162. ck_assert_int_eq(response.results[0].targets[0].targetId.nodeId.identifier.numeric, UA_NS0ID_SERVER_SERVERSTATUS_STATE);
  163. UA_BrowsePath_deleteMembers(&browsePath);
  164. UA_TranslateBrowsePathsToNodeIdsResponse_deleteMembers(&response);
  165. retVal = UA_Client_disconnect(client);
  166. ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD);
  167. UA_Client_delete(client);
  168. }
  169. END_TEST
  170. START_TEST(BrowseSimplifiedBrowsePath) {
  171. UA_QualifiedName objectsName = UA_QUALIFIEDNAME(0, "Objects");
  172. UA_BrowsePathResult bpr =
  173. UA_Server_browseSimplifiedBrowsePath(server_translate_browse,
  174. UA_NODEID_NUMERIC(0, UA_NS0ID_ROOTFOLDER),
  175. 1, &objectsName);
  176. ck_assert_int_eq(bpr.targetsSize, 1);
  177. UA_BrowsePathResult_deleteMembers(&bpr);
  178. }
  179. END_TEST
  180. static Suite *testSuite_Service_TranslateBrowsePathsToNodeIds(void) {
  181. Suite *s = suite_create("Service_TranslateBrowsePathsToNodeIds");
  182. TCase *tc_browse = tcase_create("Browse Service");
  183. tcase_add_test(tc_browse, Service_Browse_WithBrowseName);
  184. tcase_add_test(tc_browse, Service_Browse_WithMaxResults);
  185. tcase_add_test(tc_browse, Service_Browse_Recursive);
  186. suite_add_tcase(s, tc_browse);
  187. TCase *tc_translate = tcase_create("TranslateBrowsePathsToNodeIds");
  188. tcase_add_unchecked_fixture(tc_translate, setup_server, teardown_server);
  189. tcase_add_test(tc_translate, Service_TranslateBrowsePathsToNodeIds);
  190. tcase_add_test(tc_translate, BrowseSimplifiedBrowsePath);
  191. suite_add_tcase(s, tc_translate);
  192. return s;
  193. }
  194. int main(void) {
  195. int number_failed = 0;
  196. Suite *s;
  197. SRunner *sr;
  198. s = testSuite_Service_TranslateBrowsePathsToNodeIds();
  199. sr = srunner_create(s);
  200. srunner_set_fork_status(sr, CK_NOFORK);
  201. srunner_run_all(sr, CK_NORMAL);
  202. number_failed += srunner_ntests_failed(sr);
  203. srunner_free(sr);
  204. return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
  205. }