/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright (c) 2017 - 2018 Fraunhofer IOSB (Author: Andreas Ebner) */ #include "ua_server_pubsub.h" #include "src_generated/ua_types_generated_encoding_binary.h" #include "ua_config_default.h" #include "ua_network_pubsub_udp.h" #include "ua_server_internal.h" #include "check.h" UA_Server *server = NULL; UA_ServerConfig *config = NULL; static void setup(void) { config = UA_ServerConfig_new_default(); config->pubsubTransportLayers = (UA_PubSubTransportLayer *) UA_malloc(sizeof(UA_PubSubTransportLayer)); if(!config->pubsubTransportLayers) { UA_ServerConfig_delete(config); } config->pubsubTransportLayers[0] = UA_PubSubTransportLayerUDPMP(); config->pubsubTransportLayersSize++; server = UA_Server_new(config); UA_Server_run_startup(server); } static void teardown(void) { UA_Server_run_shutdown(server); UA_Server_delete(server); UA_ServerConfig_delete(config); } START_TEST(AddConnectionsWithMinimalValidConfiguration){ UA_StatusCode retVal; UA_PubSubConnectionConfig connectionConfig; memset(&connectionConfig, 0, sizeof(UA_PubSubConnectionConfig)); connectionConfig.name = UA_STRING("UADP Connection"); UA_NetworkAddressUrlDataType networkAddressUrl = {UA_STRING_NULL, UA_STRING("opc.udp://224.0.0.22:4840/")}; UA_Variant_setScalar(&connectionConfig.address, &networkAddressUrl, &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]); connectionConfig.transportProfileUri = UA_STRING("http://opcfoundation.org/UA-Profile/Transport/pubsub-udp-uadp"); retVal = UA_Server_addPubSubConnection(server, &connectionConfig, NULL); ck_assert_int_eq(server->pubSubManager.connectionsSize, 1); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); ck_assert(server->pubSubManager.connections[0].channel != NULL); retVal = UA_Server_addPubSubConnection(server, &connectionConfig, NULL); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); ck_assert(server->pubSubManager.connections[1].channel != NULL); ck_assert_int_eq(server->pubSubManager.connectionsSize, 2); } END_TEST START_TEST(AddRemoveAddConnectionWithMinimalValidConfiguration){ UA_StatusCode retVal; UA_PubSubConnectionConfig connectionConfig; memset(&connectionConfig, 0, sizeof(UA_PubSubConnectionConfig)); connectionConfig.name = UA_STRING("UADP Connection"); UA_NetworkAddressUrlDataType networkAddressUrl = {UA_STRING_NULL, UA_STRING("opc.udp://224.0.0.22:4840/")}; UA_Variant_setScalar(&connectionConfig.address, &networkAddressUrl, &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]); connectionConfig.transportProfileUri = UA_STRING("http://opcfoundation.org/UA-Profile/Transport/pubsub-udp-uadp"); UA_NodeId connectionIdent; retVal = UA_Server_addPubSubConnection(server, &connectionConfig, &connectionIdent); ck_assert_int_eq(server->pubSubManager.connectionsSize, 1); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); ck_assert(server->pubSubManager.connections[0].channel != NULL); retVal |= UA_Server_removePubSubConnection(server, connectionIdent); ck_assert_int_eq(server->pubSubManager.connectionsSize, 0); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); retVal = UA_Server_addPubSubConnection(server, &connectionConfig, &connectionIdent); ck_assert_int_eq(server->pubSubManager.connectionsSize, 1); ck_assert(server->pubSubManager.connections[0].channel != NULL); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); } END_TEST START_TEST(AddConnectionWithInvalidAddress){ UA_StatusCode retVal; UA_PubSubConnectionConfig connectionConfig; memset(&connectionConfig, 0, sizeof(UA_PubSubConnectionConfig)); connectionConfig.name = UA_STRING("UADP Connection"); UA_NetworkAddressUrlDataType networkAddressUrl = {UA_STRING_NULL, UA_STRING("opc.udp://256.0.0.22:4840/")}; UA_Variant_setScalar(&connectionConfig.address, &networkAddressUrl, &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]); connectionConfig.transportProfileUri = UA_STRING("http://opcfoundation.org/UA-Profile/Transport/pubsub-udp-uadp"); retVal = UA_Server_addPubSubConnection(server, &connectionConfig, NULL); ck_assert_int_eq(server->pubSubManager.connectionsSize, 0); ck_assert_int_ne(retVal, UA_STATUSCODE_GOOD); retVal = UA_Server_addPubSubConnection(server, &connectionConfig, NULL); ck_assert_int_ne(retVal, UA_STATUSCODE_GOOD); ck_assert_int_eq(server->pubSubManager.connectionsSize, 0); } END_TEST START_TEST(AddConnectionWithUnknownTransportURL){ UA_StatusCode retVal; UA_PubSubConnectionConfig connectionConfig; memset(&connectionConfig, 0, sizeof(UA_PubSubConnectionConfig)); connectionConfig.name = UA_STRING("UADP Connection"); UA_NetworkAddressUrlDataType networkAddressUrl = {UA_STRING_NULL, UA_STRING("opc.udp://224.0.0.22:4840/")}; UA_Variant_setScalar(&connectionConfig.address, &networkAddressUrl, &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]); connectionConfig.transportProfileUri = UA_STRING("http://opcfoundation.org/UA-Profile/Transport/unknown-udp-uadp"); UA_NodeId connectionIdent; retVal = UA_Server_addPubSubConnection(server, &connectionConfig, &connectionIdent); ck_assert_int_eq(server->pubSubManager.connectionsSize, 0); ck_assert_int_ne(retVal, UA_STATUSCODE_GOOD); } END_TEST START_TEST(AddConnectionWithNullConfig){ UA_StatusCode retVal; retVal = UA_Server_addPubSubConnection(server, NULL, NULL); ck_assert_int_eq(server->pubSubManager.connectionsSize, 0); ck_assert_int_ne(retVal, UA_STATUSCODE_GOOD); } END_TEST START_TEST(AddSingleConnectionWithMaximalConfiguration){ UA_NetworkAddressUrlDataType networkAddressUrlData = {UA_STRING("127.0.0.1"), UA_STRING("opc.udp://224.0.0.22:4840/")}; UA_Variant address; UA_Variant_setScalar(&address, &networkAddressUrlData, &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]); UA_KeyValuePair connectionOptions[3]; connectionOptions[0].key = UA_QUALIFIEDNAME(0, "ttl"); UA_UInt32 ttl = 10; UA_Variant_setScalar(&connectionOptions[0].value, &ttl, &UA_TYPES[UA_TYPES_UINT32]); connectionOptions[1].key = UA_QUALIFIEDNAME(0, "loopback"); UA_Boolean loopback = UA_FALSE; UA_Variant_setScalar(&connectionOptions[1].value, &loopback, &UA_TYPES[UA_TYPES_BOOLEAN]); connectionOptions[2].key = UA_QUALIFIEDNAME(0, "reuse"); UA_Boolean reuse = UA_TRUE; UA_Variant_setScalar(&connectionOptions[2].value, &reuse, &UA_TYPES[UA_TYPES_BOOLEAN]); UA_PubSubConnectionConfig connectionConf; memset(&connectionConf, 0, sizeof(UA_PubSubConnectionConfig)); connectionConf.name = UA_STRING("UADP Connection"); connectionConf.transportProfileUri = UA_STRING("http://opcfoundation.org/UA-Profile/Transport/pubsub-udp-uadp"); connectionConf.enabled = true; connectionConf.publisherId.numeric = 223344; connectionConf.connectionPropertiesSize = 3; connectionConf.connectionProperties = connectionOptions; connectionConf.address = address; UA_NodeId connection; UA_StatusCode retVal = UA_Server_addPubSubConnection(server, &connectionConf, &connection); ck_assert_int_eq(server->pubSubManager.connectionsSize, 1); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); ck_assert(server->pubSubManager.connections[0].channel != NULL); } END_TEST START_TEST(GetMaximalConnectionConfigurationAndCompareValues){ UA_NetworkAddressUrlDataType networkAddressUrlData = {UA_STRING("127.0.0.1"), UA_STRING("opc.udp://224.0.0.22:4840/")}; UA_Variant address; UA_Variant_setScalar(&address, &networkAddressUrlData, &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]); UA_KeyValuePair connectionOptions[3]; connectionOptions[0].key = UA_QUALIFIEDNAME(0, "ttl"); UA_UInt32 ttl = 10; UA_Variant_setScalar(&connectionOptions[0].value, &ttl, &UA_TYPES[UA_TYPES_UINT32]); connectionOptions[1].key = UA_QUALIFIEDNAME(0, "loopback"); UA_Boolean loopback = UA_FALSE; UA_Variant_setScalar(&connectionOptions[1].value, &loopback, &UA_TYPES[UA_TYPES_BOOLEAN]); connectionOptions[2].key = UA_QUALIFIEDNAME(0, "reuse"); UA_Boolean reuse = UA_TRUE; UA_Variant_setScalar(&connectionOptions[2].value, &reuse, &UA_TYPES[UA_TYPES_BOOLEAN]); UA_PubSubConnectionConfig connectionConf; memset(&connectionConf, 0, sizeof(UA_PubSubConnectionConfig)); connectionConf.name = UA_STRING("UADP Connection"); connectionConf.transportProfileUri = UA_STRING("http://opcfoundation.org/UA-Profile/Transport/pubsub-udp-uadp"); connectionConf.enabled = true; connectionConf.publisherId.numeric = 223344; connectionConf.connectionPropertiesSize = 3; connectionConf.connectionProperties = connectionOptions; connectionConf.address = address; UA_NodeId connection; UA_StatusCode retVal = UA_Server_addPubSubConnection(server, &connectionConf, &connection); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); UA_PubSubConnectionConfig connectionConfig; memset(&connectionConfig, 0, sizeof(UA_PubSubConnectionConfig)); retVal |= UA_Server_getPubSubConnectionConfig(server, connection, &connectionConfig); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); ck_assert(connectionConfig.connectionPropertiesSize == connectionConf.connectionPropertiesSize); ck_assert(UA_String_equal(&connectionConfig.name, &connectionConf.name) == UA_TRUE); ck_assert(UA_String_equal(&connectionConfig.transportProfileUri, &connectionConf.transportProfileUri) == UA_TRUE); UA_NetworkAddressUrlDataType networkAddressUrlDataCopy = *((UA_NetworkAddressUrlDataType *)connectionConfig.address.data); ck_assert(UA_NetworkAddressUrlDataType_calcSizeBinary(&networkAddressUrlDataCopy) == UA_NetworkAddressUrlDataType_calcSizeBinary(&networkAddressUrlData)); for(size_t i = 0; i < connectionConfig.connectionPropertiesSize; i++){ ck_assert(UA_String_equal(&connectionConfig.connectionProperties[i].key.name, &connectionConf.connectionProperties[i].key.name) == UA_TRUE); ck_assert(UA_Variant_calcSizeBinary(&connectionConfig.connectionProperties[i].value) == UA_Variant_calcSizeBinary(&connectionConf.connectionProperties[i].value)); } UA_PubSubConnectionConfig_deleteMembers(&connectionConfig); } END_TEST int main(void) { TCase *tc_add_pubsub_connections_minimal_config = tcase_create("Create PubSub UDP Connections with minimal valid config"); tcase_add_checked_fixture(tc_add_pubsub_connections_minimal_config, setup, teardown); tcase_add_test(tc_add_pubsub_connections_minimal_config, AddConnectionsWithMinimalValidConfiguration); tcase_add_test(tc_add_pubsub_connections_minimal_config, AddRemoveAddConnectionWithMinimalValidConfiguration); TCase *tc_add_pubsub_connections_invalid_config = tcase_create("Create PubSub UDP Connections with invalid configurations"); tcase_add_checked_fixture(tc_add_pubsub_connections_invalid_config, setup, teardown); tcase_add_test(tc_add_pubsub_connections_invalid_config, AddConnectionWithInvalidAddress); tcase_add_test(tc_add_pubsub_connections_invalid_config, AddConnectionWithUnknownTransportURL); tcase_add_test(tc_add_pubsub_connections_invalid_config, AddConnectionWithNullConfig); TCase *tc_add_pubsub_connections_maximal_config = tcase_create("Create PubSub UDP Connections with maximal valid config"); tcase_add_checked_fixture(tc_add_pubsub_connections_maximal_config, setup, teardown); tcase_add_test(tc_add_pubsub_connections_maximal_config, AddSingleConnectionWithMaximalConfiguration); tcase_add_test(tc_add_pubsub_connections_maximal_config, GetMaximalConnectionConfigurationAndCompareValues); Suite *s = suite_create("PubSub UDP connection creation"); suite_add_tcase(s, tc_add_pubsub_connections_minimal_config); suite_add_tcase(s, tc_add_pubsub_connections_invalid_config); suite_add_tcase(s, tc_add_pubsub_connections_maximal_config); //suite_add_tcase(s, tc_decode); SRunner *sr = srunner_create(s); srunner_set_fork_status(sr, CK_NOFORK); srunner_run_all(sr,CK_NORMAL); int number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; }