mirror of
https://github.com/open62541/open62541.git
synced 2026-10-29 05:11:36 +08:00
Use pointer-sized atomic run flags in threaded fixtures, including dynamically allocated discovery and browse flags. Pointer sizing supports the MSVC atomic implementation as well as C11 and GCC atomics. Serialize the client error-injection test with the server network callbacks before accessing the internal session and shared send buffer.
137 lines
4.4 KiB
C
137 lines
4.4 KiB
C
/* 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/. */
|
|
|
|
#include "nodeset_loader_test.h"
|
|
#include <open62541/server.h>
|
|
#include <open62541/server_config_default.h>
|
|
#include <open62541/util.h>
|
|
|
|
#include "open62541/client_highlevel.h"
|
|
|
|
#include <check.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "test_helpers.h"
|
|
#include "testing_clock.h"
|
|
#include "thread_wrapper.h"
|
|
|
|
static UA_Server *server = NULL;
|
|
static UA_Client *client = NULL;
|
|
static UA_atomic(uintptr_t) running = false;
|
|
static THREAD_HANDLE server_thread;
|
|
|
|
#define DEVICE_HEALTH_NODE_ID 70001
|
|
|
|
THREAD_CALLBACK(serverloop) {
|
|
while(UA_atomic_load(&running))
|
|
UA_Server_run_iterate(server, true);
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
setup(void) {
|
|
UA_atomic_store(&running, true);
|
|
server = UA_Server_newForUnitTest();
|
|
ck_assert(server != NULL);
|
|
|
|
const UA_StatusCode retVal = loadNodesetFile(server,
|
|
OPEN62541_NODESET_DIR "DI/Opc.Ua.Di.NodeSet2.xml", NULL);
|
|
ck_assert(UA_StatusCode_isGood(retVal));
|
|
const UA_UInt16 nsIndex = UA_Server_addNamespace(server,
|
|
"http://opcfoundation.org/UA/DI/");
|
|
ck_assert_uint_ne(0, nsIndex);
|
|
|
|
const UA_NodeId dti = UA_NODEID_NUMERIC(nsIndex, 6244);
|
|
const UA_DataType* deviceHealthEnumerationType = UA_Server_findDataType(server, &dti);
|
|
ck_assert(NULL != deviceHealthEnumerationType);
|
|
|
|
UA_VariableAttributes attr = UA_VariableAttributes_default;
|
|
UA_Int32 health = 2;
|
|
UA_Variant_setScalar(&attr.value, &health, deviceHealthEnumerationType);
|
|
attr.dataType = dti;
|
|
attr.displayName = UA_LOCALIZEDTEXT("en-US", "DeviceHealth");
|
|
attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE;
|
|
|
|
const UA_StatusCode addVarStatus = UA_Server_addVariableNode(server,
|
|
UA_NODEID_NUMERIC(nsIndex, DEVICE_HEALTH_NODE_ID),
|
|
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
|
|
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
|
|
UA_QUALIFIEDNAME(nsIndex, "DeviceHealth"),
|
|
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
|
|
attr, NULL, NULL);
|
|
ck_assert_uint_eq(UA_STATUSCODE_GOOD, addVarStatus);
|
|
|
|
ck_assert_uint_eq(UA_STATUSCODE_GOOD, UA_Server_run_startup(server));
|
|
THREAD_CREATE(server_thread, serverloop);
|
|
|
|
client = UA_Client_newForUnitTest();
|
|
ck_assert(client != NULL);
|
|
|
|
const UA_StatusCode resConnect = UA_Client_connect(client, "opc.tcp://localhost:4840");
|
|
ck_assert_uint_eq(resConnect, UA_STATUSCODE_GOOD);
|
|
}
|
|
|
|
static void
|
|
teardown(void) {
|
|
UA_Client_disconnect(client);
|
|
UA_Client_delete(client);
|
|
client = NULL;
|
|
|
|
UA_atomic_store(&running, false);
|
|
THREAD_JOIN(server_thread);
|
|
|
|
UA_Server_run_shutdown(server);
|
|
UA_Server_delete(server);
|
|
server = NULL;
|
|
}
|
|
|
|
START_TEST(Client_writeCustomEnum) {
|
|
UA_UInt16 nsIdx = 0;
|
|
ck_assert_uint_eq(UA_STATUSCODE_GOOD, UA_Client_addNamespace(client,
|
|
UA_STRING("http://opcfoundation.org/UA/DI/"), &nsIdx));
|
|
ck_assert_uint_ne(0, nsIdx);
|
|
|
|
UA_Int32 newValue = 3;
|
|
UA_Variant value;
|
|
UA_Variant_init(&value);
|
|
UA_Variant_setScalar(&value, &newValue, &UA_TYPES[UA_TYPES_INT32]);
|
|
|
|
UA_NodeId nodeId = UA_NODEID_NUMERIC(nsIdx, DEVICE_HEALTH_NODE_ID);
|
|
const UA_StatusCode writeStatus =
|
|
UA_Client_writeValueAttribute(client, nodeId, &value);
|
|
ck_assert_uint_eq(writeStatus, UA_STATUSCODE_GOOD);
|
|
|
|
UA_Variant stored;
|
|
UA_Variant_init(&stored);
|
|
ck_assert_uint_eq(UA_Server_readValue(server, nodeId, &stored),
|
|
UA_STATUSCODE_GOOD);
|
|
const UA_NodeId dataTypeId = UA_NODEID_NUMERIC(nsIdx, 6244);
|
|
ck_assert_ptr_ne(stored.type, NULL);
|
|
ck_assert(UA_NodeId_equal(&stored.type->typeId, &dataTypeId));
|
|
ck_assert_int_eq(*(UA_Int32*)stored.data, newValue);
|
|
UA_Variant_clear(&stored);
|
|
}
|
|
END_TEST
|
|
|
|
static Suite *
|
|
testSuite_Client(void) {
|
|
Suite *s = suite_create("Client Write Custom Datatypes");
|
|
TCase *tc_client = tcase_create("DeviceHealthEnumeration");
|
|
tcase_add_unchecked_fixture(tc_client, setup, teardown);
|
|
tcase_add_test(tc_client, Client_writeCustomEnum);
|
|
suite_add_tcase(s, tc_client);
|
|
return s;
|
|
}
|
|
|
|
int
|
|
main(void) {
|
|
Suite *s = testSuite_Client();
|
|
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;
|
|
}
|