ChimeraTK-ControlSystemAdapter-OPCUAAdapter  04.00.01
test_opcua_processvariable.cpp
Go to the documentation of this file.
1 #include "open62541/plugin/log_stdout.h"
2 #include <csa_opcua_adapter.h>
3 #include <test_sample_data.h>
4 #include <ua_adapter.h>
5 
6 #include <boost/fusion/container/map.hpp>
7 #include <boost/test/included/unit_test.hpp>
8 
9 #include <string.h>
10 
11 extern "C" {
12 #include "csa_namespace.h"
13 #include "unistd.h"
14 }
15 
16 using namespace boost::unit_test_framework;
17 using namespace std;
18 namespace fusion = boost::fusion;
19 
20 typedef 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 
26 static 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 
48 template<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()) {
121  ua_processvariable test(
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 
1147 class 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 
1155 test_suite* init_unit_test_suite(int /*argc*/, char** /*argv[]*/) {
1156  framework::master_test_suite().add(new ProcessVariableTestSuite);
1157  return 0;
1158 }
csa_opcua_adapter.h
ProcessVariableTest
Definition: test_opcua_processvariable.cpp:37
ProcessVariableTestSuite
Definition: test_opcua_processvariable.cpp:1147
ChimeraTK::ua_processvariable::getEngineeringUnit
string getEngineeringUnit()
Get engineering unit of processvariable.
Definition: csa_processvariable.cpp:107
ChimeraTK::ua_processvariable::setValue
UA_StatusCode setValue(const UA_Variant *data)
Definition: csa_processvariable.cpp:318
ProcessVariableTest::testClientSide
static void testClientSide()
Definition: test_opcua_processvariable.cpp:206
TestTypesMap
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
Definition: test_opcua_processvariable.cpp:24
TestFixtureServerSet::runUAServer
UA_Boolean runUAServer
Definition: test_sample_data.h:99
csa_namespace.h
ChimeraTK::ua_processvariable::getName
string getName()
Get name of processvariable.
Definition: csa_processvariable.cpp:66
ChimeraTK::ua_processvariable::getOwnNodeId
UA_NodeId getOwnNodeId()
Get node id of this processvariable instance.
Definition: csa_processvariable.cpp:729
TestFixturePVSet
Definition: test_sample_data.h:33
ua_adapter.h
TestFixturePVSet::csManager
boost::shared_ptr< ControlSystemPVManager > csManager
Definition: test_sample_data.h:35
ChimeraTK::ua_processvariable::getSourceTimeStamp
UA_DateTime getSourceTimeStamp()
Reimplement the sourcetimestamp for every processvariable.
Definition: csa_processvariable.cpp:717
ProcessVariableTest::testData
static void testData(ProcessVariable::SharedPtr oneProcessVariable, TestFixturePVSet *pvSet, ua_processvariable *test)
Definition: test_opcua_processvariable.cpp:49
ChimeraTK::ua_processvariable::getDescription
string getDescription()
Get description unit of processvariable.
Definition: csa_processvariable.cpp:179
init_unit_test_suite
test_suite * init_unit_test_suite(int, char **)
Definition: test_opcua_processvariable.cpp:1155
ChimeraTK::ua_processvariable::getType
string getType()
Get type of processvariable.
Definition: csa_processvariable.cpp:206
test_sample_data.h
TestFixtureServerSet::mappedServer
UA_Server * mappedServer
Definition: test_sample_data.h:97
ProcessVariableTestSuite::ProcessVariableTestSuite
ProcessVariableTestSuite()
Definition: test_opcua_processvariable.cpp:1149
UASTRING_TO_CPPSTRING
#define UASTRING_TO_CPPSTRING(_p_uastring, _p_cppstring)
Definition: ua_typeconversion.h:53
TestFixtureServerSet
Definition: test_sample_data.h:93
ChimeraTK::ua_processvariable::setEngineeringUnit
void setEngineeringUnit(string engineeringUnit)
Set engineering unit of processvariable.
Definition: csa_processvariable.cpp:87
TestFixtureServerSet::baseNodeId
UA_NodeId baseNodeId
Definition: test_sample_data.h:98
ProcessVariableTest::testClassSide
static void testClassSide()
Definition: test_opcua_processvariable.cpp:107
TestFixtureServerSet::opcuaPort
uint32_t opcuaPort
Definition: test_sample_data.h:94
ChimeraTK::ua_processvariable::getValue
UA_StatusCode getValue(UA_Variant *v, const UA_NumericRange *range)
Definition: csa_processvariable.cpp:257
ChimeraTK::ua_processvariable
This class represent a processvariable of the controlsystemadapter in the information model of a OPC ...
Definition: csa_processvariable.h:49