ChimeraTK-ControlSystemAdapter-OPCUAAdapter 04.00.05
Loading...
Searching...
No Matches
test_opcua_processvariable.cpp
Go to the documentation of this file.
1#include "open62541/plugin/log_stdout.h"
2
3#include <boost/fusion/container/map.hpp>
4#include <boost/test/included/unit_test.hpp>
5
6#include <csa_opcua_adapter.h>
7#include <string.h>
8#include <test_sample_data.h>
9#include <ua_adapter.h>
10
11extern "C" {
12#include "csa_namespace.h"
13#include "unistd.h"
14}
15
16using namespace boost::unit_test_framework;
17using namespace std;
18namespace fusion = boost::fusion;
19
20typedef fusion::map<fusion::pair<uint8_t, UA_DataType>, fusion::pair<int8_t, UA_DataType>,
21 fusion::pair<uint16_t, UA_DataType>, fusion::pair<int16_t, UA_DataType>, fusion::pair<uint32_t, UA_DataType>,
22 fusion::pair<int32_t, UA_DataType>, fusion::pair<uint64_t, UA_DataType>, fusion::pair<int64_t, UA_DataType>,
23 fusion::pair<float, UA_DataType>, fusion::pair<double, UA_DataType>>
25
26static TestTypesMap tMap{fusion::make_pair<uint8_t>(UA_TYPES[UA_TYPES_SBYTE]),
27 fusion::make_pair<int8_t>(UA_TYPES[UA_TYPES_BYTE]), fusion::make_pair<uint16_t>(UA_TYPES[UA_TYPES_UINT16]),
28 fusion::make_pair<int16_t>(UA_TYPES[UA_TYPES_INT16]), fusion::make_pair<uint32_t>(UA_TYPES[UA_TYPES_UINT32]),
29 fusion::make_pair<int32_t>(UA_TYPES[UA_TYPES_INT32]), fusion::make_pair<uint64_t>(UA_TYPES[UA_TYPES_UINT64]),
30 fusion::make_pair<int64_t>(UA_TYPES[UA_TYPES_INT64]), fusion::make_pair<float>(UA_TYPES[UA_TYPES_FLOAT]),
31 fusion::make_pair<double>(UA_TYPES[UA_TYPES_DOUBLE])};
32
33/*
34 * ProcessVariableTest
35 *
36 */
38 public:
39 static void testClassSide();
40
41 static void testClientSide();
42
43 template<typename CTK_TYPE>
44 static void testData(
45 ProcessVariable::SharedPtr oneProcessVariable, TestFixturePVSet* pvSet, ua_processvariable* test);
46};
47
48template<typename CTK_TYPE>
50 ProcessVariable::SharedPtr oneProcessVariable, TestFixturePVSet* pvSet, ua_processvariable* test) {
51 vector<CTK_TYPE> valueArray =
52 pvSet->csManager->getProcessArray<CTK_TYPE>(oneProcessVariable->getName())->accessChannel(0);
53 UA_Variant* var = UA_Variant_new();
54 test->getValue<CTK_TYPE>(var, nullptr);
55 if(valueArray.size() == 1) {
56 CTK_TYPE newValue;
57 BOOST_CHECK(*(CTK_TYPE*)(var->data) == 0);
58 newValue = 100;
59 UA_Variant_clear(var);
60 UA_Variant_setScalarCopy(var, &newValue, &fusion::at_key<CTK_TYPE>(tMap));
61 test->setValue<CTK_TYPE>(var);
62
63 auto time = oneProcessVariable->getVersionNumber().getTime();
64 auto usecs = std::chrono::duration_cast<std::chrono::microseconds>(time.time_since_epoch()).count();
65 BOOST_CHECK(test->getSourceTimeStamp() == usecs * UA_DATETIME_USEC + UA_DATETIME_UNIX_EPOCH);
66
67 // Check value on controlsystemmanager side
68 vector<CTK_TYPE> csValueArray =
69 pvSet->csManager->getProcessArray<CTK_TYPE>(oneProcessVariable->getName())->accessChannel(0);
70 BOOST_CHECK(csValueArray.size() == 1);
71 BOOST_CHECK(csValueArray.at(0) == 100);
72 }
73 else {
74 // if Array
75 std::vector<CTK_TYPE> newVector(var->arrayLength);
76 for(size_t i = 0; i < var->arrayLength; i++) {
77 BOOST_CHECK(((CTK_TYPE*)(var->data))[i] == 0);
78 newVector.at(i) = (100 - i);
79 }
80 UA_Variant_clear(var);
81 UA_Variant_setArrayCopy(var, newVector.data(), newVector.size(), &fusion::at_key<CTK_TYPE>(tMap));
82 test->setValue<CTK_TYPE>(var);
83
84 // Check value on controlsystemmanager side
85 vector<CTK_TYPE> valueArray =
86 pvSet->csManager->getProcessArray<CTK_TYPE>(oneProcessVariable->getName())->accessChannel(0);
87 size_t i = 0;
88 for(auto value : valueArray) {
89 BOOST_CHECK(value == (CTK_TYPE)(100 - i));
90 i++;
91 }
92
93 // now a certain range
94 UA_Variant_clear(var);
95 UA_NumericRange range = UA_NUMERICRANGE("0:5");
96 // UA_NumericRange_parse(&range, UA_String_fromChars("0:5"));
97 test->getValue<CTK_TYPE>(var, &range);
98 BOOST_CHECK(var->arrayLength == 6);
99 for(size_t i = 0; i < var->arrayLength; i++) {
100 BOOST_CHECK(((CTK_TYPE*)(var->data))[i] == (CTK_TYPE)(100 - i));
101 }
102 UA_free(range.dimensions);
103 }
104 UA_Variant_delete(var);
105}
106
108 std::cout << "Enter ProcessVariableTest with ClassSide" << std::endl;
109 TestFixtureServerSet serverSet;
110 TestFixturePVSet pvSet;
111
112 thread* serverThread = new std::thread(UA_Server_run, serverSet.mappedServer, &serverSet.runUAServer);
113
114 // check server
115 if(serverSet.mappedServer == nullptr) {
116 BOOST_CHECK(false);
117 }
118
119 // ua_processvariable *test;
120 for(ProcessVariable::SharedPtr oneProcessVariable : pvSet.csManager->getAllProcessVariables()) {
122 serverSet.mappedServer, serverSet.baseNodeId, oneProcessVariable->getName(), pvSet.csManager, UA_Log_Stdout);
123
124 BOOST_CHECK(test.getName() == oneProcessVariable->getName());
125
126 BOOST_CHECK(test.getEngineeringUnit() == oneProcessVariable->getUnit());
127 test.setEngineeringUnit("test");
128 BOOST_CHECK(test.getEngineeringUnit() == "test");
129
130 // Description
131 string description = "";
132 description = test.getDescription();
133 BOOST_CHECK(description == oneProcessVariable->getDescription());
134
135 // auto time = oneProcessVariable->getVersionNumber().getTime();
136 // auto usecs = std::chrono::duration_cast<std::chrono::microseconds>(time.time_since_epoch()).count();
137 // BOOST_CHECK(test.getSourceTimeStamp() == usecs * UA_DATETIME_USEC + UA_DATETIME_UNIX_EPOCH);
138 std::string valueType = test.getType();
139
140 cout << "Check Processvariable: " << test.getName() << endl;
141 if(valueType == "int8_t") {
142 BOOST_CHECK(valueType == "int8_t");
143 testData<int8_t>(oneProcessVariable, &pvSet, &test);
144 }
145 else if(valueType == "uint8_t") {
146 BOOST_CHECK(valueType == "uint8_t");
147 testData<uint8_t>(oneProcessVariable, &pvSet, &test);
148 }
149 else if(valueType == "int16_t") {
150 BOOST_CHECK(valueType == "int16_t");
151 testData<int16_t>(oneProcessVariable, &pvSet, &test);
152 }
153 else if(valueType == "uint16_t") {
154 BOOST_CHECK(valueType == "uint16_t");
155 testData<uint16_t>(oneProcessVariable, &pvSet, &test);
156 }
157 else if(valueType == "int32_t") {
158 BOOST_CHECK(valueType == "int32_t");
159 testData<int32_t>(oneProcessVariable, &pvSet, &test);
160 }
161 else if(valueType == "uint32_t") {
162 BOOST_CHECK(valueType == "uint32_t");
163 testData<uint32_t>(oneProcessVariable, &pvSet, &test);
164 }
165 else if(valueType == "int64_t") {
166 BOOST_CHECK(valueType == "int64_t");
167 testData<int64_t>(oneProcessVariable, &pvSet, &test);
168 }
169 else if(valueType == "uint64_t") {
170 BOOST_CHECK(valueType == "uint64_t");
171 testData<uint64_t>(oneProcessVariable, &pvSet, &test);
172 }
173 else if(valueType == "float") {
174 BOOST_CHECK(valueType == "float");
175 testData<float>(oneProcessVariable, &pvSet, &test);
176 }
177 else if(valueType == "double") {
178 BOOST_CHECK(valueType == "double");
179 testData<double>(oneProcessVariable, &pvSet, &test);
180 }
181 else if(valueType == "string") {
182 }
183 else
184 BOOST_CHECK(false);
185
186 UA_NodeId nodeId = test.getOwnNodeId();
187 BOOST_CHECK(!UA_NodeId_isNull(&nodeId));
188 UA_NodeId_clear(&nodeId);
189
190 string newName = "";
191 newName = oneProcessVariable->getName();
192 // Should not being changed
193 BOOST_CHECK(test.getName() != "");
194 }
195
196 serverSet.runUAServer = UA_FALSE;
197
198 if(serverThread->joinable()) {
199 serverThread->join();
200 }
201
202 delete serverThread;
203 serverThread = NULL;
204};
205
207 std::cout << "Enter ProcessVariableTest with ExampleSet and ClientSide testing" << std::endl;
208
209 TestFixtureServerSet serverSet;
210 TestFixturePVSet pvSet;
211 thread* serverThread = new std::thread(UA_Server_run, serverSet.mappedServer, &serverSet.runUAServer);
212
213 // check server
214 if(serverSet.mappedServer == nullptr) {
215 BOOST_CHECK(false);
216 }
217
218 // add set
219 vector<ua_processvariable*> varList;
220 for(ProcessVariable::SharedPtr oneProcessVariable : pvSet.csManager->getAllProcessVariables()) {
221 varList.push_back(new ua_processvariable(
222 serverSet.mappedServer, serverSet.baseNodeId, oneProcessVariable->getName(), pvSet.csManager, UA_Log_Stdout));
223 }
224
225 // Create client to connect to server
226 UA_Client* client = UA_Client_new();
227 UA_ClientConfig* cc = UA_Client_getConfig(client);
228 UA_ClientConfig_setDefault(cc);
229 string endpointURL = "opc.tcp://localhost:" + to_string(serverSet.opcuaPort);
230 UA_StatusCode retval = UA_Client_connect(client, endpointURL.c_str());
231 sleep(1);
232
233 int k = 1;
234 while(retval != UA_STATUSCODE_GOOD & k < 10) {
235 retval = UA_Client_connect(client, endpointURL.c_str());
236 sleep(1);
237 k++;
238 }
239
240 if(retval != UA_STATUSCODE_GOOD) {
241 std::cout << "Failed to connect to server"
242 << "opc.tcp://localhost:" << serverSet.opcuaPort << std::endl;
243 BOOST_CHECK(false);
244 }
245
246 UA_BrowseRequest bReq;
247 UA_BrowseRequest_init(&bReq);
248 bReq.requestedMaxReferencesPerNode = 0;
249 bReq.nodesToBrowse = UA_BrowseDescription_new();
250 bReq.nodesToBrowseSize = 1;
251 bReq.nodesToBrowse[0].nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
252 bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; // return everything
253 UA_BrowseResponse bResp = UA_Client_Service_browse(client, bReq);
254
255 for(size_t i = 0; i < bResp.resultsSize; ++i) {
256 for(size_t j = 0; j < bResp.results[i].referencesSize; ++j) {
257 UA_ReferenceDescription* ref = &(bResp.results[i].references[j]);
258 if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_NUMERIC) {
259 size_t lenBrowseName = (int)ref->browseName.name.length;
260 std::string browseNameFound(reinterpret_cast<char const*>(ref->browseName.name.data), lenBrowseName);
261
262 UA_BrowseRequest bReq2;
263 UA_BrowseRequest_init(&bReq2);
264 bReq2.requestedMaxReferencesPerNode = 0;
265 bReq2.nodesToBrowse = UA_BrowseDescription_new();
266 bReq2.nodesToBrowseSize = 1;
267 bReq2.nodesToBrowse[0].nodeId = ref->nodeId.nodeId;
268 bReq2.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL;
269 UA_BrowseResponse bResp2 = UA_Client_Service_browse(client, bReq2);
270
271 UA_NodeId valueNodeId = UA_NODEID_NULL;
272 UA_NodeId typeNodeId = UA_NODEID_NULL;
273 UA_NodeId nameNodeId = UA_NODEID_NULL;
274 UA_NodeId engineeringUnitNodeId = UA_NODEID_NULL;
275 UA_NodeId descriptionNodeId = UA_NODEID_NULL;
276 string name = "";
277
278 UA_ReferenceDescription* refe;
279 for(size_t m = 0; m < bResp2.resultsSize; ++m) {
280 for(size_t k = 0; k < bResp2.results[m].referencesSize; ++k) {
281 refe = &(bResp2.results[m].references[k]);
282 if(refe->nodeId.nodeId.identifierType == UA_NODEIDTYPE_NUMERIC ||
283 refe->nodeId.nodeId.identifierType == UA_NODEIDTYPE_STRING) {
284 size_t lenBrowseName2 = (int)refe->browseName.name.length;
285 string browseNameFound2(reinterpret_cast<char const*>(refe->browseName.name.data), lenBrowseName2);
286
287 if(browseNameFound2 == "Type") {
288 UA_NodeId_copy(&refe->nodeId.nodeId, &typeNodeId);
289 }
290
291 if(browseNameFound2 == "Name") {
292 UA_NodeId_copy(&refe->nodeId.nodeId, &nameNodeId);
293 }
294
295 if(browseNameFound2 == "Value") {
296 UA_NodeId_copy(&refe->nodeId.nodeId, &valueNodeId);
297 name = browseNameFound;
298 cout << "Checking ProcessVariable: " << name << endl;
299 }
300 if(browseNameFound2 == "EngineeringUnit") {
301 UA_NodeId_copy(&refe->nodeId.nodeId, &engineeringUnitNodeId);
302 }
303
304 if(browseNameFound2 == "Description") {
305 UA_NodeId_copy(&refe->nodeId.nodeId, &descriptionNodeId);
306 }
307 }
308 }
309 }
310 UA_BrowseRequest_clear(&bReq2);
311 UA_BrowseResponse_clear(&bResp2);
312
313 if(!UA_NodeId_isNull(&valueNodeId)) {
314 UA_Variant* valueToCheck = UA_Variant_new();
315 UA_Variant_init(valueToCheck);
316 UA_StatusCode retvalValue = UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
317 if(retvalValue != UA_STATUSCODE_GOOD) {
318 BOOST_CHECK(false);
319 }
320
321 UA_Variant* datatypeToCheck = UA_Variant_new();
322 UA_Variant_init(datatypeToCheck);
323 UA_StatusCode retvalValueDatatype = UA_Client_readValueAttribute(client, typeNodeId, datatypeToCheck);
324 if(retvalValueDatatype != UA_STATUSCODE_GOOD) {
325 BOOST_CHECK(false);
326 }
327
328 UA_Variant* nameToCheck = UA_Variant_new();
329 UA_Variant_init(nameToCheck);
330 UA_StatusCode retvalValueName = UA_Client_readValueAttribute(client, nameNodeId, nameToCheck);
331 if(retvalValueName != UA_STATUSCODE_GOOD) {
332 BOOST_CHECK(false);
333 }
334
335 UA_Variant* euToCheck = UA_Variant_new();
336 UA_Variant_init(euToCheck);
337 UA_StatusCode retvalValueEu = UA_Client_readValueAttribute(client, engineeringUnitNodeId, euToCheck);
338 if(retvalValueEu != UA_STATUSCODE_GOOD) {
339 BOOST_CHECK(false);
340 }
341
342 UA_Variant* descToCheck = UA_Variant_new();
343 UA_Variant_init(descToCheck);
344 UA_StatusCode retvalValueDesc = UA_Client_readValueAttribute(client, descriptionNodeId, descToCheck);
345 if(retvalValueDesc != UA_STATUSCODE_GOOD) {
346 BOOST_CHECK(false);
347 }
348
349 UA_NodeId datatypeId;
350 if(retvalValue == UA_STATUSCODE_GOOD) {
351 UA_StatusCode retvalDatatype = UA_Client_readDataTypeAttribute(client, valueNodeId, &datatypeId);
352 if(retvalDatatype != UA_STATUSCODE_GOOD) {
353 BOOST_CHECK(false);
354 }
355 }
356
357 if(retvalValue == UA_STATUSCODE_GOOD) {
358 string datatype = "";
359 string valName = "";
360 string description = "";
361 string engineeringUnit = "";
362
363 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
364
365 // Check EngineeringUnit -> for all the same
366 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)euToCheck->data)), engineeringUnit);
367 // cout << "EngineeringUnit: " << valName << endl;
368 if((valName.compare("/int8Scalar") == 0) || (valName.compare("/Mein/Name_ist#int8Array_s15") == 0) ||
369 (valName.compare("/Unser/Name/ist_uint8Array_s10") == 0)) {
370 BOOST_CHECK(engineeringUnit == "Einheit");
371 }
372 else {
373 BOOST_CHECK(engineeringUnit == "n./a.");
374 }
375
376 // Write new engineering unit
377 string merker = "mHensel/Iatrou";
378 UA_String newEU = UA_String_fromChars((char*)merker.c_str());
379 UA_Variant_init(euToCheck);
380 UA_Variant_setScalarCopy(euToCheck, &newEU, &UA_TYPES[UA_TYPES_STRING]);
381 UA_StatusCode retvalNewEU = UA_Client_writeValueAttribute(client, engineeringUnitNodeId, euToCheck);
382 if(retvalNewEU != UA_STATUSCODE_GOOD) {
383 BOOST_CHECK(false);
384 }
385 UA_String_clear(&newEU);
386 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)euToCheck->data)), engineeringUnit);
387 BOOST_CHECK(engineeringUnit == "mHensel/Iatrou");
388
389 // Check Description -> for all the same
390 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)descToCheck->data)), description);
391 // cout << "Description: " << valName << endl;
392 if((valName.compare("/int8Scalar") == 0) || (valName.compare("/Mein/Name_ist#int8Array_s15") == 0) ||
393 (valName.compare("/Unser/Name/ist_uint8Array_s10") == 0)) {
394 BOOST_CHECK(description == "Beschreibung der Variable");
395 }
396 else {
397 BOOST_CHECK(description == "");
398 }
399 // Write new engineering unit
400 merker = "Beschreibung";
401 UA_String newDesc = UA_String_fromChars((char*)merker.c_str());
402 UA_Variant_init(descToCheck);
403 UA_Variant_setScalarCopy(descToCheck, &newDesc, &UA_TYPES[UA_TYPES_STRING]);
404 UA_StatusCode retvalNewDesc = UA_Client_writeValueAttribute(client, descriptionNodeId, descToCheck);
405 if(retvalNewDesc != UA_STATUSCODE_GOOD) {
406 BOOST_CHECK(false);
407 }
408 UA_String_clear(&newDesc);
409 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)descToCheck->data)), valName);
410 BOOST_CHECK(valName == "Beschreibung");
411
412 // i know, this part is perfecly for makro stuff... but common, for maintainability reason we should use simple code...
413 if(valueToCheck->arrayLength < 1) {
414 switch(datatypeId.identifier.numeric - 1) {
415 case UA_TYPES_SBYTE: {
416 // Check Datatype
417 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
418 BOOST_CHECK(datatype == "int8_t");
419 // Check Name
420 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
421 BOOST_CHECK(valName == "/int8Scalar");
422 // Check Value
423 uint8_t value = (uint8_t)*((uint8_t*)valueToCheck->data);
424 BOOST_CHECK(value == 0);
425 // cout << "Wert: " << std::to_string(value) << endl;
426 // set new value
427 uint8_t newValue = 123;
428 UA_Variant_init(valueToCheck);
429 UA_Variant_setScalarCopy(valueToCheck, &newValue, &UA_TYPES[UA_TYPES_SBYTE]);
430 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
431 if(retvalNewVar == UA_STATUSCODE_GOOD) {
432 // get value from server
433 UA_Variant_init(valueToCheck);
434 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
435 value = (uint8_t)*((uint8_t*)valueToCheck->data);
436 BOOST_CHECK(value == newValue);
437 }
438 else {
439 BOOST_CHECK(false);
440 }
441 break;
442 }
443 case UA_TYPES_BYTE: {
444 // Check Datatype
445 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
446 BOOST_CHECK(datatype == "uint8_t");
447 // Check Name
448 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
449 BOOST_CHECK(valName == "/uint8Scalar");
450 // Check Value
451 int8_t value = (int8_t)*((int8_t*)valueToCheck->data);
452 BOOST_CHECK(value == 0);
453 // cout << "Wert: " << std::to_string(value) << endl;
454 // set new value
455 int8_t newValue = 122;
456 UA_Variant_init(valueToCheck);
457 UA_Variant_setScalarCopy(valueToCheck, &newValue, &UA_TYPES[UA_TYPES_BYTE]);
458 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
459 if(retvalNewVar == UA_STATUSCODE_GOOD) {
460 // get value from server
461 UA_Variant_init(valueToCheck);
462 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
463 value = (int8_t)*((int8_t*)valueToCheck->data);
464 BOOST_CHECK(value == newValue);
465 }
466 else {
467 BOOST_CHECK(false);
468 }
469 break;
470 }
471 case UA_TYPES_INT16: {
472 // Check Datatype
473 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
474 BOOST_CHECK(datatype == "int16_t");
475 // Check Name
476 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
477 BOOST_CHECK(valName == "/int16Scalar");
478 // Check Value
479 int16_t value = (int16_t)*((int16_t*)valueToCheck->data);
480 BOOST_CHECK(value == 0);
481 // cout << "Wert: " << std::to_string(value) << endl;
482 // set new value, should be wrong
483 int16_t newValue = 123;
484 UA_Variant_init(valueToCheck);
485 UA_Variant_setScalarCopy(valueToCheck, &newValue, &UA_TYPES[UA_TYPES_INT16]);
486 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
487 if(retvalNewVar == UA_STATUSCODE_GOOD) {
488 // get value from server
489 UA_Variant_init(valueToCheck);
490 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
491 value = (int16_t)*((int16_t*)valueToCheck->data);
492 BOOST_CHECK(value == newValue);
493 }
494 else {
495 BOOST_CHECK(false);
496 }
497 break;
498 }
499 case UA_TYPES_UINT16: {
500 // Check Datatype
501 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
502 BOOST_CHECK(datatype == "uint16_t");
503 // Check Name
504 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
505 BOOST_CHECK(valName == "/uint16Scalar");
506 // Check Value
507 uint16_t value = (uint16_t)*((uint16_t*)valueToCheck->data);
508 BOOST_CHECK(value == 0);
509 // cout << "Wert: " << std::to_string(value) << endl;
510 // set new value
511 uint16_t newValue = 123;
512 UA_Variant_init(valueToCheck);
513 UA_Variant_setScalarCopy(valueToCheck, &newValue, &UA_TYPES[UA_TYPES_UINT16]);
514 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
515 if(retvalNewVar == UA_STATUSCODE_GOOD) {
516 // get value from server
517 UA_Variant_init(valueToCheck);
518 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
519 value = (uint16_t)*((uint16_t*)valueToCheck->data);
520 BOOST_CHECK(value == newValue);
521 }
522 else {
523 BOOST_CHECK(false);
524 }
525 break;
526 }
527 case UA_TYPES_INT32: {
528 // Check Datatype
529 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
530 BOOST_CHECK(datatype == "int32_t");
531 // Check Name
532 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
533 BOOST_CHECK(valName == "/Dein/Name/ist/int32Scalar");
534 // Check Value
535 int32_t value = (int32_t)*((int32_t*)valueToCheck->data);
536 BOOST_CHECK(value == 0);
537 // cout << "Wert: " << std::to_string(value) << endl;
538 // set new value
539 int32_t newValue = 123;
540 UA_Variant_init(valueToCheck);
541 UA_Variant_setScalarCopy(valueToCheck, &newValue, &UA_TYPES[UA_TYPES_INT32]);
542 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
543 if(retvalNewVar == UA_STATUSCODE_GOOD) {
544 // get value from server
545 UA_Variant_init(valueToCheck);
546 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
547 value = (int32_t)*((int32_t*)valueToCheck->data);
548 BOOST_CHECK(value == newValue);
549 }
550 else {
551 BOOST_CHECK(false);
552 }
553 break;
554 }
555 case UA_TYPES_UINT32: {
556 // Check Datatype
557 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
558 BOOST_CHECK(datatype == "uint32_t");
559 // Check Name
560 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
561 BOOST_CHECK(valName == "/Mein/Name/ist/uint32Scalar");
562 // Check Value
563 uint32_t value = (uint32_t)*((uint32_t*)valueToCheck->data);
564 BOOST_CHECK(value == 0);
565 // cout << "Wert: " << std::to_string(value) << endl;
566 // set new value
567 uint32_t newValue = 123;
568 UA_Variant_init(valueToCheck);
569 UA_Variant_setScalarCopy(valueToCheck, &newValue, &UA_TYPES[UA_TYPES_UINT32]);
570 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
571 if(retvalNewVar == UA_STATUSCODE_GOOD) {
572 // get value from server
573 UA_Variant_init(valueToCheck);
574 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
575 value = (uint32_t)*((uint32_t*)valueToCheck->data);
576 BOOST_CHECK(value == newValue);
577 }
578 else {
579 BOOST_CHECK(false);
580 }
581 break;
582 }
583 case UA_TYPES_INT64: {
584 // Check Datatype
585 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
586 BOOST_CHECK(datatype == "int64_t");
587 // Check Name
588 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
589 BOOST_CHECK(valName == "/Mein/Name/ist/int64Scalar");
590 // Check Value
591 int64_t value = (int64_t)*((int64_t*)valueToCheck->data);
592 BOOST_CHECK(value == 0);
593 // cout << "Wert: " << std::to_string(value) << endl;
594 // set new value
595 int64_t newValue = 123;
596 UA_Variant_init(valueToCheck);
597 UA_Variant_setScalarCopy(valueToCheck, &newValue, &UA_TYPES[UA_TYPES_INT64]);
598 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
599 if(retvalNewVar == UA_STATUSCODE_GOOD) {
600 // get value from server
601 UA_Variant_init(valueToCheck);
602 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
603 value = (int64_t)*((int64_t*)valueToCheck->data);
604 BOOST_CHECK(value == newValue);
605 }
606 else {
607 BOOST_CHECK(false);
608 }
609 break;
610 }
611 case UA_TYPES_UINT64: {
612 // Check Datatype
613 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
614 BOOST_CHECK(datatype == "uint64_t");
615 // Check Name
616 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
617 BOOST_CHECK(valName == "/Mein/Name/ist/uint64Scalar");
618 // Check Value
619 uint64_t value = (uint64_t)*((uint64_t*)valueToCheck->data);
620 BOOST_CHECK(value == 0);
621 // cout << "Wert: " << std::to_string(value) << endl;
622 // set new value
623 uint64_t newValue = 123;
624 UA_Variant_init(valueToCheck);
625 UA_Variant_setScalarCopy(valueToCheck, &newValue, &UA_TYPES[UA_TYPES_UINT64]);
626 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
627 if(retvalNewVar == UA_STATUSCODE_GOOD) {
628 // get value from server
629 UA_Variant_init(valueToCheck);
630 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
631 value = (uint64_t)*((uint64_t*)valueToCheck->data);
632 BOOST_CHECK(value == newValue);
633 }
634 else {
635 BOOST_CHECK(false);
636 }
637 break;
638 }
639 case UA_TYPES_DOUBLE: {
640 // Check Datatype
641 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
642 BOOST_CHECK(datatype == "double");
643 // Check Name
644 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
645 BOOST_CHECK(valName == "/Dieser/Name/ist/doubleScalar");
646 // Check Value
647 double value = (double)*((double*)valueToCheck->data);
648 BOOST_CHECK(value == 0);
649 // cout << "Wert: " << std::to_string(value) << endl;
650 // set new value
651 double newValue = 123.12;
652 UA_Variant_init(valueToCheck);
653 UA_Variant_setScalarCopy(valueToCheck, &newValue, &UA_TYPES[UA_TYPES_DOUBLE]);
654 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
655 if(retvalNewVar == UA_STATUSCODE_GOOD) {
656 // get value from server
657 UA_Variant_init(valueToCheck);
658 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
659 value = (double)*((double*)valueToCheck->data);
660 BOOST_CHECK(((int32_t)value * 100) == ((int32_t)newValue * 100));
661 }
662 else {
663 BOOST_CHECK(false);
664 }
665 break;
666 }
667 case UA_TYPES_FLOAT: {
668 // Check Datatype
669 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
670 BOOST_CHECK(datatype == "float");
671 // Check Name
672 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
673 BOOST_CHECK(valName == "/floatScalar");
674 // Check Value
675 float value = (float)*((float*)valueToCheck->data);
676 BOOST_CHECK(value == 0);
677 // cout << "Wert: " << std::to_string(value) << endl;
678 // set new value
679 float newValue = 123.12;
680 UA_Variant_init(valueToCheck);
681 UA_Variant_setScalarCopy(valueToCheck, &newValue, &UA_TYPES[UA_TYPES_FLOAT]);
682 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
683 if(retvalNewVar == UA_STATUSCODE_GOOD) {
684 // get value from server
685 UA_Variant_init(valueToCheck);
686 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
687 value = (float)*((float*)valueToCheck->data);
688 BOOST_CHECK(((int32_t)value * 100) == ((int32_t)newValue * 100));
689 }
690 else {
691 BOOST_CHECK(false);
692 }
693 break;
694 }
695 default: {
696 printf("Not define: %-16d\n", datatypeId.identifier.numeric);
697 BOOST_CHECK(false);
698 }
699 }
700 }
701 else {
702 /*
703 * Begin array section
704 */
705 switch(datatypeId.identifier.numeric - 1) {
706 case UA_TYPES_SBYTE: {
707 // Check Datatype
708 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
709 BOOST_CHECK(datatype == "int8_t");
710 // Check Name
711 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
712 // cout << valName << endl;
713 BOOST_CHECK(valName == "/Mein/Name_ist#int8Array_s15");
714 // Check Value
715 size_t arrayLength = valueToCheck->arrayLength;
716 int8_t* value = (int8_t*)valueToCheck->data;
717 for(uint32_t i = 0; i < arrayLength; i++) {
718 BOOST_CHECK(value[i] == 0);
719 }
720 // set new value
721 int8_t varArray[arrayLength];
722 int8_t* newValue = varArray;
723 for(uint32_t i = 0; i < arrayLength; i++) {
724 newValue[i] = i;
725 }
726
727 UA_Variant_init(valueToCheck);
728 UA_Variant_setArrayCopy(valueToCheck, newValue, arrayLength, &UA_TYPES[UA_TYPES_SBYTE]);
729 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
730 if(retvalNewVar == UA_STATUSCODE_GOOD) {
731 // get value from server -> should be the new one
732 UA_Variant_init(valueToCheck);
733 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
734 value = (int8_t*)valueToCheck->data;
735 for(uint32_t i = 0; i < arrayLength; i++) {
736 BOOST_CHECK(value[i] == newValue[i]);
737 }
738 }
739 else {
740 BOOST_CHECK(false);
741 }
742 break;
743 }
744 case UA_TYPES_BYTE: {
745 // Check Datatype
746 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
747 BOOST_CHECK(datatype == "uint8_t");
748 // Check Name
749 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
750 // cout << valName << endl;
751 BOOST_CHECK(valName == "/Dein/Name/ist/uint8Array_s10");
752 // Check Value
753 size_t arrayLength = valueToCheck->arrayLength;
754 uint8_t* value = (uint8_t*)valueToCheck->data;
755 for(uint32_t i = 0; i < arrayLength; i++) {
756 BOOST_CHECK(value[i] == 0);
757 }
758 // set new value
759 uint8_t varArray[arrayLength];
760 uint8_t* newValue = varArray;
761 for(uint32_t i = 0; i < arrayLength; i++) {
762 newValue[i] = i;
763 }
764
765 UA_Variant_init(valueToCheck);
766 UA_Variant_setArrayCopy(valueToCheck, newValue, arrayLength, &UA_TYPES[UA_TYPES_BYTE]);
767 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
768 if(retvalNewVar == UA_STATUSCODE_GOOD) {
769 // get value from server
770 UA_Variant_init(valueToCheck);
771 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
772 value = (uint8_t*)valueToCheck->data;
773 for(uint32_t i = 0; i < arrayLength; i++) {
774 BOOST_CHECK(value[i] == newValue[i]);
775 }
776 }
777 else {
778 BOOST_CHECK(false);
779 }
780 break;
781 }
782 case UA_TYPES_INT16: {
783 // Check Datatype
784 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
785 BOOST_CHECK(datatype == "int16_t");
786 // Check Name
787 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
788 BOOST_CHECK(valName == "/Unser/Name/ist_int16Array_s10");
789 // Check Value
790 size_t arrayLength = valueToCheck->arrayLength;
791 int16_t* value = (int16_t*)valueToCheck->data;
792 for(uint32_t i = 0; i < arrayLength; i++) {
793 BOOST_CHECK(value[i] == 0);
794 }
795 // set new value
796 value = (int16_t*)valueToCheck->data;
797 for(uint32_t i = 0; i < arrayLength; i++) {
798 BOOST_CHECK(value[i] == 0);
799 }
800 // set new value
801 int16_t varArray[arrayLength];
802 int16_t* newValue = varArray;
803 for(uint32_t i = 0; i < arrayLength; i++) {
804 newValue[i] = i;
805 }
806
807 UA_Variant_init(valueToCheck);
808 UA_Variant_setArrayCopy(valueToCheck, newValue, arrayLength, &UA_TYPES[UA_TYPES_INT16]);
809 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
810 if(retvalNewVar == UA_STATUSCODE_GOOD) {
811 // get value from server
812 UA_Variant_init(valueToCheck);
813 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
814 value = (int16_t*)valueToCheck->data;
815 for(uint32_t i = 0; i < arrayLength; i++) {
816 BOOST_CHECK(value[i] == newValue[i]);
817 }
818 }
819 else {
820 BOOST_CHECK(false);
821 }
822 break;
823 }
824 case UA_TYPES_UINT16: {
825 // Check Datatype
826 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
827 BOOST_CHECK(datatype == "uint16_t");
828 // Check Name
829 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
830 BOOST_CHECK(valName == "/Unser/Name/ist_uint8Array_s10");
831 // Check Value
832 size_t arrayLength = valueToCheck->arrayLength;
833 uint16_t* value = (uint16_t*)valueToCheck->data;
834 for(uint32_t i = 0; i < arrayLength; i++) {
835 BOOST_CHECK(value[i] == 0);
836 }
837 // set new value
838 value = (uint16_t*)valueToCheck->data;
839 for(uint32_t i = 0; i < arrayLength; i++) {
840 BOOST_CHECK(value[i] == 0);
841 }
842 // cout << "Wert: " << std::to_string(value) << endl;
843 // set new value
844 uint16_t varArray[arrayLength];
845 uint16_t* newValue = varArray;
846 for(uint32_t i = 0; i < arrayLength; i++) {
847 newValue[i] = i;
848 }
849
850 UA_Variant_init(valueToCheck);
851 UA_Variant_setArrayCopy(valueToCheck, newValue, arrayLength, &UA_TYPES[UA_TYPES_UINT16]);
852 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
853 if(retvalNewVar == UA_STATUSCODE_GOOD) {
854 // get value from server
855 UA_Variant_init(valueToCheck);
856 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
857 value = (uint16_t*)valueToCheck->data;
858 for(uint32_t i = 0; i < arrayLength; i++) {
859 BOOST_CHECK(value[i] == newValue[i]);
860 }
861 }
862 else {
863 BOOST_CHECK(false);
864 }
865 break;
866 }
867 case UA_TYPES_INT32: {
868 // Check Datatype
869 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
870 BOOST_CHECK(datatype == "int32_t");
871 // Check Name
872 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
873 BOOST_CHECK(valName == "/int32Array_s15");
874 // Check Value
875 size_t arrayLength = valueToCheck->arrayLength;
876 int32_t* value = (int32_t*)valueToCheck->data;
877 for(uint32_t i = 0; i < arrayLength; i++) {
878 BOOST_CHECK(value[i] == 0);
879 }
880 // set new value
881 value = (int32_t*)valueToCheck->data;
882 for(uint32_t i = 0; i < arrayLength; i++) {
883 BOOST_CHECK(value[i] == 0);
884 }
885 // cout << "Wert: " << std::to_string(value) << endl;
886 // set new value
887 int32_t varArray[arrayLength];
888 int32_t* newValue = varArray;
889 for(uint32_t i = 0; i < arrayLength; i++) {
890 newValue[i] = i;
891 }
892
893 UA_Variant_init(valueToCheck);
894 UA_Variant_setArrayCopy(valueToCheck, newValue, arrayLength, &UA_TYPES[UA_TYPES_INT32]);
895 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
896 if(retvalNewVar == UA_STATUSCODE_GOOD) {
897 // get value from server
898 UA_Variant_init(valueToCheck);
899 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
900 value = (int32_t*)valueToCheck->data;
901 for(uint32_t i = 0; i < arrayLength; i++) {
902 BOOST_CHECK(value[i] == newValue[i]);
903 }
904 }
905 else {
906 BOOST_CHECK(false);
907 }
908 break;
909 }
910 case UA_TYPES_UINT32: {
911 // Check Datatype
912 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
913 BOOST_CHECK(datatype == "uint32_t");
914 // Check Name
915 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
916 // cout << valName << endl;
917 BOOST_CHECK(valName == "/uint32Array_s10");
918 // Check Value
919 size_t arrayLength = valueToCheck->arrayLength;
920 uint32_t* value = (uint32_t*)valueToCheck->data;
921 for(uint32_t i = 0; i < arrayLength; i++) {
922 BOOST_CHECK(value[i] == 0);
923 }
924 // set new value
925 uint32_t varArray[arrayLength];
926 uint32_t* newValue = varArray;
927 for(uint32_t i = 0; i < arrayLength; i++) {
928 newValue[i] = i;
929 }
930
931 UA_Variant_init(valueToCheck);
932 UA_Variant_setArrayCopy(valueToCheck, newValue, arrayLength, &UA_TYPES[UA_TYPES_UINT32]);
933 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
934 if(retvalNewVar == UA_STATUSCODE_GOOD) {
935 // get value from server
936 UA_Variant_init(valueToCheck);
937 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
938 value = (uint32_t*)valueToCheck->data;
939 for(uint32_t i = 0; i < arrayLength; i++) {
940 BOOST_CHECK(value[i] == newValue[i]);
941 }
942 }
943 else {
944 BOOST_CHECK(false);
945 }
946 break;
947 }
948 case UA_TYPES_INT64: {
949 // Check Datatype
950 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
951 BOOST_CHECK(datatype == "int64_t");
952 // Check Name
953 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
954 BOOST_CHECK(valName == "/int64Array_s15");
955 // Check Value
956 size_t arrayLength = valueToCheck->arrayLength;
957 int64_t* value = (int64_t*)valueToCheck->data;
958 for(uint32_t i = 0; i < arrayLength; i++) {
959 BOOST_CHECK(value[i] == 0);
960 }
961 // set new value
962 value = (int64_t*)valueToCheck->data;
963 for(uint32_t i = 0; i < arrayLength; i++) {
964 BOOST_CHECK(value[i] == 0);
965 }
966 // cout << "Wert: " << std::to_string(value) << endl;
967 // set new value
968 int64_t varArray[arrayLength];
969 int64_t* newValue = varArray;
970 for(uint32_t i = 0; i < arrayLength; i++) {
971 newValue[i] = i;
972 }
973
974 UA_Variant_init(valueToCheck);
975 UA_Variant_setArrayCopy(valueToCheck, newValue, arrayLength, &UA_TYPES[UA_TYPES_INT64]);
976 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
977 if(retvalNewVar == UA_STATUSCODE_GOOD) {
978 // get value from server
979 UA_Variant_init(valueToCheck);
980 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
981 value = (int64_t*)valueToCheck->data;
982 for(uint32_t i = 0; i < arrayLength; i++) {
983 BOOST_CHECK(value[i] == newValue[i]);
984 }
985 }
986 else {
987 BOOST_CHECK(false);
988 }
989 break;
990 }
991 case UA_TYPES_UINT64: {
992 // Check Datatype
993 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
994 BOOST_CHECK(datatype == "uint64_t");
995 // Check Name
996 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
997 BOOST_CHECK(valName == "/uint64Array_s10");
998 // Check Value
999 size_t arrayLength = valueToCheck->arrayLength;
1000 uint64_t* value = (uint64_t*)valueToCheck->data;
1001 for(uint32_t i = 0; i < arrayLength; i++) {
1002 BOOST_CHECK(value[i] == 0);
1003 }
1004 // set new value
1005 value = (uint64_t*)valueToCheck->data;
1006 for(uint32_t i = 0; i < arrayLength; i++) {
1007 BOOST_CHECK(value[i] == 0);
1008 }
1009 // cout << "Wert: " << std::to_string(value) << endl;
1010 // set new value
1011 uint64_t varArray[arrayLength];
1012 uint64_t* newValue = varArray;
1013 for(uint32_t i = 0; i < arrayLength; i++) {
1014 newValue[i] = i;
1015 }
1016
1017 UA_Variant_init(valueToCheck);
1018 UA_Variant_setArrayCopy(valueToCheck, newValue, arrayLength, &UA_TYPES[UA_TYPES_UINT64]);
1019 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
1020 if(retvalNewVar == UA_STATUSCODE_GOOD) {
1021 // get value from server
1022 UA_Variant_init(valueToCheck);
1023 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
1024 value = (uint64_t*)valueToCheck->data;
1025 for(uint32_t i = 0; i < arrayLength; i++) {
1026 BOOST_CHECK(value[i] == newValue[i]);
1027 }
1028 }
1029 else {
1030 BOOST_CHECK(false);
1031 }
1032 break;
1033 }
1034 case UA_TYPES_DOUBLE: {
1035 // Check Datatype
1036 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
1037 BOOST_CHECK(datatype == "double");
1038 // Check Name
1039 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
1040 // cout << valName << endl;
1041 BOOST_CHECK(valName == "/doubleArray_s15");
1042 // Check Value
1043 size_t arrayLength = valueToCheck->arrayLength;
1044 double* value = (double*)valueToCheck->data;
1045 for(uint32_t i = 0; i < arrayLength; i++) {
1046 BOOST_CHECK(value[i] == 0);
1047 }
1048 // cout << "Wert: " << std::to_string(value) << endl;
1049 // set new value
1050 double varArray[arrayLength];
1051 double* newValue = varArray;
1052 for(uint32_t i = 0; i < arrayLength; i++) {
1053 newValue[i] = i * 0.5;
1054 }
1055
1056 UA_Variant_init(valueToCheck);
1057 UA_Variant_setArrayCopy(valueToCheck, newValue, arrayLength, &UA_TYPES[UA_TYPES_DOUBLE]);
1058 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
1059 if(retvalNewVar == UA_STATUSCODE_GOOD) {
1060 // get value from server
1061 UA_Variant_init(valueToCheck);
1062 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
1063 value = (double*)valueToCheck->data;
1064 for(uint32_t i = 0; i < arrayLength; i++) {
1065 BOOST_CHECK(((int32_t)(value[i] * 100)) == ((int32_t)(newValue[i] * 100)));
1066 }
1067 }
1068 else {
1069 BOOST_CHECK(false);
1070 }
1071 break;
1072 }
1073 case UA_TYPES_FLOAT: {
1074 // Check Datatype
1075 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)datatypeToCheck->data)), datatype);
1076 BOOST_CHECK(datatype == "float");
1077 // Check Name
1078 UASTRING_TO_CPPSTRING(((UA_String) * ((UA_String*)nameToCheck->data)), valName);
1079 BOOST_CHECK(valName == "/floatArray_s101234");
1080 // Check Value
1081 size_t arrayLength = valueToCheck->arrayLength;
1082 float* value = (float*)valueToCheck->data;
1083 for(uint32_t i = 0; i < arrayLength; i++) {
1084 BOOST_CHECK(value[i] == 0);
1085 }
1086 // cout << "Wert: " << std::to_string(value) << endl;
1087 // set new value
1088 float varArray[arrayLength];
1089 float* newValue = varArray;
1090 for(uint32_t i = 0; i < arrayLength; i++) {
1091 newValue[i] = i * 0.5;
1092 }
1093
1094 UA_Variant_init(valueToCheck);
1095 UA_Variant_setArrayCopy(valueToCheck, newValue, arrayLength, &UA_TYPES[UA_TYPES_FLOAT]);
1096 UA_StatusCode retvalNewVar = UA_Client_writeValueAttribute(client, valueNodeId, valueToCheck);
1097 if(retvalNewVar == UA_STATUSCODE_GOOD) {
1098 // get value from server
1099 UA_Variant_init(valueToCheck);
1100 UA_Client_readValueAttribute(client, valueNodeId, valueToCheck);
1101 value = (float*)valueToCheck->data;
1102 for(uint32_t i = 0; i < arrayLength; i++) {
1103 BOOST_CHECK(((int32_t)(value[i] * 100)) == ((int32_t)(newValue[i] * 100)));
1104 }
1105 }
1106 else {
1107 BOOST_CHECK(false);
1108 }
1109 break;
1110 }
1111 default: {
1112 printf("Not define: %-16d\n", datatypeId.identifier.numeric);
1113 BOOST_CHECK(false);
1114 }
1115 }
1116 }
1117 }
1118 UA_Variant_delete(valueToCheck);
1119 UA_Variant_delete(euToCheck);
1120 UA_Variant_delete(nameToCheck);
1121 UA_Variant_delete(datatypeToCheck);
1122 UA_Variant_delete(descToCheck);
1123 }
1124 }
1125 }
1126 }
1127
1128 UA_BrowseRequest_clear(&bReq);
1129 UA_BrowseResponse_clear(&bResp);
1130 UA_Client_disconnect(client);
1131 /* Some times there is a double free corruption. */
1132 UA_Client_delete(client);
1133
1134 serverSet.runUAServer = UA_FALSE;
1135
1136 if(serverThread->joinable()) {
1137 serverThread->join();
1138 }
1139
1140 cout << "Delete ServerThread" << endl;
1141 delete serverThread;
1142 serverThread = NULL;
1143
1144 for(auto& ptr : varList) delete ptr;
1145}
1146
1147class ProcessVariableTestSuite : public test_suite {
1148 public:
1149 ProcessVariableTestSuite() : test_suite("ua_processvariable Test Suite") {
1150 add(BOOST_TEST_CASE(&ProcessVariableTest::testClassSide));
1151 add(BOOST_TEST_CASE(&ProcessVariableTest::testClientSide));
1152 }
1153};
1154
1155test_suite* init_unit_test_suite(int /*argc*/, char** /*argv[]*/) {
1156 framework::master_test_suite().add(new ProcessVariableTestSuite);
1157 return 0;
1158}
This class represent a processvariable of the controlsystemadapter in the information model of a OPC ...
void setEngineeringUnit(string engineeringUnit)
Set engineering unit of processvariable.
string getName()
Get name of processvariable.
string getType()
Get type of processvariable.
UA_DateTime getSourceTimeStamp()
Reimplement the sourcetimestamp for every processvariable.
UA_NodeId getOwnNodeId()
Get node id of this processvariable instance.
string getEngineeringUnit()
Get engineering unit of processvariable.
UA_StatusCode setValue(const UA_Variant *data)
UA_StatusCode getValue(UA_Variant *v, const UA_NumericRange *range)
string getDescription()
Get description unit of processvariable.
static void testData(ProcessVariable::SharedPtr oneProcessVariable, TestFixturePVSet *pvSet, ua_processvariable *test)
boost::shared_ptr< ControlSystemPVManager > csManager
test_suite * init_unit_test_suite(int, char **)
fusion::map< fusion::pair< uint8_t, UA_DataType >, fusion::pair< int8_t, UA_DataType >, fusion::pair< uint16_t, UA_DataType >, fusion::pair< int16_t, UA_DataType >, fusion::pair< uint32_t, UA_DataType >, fusion::pair< int32_t, UA_DataType >, fusion::pair< uint64_t, UA_DataType >, fusion::pair< int64_t, UA_DataType >, fusion::pair< float, UA_DataType >, fusion::pair< double, UA_DataType > > TestTypesMap
#define UASTRING_TO_CPPSTRING(_p_uastring, _p_cppstring)