source: finroc_plugins_data_ports/tests/test_collection.cpp @ 180:7d8de25a4af2

Last change on this file since 180:7d8de25a4af2 was 180:7d8de25a4af2, checked in by Max Reichardt <mreichardt@…>, 3 years ago

Merge with 17.03

File size: 24.8 KB
Line 
1//
2// You received this file as part of Finroc
3// A framework for intelligent robot control
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License along
18// with this program; if not, write to the Free Software Foundation, Inc.,
19// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21//----------------------------------------------------------------------
22/*!\file    plugins/data_ports/tests/test_collection.cpp
23 *
24 * \author  Max Reichardt
25 *
26 * \date    2013-01-03
27 *
28 * Collections of tests.
29 * This is the place to add simple tests for data_ports.
30 */
31//----------------------------------------------------------------------
32
33//----------------------------------------------------------------------
34// External includes (system with <>, local with "")
35//----------------------------------------------------------------------
36#include "core/tRuntimeEnvironment.h"
37#include "rrlib/util/tUnitTestSuite.h"
38
39//----------------------------------------------------------------------
40// Internal includes with ""
41//----------------------------------------------------------------------
42#include "plugins/data_ports/tInputPort.h"
43#include "plugins/data_ports/tOutputPort.h"
44#include "plugins/data_ports/tProxyPort.h"
45#include "plugins/data_ports/tThreadLocalBufferManagement.h"
46#include "plugins/data_ports/tPortPack.h"
47#include "plugins/data_ports/tMetadata.h"
48
49#include "plugins/structure/tModule.h"
50
51//----------------------------------------------------------------------
52// Debugging
53//----------------------------------------------------------------------
54#include <cassert>
55
56//----------------------------------------------------------------------
57// Namespace usage
58//----------------------------------------------------------------------
59
60//----------------------------------------------------------------------
61// Namespace declaration
62//----------------------------------------------------------------------
63namespace finroc
64{
65namespace data_ports
66{
67
68//----------------------------------------------------------------------
69// Forward declarations / typedefs / enums
70//----------------------------------------------------------------------
71
72//----------------------------------------------------------------------
73// Const values
74//----------------------------------------------------------------------
75
76//----------------------------------------------------------------------
77// Implementation
78//----------------------------------------------------------------------
79
80void TestPortChains()
81{
82  FINROC_LOG_PRINT(DEBUG_VERBOSE_1, "\nTesting forwarding data among port chains");
83  core::tFrameworkElement* parent = new core::tFrameworkElement(&core::tRuntimeEnvironment::GetInstance(), "TestPortChains");
84
85  // Create ports
86  tOutputPort<std::string> output_port1("Output Port 1", parent);
87  tOutputPort<std::string> output_port2("Output Port 2", parent);
88  tOutputPort<std::string> output_port3("Output Port 3", parent);
89  tProxyPort<std::string, true> proxy_port1("Proxy Port 1", parent);
90  tProxyPort<std::string, true> proxy_port2("Proxy Port 2", parent);
91  tProxyPort<std::string, true> proxy_port3("Proxy Port 3", parent);
92  tInputPort<std::string> input_port1("Input Port 1", parent);
93  tInputPort<std::string> input_port2("Input Port 2", parent);
94  tInputPort<std::string> input_port3("Input Port 3", parent);
95
96  // Connect ports
97  output_port1.ConnectTo(proxy_port1);
98  output_port2.ConnectTo(proxy_port2);
99  output_port3.ConnectTo(proxy_port3);
100  proxy_port1.ConnectTo(input_port1);
101  proxy_port2.ConnectTo(input_port2);
102  proxy_port3.ConnectTo(input_port3);
103  parent->Init();
104
105  std::string test_string = "12345";
106  for (int i = 0; i < 20; i++)
107  {
108    // Publish data
109    tPortDataPointer<std::string> unused_buffer = output_port1.GetUnusedBuffer();
110    std::string test_string2 = "Test" + std::to_string(i);
111    *unused_buffer = test_string2;
112    output_port1.Publish(unused_buffer);
113
114    // Forward data to second and third chain
115    output_port2.Publish(input_port1.GetPointer());
116    output_port3.Publish(input_port2.GetPointer());
117    RRLIB_UNIT_TESTS_ASSERT(test_string2 == *input_port3.GetPointer());
118
119    if (i > 10)
120    {
121      output_port2.Publish(test_string);
122      output_port3.Publish(input_port2.GetPointer());
123      RRLIB_UNIT_TESTS_ASSERT(test_string == *input_port3.GetPointer());
124      RRLIB_UNIT_TESTS_ASSERT(test_string == *input_port2.GetPointer());
125      RRLIB_UNIT_TESTS_ASSERT(test_string2 == *input_port1.GetPointer());
126    }
127  }
128
129  parent->ManagedDelete();
130}
131
132template <typename T>
133void TestPortQueues(const T& value1, const T& value2, const T& value3)
134{
135  FINROC_LOG_PRINT(DEBUG_VERBOSE_1, "\nTesting port queue basic operation for type ", (rrlib::rtti::tDataType<T>()).GetName());
136  core::tFrameworkElement* parent = new core::tFrameworkElement(&core::tRuntimeEnvironment::GetInstance(), "TestPortQueue");
137
138  tOutputPort<T> output_port("Output Port", parent);
139  tInputPort<T> input_port_fifo("Input Port FIFO", parent, tQueueSettings(false));
140  tInputPort<T> input_port_all("Input Port ALL", parent, tQueueSettings(true));
141  output_port.ConnectTo(input_port_fifo);
142  output_port.ConnectTo(input_port_all);
143  parent->Init();
144
145  FINROC_LOG_PRINT(DEBUG_VERBOSE_1, " Enqueueing three values");
146  output_port.Publish(value1);
147  output_port.Publish(value2);
148  output_port.Publish(value3);
149
150  FINROC_LOG_PRINT(DEBUG_VERBOSE_1, " Dequeueing five values FIFO");
151  for (size_t i = 0; i < 5; ++i)
152  {
153    tPortDataPointer<const T> result = input_port_fifo.Dequeue();
154    if (result)
155    {
156      FINROC_LOG_PRINT(DEBUG_VERBOSE_1, "  Dequeued ", *result);
157    }
158    else
159    {
160      FINROC_LOG_PRINT(DEBUG_VERBOSE_1, "  Dequeued nothing");
161    }
162    RRLIB_UNIT_TESTS_ASSERT((i == 0 && value1 == *result) || (i == 1 && value2 == *result) || (i == 2 && value3 == *result) || (i > 2 && (!result)));
163  }
164
165  FINROC_LOG_PRINT(DEBUG_VERBOSE_1, " Dequeueing all values at once");
166  tPortBuffers<tPortDataPointer<const T>> dequeued = input_port_all.DequeueAllBuffers();
167  size_t i = 0;
168  while (!dequeued.Empty())
169  {
170    T result = *dequeued.PopFront();
171    FINROC_LOG_PRINT(DEBUG_VERBOSE_1, "  Dequeued ", result);
172    RRLIB_UNIT_TESTS_ASSERT((i == 0 && value1 == result) || (i == 1 && value2 == result) || (i == 2 && value3 == result));
173    i++;
174  }
175
176  parent->ManagedDelete();
177};
178
179
180
181template <typename T>
182void TestPortListeners(const T& publish_value)
183{
184  class tListener
185  {
186  public:
187    void OnPortChange(const T& value, tChangeContext& change_context)
188    {
189      FINROC_LOG_PRINT(DEBUG_VERBOSE_1, "  Port Changed: ", value);
190      this->value1 = value;
191      this->calls++;
192    }
193    void OnPortChange(tPortDataPointer<const T>& value, tChangeContext& change_context)
194    {
195      FINROC_LOG_PRINT(DEBUG_VERBOSE_1, "  Port Changed (tPortDataPointer): ", *value);
196      this->value2 = *value;
197      this->calls++;
198    }
199    void OnPortChange(const rrlib::rtti::tGenericObject& value, tChangeContext& change_context)
200    {
201      rrlib::serialization::tStringOutputStream stream;
202      value.Serialize(stream);
203      FINROC_LOG_PRINT(DEBUG_VERBOSE_1, "  Port Changed Generic: ", stream.ToString());
204      this->calls++;
205    }
206    void OnPortChange(tPortDataPointer<const rrlib::rtti::tGenericObject>& value, tChangeContext& change_context)
207    {
208      rrlib::serialization::tStringOutputStream stream;
209      value->Serialize(stream);
210      FINROC_LOG_PRINT(DEBUG_VERBOSE_1, "  Port Changed Generic (tPortDataPointer): ", stream.ToString());
211      this->calls++;
212    }
213    void OnPortChange(tChangeContext& change_context)
214    {
215      FINROC_LOG_PRINT(DEBUG_VERBOSE_1, "  Port Changed Simple");
216      this->calls++;
217    }
218
219    T value1, value2;
220    size_t calls;
221
222    tListener() : value1(), value2(), calls(0) {}
223  };
224
225  FINROC_LOG_PRINT(DEBUG_VERBOSE_1, "\nTesting port listeners for type ", (rrlib::rtti::tDataType<T>()).GetName());
226  tListener listener;
227  core::tFrameworkElement* parent = new core::tFrameworkElement(&core::tRuntimeEnvironment::GetInstance(), "TestPortListeners");
228
229  tOutputPort<T> output_port("Output Port", parent);
230  tInputPort<T> input_port("Input Port", parent);
231  output_port.ConnectTo(input_port);
232  input_port.AddPortListener(listener);
233  input_port.AddPortListenerForPointer(listener);
234  input_port.AddPortListenerSimple(listener);
235  tGenericPort generic_input_port = tGenericPort::Wrap(*input_port.GetWrapped());
236  generic_input_port.AddPortListener(listener);
237  generic_input_port.AddPortListenerForPointer(listener);
238  generic_input_port.AddPortListenerSimple(listener);
239  parent->Init();
240
241  output_port.Publish(publish_value);
242
243  RRLIB_UNIT_TESTS_ASSERT(listener.value1 == publish_value && listener.value2 == publish_value && listener.calls == 6);
244
245  parent->ManagedDelete();
246}
247
248template <typename T>
249void TestNetworkConnectionLoss(const T& default_value, const T& publish_value)
250{
251  core::tFrameworkElement* parent = new core::tFrameworkElement(&core::tRuntimeEnvironment::GetInstance(), "TestNetworkConnectionLoss");
252
253  tOutputPort<T> output_port("Output Port", parent);
254  tInputPort<T> input_port_no_explicit_default("Input Port No Explicit Default", parent, core::tFrameworkElement::tFlag::DEFAULT_ON_DISCONNECT);
255  tInputPort<T> input_port_explicit_default("Input Port Explicit Default", parent, core::tFrameworkElement::tFlag::DEFAULT_ON_DISCONNECT, default_value);
256  tInputPort<T> input_port_deferred_default("Input Port Deferred Default", parent, core::tFrameworkElement::tFlag::DEFAULT_ON_DISCONNECT);
257  input_port_deferred_default.SetDefault(default_value);
258  output_port.ConnectTo(input_port_no_explicit_default);
259  output_port.ConnectTo(input_port_explicit_default);
260  output_port.ConnectTo(input_port_deferred_default);
261  parent->Init();
262
263  output_port.Publish(publish_value);
264  RRLIB_UNIT_TESTS_EQUALITY(publish_value, *input_port_no_explicit_default.GetPointer());
265  RRLIB_UNIT_TESTS_EQUALITY(publish_value, *input_port_explicit_default.GetPointer());
266  RRLIB_UNIT_TESTS_EQUALITY(publish_value, *input_port_deferred_default.GetPointer());
267  input_port_no_explicit_default.GetWrapped()->NotifyOfNetworkConnectionLoss();
268  input_port_explicit_default.GetWrapped()->NotifyOfNetworkConnectionLoss();
269  input_port_deferred_default.GetWrapped()->NotifyOfNetworkConnectionLoss();
270  RRLIB_UNIT_TESTS_EQUALITY(T(), *input_port_no_explicit_default.GetPointer());
271  RRLIB_UNIT_TESTS_EQUALITY(default_value, *input_port_explicit_default.GetPointer());
272  RRLIB_UNIT_TESTS_EQUALITY(default_value, *input_port_deferred_default.GetPointer());
273  output_port.Publish(publish_value);
274  RRLIB_UNIT_TESTS_EQUALITY(publish_value, *input_port_no_explicit_default.GetPointer());
275  RRLIB_UNIT_TESTS_EQUALITY(publish_value, *input_port_explicit_default.GetPointer());
276  RRLIB_UNIT_TESTS_EQUALITY(publish_value, *input_port_deferred_default.GetPointer());
277  output_port.DisconnectAll();
278  RRLIB_UNIT_TESTS_EQUALITY(T(), *input_port_no_explicit_default.GetPointer());
279  RRLIB_UNIT_TESTS_EQUALITY(default_value, *input_port_explicit_default.GetPointer());
280  RRLIB_UNIT_TESTS_EQUALITY(default_value, *input_port_deferred_default.GetPointer());
281
282  parent->ManagedDelete();
283}
284
285void TestOutOfBoundsPublish()
286{
287  core::tFrameworkElement* parent = new core::tFrameworkElement(&core::tRuntimeEnvironment::GetInstance(), "TestOutOfBoundsPublish");
288
289  tOutputPort<int> output_port("Output Port", parent, tBounds<int>(0, 2, tOutOfBoundsAction::DISCARD));
290  tInputPort<int> input_port("Input Port", parent, tBounds<int>(0, 1));
291  output_port.ConnectTo(input_port);
292  parent->Init();
293
294  output_port.Publish(3);
295  RRLIB_UNIT_TESTS_EQUALITY(0, input_port.Get());
296  output_port.Publish(2);
297  RRLIB_UNIT_TESTS_EQUALITY(1, input_port.Get());
298
299  parent->ManagedDelete();
300}
301
302template <typename T>
303void TestHijackedPublishing(const T& value_to_publish)
304{
305  core::tFrameworkElement* parent = new core::tFrameworkElement(&core::tRuntimeEnvironment::GetInstance(), "TestHijackedPublishing");
306  T default_value = T();
307
308  tOutputPort<T> output_port("Output Port", parent);
309  tProxyPort<T, true> proxy_port("Proxy Port", parent, core::tFrameworkElementFlag::PUSH_STRATEGY);
310  tInputPort<T> input_port("Input Port", parent);
311  output_port.ConnectTo(proxy_port);
312  proxy_port.ConnectTo(input_port);
313  parent->Init();
314
315  output_port.Publish(value_to_publish);
316  RRLIB_UNIT_TESTS_EQUALITY(value_to_publish, *proxy_port.GetPointer());
317  RRLIB_UNIT_TESTS_EQUALITY(value_to_publish, *input_port.GetPointer());
318  input_port.GetWrapped()->SetHijacked(true);
319  RRLIB_UNIT_TESTS_EQUALITY(value_to_publish, *proxy_port.GetPointer());
320  RRLIB_UNIT_TESTS_EQUALITY(value_to_publish, *input_port.GetPointer());
321  output_port.Publish(default_value);
322  RRLIB_UNIT_TESTS_EQUALITY(default_value, *proxy_port.GetPointer());
323  RRLIB_UNIT_TESTS_EQUALITY(value_to_publish, *input_port.GetPointer());
324  proxy_port.GetWrapped()->SetHijacked(true);
325  input_port.GetWrapped()->SetHijacked(false);
326  output_port.Publish(value_to_publish);
327  RRLIB_UNIT_TESTS_EQUALITY(default_value, *proxy_port.GetPointer());
328  RRLIB_UNIT_TESTS_EQUALITY(value_to_publish, *input_port.GetPointer());
329  output_port.GetWrapped()->SetHijacked(true);
330  output_port.Publish(value_to_publish);
331
332  parent->ManagedDelete();
333}
334
335template <typename T>
336void TestGenericPorts(T value_to_publish, T another_value)
337{
338  core::tFrameworkElement* parent = new core::tFrameworkElement(&core::tRuntimeEnvironment::GetInstance(), "TestGenericPorts");
339  T default_value = T();
340  rrlib::rtti::tGenericObjectWrapper<T> default_buffer(default_value);
341  rrlib::rtti::tGenericObjectWrapper<T> value_buffer(value_to_publish);
342  rrlib::rtti::tGenericObjectWrapper<T> another_value_buffer(another_value);
343
344  tGenericPort output_port("Output Port", rrlib::rtti::tDataType<T>(), parent, core::tFrameworkElement::tFlag::EMITS_DATA | core::tFrameworkElement::tFlag::OUTPUT_PORT);
345  tGenericPort proxy_port("Proxy Port", rrlib::rtti::tDataType<T>(), parent, core::tFrameworkElement::tFlag::ACCEPTS_DATA | core::tFrameworkElement::tFlag::PUSH_STRATEGY | core::tFrameworkElement::tFlag::EMITS_DATA);
346  tGenericPort input_port("Input Port", rrlib::rtti::tDataType<T>(), parent, core::tFrameworkElement::tFlag::ACCEPTS_DATA | core::tFrameworkElement::tFlag::PUSH_STRATEGY);
347  output_port.ConnectTo(proxy_port);
348  proxy_port.ConnectTo(input_port);
349  parent->Init();
350
351  // Publish by value
352  T get_value = T();
353  rrlib::rtti::tGenericObjectWrapper<T> get_buffer(get_value);
354  input_port.Get(get_buffer);
355  RRLIB_UNIT_TESTS_EQUALITY(default_value, get_value);
356  output_port.Publish(value_buffer);
357  proxy_port.Get(get_buffer);
358  RRLIB_UNIT_TESTS_EQUALITY(value_to_publish, get_value);
359  input_port.Get(get_buffer);
360  RRLIB_UNIT_TESTS_EQUALITY(value_to_publish, get_value);
361
362  // Publish via buffer
363  auto unused_buffer = output_port.GetUnusedBuffer();
364  unused_buffer->GetData<T>() = another_value;
365  output_port.Publish(unused_buffer);
366  proxy_port.Get(get_buffer);
367  RRLIB_UNIT_TESTS_EQUALITY(another_value, get_value);
368  input_port.Get(get_buffer);
369  RRLIB_UNIT_TESTS_EQUALITY(another_value, get_value);
370
371  parent->ManagedDelete();
372}
373
374struct mTestModule : structure::tModule
375{
376  using tModule::tModule;
377  void Update() override {}
378};
379
380template <typename ... T, typename NAMES>
381void PortPackTestHelper(core::tFrameworkElement *parent, const std::initializer_list<NAMES> &names_initializer)
382{
383  data_ports::tPortPack<mTestModule::tInput, T...> ports(parent, "X", 0);
384
385  RRLIB_UNIT_TESTS_EQUALITY(sizeof...(T), ports.NumberOfPorts());
386  for (size_t i = 0; i < sizeof...(T); ++i)
387  {
388    RRLIB_UNIT_TESTS_EQUALITY("X" + std::to_string(i), ports.GetPort(i).GetName());
389  }
390
391  std::array<NAMES, sizeof...(T)> names;
392  assert(names_initializer.size() == names.size());
393  std::copy(names_initializer.begin(), names_initializer.end(), names.begin());
394  data_ports::tPortPack<tInputPort, T...> named_ports(parent, names.begin(), names.end());
395
396  RRLIB_UNIT_TESTS_EQUALITY(sizeof...(T), named_ports.NumberOfPorts());
397  for (size_t i = 0; i < sizeof...(T); ++i)
398  {
399    RRLIB_UNIT_TESTS_EQUALITY(std::string(names[i]), named_ports.GetPort(i).GetName());
400  }
401}
402
403template <typename T>
404void SetBoundsGeneric(T min, T max, tOutOfBoundsAction action)
405{
406  common::tAbstractDataPortCreationInfo creation_info;
407  creation_info.name = "Bounds Test";
408  creation_info.flags = cDEFAULT_INPUT_PORT_FLAGS;
409  creation_info.parent = &core::tRuntimeEnvironment::GetInstance();
410  creation_info.data_type = rrlib::rtti::tDataType<T>();
411
412  if (!std::is_arithmetic<T>::value)
413  {
414    common::tAbstractDataPortCreationInfo::RegisterBoundedPortCreateFunction<T>();
415  }
416
417  rrlib::rtti::tGenericObjectWrapper<T> min_object(min);
418  rrlib::rtti::tGenericObjectWrapper<T> max_object(max);
419  creation_info.SetBoundsGeneric(min_object, max_object, action);
420
421  tGenericPort port(creation_info);
422  RRLIB_UNIT_TESTS_ASSERT(typeid(*port.GetWrapped()) == typeid(api::tBoundedPort<T>));
423  api::tBoundedPort<T>& bounded_port = static_cast<api::tBoundedPort<T>&>(*port.GetWrapped());
424  auto bounds = bounded_port.GetBounds();
425  RRLIB_UNIT_TESTS_ASSERT(bounds.GetMin() == min);
426  RRLIB_UNIT_TESTS_ASSERT(bounds.GetMax() == max);
427  RRLIB_UNIT_TESTS_ASSERT(bounds.GetOutOfBoundsAction() == action);
428  port.ManagedDelete();
429}
430
431template <typename T>
432void TestMetadata(const T& value_to_publish_1, const T& value_to_publish_2)
433{
434  core::tFrameworkElement* parent = new core::tFrameworkElement(&core::tRuntimeEnvironment::GetInstance(), "TestMetadata");
435
436  tOutputPort<T> output_port("Output Port", parent);
437  tInputPort<T> input_port("Input Port", parent);
438  tInputPort<std::pair<T, tMetadata>> input_port_with_meta_data("Input Port With Meta Data", parent);
439  tInputPort<tMetadata> input_port_meta_data("Input Port Meta Data", parent);
440  tInputPort<numeric::tNumber> input_port_meta_data_number("Input Port Meta Data Number", parent);
441  output_port.ConnectTo(input_port);
442  output_port.ConnectTo(input_port_with_meta_data, cAPPEND_META_DATA_OPERATION);
443  output_port.ConnectTo(input_port_meta_data, cCAPTURE_META_DATA_OPERATION);
444  output_port.ConnectTo(input_port_meta_data_number, cCAPTURE_META_DATA_OPERATION);
445  parent->Init();
446
447  numeric::tNumber number1(42), number2(-0.445);
448  rrlib::time::tTimestamp now = rrlib::time::Now();
449  data_ports::tEvent event;
450  {
451    rrlib::time::tDuration duration = std::chrono::milliseconds(12378);
452    float f = -3.551;
453
454    tScopedMetadata scoped_meta_data(duration, f);
455    output_port.Publish(value_to_publish_1, tMetadata::Tie(number1, event, number2));
456
457    RRLIB_UNIT_TESTS_EQUALITY(value_to_publish_1, *input_port.GetPointer());
458    RRLIB_UNIT_TESTS_EQUALITY(value_to_publish_1, input_port_with_meta_data.GetPointer()->first);
459    RRLIB_UNIT_TESTS_ASSERT(tMetadata::Tie(duration, f, number1, event, number2) == input_port_with_meta_data.GetPointer()->second);
460    RRLIB_UNIT_TESTS_ASSERT(tMetadata::Tie(duration, f, number1, event, number2) == *input_port_meta_data.GetPointer());
461    RRLIB_UNIT_TESTS_ASSERT(duration == *input_port_meta_data.GetPointer()->Get<rrlib::time::tDuration>());
462    RRLIB_UNIT_TESTS_EQUALITY(number1, input_port_meta_data_number.Get());
463
464    output_port.Publish(value_to_publish_2);
465
466    RRLIB_UNIT_TESTS_EQUALITY(value_to_publish_2, *input_port.GetPointer());
467    RRLIB_UNIT_TESTS_EQUALITY(value_to_publish_2, input_port_with_meta_data.GetPointer()->first);
468    RRLIB_UNIT_TESTS_ASSERT(tMetadata::Tie(duration, f) == input_port_with_meta_data.GetPointer()->second);
469    RRLIB_UNIT_TESTS_ASSERT(tMetadata::Tie(duration, f) == *input_port_meta_data.GetPointer());
470    RRLIB_UNIT_TESTS_ASSERT(duration == *input_port_meta_data.GetPointer()->Get<rrlib::time::tDuration>());
471  }
472
473  output_port.Publish(value_to_publish_1, now, tMetadata::Tie(number2, event, number1));
474
475  RRLIB_UNIT_TESTS_EQUALITY(value_to_publish_1, *input_port.GetPointer());
476  RRLIB_UNIT_TESTS_EQUALITY(value_to_publish_1, input_port_with_meta_data.GetPointer()->first);
477  RRLIB_UNIT_TESTS_ASSERT(tMetadata::Tie(number2, event, number1) == input_port_with_meta_data.GetPointer()->second);
478  RRLIB_UNIT_TESTS_ASSERT(tMetadata::Tie(number2, event, number1) == *input_port_meta_data.GetPointer());
479  RRLIB_UNIT_TESTS_ASSERT(input_port_meta_data.GetPointer()->Get<rrlib::time::tDuration>() == nullptr);
480  RRLIB_UNIT_TESTS_EQUALITY(number2, *input_port_meta_data.GetPointer()->Get<numeric::tNumber>());
481  RRLIB_UNIT_TESTS_EQUALITY(number2, input_port_meta_data_number.Get());
482
483  output_port.Publish(value_to_publish_2, now);
484  RRLIB_UNIT_TESTS_EQUALITY(value_to_publish_2, *input_port.GetPointer());
485  RRLIB_UNIT_TESTS_EQUALITY(value_to_publish_2, input_port_with_meta_data.GetPointer()->first);
486  RRLIB_UNIT_TESTS_EQUALITY(true, input_port_with_meta_data.GetPointer()->second.Empty());
487  RRLIB_UNIT_TESTS_ASSERT(tMetadata::Tie() == *input_port_meta_data.GetPointer());
488  RRLIB_UNIT_TESTS_ASSERT(input_port_meta_data.GetPointer()->Get<numeric::tNumber>() == nullptr);
489
490  parent->ManagedDelete();
491}
492
493class DataPortsTestCollection : public rrlib::util::tUnitTestSuite
494{
495  RRLIB_UNIT_TESTS_BEGIN_SUITE(DataPortsTestCollection);
496  RRLIB_UNIT_TESTS_ADD_TEST(Test);
497  RRLIB_UNIT_TESTS_ADD_TEST(PortPack);
498  RRLIB_UNIT_TESTS_ADD_TEST(PortPackLegacy);
499  RRLIB_UNIT_TESTS_ADD_TEST(TestMetadata);
500  RRLIB_UNIT_TESTS_END_SUITE;
501
502  void Test()
503  {
504    TestPortChains();
505    TestPortQueues<int>(1, 2, 3);
506    TestPortQueues<std::string>("1", "2", "3");
507    TestPortListeners<int>(1);
508    TestPortListeners<std::string>("test");
509    TestNetworkConnectionLoss<int>(4, 7);
510    TestNetworkConnectionLoss<std::string>("default_value", "published_value");
511    TestOutOfBoundsPublish();
512    TestHijackedPublishing<int>(42);
513    TestHijackedPublishing<std::string>("test");
514    TestGenericPorts<bool>(true, false);
515    TestGenericPorts<std::string>("123", "45");
516
517    tThreadLocalBufferManagement local_buffers;
518    TestPortChains();
519    TestPortQueues<int>(1, 2, 3);
520    TestPortListeners<int>(1);
521    TestNetworkConnectionLoss<int>(4, 7);
522    TestOutOfBoundsPublish();
523    TestHijackedPublishing<int>(42);
524    TestGenericPorts<bool>(true, false);
525
526    SetBoundsGeneric<uint8_t>(4, 9, tOutOfBoundsAction::ADJUST_TO_RANGE);
527    SetBoundsGeneric<int16_t>(-12, 900, tOutOfBoundsAction::APPLY_DEFAULT);
528    SetBoundsGeneric<int32_t>(-121, 5235623, tOutOfBoundsAction::DISCARD);
529    SetBoundsGeneric<int64_t>(-552121, 523511352456623, tOutOfBoundsAction::ADJUST_TO_RANGE);
530    SetBoundsGeneric<double>(-552121., 523511352456623, tOutOfBoundsAction::ADJUST_TO_RANGE);
531    SetBoundsGeneric<numeric::tNumber>(-552121., 523511352456623, tOutOfBoundsAction::ADJUST_TO_RANGE);
532    SetBoundsGeneric<std::pair<int, uint8_t>>(std::pair<int, uint8_t>(-44315, 90), std::pair<int, uint8_t>(-2, 177), tOutOfBoundsAction::APPLY_DEFAULT);
533    SetBoundsGeneric<std::array<short, 3>>({ -2, 5, 2}, { 5, -11233, 77 }, tOutOfBoundsAction::APPLY_DEFAULT);
534    SetBoundsGeneric<std::tuple<double, short, float>>(std::tuple<double, short, float>(-0.5, 1133, 0.11), std::tuple<double, short, float>(55, -1133, 6436.2), tOutOfBoundsAction::APPLY_DEFAULT);
535  }
536
537  void PortPack()
538  {
539    auto parent = new mTestModule(&core::tRuntimeEnvironment::GetInstance(), "TestModule");
540
541    PortPackTestHelper<int, double, std::string, bool>(parent, {"foo", "bar", "baz", "fnord"});
542
543    std::array<std::string, 0> empty_names;
544    RRLIB_UNIT_TESTS_EQUALITY(size_t(0), data_ports::tPortPack<mTestModule::tInput>(parent, "X").NumberOfPorts());
545    RRLIB_UNIT_TESTS_EQUALITY(size_t(0), data_ports::tPortPack<mTestModule::tInput>(parent, empty_names.begin(), empty_names.end()).NumberOfPorts());
546  }
547
548  void PortPackLegacy()
549  {
550    auto parent = new mTestModule(&core::tRuntimeEnvironment::GetInstance(), "TestModule");
551
552    using tTypeList = rrlib::util::tTypeList<int, double, std::string, bool>;
553    data_ports::tPortPack<mTestModule::tInput, tTypeList> ports(parent, "X");
554
555    RRLIB_UNIT_TESTS_EQUALITY(tTypeList::cSIZE, ports.NumberOfPorts());
556
557    for (size_t i = 0; i < tTypeList::cSIZE; ++i)
558    {
559      RRLIB_UNIT_TESTS_EQUALITY("X" + std::to_string(i + 1), ports.GetPort(i).GetName());
560    }
561
562    std::array<std::string, tTypeList::cSIZE> names {"foo", "bar", "baz", "fnord"};
563    data_ports::tPortPack<mTestModule::tInput, tTypeList> named_ports(parent, names.begin(), names.end());
564
565    for (size_t i = 0; i < tTypeList::cSIZE; ++i)
566    {
567      RRLIB_UNIT_TESTS_EQUALITY(names[i], named_ports.GetPort(i).GetName());
568    }
569  }
570
571  void TestMetadata()
572  {
573    data_ports::TestMetadata<double>(7, -3.5);
574    data_ports::TestMetadata<std::string>("testing", "meta data");
575  }
576};
577
578RRLIB_UNIT_TESTS_REGISTER_SUITE(DataPortsTestCollection);
579
580//----------------------------------------------------------------------
581// End of namespace declaration
582//----------------------------------------------------------------------
583}
584}
Note: See TracBrowser for help on using the repository browser.