Forráskód Böngészése

Add check for double references (taken from #2866)

Julius Pfrommer 5 éve
szülő
commit
227c0ba978
1 módosított fájl, 95 hozzáadás és 0 törlés
  1. 95 0
      tests/server/check_services_nodemanagement.c

+ 95 - 0
tests/server/check_services_nodemanagement.c

@@ -469,6 +469,96 @@ START_TEST(InstantiateObjectType) {
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 } END_TEST
 
+static UA_NodeId
+findReference(const UA_NodeId sourceId, const UA_NodeId refTypeId) {
+	UA_BrowseDescription * bDesc = UA_BrowseDescription_new();
+	UA_NodeId_copy(&sourceId, &bDesc->nodeId);
+	bDesc->browseDirection = UA_BROWSEDIRECTION_FORWARD;
+	bDesc->includeSubtypes = true;
+	bDesc->resultMask = UA_BROWSERESULTMASK_REFERENCETYPEID;
+	UA_BrowseResult bRes = UA_Server_browse(server, 0, bDesc);
+	ck_assert(bRes.statusCode == UA_STATUSCODE_GOOD);
+
+	UA_NodeId outNodeId = UA_NODEID_NULL;
+    for(size_t i = 0; i < bRes.referencesSize; i++) {
+        UA_ReferenceDescription rDesc = bRes.references[i];
+        if(UA_NodeId_equal(&rDesc.referenceTypeId, &refTypeId)) {
+            UA_NodeId_copy(&rDesc.nodeId.nodeId, &outNodeId);
+            break;
+        }
+    }
+
+	UA_BrowseDescription_deleteMembers(bDesc);
+	UA_BrowseDescription_delete(bDesc);
+	UA_BrowseResult_deleteMembers(&bRes);
+	return outNodeId;
+}
+
+static UA_NodeId
+registerRefType(char *forwName, char *invName) {
+	UA_NodeId outNodeId;
+	UA_ReferenceTypeAttributes refattr = UA_ReferenceTypeAttributes_default;
+	refattr.displayName = UA_LOCALIZEDTEXT(NULL, forwName);
+	refattr.inverseName = UA_LOCALIZEDTEXT(NULL, invName );
+	UA_QualifiedName browseName = UA_QUALIFIEDNAME(1, forwName);
+	UA_StatusCode st =
+        UA_Server_addReferenceTypeNode(server, UA_NODEID_NULL,
+                                       UA_NODEID_NUMERIC(0, UA_NS0ID_NONHIERARCHICALREFERENCES),
+                                       UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
+                                       browseName, refattr, NULL, &outNodeId);
+	ck_assert(st == UA_STATUSCODE_GOOD);
+	return outNodeId;
+}
+
+static UA_NodeId
+addObjInstance(const UA_NodeId parentNodeId, char *dispName) {
+	UA_NodeId outNodeId;
+	UA_ObjectAttributes oAttr = UA_ObjectAttributes_default;
+	oAttr.displayName = UA_LOCALIZEDTEXT(NULL, dispName);
+	UA_QualifiedName browseName = UA_QUALIFIEDNAME(1, dispName);
+	UA_StatusCode st =
+        UA_Server_addObjectNode(server, UA_NODEID_NULL, 
+                                parentNodeId, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
+                                browseName, UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),
+                                oAttr, NULL, &outNodeId);
+	ck_assert(st == UA_STATUSCODE_GOOD);
+	return outNodeId;
+}
+
+START_TEST(AddDoubleReference) {
+	// create two different reference types
+	UA_NodeId ref1TypeId = registerRefType("HasRef1", "IsRefOf1");
+	UA_NodeId ref2TypeId = registerRefType("HasRef2", "IsRefOf2");
+
+	// create two different object instances
+    UA_NodeId objectsNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
+	UA_NodeId sourceId = addObjInstance(objectsNodeId, "obj1");
+	UA_NodeId targetId = addObjInstance(objectsNodeId, "obj2");
+
+	// connect them twice, one time per reference type
+	UA_ExpandedNodeId targetExpId;
+	targetExpId.nodeId       = targetId;
+	targetExpId.namespaceUri = UA_STRING_NULL;
+	targetExpId.serverIndex  = 0;
+	UA_StatusCode st;
+	st = UA_Server_addReference(server, sourceId, ref1TypeId, targetExpId, true);
+	ck_assert(st == UA_STATUSCODE_GOOD);
+	st = UA_Server_addReference(server, sourceId, ref2TypeId, targetExpId, true);
+	ck_assert(st == UA_STATUSCODE_GOOD);
+    /* repetition fails */
+	st = UA_Server_addReference(server, sourceId, ref2TypeId, targetExpId, true);
+	ck_assert(st != UA_STATUSCODE_GOOD);
+
+	// check references where added
+	UA_NodeId targetCheckId;
+	targetCheckId = findReference(sourceId, ref1TypeId);
+	ck_assert(UA_NodeId_equal(&targetCheckId, &targetId));
+	targetCheckId = findReference(sourceId, ref2TypeId);
+	ck_assert(UA_NodeId_equal(&targetCheckId, &targetId));
+
+
+} END_TEST
+
 int main(void) {
     Suite *s = suite_create("services_nodemanagement");
 
@@ -490,6 +580,11 @@ int main(void) {
     tcase_add_test(tc_deletenodes, DeleteObjectAndReferences);
     suite_add_tcase(s, tc_deletenodes);
 
+    TCase *tc_addreferences = tcase_create("addreferences");
+    tcase_add_checked_fixture(tc_addreferences, setup, teardown);
+    tcase_add_test(tc_addreferences, AddDoubleReference);
+    suite_add_tcase(s, tc_addreferences);
+
     SRunner *sr = srunner_create(s);
     srunner_set_fork_status(sr, CK_NOFORK);
     srunner_run_all(sr, CK_NORMAL);