check_services_attributes.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include "check.h"
  5. #include "server/ua_nodestore.h"
  6. #include "server/ua_services.h"
  7. #include "ua_client.h"
  8. #include "ua_nodeids.h"
  9. #include "ua_types.h"
  10. #include "ua_config_standard.h"
  11. #include "server/ua_server_internal.h"
  12. #ifdef UA_ENABLE_MULTITHREADING
  13. #include <pthread.h>
  14. #include <urcu.h>
  15. #endif
  16. static UA_StatusCode
  17. readCPUTemperature(void *handle, const UA_NodeId nodeid, UA_Boolean sourceTimeStamp,
  18. const UA_NumericRange *range, UA_DataValue *dataValue) {
  19. UA_Float temp = 20.5f;
  20. UA_Variant_setScalarCopy(&dataValue->value, &temp, &UA_TYPES[UA_TYPES_FLOAT]);
  21. dataValue->hasValue = true;
  22. return UA_STATUSCODE_GOOD;
  23. }
  24. static UA_Server *
  25. makeTestSequence(void) {
  26. UA_Server * server = UA_Server_new(UA_ServerConfig_standard);
  27. UA_StatusCode retval = UA_STATUSCODE_GOOD;
  28. /* VariableNode */
  29. UA_VariableAttributes vattr;
  30. UA_VariableAttributes_init(&vattr);
  31. UA_Int32 myInteger = 42;
  32. UA_Variant_setScalar(&vattr.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]);
  33. vattr.description = UA_LOCALIZEDTEXT("locale","the answer");
  34. vattr.displayName = UA_LOCALIZEDTEXT("locale","the answer");
  35. vattr.valueRank = -2;
  36. UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, "the answer");
  37. UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, "the.answer");
  38. UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
  39. UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
  40. retval = UA_Server_addVariableNode(server, myIntegerNodeId, parentNodeId,
  41. parentReferenceNodeId, myIntegerName,
  42. UA_NODEID_NULL, vattr, NULL, NULL);
  43. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  44. /* DataSource VariableNode */
  45. UA_VariableAttributes_init(&vattr);
  46. UA_DataSource temperatureDataSource =
  47. (UA_DataSource) {.handle = NULL, .read = readCPUTemperature, .write = NULL};
  48. vattr.description = UA_LOCALIZEDTEXT("en_US","temperature");
  49. vattr.displayName = UA_LOCALIZEDTEXT("en_US","temperature");
  50. retval = UA_Server_addDataSourceVariableNode(server, UA_NODEID_STRING(1, "cpu.temperature"),
  51. UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
  52. UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
  53. UA_QUALIFIEDNAME(1, "cpu temperature"),
  54. UA_NODEID_NULL, vattr, temperatureDataSource, NULL);
  55. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  56. /* VariableNode with array */
  57. UA_VariableAttributes_init(&vattr);
  58. UA_Int32 myIntegerArray[9] = {1,2,3,4,5,6,7,8,9};
  59. UA_Variant_setArray(&vattr.value, &myIntegerArray, 9, &UA_TYPES[UA_TYPES_INT32]);
  60. vattr.valueRank = -2;
  61. UA_UInt32 myIntegerDimensions[2] = {3,3};
  62. vattr.value.arrayDimensions = myIntegerDimensions;
  63. vattr.value.arrayDimensionsSize = 2;
  64. vattr.displayName = UA_LOCALIZEDTEXT("locale","myarray");
  65. myIntegerName = UA_QUALIFIEDNAME(1, "myarray");
  66. myIntegerNodeId = UA_NODEID_STRING(1, "myarray");
  67. parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
  68. parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
  69. retval = UA_Server_addVariableNode(server, myIntegerNodeId, parentNodeId,
  70. parentReferenceNodeId, myIntegerName,
  71. UA_NODEID_NULL, vattr, NULL, NULL);
  72. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  73. /* ObjectNode */
  74. UA_ObjectAttributes obj_attr;
  75. UA_ObjectAttributes_init(&obj_attr);
  76. obj_attr.description = UA_LOCALIZEDTEXT("en_US","Demo");
  77. obj_attr.displayName = UA_LOCALIZEDTEXT("en_US","Demo");
  78. retval = UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(1, 50),
  79. UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
  80. UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
  81. UA_QUALIFIEDNAME(1, "Demo"),
  82. UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE),
  83. obj_attr, NULL, NULL);
  84. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  85. /* ViewNode */
  86. UA_ViewAttributes view_attr;
  87. UA_ViewAttributes_init(&view_attr);
  88. view_attr.description = UA_LOCALIZEDTEXT("en_US", "Viewtest");
  89. view_attr.displayName = UA_LOCALIZEDTEXT("en_US", "Viewtest");
  90. retval = UA_Server_addViewNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_VIEWNODE),
  91. UA_NODEID_NUMERIC(0, UA_NS0ID_VIEWSFOLDER),
  92. UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
  93. UA_QUALIFIEDNAME(0, "Viewtest"), view_attr, NULL, NULL);
  94. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  95. #ifdef UA_ENABLE_METHODCALLS
  96. /* MethodNode */
  97. UA_MethodAttributes ma;
  98. UA_MethodAttributes_init(&ma);
  99. ma.description = UA_LOCALIZEDTEXT("en_US", "Methodtest");
  100. ma.displayName = UA_LOCALIZEDTEXT("en_US", "Methodtest");
  101. retval = UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_METHODNODE),
  102. UA_NODEID_NUMERIC(0, 3),
  103. UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
  104. UA_QUALIFIEDNAME(0, "Methodtest"), ma,
  105. NULL, NULL, 0, NULL, 0, NULL, NULL);
  106. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  107. #endif
  108. return server;
  109. }
  110. static UA_VariableNode* makeCompareSequence(void) {
  111. UA_VariableNode *node = UA_NodeStore_newVariableNode();
  112. UA_Int32 myInteger = 42;
  113. UA_Variant_setScalarCopy(&node->value.data.value.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]);
  114. node->value.data.value.hasValue = true;
  115. const UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, "the answer");
  116. UA_QualifiedName_copy(&myIntegerName,&node->browseName);
  117. const UA_LocalizedText myIntegerDisplName = UA_LOCALIZEDTEXT("locale", "the answer");
  118. UA_LocalizedText_copy(&myIntegerDisplName, &node->displayName);
  119. UA_LocalizedText_copy(&myIntegerDisplName, &node->description);
  120. const UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, "the.answer");
  121. UA_NodeId_copy(&myIntegerNodeId,&node->nodeId);
  122. return node;
  123. }
  124. START_TEST(ReadSingleAttributeValueWithoutTimestamp) {
  125. UA_Server *server = makeTestSequence();
  126. UA_ReadValueId rvi;
  127. UA_ReadValueId_init(&rvi);
  128. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  129. rvi.attributeId = UA_ATTRIBUTEID_VALUE;
  130. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  131. ck_assert_int_eq(resp.status, UA_STATUSCODE_GOOD);
  132. ck_assert_int_eq(0, resp.value.arrayLength);
  133. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_INT32], resp.value.type);
  134. ck_assert_int_eq(42, *(UA_Int32* )resp.value.data);
  135. UA_Server_delete(server);
  136. UA_DataValue_deleteMembers(&resp);
  137. } END_TEST
  138. START_TEST(ReadSingleAttributeValueRangeWithoutTimestamp) {
  139. UA_Server *server = makeTestSequence();
  140. UA_ReadValueId rvi;
  141. UA_ReadValueId_init(&rvi);
  142. rvi.nodeId = UA_NODEID_STRING(1, "myarray");
  143. rvi.indexRange = UA_STRING("1:2,0:1");
  144. rvi.attributeId = UA_ATTRIBUTEID_VALUE;
  145. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  146. ck_assert_int_eq(4, resp.value.arrayLength);
  147. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_INT32], resp.value.type);
  148. UA_Server_delete(server);
  149. UA_DataValue_deleteMembers(&resp);
  150. } END_TEST
  151. START_TEST(ReadSingleAttributeNodeIdWithoutTimestamp) {
  152. UA_Server *server = makeTestSequence();
  153. UA_ReadValueId rvi;
  154. UA_ReadValueId_init(&rvi);
  155. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  156. rvi.attributeId = UA_ATTRIBUTEID_NODEID;
  157. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  158. const UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, "the.answer");
  159. ck_assert_int_eq(0, resp.value.arrayLength);
  160. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_NODEID], resp.value.type);
  161. UA_NodeId* respval = (UA_NodeId*) resp.value.data;
  162. ck_assert_int_eq(1, respval->namespaceIndex);
  163. ck_assert(UA_String_equal(&myIntegerNodeId.identifier.string, &respval->identifier.string));
  164. UA_DataValue_deleteMembers(&resp);
  165. UA_Server_delete(server);
  166. } END_TEST
  167. START_TEST(ReadSingleAttributeNodeClassWithoutTimestamp) {
  168. UA_Server *server = makeTestSequence();
  169. UA_ReadValueId rvi;
  170. UA_ReadValueId_init(&rvi);
  171. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  172. rvi.attributeId = UA_ATTRIBUTEID_NODECLASS;
  173. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  174. ck_assert_int_eq(0, resp.value.arrayLength);
  175. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_NODECLASS],resp.value.type);
  176. ck_assert_int_eq(*(UA_Int32*)resp.value.data,UA_NODECLASS_VARIABLE);
  177. UA_DataValue_deleteMembers(&resp);
  178. UA_Server_delete(server);
  179. } END_TEST
  180. START_TEST(ReadSingleAttributeBrowseNameWithoutTimestamp) {
  181. UA_Server *server = makeTestSequence();
  182. UA_ReadValueId rvi;
  183. UA_ReadValueId_init(&rvi);
  184. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  185. rvi.attributeId = UA_ATTRIBUTEID_BROWSENAME;
  186. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  187. UA_QualifiedName* respval = (UA_QualifiedName*) resp.value.data;
  188. const UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, "the answer");
  189. ck_assert_int_eq(0, resp.value.arrayLength);
  190. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_QUALIFIEDNAME], resp.value.type);
  191. ck_assert_int_eq(1, respval->namespaceIndex);
  192. ck_assert(UA_String_equal(&myIntegerName.name, &respval->name));
  193. UA_DataValue_deleteMembers(&resp);
  194. UA_Server_delete(server);
  195. } END_TEST
  196. START_TEST(ReadSingleAttributeDisplayNameWithoutTimestamp) {
  197. UA_Server *server = makeTestSequence();
  198. UA_ReadValueId rvi;
  199. UA_ReadValueId_init(&rvi);
  200. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  201. rvi.attributeId = UA_ATTRIBUTEID_DISPLAYNAME;
  202. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  203. UA_LocalizedText* respval = (UA_LocalizedText*) resp.value.data;
  204. const UA_LocalizedText comp = UA_LOCALIZEDTEXT("locale", "the answer");
  205. UA_VariableNode* compNode = makeCompareSequence();
  206. ck_assert_int_eq(0, resp.value.arrayLength);
  207. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_LOCALIZEDTEXT], resp.value.type);
  208. ck_assert(UA_String_equal(&comp.text, &respval->text));
  209. ck_assert(UA_String_equal(&compNode->displayName.locale, &respval->locale));
  210. UA_Server_delete(server);
  211. UA_DataValue_deleteMembers(&resp);
  212. UA_NodeStore_deleteNode((UA_Node*)compNode);
  213. } END_TEST
  214. START_TEST(ReadSingleAttributeDescriptionWithoutTimestamp) {
  215. UA_Server *server = makeTestSequence();
  216. UA_ReadValueId rvi;
  217. UA_ReadValueId_init(&rvi);
  218. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  219. rvi.attributeId = UA_ATTRIBUTEID_DESCRIPTION;
  220. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  221. UA_LocalizedText* respval = (UA_LocalizedText*) resp.value.data;
  222. UA_VariableNode* compNode = makeCompareSequence();
  223. ck_assert_int_eq(0, resp.value.arrayLength);
  224. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_LOCALIZEDTEXT], resp.value.type);
  225. ck_assert(UA_String_equal(&compNode->description.locale, &respval->locale));
  226. ck_assert(UA_String_equal(&compNode->description.text, &respval->text));
  227. UA_DataValue_deleteMembers(&resp);
  228. UA_NodeStore_deleteNode((UA_Node*)compNode);
  229. UA_Server_delete(server);
  230. } END_TEST
  231. START_TEST(ReadSingleAttributeWriteMaskWithoutTimestamp) {
  232. UA_Server *server = makeTestSequence();
  233. UA_ReadValueId rvi;
  234. UA_ReadValueId_init(&rvi);
  235. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  236. rvi.attributeId = UA_ATTRIBUTEID_WRITEMASK;
  237. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  238. UA_UInt32* respval = (UA_UInt32*) resp.value.data;
  239. ck_assert_int_eq(0, resp.value.arrayLength);
  240. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_UINT32], resp.value.type);
  241. ck_assert_int_eq(0,*respval);
  242. UA_DataValue_deleteMembers(&resp);
  243. UA_Server_delete(server);
  244. } END_TEST
  245. START_TEST(ReadSingleAttributeUserWriteMaskWithoutTimestamp) {
  246. UA_Server *server = makeTestSequence();
  247. UA_ReadValueId rvi;
  248. UA_ReadValueId_init(&rvi);
  249. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  250. rvi.attributeId = UA_ATTRIBUTEID_USERWRITEMASK;
  251. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  252. /* Uncommented since the userwritemask is always 0xffffffff for the local admin user */
  253. /* UA_UInt32* respval = (UA_UInt32*) resp.value.data; */
  254. /* ck_assert_int_eq(0, resp.value.arrayLength); */
  255. /* ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_UINT32], resp.value.type); */
  256. /* ck_assert_int_eq(0,*respval); */
  257. UA_DataValue_deleteMembers(&resp);
  258. UA_Server_delete(server);
  259. } END_TEST
  260. START_TEST(ReadSingleAttributeIsAbstractWithoutTimestamp) {
  261. UA_Server *server = makeTestSequence();
  262. UA_ReadValueId rvi;
  263. UA_ReadValueId_init(&rvi);
  264. rvi.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
  265. rvi.attributeId = UA_ATTRIBUTEID_ISABSTRACT;
  266. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  267. ck_assert_int_eq(0, resp.value.arrayLength);
  268. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_BOOLEAN], resp.value.type);
  269. ck_assert(*(UA_Boolean* )resp.value.data==false);
  270. UA_DataValue_deleteMembers(&resp);
  271. UA_Server_delete(server);
  272. } END_TEST
  273. START_TEST(ReadSingleAttributeSymmetricWithoutTimestamp) {
  274. UA_Server *server = makeTestSequence();
  275. UA_ReadValueId rvi;
  276. UA_ReadValueId_init(&rvi);
  277. rvi.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
  278. rvi.attributeId = UA_ATTRIBUTEID_SYMMETRIC;
  279. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  280. ck_assert_int_eq(0, resp.value.arrayLength);
  281. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_BOOLEAN], resp.value.type);
  282. ck_assert(*(UA_Boolean* )resp.value.data==false);
  283. UA_DataValue_deleteMembers(&resp);
  284. UA_Server_delete(server);
  285. } END_TEST
  286. START_TEST(ReadSingleAttributeInverseNameWithoutTimestamp) {
  287. UA_Server *server = makeTestSequence();
  288. UA_ReadValueId rvi;
  289. UA_ReadValueId_init(&rvi);
  290. rvi.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
  291. rvi.attributeId = UA_ATTRIBUTEID_INVERSENAME;
  292. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  293. UA_LocalizedText* respval = (UA_LocalizedText*) resp.value.data;
  294. const UA_LocalizedText comp = UA_LOCALIZEDTEXT("en_US", "OrganizedBy");
  295. ck_assert_int_eq(0, resp.value.arrayLength);
  296. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_LOCALIZEDTEXT],resp.value.type);
  297. ck_assert(UA_String_equal(&comp.text, &respval->text));
  298. ck_assert(UA_String_equal(&comp.locale, &respval->locale));
  299. UA_DataValue_deleteMembers(&resp);
  300. UA_Server_delete(server);
  301. } END_TEST
  302. START_TEST(ReadSingleAttributeContainsNoLoopsWithoutTimestamp) {
  303. UA_Server *server = makeTestSequence();
  304. UA_ReadValueId rvi;
  305. UA_ReadValueId_init(&rvi);
  306. rvi.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_VIEWNODE);
  307. rvi.attributeId = UA_ATTRIBUTEID_CONTAINSNOLOOPS;
  308. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  309. ck_assert_int_eq(0, resp.value.arrayLength);
  310. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_BOOLEAN], resp.value.type);
  311. ck_assert(*(UA_Boolean* )resp.value.data==false);
  312. UA_DataValue_deleteMembers(&resp);
  313. UA_Server_delete(server);
  314. } END_TEST
  315. START_TEST(ReadSingleAttributeEventNotifierWithoutTimestamp) {
  316. UA_Server *server = makeTestSequence();
  317. UA_ReadValueId rvi;
  318. UA_ReadValueId_init(&rvi);
  319. rvi.nodeId = UA_NODEID_NUMERIC(1, 50);
  320. rvi.attributeId = UA_ATTRIBUTEID_EVENTNOTIFIER;
  321. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  322. ck_assert_int_eq(UA_STATUSCODE_GOOD, resp.status);
  323. ck_assert_int_eq(0, resp.value.arrayLength);
  324. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_BYTE],resp.value.type);
  325. ck_assert_int_eq(*(UA_Byte*)resp.value.data, 0);
  326. UA_DataValue_deleteMembers(&resp);
  327. UA_Server_delete(server);
  328. } END_TEST
  329. START_TEST(ReadSingleAttributeDataTypeWithoutTimestamp) {
  330. UA_Server *server = makeTestSequence();
  331. UA_ReadValueId rvi;
  332. UA_ReadValueId_init(&rvi);
  333. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  334. rvi.attributeId = UA_ATTRIBUTEID_DATATYPE;
  335. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  336. ck_assert_int_eq(0, resp.value.arrayLength);
  337. ck_assert_int_eq(UA_STATUSCODE_GOOD, resp.status);
  338. ck_assert_int_eq(true, resp.hasValue);
  339. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_NODEID], resp.value.type);
  340. UA_NodeId* respval = (UA_NodeId*)resp.value.data;
  341. ck_assert_int_eq(respval->namespaceIndex,0);
  342. ck_assert_int_eq(respval->identifier.numeric, UA_NS0ID_BASEDATATYPE);
  343. UA_DataValue_deleteMembers(&resp);
  344. UA_Server_delete(server);
  345. } END_TEST
  346. START_TEST(ReadSingleAttributeValueRankWithoutTimestamp) {
  347. UA_Server *server = makeTestSequence();
  348. UA_ReadValueId rvi;
  349. UA_ReadValueId_init(&rvi);
  350. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  351. rvi.attributeId = UA_ATTRIBUTEID_VALUERANK;
  352. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  353. ck_assert_int_eq(0, resp.value.arrayLength);
  354. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_INT32], resp.value.type);
  355. ck_assert_int_eq(-2, *(UA_Int32* )resp.value.data);
  356. UA_DataValue_deleteMembers(&resp);
  357. UA_Server_delete(server);
  358. } END_TEST
  359. START_TEST(ReadSingleAttributeArrayDimensionsWithoutTimestamp) {
  360. UA_Server *server = makeTestSequence();
  361. UA_ReadValueId rvi;
  362. UA_ReadValueId_init(&rvi);
  363. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  364. rvi.attributeId = UA_ATTRIBUTEID_ARRAYDIMENSIONS;
  365. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  366. ck_assert_int_eq(0, resp.value.arrayLength);
  367. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_INT32], resp.value.type);
  368. ck_assert_ptr_eq((UA_Int32*)resp.value.data,0);
  369. UA_DataValue_deleteMembers(&resp);
  370. UA_Server_delete(server);
  371. } END_TEST
  372. START_TEST(ReadSingleAttributeAccessLevelWithoutTimestamp) {
  373. UA_Server *server = makeTestSequence();
  374. UA_ReadValueId rvi;
  375. UA_ReadValueId_init(&rvi);
  376. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  377. rvi.attributeId = UA_ATTRIBUTEID_ACCESSLEVEL;
  378. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  379. ck_assert_int_eq(0, resp.value.arrayLength);
  380. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_BYTE], resp.value.type);
  381. ck_assert_int_eq(*(UA_Byte*)resp.value.data, 0);
  382. UA_DataValue_deleteMembers(&resp);
  383. UA_Server_delete(server);
  384. } END_TEST
  385. START_TEST(ReadSingleAttributeUserAccessLevelWithoutTimestamp) {
  386. UA_Server *server = makeTestSequence();
  387. UA_ReadValueId rvi;
  388. UA_ReadValueId_init(&rvi);
  389. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  390. rvi.attributeId = UA_ATTRIBUTEID_USERACCESSLEVEL;
  391. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  392. /* Uncommented since the accesslevel is always 0xff for the local admin user */
  393. /* UA_RCU_LOCK(); */
  394. /* const UA_VariableNode* compNode = */
  395. /* (const UA_VariableNode*)UA_NodeStore_get(server->nodestore, &rvi.nodeId); */
  396. /* ck_assert_int_eq(0, resp.value.arrayLength); */
  397. /* ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_BYTE], resp.value.type); */
  398. /* ck_assert_int_eq(*(UA_Byte*)resp.value.data, compNode->accessLevel & 0xFF); // 0xFF is the default userAccessLevel */
  399. /* UA_RCU_UNLOCK(); */
  400. UA_Server_delete(server);
  401. UA_DataValue_deleteMembers(&resp);
  402. } END_TEST
  403. START_TEST(ReadSingleAttributeMinimumSamplingIntervalWithoutTimestamp) {
  404. UA_Server *server = makeTestSequence();
  405. UA_ReadValueId rvi;
  406. UA_ReadValueId_init(&rvi);
  407. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  408. rvi.attributeId = UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL;
  409. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  410. UA_Double* respval = (UA_Double*) resp.value.data;
  411. UA_VariableNode *compNode = makeCompareSequence();
  412. UA_Double comp = (UA_Double) compNode->minimumSamplingInterval;
  413. ck_assert_int_eq(0, resp.value.arrayLength);
  414. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_DOUBLE], resp.value.type);
  415. ck_assert(*respval == comp);
  416. UA_DataValue_deleteMembers(&resp);
  417. UA_NodeStore_deleteNode((UA_Node*)compNode);
  418. UA_Server_delete(server);
  419. } END_TEST
  420. START_TEST(ReadSingleAttributeHistorizingWithoutTimestamp) {
  421. UA_Server *server = makeTestSequence();
  422. UA_ReadValueId rvi;
  423. UA_ReadValueId_init(&rvi);
  424. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  425. rvi.attributeId = UA_ATTRIBUTEID_HISTORIZING;
  426. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  427. ck_assert_int_eq(0, resp.value.arrayLength);
  428. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_BOOLEAN], resp.value.type);
  429. ck_assert(*(UA_Boolean*)resp.value.data==false);
  430. UA_DataValue_deleteMembers(&resp);
  431. UA_Server_delete(server);
  432. } END_TEST
  433. START_TEST(ReadSingleAttributeExecutableWithoutTimestamp) {
  434. UA_Server *server = makeTestSequence();
  435. #ifdef UA_ENABLE_METHODCALLS
  436. UA_ReadValueId rvi;
  437. UA_ReadValueId_init(&rvi);
  438. rvi.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_METHODNODE);
  439. rvi.attributeId = UA_ATTRIBUTEID_EXECUTABLE;
  440. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  441. ck_assert_int_eq(true, resp.hasValue);
  442. ck_assert_int_eq(0, resp.value.arrayLength);
  443. ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_BOOLEAN], resp.value.type);
  444. ck_assert(*(UA_Boolean*)resp.value.data==false);
  445. UA_DataValue_deleteMembers(&resp);
  446. #endif
  447. UA_Server_delete(server);
  448. } END_TEST
  449. START_TEST(ReadSingleAttributeUserExecutableWithoutTimestamp) {
  450. #ifdef UA_ENABLE_METHODCALLS
  451. UA_Server *server = makeTestSequence();
  452. UA_ReadValueId rvi;
  453. UA_ReadValueId_init(&rvi);
  454. rvi.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_METHODNODE);
  455. rvi.attributeId = UA_ATTRIBUTEID_USEREXECUTABLE;
  456. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  457. /* Uncommented since userexecutable is always true for the local admin user */
  458. /* ck_assert_int_eq(0, resp.value.arrayLength); */
  459. /* ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_BOOLEAN], resp.value.type); */
  460. /* ck_assert(*(UA_Boolean*)resp.value.data==false); */
  461. UA_DataValue_deleteMembers(&resp);
  462. UA_Server_delete(server);
  463. #endif
  464. } END_TEST
  465. START_TEST(ReadSingleDataSourceAttributeValueWithoutTimestamp) {
  466. UA_Server *server = makeTestSequence();
  467. UA_ReadValueId rvi;
  468. UA_ReadValueId_init(&rvi);
  469. rvi.nodeId = UA_NODEID_STRING(1, "cpu.temperature");
  470. rvi.attributeId = UA_ATTRIBUTEID_VALUE;
  471. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  472. ck_assert_int_eq(UA_STATUSCODE_GOOD, resp.status);
  473. UA_Server_delete(server);
  474. UA_DataValue_deleteMembers(&resp);
  475. } END_TEST
  476. START_TEST(ReadSingleDataSourceAttributeDataTypeWithoutTimestamp) {
  477. UA_Server *server = makeTestSequence();
  478. UA_ReadValueId rvi;
  479. UA_ReadValueId_init(&rvi);
  480. rvi.nodeId = UA_NODEID_STRING(1, "cpu.temperature");
  481. rvi.attributeId = UA_ATTRIBUTEID_DATATYPE;
  482. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  483. ck_assert_int_eq(UA_STATUSCODE_GOOD, resp.status);
  484. ck_assert_int_eq(resp.hasServerTimestamp, false);
  485. UA_Server_delete(server);
  486. UA_DataValue_deleteMembers(&resp);
  487. } END_TEST
  488. START_TEST (ReadSingleDataSourceAttributeArrayDimensionsWithoutTimestamp) {
  489. UA_Server *server = makeTestSequence();
  490. UA_ReadValueId rvi;
  491. UA_ReadValueId_init(&rvi);
  492. rvi.nodeId = UA_NODEID_STRING(1, "cpu.temperature");
  493. rvi.attributeId = UA_ATTRIBUTEID_ARRAYDIMENSIONS;
  494. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  495. ck_assert_int_eq(UA_STATUSCODE_GOOD, resp.status);
  496. UA_Server_delete(server);
  497. UA_DataValue_deleteMembers(&resp);
  498. } END_TEST
  499. /* Tests for writeValue method */
  500. START_TEST(WriteSingleAttributeNodeId) {
  501. UA_Server *server = makeTestSequence();
  502. UA_WriteValue wValue;
  503. UA_WriteValue_init(&wValue);
  504. UA_NodeId id;
  505. UA_NodeId_init(&id);
  506. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  507. wValue.attributeId = UA_ATTRIBUTEID_NODEID;
  508. wValue.value.hasValue = true;
  509. UA_Variant_setScalar(&wValue.value.value, &id, &UA_TYPES[UA_TYPES_NODEID]);
  510. UA_StatusCode retval = UA_Server_write(server, &wValue);
  511. ck_assert_int_eq(retval, UA_STATUSCODE_BADWRITENOTSUPPORTED);
  512. UA_Server_delete(server);
  513. } END_TEST
  514. START_TEST(WriteSingleAttributeNodeclass) {
  515. UA_Server *server = makeTestSequence();
  516. UA_WriteValue wValue;
  517. UA_WriteValue_init(&wValue);
  518. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  519. UA_NodeClass class;
  520. UA_NodeClass_init(&class);
  521. wValue.attributeId = UA_ATTRIBUTEID_NODECLASS;
  522. wValue.value.hasValue = true;
  523. UA_Variant_setScalar(&wValue.value.value, &class, &UA_TYPES[UA_TYPES_NODECLASS]);
  524. UA_StatusCode retval = UA_Server_write(server, &wValue);
  525. ck_assert_int_eq(retval, UA_STATUSCODE_BADWRITENOTSUPPORTED);
  526. UA_Server_delete(server);
  527. } END_TEST
  528. START_TEST(WriteSingleAttributeBrowseName) {
  529. UA_Server *server = makeTestSequence();
  530. UA_WriteValue wValue;
  531. UA_WriteValue_init(&wValue);
  532. UA_QualifiedName testValue = UA_QUALIFIEDNAME(1, "the.answer");
  533. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_QUALIFIEDNAME]);
  534. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  535. wValue.attributeId = UA_ATTRIBUTEID_BROWSENAME;
  536. wValue.value.hasValue = true;
  537. UA_StatusCode retval = UA_Server_write(server, &wValue);
  538. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  539. UA_Server_delete(server);
  540. } END_TEST
  541. START_TEST(WriteSingleAttributeDisplayName) {
  542. UA_Server *server = makeTestSequence();
  543. UA_WriteValue wValue;
  544. UA_WriteValue_init(&wValue);
  545. UA_LocalizedText testValue = UA_LOCALIZEDTEXT("en_EN", "the.answer");
  546. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
  547. wValue.value.hasValue = true;
  548. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  549. wValue.attributeId = UA_ATTRIBUTEID_DISPLAYNAME;
  550. UA_StatusCode retval = UA_Server_write(server, &wValue);
  551. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  552. UA_Server_delete(server);
  553. } END_TEST
  554. START_TEST(WriteSingleAttributeDescription) {
  555. UA_Server *server = makeTestSequence();
  556. UA_WriteValue wValue;
  557. UA_WriteValue_init(&wValue);
  558. UA_LocalizedText testValue = UA_LOCALIZEDTEXT("en_EN", "the.answer");
  559. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
  560. wValue.value.hasValue = true;
  561. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  562. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  563. wValue.attributeId = UA_ATTRIBUTEID_DESCRIPTION;
  564. wValue.value.hasValue = true;
  565. UA_StatusCode retval = UA_Server_write(server, &wValue);
  566. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  567. UA_Server_delete(server);
  568. } END_TEST
  569. START_TEST(WriteSingleAttributeWriteMask) {
  570. UA_Server *server = makeTestSequence();
  571. UA_WriteValue wValue;
  572. UA_WriteValue_init(&wValue);
  573. UA_Int32 testValue = 0;
  574. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_UINT32]);
  575. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  576. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  577. wValue.attributeId = UA_ATTRIBUTEID_WRITEMASK;
  578. wValue.value.hasValue = true;
  579. UA_StatusCode retval = UA_Server_write(server, &wValue);
  580. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  581. UA_Server_delete(server);
  582. } END_TEST
  583. START_TEST(WriteSingleAttributeIsAbstract) {
  584. UA_Server *server = makeTestSequence();
  585. UA_WriteValue wValue;
  586. UA_WriteValue_init(&wValue);
  587. UA_Boolean testValue = true;
  588. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_BOOLEAN]);
  589. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  590. wValue.attributeId = UA_ATTRIBUTEID_ISABSTRACT;
  591. wValue.value.hasValue = true;
  592. UA_StatusCode retval = UA_Server_write(server, &wValue);
  593. ck_assert_int_eq(retval, UA_STATUSCODE_BADNODECLASSINVALID);
  594. UA_Server_delete(server);
  595. } END_TEST
  596. START_TEST(WriteSingleAttributeSymmetric) {
  597. UA_Server *server = makeTestSequence();
  598. UA_WriteValue wValue;
  599. UA_WriteValue_init(&wValue);
  600. UA_Boolean testValue = true;
  601. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_BOOLEAN]);
  602. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  603. wValue.attributeId = UA_ATTRIBUTEID_SYMMETRIC;
  604. wValue.value.hasValue = true;
  605. UA_StatusCode retval = UA_Server_write(server, &wValue);
  606. ck_assert_int_eq(retval, UA_STATUSCODE_BADNODECLASSINVALID);
  607. UA_Server_delete(server);
  608. } END_TEST
  609. START_TEST(WriteSingleAttributeInverseName) {
  610. UA_Server *server = makeTestSequence();
  611. UA_WriteValue wValue;
  612. UA_WriteValue_init(&wValue);
  613. UA_LocalizedText testValue = UA_LOCALIZEDTEXT("en_US", "not.the.answer");
  614. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
  615. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  616. wValue.attributeId = UA_ATTRIBUTEID_INVERSENAME;
  617. wValue.value.hasValue = true;
  618. UA_StatusCode retval = UA_Server_write(server, &wValue);
  619. ck_assert_int_eq(retval, UA_STATUSCODE_BADNODECLASSINVALID);
  620. UA_Server_delete(server);
  621. } END_TEST
  622. START_TEST(WriteSingleAttributeContainsNoLoops) {
  623. UA_Server *server = makeTestSequence();
  624. UA_WriteValue wValue;
  625. UA_WriteValue_init(&wValue);
  626. UA_Boolean testValue = true;
  627. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_BOOLEAN]);
  628. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  629. wValue.attributeId = UA_ATTRIBUTEID_CONTAINSNOLOOPS;
  630. wValue.value.hasValue = true;
  631. UA_StatusCode retval = UA_Server_write(server, &wValue);
  632. ck_assert_int_eq(retval, UA_STATUSCODE_BADNODECLASSINVALID);
  633. UA_Server_delete(server);
  634. } END_TEST
  635. START_TEST(WriteSingleAttributeEventNotifier) {
  636. UA_Server *server = makeTestSequence();
  637. UA_WriteValue wValue;
  638. UA_WriteValue_init(&wValue);
  639. UA_Byte testValue = 0;
  640. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_BYTE]);
  641. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  642. wValue.attributeId = UA_ATTRIBUTEID_EVENTNOTIFIER;
  643. wValue.value.hasValue = true;
  644. UA_StatusCode retval = UA_Server_write(server, &wValue);
  645. ck_assert_int_eq(retval, UA_STATUSCODE_BADNODECLASSINVALID);
  646. UA_Server_delete(server);
  647. } END_TEST
  648. START_TEST(WriteSingleAttributeValue) {
  649. UA_Server *server = makeTestSequence();
  650. UA_WriteValue wValue;
  651. UA_WriteValue_init(&wValue);
  652. UA_Int32 myInteger = 20;
  653. UA_Variant_setScalar(&wValue.value.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]);
  654. wValue.value.hasValue = true;
  655. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  656. wValue.attributeId = UA_ATTRIBUTEID_VALUE;
  657. UA_StatusCode retval = UA_Server_write(server, &wValue);
  658. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  659. UA_ReadValueId rvi;
  660. UA_ReadValueId_init(&rvi);
  661. rvi.nodeId = UA_NODEID_STRING(1, "the.answer");
  662. rvi.attributeId = UA_ATTRIBUTEID_VALUE;
  663. UA_DataValue resp = UA_Server_read(server, &rvi, UA_TIMESTAMPSTORETURN_NEITHER);
  664. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  665. ck_assert(resp.hasValue);
  666. ck_assert_int_eq(20, *(UA_Int32*)resp.value.data);
  667. UA_DataValue_deleteMembers(&resp);
  668. UA_Server_delete(server);
  669. } END_TEST
  670. START_TEST(WriteSingleAttributeValueRangeFromScalar) {
  671. UA_Server *server = makeTestSequence();
  672. UA_WriteValue wValue;
  673. UA_WriteValue_init(&wValue);
  674. UA_Int32 myInteger = 20;
  675. UA_Variant_setScalar(&wValue.value.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]);
  676. wValue.value.hasValue = true;
  677. wValue.nodeId = UA_NODEID_STRING(1, "myarray");
  678. wValue.indexRange = UA_STRING("0,0");
  679. wValue.attributeId = UA_ATTRIBUTEID_VALUE;
  680. UA_StatusCode retval = UA_Server_write(server, &wValue);
  681. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  682. UA_Server_delete(server);
  683. } END_TEST
  684. START_TEST(WriteSingleAttributeValueRangeFromArray) {
  685. UA_Server *server = makeTestSequence();
  686. UA_WriteValue wValue;
  687. UA_WriteValue_init(&wValue);
  688. UA_Int32 myInteger = 20;
  689. UA_Variant_setArray(&wValue.value.value, &myInteger, 1, &UA_TYPES[UA_TYPES_INT32]);
  690. wValue.value.hasValue = true;
  691. wValue.nodeId = UA_NODEID_STRING(1, "myarray");
  692. wValue.indexRange = UA_STRING("0,0");
  693. wValue.attributeId = UA_ATTRIBUTEID_VALUE;
  694. UA_StatusCode retval = UA_Server_write(server, &wValue);
  695. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  696. UA_Server_delete(server);
  697. } END_TEST
  698. START_TEST(WriteSingleAttributeDataType) {
  699. UA_Server *server = makeTestSequence();
  700. UA_WriteValue wValue;
  701. UA_WriteValue_init(&wValue);
  702. UA_NodeId typeId;
  703. UA_NodeId_init(&typeId);
  704. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  705. wValue.attributeId = UA_ATTRIBUTEID_DATATYPE;
  706. wValue.value.hasValue = true;
  707. UA_Variant_setScalar(&wValue.value.value, &typeId, &UA_TYPES[UA_TYPES_NODEID]);
  708. UA_StatusCode retval = UA_Server_write(server, &wValue);
  709. ck_assert_int_eq(retval, UA_STATUSCODE_BADTYPEMISMATCH);
  710. UA_Server_delete(server);
  711. } END_TEST
  712. START_TEST(WriteSingleAttributeValueRank) {
  713. UA_Server *server = makeTestSequence();
  714. UA_WriteValue wValue;
  715. UA_WriteValue_init(&wValue);
  716. UA_Int32 testValue = -1;
  717. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_INT32]);
  718. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  719. wValue.attributeId = UA_ATTRIBUTEID_VALUERANK;
  720. wValue.value.hasValue = true;
  721. UA_StatusCode retval = UA_Server_write(server, &wValue);
  722. // Returns attributeInvalid, since variant/value may be writable
  723. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  724. UA_Server_delete(server);
  725. } END_TEST
  726. START_TEST(WriteSingleAttributeArrayDimensions) {
  727. UA_Server *server = makeTestSequence();
  728. UA_WriteValue wValue;
  729. UA_WriteValue_init(&wValue);
  730. UA_UInt32 testValue[] = {1,1,1};
  731. UA_Variant_setArray(&wValue.value.value, &testValue, 3, &UA_TYPES[UA_TYPES_UINT32]);
  732. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  733. wValue.attributeId = UA_ATTRIBUTEID_ARRAYDIMENSIONS;
  734. wValue.value.hasValue = true;
  735. UA_StatusCode retval = UA_Server_write(server, &wValue);
  736. // Returns attributeInvalid, since variant/value may be writable
  737. ck_assert_int_eq(retval, UA_STATUSCODE_BADTYPEMISMATCH);
  738. UA_Server_delete(server);
  739. } END_TEST
  740. START_TEST(WriteSingleAttributeAccessLevel) {
  741. UA_Server *server = makeTestSequence();
  742. UA_WriteValue wValue;
  743. UA_WriteValue_init(&wValue);
  744. UA_Byte testValue = 0;
  745. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_BYTE]);
  746. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  747. wValue.attributeId = UA_ATTRIBUTEID_ACCESSLEVEL;
  748. wValue.value.hasValue = true;
  749. UA_StatusCode retval = UA_Server_write(server, &wValue);
  750. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  751. UA_Server_delete(server);
  752. } END_TEST
  753. START_TEST(WriteSingleAttributeMinimumSamplingInterval) {
  754. UA_Server *server = makeTestSequence();
  755. UA_WriteValue wValue;
  756. UA_WriteValue_init(&wValue);
  757. UA_Double testValue = 0.0;
  758. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_DOUBLE]);
  759. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  760. wValue.attributeId = UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL;
  761. wValue.value.hasValue = true;
  762. UA_StatusCode retval = UA_Server_write(server, &wValue);
  763. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  764. UA_Server_delete(server);
  765. } END_TEST
  766. START_TEST(WriteSingleAttributeHistorizing) {
  767. UA_Server *server = makeTestSequence();
  768. UA_WriteValue wValue;
  769. UA_WriteValue_init(&wValue);
  770. UA_Boolean testValue = true;
  771. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_BOOLEAN]);
  772. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  773. wValue.attributeId = UA_ATTRIBUTEID_HISTORIZING;
  774. wValue.value.hasValue = true;
  775. UA_StatusCode retval = UA_Server_write(server, &wValue);
  776. ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
  777. UA_Server_delete(server);
  778. } END_TEST
  779. START_TEST(WriteSingleAttributeExecutable) {
  780. UA_Server *server = makeTestSequence();
  781. UA_WriteValue wValue;
  782. UA_WriteValue_init(&wValue);
  783. UA_Boolean testValue = true;
  784. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_BOOLEAN]);
  785. wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
  786. wValue.attributeId = UA_ATTRIBUTEID_EXECUTABLE;
  787. wValue.value.hasValue = true;
  788. UA_StatusCode retval = UA_Server_write(server, &wValue);
  789. ck_assert_int_eq(retval, UA_STATUSCODE_BADNODECLASSINVALID);
  790. UA_Server_delete(server);
  791. } END_TEST
  792. START_TEST(WriteSingleDataSourceAttributeValue) {
  793. UA_Server *server = makeTestSequence();
  794. UA_WriteValue wValue;
  795. UA_WriteValue_init(&wValue);
  796. UA_Int32 testValue = 0;
  797. UA_Variant_setScalar(&wValue.value.value, &testValue, &UA_TYPES[UA_TYPES_INT32]);
  798. wValue.nodeId = UA_NODEID_STRING(1, "cpu.temperature");
  799. wValue.attributeId = UA_ATTRIBUTEID_VALUE;
  800. wValue.value.hasValue = true;
  801. UA_StatusCode retval = UA_Server_write(server, &wValue);
  802. ck_assert_int_eq(retval, UA_STATUSCODE_BADWRITENOTSUPPORTED);
  803. UA_Server_delete(server);
  804. } END_TEST
  805. static Suite * testSuite_services_attributes(void) {
  806. Suite *s = suite_create("services_attributes_read");
  807. TCase *tc_readSingleAttributes = tcase_create("readSingleAttributes");
  808. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeValueWithoutTimestamp);
  809. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeValueRangeWithoutTimestamp);
  810. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeNodeIdWithoutTimestamp);
  811. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeNodeClassWithoutTimestamp);
  812. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeBrowseNameWithoutTimestamp);
  813. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeDisplayNameWithoutTimestamp);
  814. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeDescriptionWithoutTimestamp);
  815. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeWriteMaskWithoutTimestamp);
  816. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeUserWriteMaskWithoutTimestamp);
  817. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeIsAbstractWithoutTimestamp);
  818. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeSymmetricWithoutTimestamp);
  819. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeInverseNameWithoutTimestamp);
  820. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeContainsNoLoopsWithoutTimestamp);
  821. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeEventNotifierWithoutTimestamp);
  822. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeDataTypeWithoutTimestamp);
  823. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeValueRankWithoutTimestamp);
  824. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeArrayDimensionsWithoutTimestamp);
  825. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeAccessLevelWithoutTimestamp);
  826. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeUserAccessLevelWithoutTimestamp);
  827. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeMinimumSamplingIntervalWithoutTimestamp);
  828. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeHistorizingWithoutTimestamp);
  829. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeExecutableWithoutTimestamp);
  830. tcase_add_test(tc_readSingleAttributes, ReadSingleAttributeUserExecutableWithoutTimestamp);
  831. tcase_add_test(tc_readSingleAttributes, ReadSingleDataSourceAttributeValueWithoutTimestamp);
  832. tcase_add_test(tc_readSingleAttributes, ReadSingleDataSourceAttributeDataTypeWithoutTimestamp);
  833. tcase_add_test(tc_readSingleAttributes, ReadSingleDataSourceAttributeArrayDimensionsWithoutTimestamp);
  834. suite_add_tcase(s, tc_readSingleAttributes);
  835. TCase *tc_writeSingleAttributes = tcase_create("writeSingleAttributes");
  836. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeNodeId);
  837. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeNodeclass);
  838. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeBrowseName);
  839. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeDisplayName);
  840. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeDescription);
  841. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeWriteMask);
  842. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeIsAbstract);
  843. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeSymmetric);
  844. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeInverseName);
  845. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeContainsNoLoops);
  846. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeEventNotifier);
  847. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeValue);
  848. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeDataType);
  849. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeValueRangeFromScalar);
  850. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeValueRangeFromArray);
  851. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeValueRank);
  852. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeArrayDimensions);
  853. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeAccessLevel);
  854. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeMinimumSamplingInterval);
  855. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeHistorizing);
  856. tcase_add_test(tc_writeSingleAttributes, WriteSingleAttributeExecutable);
  857. tcase_add_test(tc_writeSingleAttributes, WriteSingleDataSourceAttributeValue);
  858. suite_add_tcase(s, tc_writeSingleAttributes);
  859. return s;
  860. }
  861. int main(void) {
  862. int number_failed = 0;
  863. Suite *s;
  864. s = testSuite_services_attributes();
  865. SRunner *sr = srunner_create(s);
  866. srunner_set_fork_status(sr, CK_NOFORK);
  867. srunner_run_all(sr, CK_NORMAL);
  868. number_failed += srunner_ntests_failed(sr);
  869. srunner_free(sr);
  870. return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
  871. }