|
@@ -87,15 +87,105 @@ START_TEST(AddNodeTwiceGivesError) {
|
|
|
UA_Server_delete(server);
|
|
|
} END_TEST
|
|
|
|
|
|
+static UA_Boolean constructorCalled = false;
|
|
|
+
|
|
|
+static void * objectConstructor(const UA_NodeId instance) {
|
|
|
+ constructorCalled = true;
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+START_TEST(AddObjectWithConstructor) {
|
|
|
+ UA_Server *server = UA_Server_new(UA_ServerConfig_standard);
|
|
|
+
|
|
|
+ /* Add an object type */
|
|
|
+ UA_NodeId objecttypeid = UA_NODEID_NUMERIC(0, 13371337);
|
|
|
+ UA_ObjectTypeAttributes attr;
|
|
|
+ UA_ObjectTypeAttributes_init(&attr);
|
|
|
+ attr.displayName = UA_LOCALIZEDTEXT("en_US","my objecttype");
|
|
|
+ UA_StatusCode res = UA_Server_addObjectTypeNode(server, objecttypeid,
|
|
|
+ UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),
|
|
|
+ UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
|
|
|
+ UA_QUALIFIEDNAME(0, "myobjecttype"), attr, NULL, NULL);
|
|
|
+ ck_assert_int_eq(res, UA_STATUSCODE_GOOD);
|
|
|
+
|
|
|
+ /* Add a constructor to the object type */
|
|
|
+ UA_ObjectLifecycleManagement olm = {objectConstructor, NULL};
|
|
|
+ res = UA_Server_setObjectTypeNode_lifecycleManagement(server, objecttypeid, olm);
|
|
|
+ ck_assert_int_eq(res, UA_STATUSCODE_GOOD);
|
|
|
+
|
|
|
+ /* Add an object of the type */
|
|
|
+ UA_ObjectAttributes attr2;
|
|
|
+ UA_ObjectAttributes_init(&attr2);
|
|
|
+ attr2.displayName = UA_LOCALIZEDTEXT("en_US","my object");
|
|
|
+ res = UA_Server_addObjectNode(server, UA_NODEID_NULL, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
|
|
|
+ UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(0, ""),
|
|
|
+ objecttypeid, attr2, NULL, NULL);
|
|
|
+ ck_assert_int_eq(res, UA_STATUSCODE_GOOD);
|
|
|
+
|
|
|
+ /* Verify that the constructor was called */
|
|
|
+ ck_assert_int_eq(constructorCalled, true);
|
|
|
+
|
|
|
+ UA_Server_delete(server);
|
|
|
+} END_TEST
|
|
|
+
|
|
|
+static UA_Boolean destructorCalled = false;
|
|
|
+
|
|
|
+static void objectDestructor(const UA_NodeId instance, void *handle) {
|
|
|
+ destructorCalled = true;
|
|
|
+}
|
|
|
+
|
|
|
+START_TEST(DeleteObjectWithDestructor) {
|
|
|
+ UA_Server *server = UA_Server_new(UA_ServerConfig_standard);
|
|
|
+
|
|
|
+ /* Add an object type */
|
|
|
+ UA_NodeId objecttypeid = UA_NODEID_NUMERIC(0, 13371337);
|
|
|
+ UA_ObjectTypeAttributes attr;
|
|
|
+ UA_ObjectTypeAttributes_init(&attr);
|
|
|
+ attr.displayName = UA_LOCALIZEDTEXT("en_US","my objecttype");
|
|
|
+ UA_StatusCode res = UA_Server_addObjectTypeNode(server, objecttypeid,
|
|
|
+ UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),
|
|
|
+ UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
|
|
|
+ UA_QUALIFIEDNAME(0, "myobjecttype"), attr, NULL, NULL);
|
|
|
+ ck_assert_int_eq(res, UA_STATUSCODE_GOOD);
|
|
|
+
|
|
|
+ /* Add a constructor to the object type */
|
|
|
+ UA_ObjectLifecycleManagement olm = {NULL, objectDestructor};
|
|
|
+ res = UA_Server_setObjectTypeNode_lifecycleManagement(server, objecttypeid, olm);
|
|
|
+ ck_assert_int_eq(res, UA_STATUSCODE_GOOD);
|
|
|
+
|
|
|
+ /* Add an object of the type */
|
|
|
+ UA_NodeId objectid = UA_NODEID_NUMERIC(0, 23372337);
|
|
|
+ UA_ObjectAttributes attr2;
|
|
|
+ UA_ObjectAttributes_init(&attr2);
|
|
|
+ attr2.displayName = UA_LOCALIZEDTEXT("en_US","my object");
|
|
|
+ res = UA_Server_addObjectNode(server, objectid, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
|
|
|
+ UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(0, ""),
|
|
|
+ objecttypeid, attr2, NULL, NULL);
|
|
|
+ ck_assert_int_eq(res, UA_STATUSCODE_GOOD);
|
|
|
+
|
|
|
+ /* Delete the object */
|
|
|
+ UA_Server_deleteNode(server, objectid, true);
|
|
|
+
|
|
|
+ /* Verify that the denstructor was called */
|
|
|
+ ck_assert_int_eq(destructorCalled, true);
|
|
|
+
|
|
|
+ UA_Server_delete(server);
|
|
|
+} END_TEST
|
|
|
+
|
|
|
static Suite * testSuite_services_nodemanagement(void) {
|
|
|
Suite *s = suite_create("services_nodemanagement");
|
|
|
|
|
|
TCase *tc_addnodes = tcase_create("addnodes");
|
|
|
tcase_add_test(tc_addnodes, AddVariableNode);
|
|
|
- tcase_add_test(tc_addnodes, AddComplexTypeWithInheritance);
|
|
|
+ tcase_add_test(tc_addnodes, AddComplexTypeWithInheritance);
|
|
|
tcase_add_test(tc_addnodes, AddNodeTwiceGivesError);
|
|
|
+ tcase_add_test(tc_addnodes, AddObjectWithConstructor);
|
|
|
+
|
|
|
+ TCase *tc_deletenodes = tcase_create("deletenodes");
|
|
|
+ tcase_add_test(tc_addnodes, DeleteObjectWithDestructor);
|
|
|
|
|
|
suite_add_tcase(s, tc_addnodes);
|
|
|
+ suite_add_tcase(s, tc_deletenodes);
|
|
|
return s;
|
|
|
}
|
|
|
|