check_monitoreditem_filter.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  4. *
  5. * Copyright 2018 (c) basysKom GmbH <opensource@basyskom.com> (Author: Peter Rustler)
  6. */
  7. #include "ua_types.h"
  8. #include "ua_server.h"
  9. #include "ua_client.h"
  10. #include "client/ua_client_internal.h"
  11. #include "ua_client_highlevel.h"
  12. #include "ua_config_default.h"
  13. #include "ua_network_tcp.h"
  14. #include "check.h"
  15. #include "testing_clock.h"
  16. #include "testing_networklayers.h"
  17. #include "thread_wrapper.h"
  18. UA_Server *server;
  19. UA_ServerConfig *config;
  20. UA_Boolean running;
  21. THREAD_HANDLE server_thread;
  22. UA_Client *client;
  23. UA_UInt32 subId;
  24. UA_NodeId parentNodeId;
  25. UA_NodeId parentReferenceNodeId;
  26. UA_NodeId outNodeId;
  27. UA_Boolean notificationReceived = false;
  28. UA_UInt32 countNotificationReceived = 0;
  29. UA_Double publishingInterval = 500.0;
  30. UA_DataValue lastValue;
  31. THREAD_CALLBACK(serverloop) {
  32. while(running)
  33. UA_Server_run_iterate(server, true);
  34. return 0;
  35. }
  36. static void setup(void) {
  37. UA_DataValue_init(&lastValue);
  38. running = true;
  39. config = UA_ServerConfig_new_default();
  40. server = UA_Server_new(config);
  41. UA_Server_run_startup(server);
  42. THREAD_CREATE(server_thread, serverloop);
  43. /* Define the attribute of the double variable node */
  44. UA_VariableAttributes attr = UA_VariableAttributes_default;
  45. UA_Double myDouble = 40.0;
  46. UA_Variant_setScalar(&attr.value, &myDouble, &UA_TYPES[UA_TYPES_DOUBLE]);
  47. attr.description = UA_LOCALIZEDTEXT("en-US","the answer");
  48. attr.displayName = UA_LOCALIZEDTEXT("en-US","the answer");
  49. attr.dataType = UA_TYPES[UA_TYPES_DOUBLE].typeId;
  50. attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE;
  51. /* Add the variable node to the information model */
  52. UA_NodeId doubleNodeId = UA_NODEID_STRING(1, "the.answer");
  53. UA_QualifiedName doubleName = UA_QUALIFIEDNAME(1, "the answer");
  54. parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
  55. parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
  56. UA_NodeId_init(&outNodeId);
  57. ck_assert_uint_eq(UA_Server_addVariableNode(server,
  58. doubleNodeId, parentNodeId,
  59. parentReferenceNodeId,
  60. doubleName,
  61. UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
  62. attr,
  63. NULL,
  64. &outNodeId)
  65. , UA_STATUSCODE_GOOD);
  66. client = UA_Client_new(UA_ClientConfig_default);
  67. UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
  68. ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
  69. UA_Client_recv = client->connection.recv;
  70. client->connection.recv = UA_Client_recvTesting;
  71. UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default();
  72. request.requestedMaxKeepAliveCount = 100;
  73. UA_CreateSubscriptionResponse response = UA_Client_Subscriptions_create(client, request,
  74. NULL, NULL, NULL);
  75. ck_assert_uint_eq(response.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  76. subId = response.subscriptionId;
  77. notificationReceived = false;
  78. countNotificationReceived = 0;
  79. }
  80. static void teardown(void) {
  81. ck_assert_uint_eq(UA_Client_Subscriptions_deleteSingle(client, subId)
  82. , UA_STATUSCODE_GOOD);
  83. /* cleanup */
  84. UA_Client_disconnect(client);
  85. UA_Client_delete(client);
  86. UA_NodeId_deleteMembers(&parentNodeId);
  87. UA_NodeId_deleteMembers(&parentReferenceNodeId);
  88. UA_NodeId_deleteMembers(&outNodeId);
  89. running = false;
  90. THREAD_JOIN(server_thread);
  91. UA_Server_run_shutdown(server);
  92. UA_Server_delete(server);
  93. UA_ServerConfig_delete(config);
  94. UA_DataValue_deleteMembers(&lastValue);
  95. }
  96. #ifdef UA_ENABLE_SUBSCRIPTIONS
  97. static void
  98. dataChangeHandler(UA_Client *thisClient, UA_UInt32 thisSubId, void *subContext,
  99. UA_UInt32 monId, void *monContext, UA_DataValue *value) {
  100. notificationReceived = true;
  101. ++countNotificationReceived;
  102. UA_DataValue_deleteMembers(&lastValue);
  103. UA_DataValue_copy(value, &lastValue);
  104. }
  105. static UA_StatusCode
  106. setDouble(UA_Client *thisClient, UA_NodeId node, UA_Double value) {
  107. UA_Variant variant;
  108. UA_Variant_setScalar(&variant, &value, &UA_TYPES[UA_TYPES_DOUBLE]);
  109. return UA_Client_writeValueAttribute(thisClient, node, &variant);
  110. }
  111. static UA_StatusCode waitForNotification(UA_UInt32 notifications, UA_UInt32 maxTries) {
  112. UA_StatusCode retval = UA_STATUSCODE_GOOD;
  113. for (UA_UInt32 i = 0; i < maxTries; ++i) {
  114. UA_fakeSleep((UA_UInt32)publishingInterval + 100);
  115. retval = UA_Client_run_iterate(client, (UA_UInt16)(publishingInterval + 100));
  116. if (retval != UA_STATUSCODE_GOOD)
  117. return retval;
  118. if (countNotificationReceived == notifications)
  119. return retval;
  120. }
  121. return retval;
  122. }
  123. static UA_Boolean fuzzyLastValueIsEqualTo(UA_Double value) {
  124. double offset = 0.001;
  125. if(lastValue.hasValue
  126. && lastValue.value.type == &UA_TYPES[UA_TYPES_DOUBLE]) {
  127. double lastDouble = *((UA_Double*)(lastValue.value.data));
  128. if (lastDouble > value - offset && lastDouble < value + offset) {
  129. return true;
  130. }
  131. }
  132. return false;
  133. }
  134. START_TEST(Server_MonitoredItemsAbsoluteFilterSetLater) {
  135. UA_DataValue_init(&lastValue);
  136. /* define a monitored item with no filter */
  137. UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
  138. UA_UInt32 newMonitoredItemIds[1];
  139. UA_Client_DataChangeNotificationCallback callbacks[1];
  140. callbacks[0] = dataChangeHandler;
  141. UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
  142. void *contexts[1];
  143. contexts[0] = NULL;
  144. UA_CreateMonitoredItemsRequest createRequest;
  145. UA_CreateMonitoredItemsRequest_init(&createRequest);
  146. createRequest.subscriptionId = subId;
  147. createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  148. createRequest.itemsToCreate = &item;
  149. createRequest.itemsToCreateSize = 1;
  150. UA_CreateMonitoredItemsResponse createResponse =
  151. UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
  152. callbacks, deleteCallbacks);
  153. ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  154. ck_assert_uint_eq(createResponse.resultsSize, 1);
  155. ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  156. newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
  157. UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);
  158. // Do we get initial value ?
  159. notificationReceived = false;
  160. countNotificationReceived = 0;
  161. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  162. ck_assert_uint_eq(notificationReceived, true);
  163. ck_assert_uint_eq(countNotificationReceived, 1);
  164. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  165. // This should trigger because no filter
  166. notificationReceived = false;
  167. countNotificationReceived = 0;
  168. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  169. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  170. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  171. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  172. ck_assert_uint_eq(notificationReceived, true);
  173. ck_assert_uint_eq(countNotificationReceived, 2);
  174. ck_assert(fuzzyLastValueIsEqualTo(42.0));
  175. notificationReceived = false;
  176. countNotificationReceived = 0;
  177. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  178. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  179. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  180. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  181. ck_assert_uint_eq(notificationReceived, true);
  182. ck_assert_uint_eq(countNotificationReceived, 2);
  183. ck_assert(fuzzyLastValueIsEqualTo(44.0));
  184. // set back to 40.0
  185. notificationReceived = false;
  186. countNotificationReceived = 0;
  187. ck_assert_uint_eq(setDouble(client, outNodeId, 40.0), UA_STATUSCODE_GOOD);
  188. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  189. ck_assert_uint_eq(notificationReceived, true);
  190. ck_assert_uint_eq(countNotificationReceived, 1);
  191. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  192. /* modify the monitored item with an absolute filter with deadbandvalue = 2.0 */
  193. UA_MonitoredItemModifyRequest itemModify;
  194. UA_MonitoredItemModifyRequest_init(&itemModify);
  195. itemModify.monitoredItemId = newMonitoredItemIds[0];
  196. itemModify.requestedParameters.samplingInterval = 250;
  197. itemModify.requestedParameters.discardOldest = true;
  198. itemModify.requestedParameters.queueSize = 1;
  199. itemModify.requestedParameters.clientHandle = newMonitoredItemIds[0];
  200. UA_DataChangeFilter filter;
  201. UA_DataChangeFilter_init(&filter);
  202. filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
  203. filter.deadbandType = UA_DEADBANDTYPE_ABSOLUTE;
  204. filter.deadbandValue = 2.0;
  205. itemModify.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
  206. itemModify.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
  207. itemModify.requestedParameters.filter.content.decoded.data = &filter;
  208. UA_ModifyMonitoredItemsRequest modifyRequest;
  209. UA_ModifyMonitoredItemsRequest_init(&modifyRequest);
  210. modifyRequest.subscriptionId = subId;
  211. modifyRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  212. modifyRequest.itemsToModify = &itemModify;
  213. modifyRequest.itemsToModifySize = 1;
  214. UA_ModifyMonitoredItemsResponse modifyResponse =
  215. UA_Client_MonitoredItems_modify(client, modifyRequest);
  216. ck_assert_uint_eq(modifyResponse.resultsSize, 1);
  217. ck_assert_uint_eq(modifyResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  218. UA_ModifyMonitoredItemsResponse_deleteMembers(&modifyResponse);
  219. // This should not trigger because now we filter
  220. notificationReceived = false;
  221. countNotificationReceived = 0;
  222. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  223. ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
  224. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  225. ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
  226. ck_assert_uint_eq(notificationReceived, false);
  227. ck_assert_uint_eq(countNotificationReceived, 0);
  228. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  229. // This should trigger once at 43.0.
  230. notificationReceived = false;
  231. countNotificationReceived = 0;
  232. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  233. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  234. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  235. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  236. ck_assert_uint_eq(notificationReceived, true);
  237. ck_assert_uint_eq(countNotificationReceived, 1);
  238. ck_assert(fuzzyLastValueIsEqualTo(43.0));
  239. // remove monitored item
  240. UA_DeleteMonitoredItemsRequest deleteRequest;
  241. UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
  242. deleteRequest.subscriptionId = subId;
  243. deleteRequest.monitoredItemIds = newMonitoredItemIds;
  244. deleteRequest.monitoredItemIdsSize = 1;
  245. UA_DeleteMonitoredItemsResponse deleteResponse =
  246. UA_Client_MonitoredItems_delete(client, deleteRequest);
  247. ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  248. ck_assert_uint_eq(deleteResponse.resultsSize, 1);
  249. ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);
  250. UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);
  251. }
  252. END_TEST
  253. START_TEST(Server_MonitoredItemsAbsoluteFilterSetOnCreateRemoveLater) {
  254. UA_DataValue_init(&lastValue);
  255. /* define a monitored item with absolute filter */
  256. UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
  257. UA_DataChangeFilter filter;
  258. UA_DataChangeFilter_init(&filter);
  259. filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
  260. filter.deadbandType = UA_DEADBANDTYPE_ABSOLUTE;
  261. filter.deadbandValue = 2.0;
  262. item.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
  263. item.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
  264. item.requestedParameters.filter.content.decoded.data = &filter;
  265. UA_UInt32 newMonitoredItemIds[1];
  266. UA_Client_DataChangeNotificationCallback callbacks[1];
  267. callbacks[0] = dataChangeHandler;
  268. UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
  269. void *contexts[1];
  270. contexts[0] = NULL;
  271. UA_CreateMonitoredItemsRequest createRequest;
  272. UA_CreateMonitoredItemsRequest_init(&createRequest);
  273. createRequest.subscriptionId = subId;
  274. createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  275. createRequest.itemsToCreate = &item;
  276. createRequest.itemsToCreateSize = 1;
  277. UA_CreateMonitoredItemsResponse createResponse =
  278. UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
  279. callbacks, deleteCallbacks);
  280. ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  281. ck_assert_uint_eq(createResponse.resultsSize, 1);
  282. ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  283. newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
  284. UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);
  285. // Do we get initial value ?
  286. notificationReceived = false;
  287. countNotificationReceived = 0;
  288. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  289. ck_assert_uint_eq(notificationReceived, true);
  290. ck_assert_uint_eq(countNotificationReceived, 1);
  291. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  292. // This should not trigger because of filter
  293. notificationReceived = false;
  294. countNotificationReceived = 0;
  295. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  296. ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
  297. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  298. ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
  299. ck_assert_uint_eq(notificationReceived, false);
  300. ck_assert_uint_eq(countNotificationReceived, 0);
  301. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  302. // This should trigger once at 43.0.
  303. notificationReceived = false;
  304. countNotificationReceived = 0;
  305. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  306. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  307. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  308. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  309. ck_assert_uint_eq(notificationReceived, true);
  310. ck_assert_uint_eq(countNotificationReceived, 1);
  311. ck_assert(fuzzyLastValueIsEqualTo(43.0));
  312. // set back to 40.0
  313. notificationReceived = false;
  314. countNotificationReceived = 0;
  315. ck_assert_uint_eq(setDouble(client, outNodeId, 40.0), UA_STATUSCODE_GOOD);
  316. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  317. ck_assert_uint_eq(notificationReceived, true);
  318. ck_assert_uint_eq(countNotificationReceived, 1);
  319. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  320. /* modify the monitored item with no filter */
  321. UA_MonitoredItemModifyRequest itemModify;
  322. UA_MonitoredItemModifyRequest_init(&itemModify);
  323. itemModify.monitoredItemId = newMonitoredItemIds[0];
  324. itemModify.requestedParameters.samplingInterval = 250;
  325. itemModify.requestedParameters.discardOldest = true;
  326. itemModify.requestedParameters.queueSize = 1;
  327. itemModify.requestedParameters.clientHandle = newMonitoredItemIds[0];
  328. UA_DataChangeFilter unsetfilter;
  329. UA_DataChangeFilter_init(&unsetfilter);
  330. unsetfilter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
  331. unsetfilter.deadbandType = UA_DEADBANDTYPE_NONE;
  332. unsetfilter.deadbandValue = 0.0;
  333. itemModify.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
  334. itemModify.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
  335. itemModify.requestedParameters.filter.content.decoded.data = &unsetfilter;
  336. UA_ModifyMonitoredItemsRequest modifyRequest;
  337. UA_ModifyMonitoredItemsRequest_init(&modifyRequest);
  338. modifyRequest.subscriptionId = subId;
  339. modifyRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  340. modifyRequest.itemsToModify = &itemModify;
  341. modifyRequest.itemsToModifySize = 1;
  342. UA_ModifyMonitoredItemsResponse modifyResponse =
  343. UA_Client_MonitoredItems_modify(client, modifyRequest);
  344. ck_assert_uint_eq(modifyResponse.resultsSize, 1);
  345. ck_assert_uint_eq(modifyResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  346. UA_ModifyMonitoredItemsResponse_deleteMembers(&modifyResponse);
  347. // This should trigger because now we do not filter
  348. notificationReceived = false;
  349. countNotificationReceived = 0;
  350. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  351. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  352. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  353. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  354. ck_assert_uint_eq(notificationReceived, true);
  355. ck_assert_uint_eq(countNotificationReceived, 2);
  356. ck_assert(fuzzyLastValueIsEqualTo(42.0));
  357. notificationReceived = false;
  358. countNotificationReceived = 0;
  359. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  360. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  361. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  362. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  363. ck_assert_uint_eq(notificationReceived, true);
  364. ck_assert_uint_eq(countNotificationReceived, 2);
  365. ck_assert(fuzzyLastValueIsEqualTo(44.0));
  366. // remove monitored item
  367. UA_DeleteMonitoredItemsRequest deleteRequest;
  368. UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
  369. deleteRequest.subscriptionId = subId;
  370. deleteRequest.monitoredItemIds = newMonitoredItemIds;
  371. deleteRequest.monitoredItemIdsSize = 1;
  372. UA_DeleteMonitoredItemsResponse deleteResponse =
  373. UA_Client_MonitoredItems_delete(client, deleteRequest);
  374. ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  375. ck_assert_uint_eq(deleteResponse.resultsSize, 1);
  376. ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);
  377. UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);
  378. }
  379. END_TEST
  380. START_TEST(Server_MonitoredItemsPercentFilterSetLater) {
  381. UA_DataValue_init(&lastValue);
  382. /* define a monitored item with no filter */
  383. UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
  384. UA_UInt32 newMonitoredItemIds[1];
  385. UA_Client_DataChangeNotificationCallback callbacks[1];
  386. callbacks[0] = dataChangeHandler;
  387. UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
  388. void *contexts[1];
  389. contexts[0] = NULL;
  390. UA_CreateMonitoredItemsRequest createRequest;
  391. UA_CreateMonitoredItemsRequest_init(&createRequest);
  392. createRequest.subscriptionId = subId;
  393. createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  394. createRequest.itemsToCreate = &item;
  395. createRequest.itemsToCreateSize = 1;
  396. UA_CreateMonitoredItemsResponse createResponse =
  397. UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
  398. callbacks, deleteCallbacks);
  399. ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  400. ck_assert_uint_eq(createResponse.resultsSize, 1);
  401. ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  402. newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
  403. UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);
  404. // Do we get initial value ?
  405. notificationReceived = false;
  406. countNotificationReceived = 0;
  407. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  408. ck_assert_uint_eq(notificationReceived, true);
  409. ck_assert_uint_eq(countNotificationReceived, 1);
  410. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  411. // This should trigger because no filter
  412. notificationReceived = false;
  413. countNotificationReceived = 0;
  414. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  415. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  416. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  417. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  418. ck_assert_uint_eq(notificationReceived, true);
  419. ck_assert_uint_eq(countNotificationReceived, 2);
  420. ck_assert(fuzzyLastValueIsEqualTo(42.0));
  421. notificationReceived = false;
  422. countNotificationReceived = 0;
  423. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  424. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  425. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  426. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  427. ck_assert_uint_eq(notificationReceived, true);
  428. ck_assert_uint_eq(countNotificationReceived, 2);
  429. ck_assert(fuzzyLastValueIsEqualTo(44.0));
  430. // set back to 40.0
  431. notificationReceived = false;
  432. countNotificationReceived = 0;
  433. ck_assert_uint_eq(setDouble(client, outNodeId, 40.0), UA_STATUSCODE_GOOD);
  434. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  435. ck_assert_uint_eq(notificationReceived, true);
  436. ck_assert_uint_eq(countNotificationReceived, 1);
  437. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  438. /* modify the monitored item with an percent filter with deadbandvalue = 2.0 */
  439. UA_MonitoredItemModifyRequest itemModify;
  440. UA_MonitoredItemModifyRequest_init(&itemModify);
  441. itemModify.monitoredItemId = newMonitoredItemIds[0];
  442. itemModify.requestedParameters.samplingInterval = 250;
  443. itemModify.requestedParameters.discardOldest = true;
  444. itemModify.requestedParameters.queueSize = 1;
  445. itemModify.requestedParameters.clientHandle = newMonitoredItemIds[0];
  446. UA_DataChangeFilter filter;
  447. UA_DataChangeFilter_init(&filter);
  448. filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
  449. filter.deadbandType = UA_DEADBANDTYPE_PERCENT;
  450. filter.deadbandValue = 2.0;
  451. itemModify.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
  452. itemModify.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
  453. itemModify.requestedParameters.filter.content.decoded.data = &filter;
  454. UA_ModifyMonitoredItemsRequest modifyRequest;
  455. UA_ModifyMonitoredItemsRequest_init(&modifyRequest);
  456. modifyRequest.subscriptionId = subId;
  457. modifyRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  458. modifyRequest.itemsToModify = &itemModify;
  459. modifyRequest.itemsToModifySize = 1;
  460. UA_ModifyMonitoredItemsResponse modifyResponse =
  461. UA_Client_MonitoredItems_modify(client, modifyRequest);
  462. ck_assert_uint_eq(modifyResponse.resultsSize, 1);
  463. ck_assert_uint_eq(modifyResponse.results[0].statusCode, UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED);
  464. UA_ModifyMonitoredItemsResponse_deleteMembers(&modifyResponse);
  465. // This should trigger because setting filter failed
  466. notificationReceived = false;
  467. countNotificationReceived = 0;
  468. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  469. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  470. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  471. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  472. ck_assert_uint_eq(notificationReceived, true);
  473. ck_assert_uint_eq(countNotificationReceived, 2);
  474. ck_assert(fuzzyLastValueIsEqualTo(42.0));
  475. notificationReceived = false;
  476. countNotificationReceived = 0;
  477. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  478. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  479. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  480. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  481. ck_assert_uint_eq(notificationReceived, true);
  482. ck_assert_uint_eq(countNotificationReceived, 2);
  483. ck_assert(fuzzyLastValueIsEqualTo(44.0));
  484. // remove monitored item
  485. UA_DeleteMonitoredItemsRequest deleteRequest;
  486. UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
  487. deleteRequest.subscriptionId = subId;
  488. deleteRequest.monitoredItemIds = newMonitoredItemIds;
  489. deleteRequest.monitoredItemIdsSize = 1;
  490. UA_DeleteMonitoredItemsResponse deleteResponse =
  491. UA_Client_MonitoredItems_delete(client, deleteRequest);
  492. ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  493. ck_assert_uint_eq(deleteResponse.resultsSize, 1);
  494. ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);
  495. UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);
  496. }
  497. END_TEST
  498. START_TEST(Server_MonitoredItemsNoFilter) {
  499. UA_DataValue_init(&lastValue);
  500. /* define a monitored item with an absolute filter with deadbandvalue = 2.0 */
  501. UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
  502. UA_UInt32 newMonitoredItemIds[1];
  503. UA_Client_DataChangeNotificationCallback callbacks[1];
  504. callbacks[0] = dataChangeHandler;
  505. UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
  506. void *contexts[1];
  507. contexts[0] = NULL;
  508. UA_CreateMonitoredItemsRequest createRequest;
  509. UA_CreateMonitoredItemsRequest_init(&createRequest);
  510. createRequest.subscriptionId = subId;
  511. createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  512. createRequest.itemsToCreate = &item;
  513. createRequest.itemsToCreateSize = 1;
  514. UA_CreateMonitoredItemsResponse createResponse =
  515. UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
  516. callbacks, deleteCallbacks);
  517. ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  518. ck_assert_uint_eq(createResponse.resultsSize, 1);
  519. ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  520. newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
  521. UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);
  522. // Do we get initial value ?
  523. notificationReceived = false;
  524. countNotificationReceived = 0;
  525. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  526. ck_assert_uint_eq(notificationReceived, true);
  527. ck_assert_uint_eq(countNotificationReceived, 1);
  528. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  529. // This should trigger because no filter
  530. notificationReceived = false;
  531. countNotificationReceived = 0;
  532. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  533. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  534. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  535. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  536. ck_assert_uint_eq(notificationReceived, true);
  537. ck_assert_uint_eq(countNotificationReceived, 2);
  538. ck_assert(fuzzyLastValueIsEqualTo(42.0));
  539. notificationReceived = false;
  540. countNotificationReceived = 0;
  541. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  542. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  543. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  544. ck_assert_uint_eq(waitForNotification(2, 10), UA_STATUSCODE_GOOD);
  545. ck_assert_uint_eq(notificationReceived, true);
  546. ck_assert_uint_eq(countNotificationReceived, 2);
  547. ck_assert(fuzzyLastValueIsEqualTo(44.0));
  548. // remove monitored item
  549. UA_DeleteMonitoredItemsRequest deleteRequest;
  550. UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
  551. deleteRequest.subscriptionId = subId;
  552. deleteRequest.monitoredItemIds = newMonitoredItemIds;
  553. deleteRequest.monitoredItemIdsSize = 1;
  554. UA_DeleteMonitoredItemsResponse deleteResponse =
  555. UA_Client_MonitoredItems_delete(client, deleteRequest);
  556. ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  557. ck_assert_uint_eq(deleteResponse.resultsSize, 1);
  558. ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);
  559. UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);
  560. }
  561. END_TEST
  562. START_TEST(Server_MonitoredItemsAbsoluteFilterSetOnCreate) {
  563. UA_DataValue_init(&lastValue);
  564. /* define a monitored item with an absolute filter with deadbandvalue = 2.0 */
  565. UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
  566. UA_DataChangeFilter filter;
  567. UA_DataChangeFilter_init(&filter);
  568. filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
  569. filter.deadbandType = UA_DEADBANDTYPE_ABSOLUTE;
  570. filter.deadbandValue = 2.0;
  571. item.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
  572. item.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
  573. item.requestedParameters.filter.content.decoded.data = &filter;
  574. UA_UInt32 newMonitoredItemIds[1];
  575. UA_Client_DataChangeNotificationCallback callbacks[1];
  576. callbacks[0] = dataChangeHandler;
  577. UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
  578. void *contexts[1];
  579. contexts[0] = NULL;
  580. UA_CreateMonitoredItemsRequest createRequest;
  581. UA_CreateMonitoredItemsRequest_init(&createRequest);
  582. createRequest.subscriptionId = subId;
  583. createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  584. createRequest.itemsToCreate = &item;
  585. createRequest.itemsToCreateSize = 1;
  586. UA_CreateMonitoredItemsResponse createResponse =
  587. UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
  588. callbacks, deleteCallbacks);
  589. ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  590. ck_assert_uint_eq(createResponse.resultsSize, 1);
  591. ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_GOOD);
  592. newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
  593. UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);
  594. // Do we get initial value ?
  595. notificationReceived = false;
  596. countNotificationReceived = 0;
  597. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  598. ck_assert_uint_eq(notificationReceived, true);
  599. ck_assert_uint_eq(countNotificationReceived, 1);
  600. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  601. // This should not trigger because of filter
  602. notificationReceived = false;
  603. countNotificationReceived = 0;
  604. ck_assert_uint_eq(setDouble(client, outNodeId, 41.0), UA_STATUSCODE_GOOD);
  605. ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
  606. ck_assert_uint_eq(setDouble(client, outNodeId, 42.0), UA_STATUSCODE_GOOD);
  607. ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
  608. ck_assert_uint_eq(notificationReceived, false);
  609. ck_assert_uint_eq(countNotificationReceived, 0);
  610. ck_assert(fuzzyLastValueIsEqualTo(40.0));
  611. // This should trigger once at 43.0.
  612. notificationReceived = false;
  613. countNotificationReceived = 0;
  614. ck_assert_uint_eq(setDouble(client, outNodeId, 43.0), UA_STATUSCODE_GOOD);
  615. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  616. ck_assert_uint_eq(setDouble(client, outNodeId, 44.0), UA_STATUSCODE_GOOD);
  617. ck_assert_uint_eq(waitForNotification(1, 10), UA_STATUSCODE_GOOD);
  618. ck_assert_uint_eq(notificationReceived, true);
  619. ck_assert_uint_eq(countNotificationReceived, 1);
  620. ck_assert(fuzzyLastValueIsEqualTo(43.0));
  621. // remove monitored item
  622. UA_DeleteMonitoredItemsRequest deleteRequest;
  623. UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
  624. deleteRequest.subscriptionId = subId;
  625. deleteRequest.monitoredItemIds = newMonitoredItemIds;
  626. deleteRequest.monitoredItemIdsSize = 1;
  627. UA_DeleteMonitoredItemsResponse deleteResponse =
  628. UA_Client_MonitoredItems_delete(client, deleteRequest);
  629. ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  630. ck_assert_uint_eq(deleteResponse.resultsSize, 1);
  631. ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_GOOD);
  632. UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);
  633. }
  634. END_TEST
  635. START_TEST(Server_MonitoredItemsPercentFilterSetOnCreate) {
  636. UA_DataValue_init(&lastValue);
  637. /* define a monitored item with an percent filter with deadbandvalue = 2.0 */
  638. UA_MonitoredItemCreateRequest item = UA_MonitoredItemCreateRequest_default(outNodeId);;
  639. UA_DataChangeFilter filter;
  640. UA_DataChangeFilter_init(&filter);
  641. filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
  642. filter.deadbandType = UA_DEADBANDTYPE_PERCENT;
  643. filter.deadbandValue = 2.0;
  644. item.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED;
  645. item.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGEFILTER];
  646. item.requestedParameters.filter.content.decoded.data = &filter;
  647. UA_UInt32 newMonitoredItemIds[1];
  648. UA_Client_DataChangeNotificationCallback callbacks[1];
  649. callbacks[0] = dataChangeHandler;
  650. UA_Client_DeleteMonitoredItemCallback deleteCallbacks[1] = {NULL};
  651. void *contexts[1];
  652. contexts[0] = NULL;
  653. UA_CreateMonitoredItemsRequest createRequest;
  654. UA_CreateMonitoredItemsRequest_init(&createRequest);
  655. createRequest.subscriptionId = subId;
  656. createRequest.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;
  657. createRequest.itemsToCreate = &item;
  658. createRequest.itemsToCreateSize = 1;
  659. UA_CreateMonitoredItemsResponse createResponse =
  660. UA_Client_MonitoredItems_createDataChanges(client, createRequest, contexts,
  661. callbacks, deleteCallbacks);
  662. ck_assert_uint_eq(createResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  663. ck_assert_uint_eq(createResponse.resultsSize, 1);
  664. ck_assert_uint_eq(createResponse.results[0].statusCode, UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED);
  665. newMonitoredItemIds[0] = createResponse.results[0].monitoredItemId;
  666. UA_CreateMonitoredItemsResponse_deleteMembers(&createResponse);
  667. // Do we get initial value ? (must fail)
  668. notificationReceived = false;
  669. countNotificationReceived = 0;
  670. ck_assert_uint_eq(waitForNotification(0, 10), UA_STATUSCODE_GOOD);
  671. ck_assert_uint_eq(notificationReceived, false);
  672. ck_assert_uint_eq(countNotificationReceived, 0);
  673. // remove monitored item (must fail)
  674. UA_DeleteMonitoredItemsRequest deleteRequest;
  675. UA_DeleteMonitoredItemsRequest_init(&deleteRequest);
  676. deleteRequest.subscriptionId = subId;
  677. deleteRequest.monitoredItemIds = newMonitoredItemIds;
  678. deleteRequest.monitoredItemIdsSize = 1;
  679. UA_DeleteMonitoredItemsResponse deleteResponse =
  680. UA_Client_MonitoredItems_delete(client, deleteRequest);
  681. ck_assert_uint_eq(deleteResponse.responseHeader.serviceResult, UA_STATUSCODE_GOOD);
  682. ck_assert_uint_eq(deleteResponse.resultsSize, 1);
  683. ck_assert_uint_eq(deleteResponse.results[0], UA_STATUSCODE_BADMONITOREDITEMIDINVALID);
  684. UA_DeleteMonitoredItemsResponse_deleteMembers(&deleteResponse);
  685. }
  686. END_TEST
  687. #endif /*UA_ENABLE_SUBSCRIPTIONS*/
  688. static Suite* testSuite_Client(void) {
  689. Suite *s = suite_create("Server monitored item filter");
  690. TCase *tc_server = tcase_create("Server monitored item filter Basic");
  691. tcase_add_checked_fixture(tc_server, setup, teardown);
  692. #ifdef UA_ENABLE_SUBSCRIPTIONS
  693. tcase_add_test(tc_server, Server_MonitoredItemsNoFilter);
  694. tcase_add_test(tc_server, Server_MonitoredItemsAbsoluteFilterSetOnCreate);
  695. tcase_add_test(tc_server, Server_MonitoredItemsAbsoluteFilterSetLater);
  696. tcase_add_test(tc_server, Server_MonitoredItemsAbsoluteFilterSetOnCreateRemoveLater);
  697. tcase_add_test(tc_server, Server_MonitoredItemsPercentFilterSetOnCreate);
  698. tcase_add_test(tc_server, Server_MonitoredItemsPercentFilterSetLater);
  699. #endif /* UA_ENABLE_SUBSCRIPTIONS */
  700. suite_add_tcase(s, tc_server);
  701. return s;
  702. }
  703. int main(void) {
  704. Suite *s = testSuite_Client();
  705. SRunner *sr = srunner_create(s);
  706. srunner_set_fork_status(sr, CK_NOFORK);
  707. srunner_run_all(sr,CK_NORMAL);
  708. int number_failed = srunner_ntests_failed(sr);
  709. srunner_free(sr);
  710. return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
  711. }