A Discrete-Event Network Simulator
API
tuple-value-test-suite.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 Universita' degli Studi di Napoli Federico II
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Stefano Avallone <stavallo@unina.it>
18  */
19 
20 #include <ns3/double.h>
21 #include <ns3/enum.h>
22 #include <ns3/log.h>
23 #include <ns3/object.h>
24 #include <ns3/ptr.h>
25 #include <ns3/string.h>
26 #include <ns3/test.h>
27 #include <ns3/tuple.h>
28 #include <ns3/uinteger.h>
29 
30 #include <algorithm>
31 #include <iterator>
32 #include <sstream>
33 #include <tuple>
34 #include <utility>
35 
36 using namespace ns3;
37 
38 NS_LOG_COMPONENT_DEFINE("TupleTestSuite");
39 
41 class TupleObject : public Object
42 {
43  public:
48  {
51  VALUE3
52  };
53 
54  TupleObject();
55  ~TupleObject() override;
56 
61  static TypeId GetTypeId();
62 
63  // NOTE EnumValue::Get() return an int, so the tuple element type must be an int
64  // in place of the enum type
65  using Tuple1Value =
69 
70  using Tuple2 = std::tuple<double, uint16_t, std::string>;
71 
76  void SetTuple1(const Tuple1& tuple);
81  Tuple1 GetTuple1() const;
86  void SetTuple2(const Tuple2& tuple);
91  Tuple2 GetTuple2() const;
92 
93  private:
96 };
97 
98 TypeId
100 {
101  static TypeId tid =
102  TypeId("ns3::TupleObject")
103  .SetParent<Object>()
104  .SetGroupName("Test")
105  .AddConstructor<TupleObject>()
106  .AddAttribute(
107  "StringStringEnumTuple",
108  "Tuple1: string, string, enum",
109  MakeTupleValue<Tuple1Pack>(Tuple1{"Hey", "Jude", TupleObject::VALUE1}),
110  MakeTupleAccessor<Tuple1Pack>(&TupleObject::m_tuple1),
111  MakeTupleChecker<Tuple1Pack>(
115  .AddAttribute(
116  "DoubleUintStringTuple",
117  "Tuple2: double, uint16_t, string",
119  MakeTupleAccessor<DoubleValue, UintegerValue, StringValue>(&TupleObject::SetTuple2,
121  MakeTupleChecker<DoubleValue, UintegerValue, StringValue>(
122  MakeDoubleChecker<double>(1.0, 10.0),
123  MakeUintegerChecker<int>(1, 30),
124  MakeStringChecker()));
125  return tid;
126 }
127 
129 {
130 }
131 
133 {
134 }
135 
136 void
138 {
139  m_tuple1 = tuple;
140 }
141 
144 {
145  return m_tuple1;
146 }
147 
148 void
150 {
151  m_tuple2 = tuple;
152 }
153 
156 {
157  return m_tuple2;
158 }
159 
162 {
163  public:
165 
167  {
168  }
169 
170  private:
171  void DoRun() override;
172 };
173 
175  : TestCase("test TupleValue attribute value")
176 {
177 }
178 
179 void
181 {
182  auto tupleObject = CreateObject<TupleObject>();
183 
184  // Test that default values have been assigned to tuple 1
185  auto t1 = tupleObject->GetTuple1();
186  NS_TEST_ASSERT_MSG_EQ((std::get<0>(t1) == "Hey"),
187  true,
188  "First element of tuple 1 not correctly set");
189  NS_TEST_ASSERT_MSG_EQ((std::get<1>(t1) == "Jude"),
190  true,
191  "Second element of tuple 1 not correctly set");
192  NS_TEST_ASSERT_MSG_EQ(std::get<2>(t1),
193  (int)(TupleObject::VALUE1),
194  "Third element of tuple 1 not correctly set");
195 
196  // Test that default values have been assigned to tuple 2
197  auto t2 = tupleObject->GetTuple2();
198  NS_TEST_ASSERT_MSG_EQ(std::get<0>(t2), 6.022, "First element of tuple 2 not correctly set");
199  NS_TEST_ASSERT_MSG_EQ(std::get<1>(t2), 23, "Second element of tuple 2 not correctly set");
200  NS_TEST_ASSERT_MSG_EQ((std::get<2>(t2) == "Avogadro"),
201  true,
202  "Third element of tuple 2 not correctly set");
203 
204  // Test that we can correctly set and get new values for tuple 1
205  bool ret1 = tupleObject->SetAttributeFailSafe(
206  "StringStringEnumTuple",
207  MakeTupleValue<TupleObject::Tuple1Pack>(
208  TupleObject::Tuple1{"Norwegian", "Wood", TupleObject::VALUE2}));
209  NS_TEST_ASSERT_MSG_EQ(ret1, true, "Setting valid values to tuple 1 failed");
210 
212  ret1 = tupleObject->GetAttributeFailSafe("StringStringEnumTuple", tupleValue1);
213  NS_TEST_ASSERT_MSG_EQ(ret1, true, "Getting values for tuple 1 failed");
214 
215  t1 = tupleValue1.Get();
216  NS_TEST_ASSERT_MSG_EQ((std::get<0>(t1) == "Norwegian"),
217  true,
218  "First element of tuple 1 not correctly set");
219  NS_TEST_ASSERT_MSG_EQ((std::get<1>(t1) == "Wood"),
220  true,
221  "Second element of tuple 1 not correctly set");
222  NS_TEST_ASSERT_MSG_EQ(std::get<2>(t1),
223  (int)(TupleObject::VALUE2),
224  "Third element of tuple 1 not correctly set");
225 
226  // Test that we can correctly set and get new values for tuple 2
227  bool ret2 = tupleObject->SetAttributeFailSafe(
228  "DoubleUintStringTuple",
230  NS_TEST_ASSERT_MSG_EQ(ret2, true, "Setting valid values to tuple 2 failed");
231 
233  ret2 = tupleObject->GetAttributeFailSafe("DoubleUintStringTuple", tupleValue2);
234  NS_TEST_ASSERT_MSG_EQ(ret2, true, "Getting values for tuple 2 failed");
235 
236  t2 = tupleValue2.Get();
237  NS_TEST_ASSERT_MSG_EQ(std::get<0>(t2), 8.987, "First element of tuple 2 not correctly set");
238  NS_TEST_ASSERT_MSG_EQ(std::get<1>(t2), 9, "Second element of tuple 2 not correctly set");
239  NS_TEST_ASSERT_MSG_EQ((std::get<2>(t2) == "Coulomb"),
240  true,
241  "Third element of tuple 2 not correctly set");
242 
243  // Test that we can set tuple 1 from string
244  ret1 = tupleObject->SetAttributeFailSafe("StringStringEnumTuple",
245  StringValue("{Come, Together, VALUE1}"));
246  NS_TEST_ASSERT_MSG_EQ(ret1, true, "Setting valid values to tuple 1 failed");
247 
248  t1 = tupleObject->GetTuple1();
249  NS_TEST_ASSERT_MSG_EQ((std::get<0>(t1) == "Come"),
250  true,
251  "First element of tuple 1 not correctly set");
252  NS_TEST_ASSERT_MSG_EQ((std::get<1>(t1) == "Together"),
253  true,
254  "Second element of tuple 1 not correctly set");
255  NS_TEST_ASSERT_MSG_EQ(std::get<2>(t1),
256  (int)(TupleObject::VALUE1),
257  "Third element of tuple 1 not correctly set");
258 
259  // Test that we can set tuple 2 from string
260  ret2 = tupleObject->SetAttributeFailSafe("DoubleUintStringTuple",
261  StringValue("{2.99, 8, LightSpeed}"));
262  NS_TEST_ASSERT_MSG_EQ(ret2, true, "Setting valid values to tuple 2 failed");
263 
264  t2 = tupleObject->GetTuple2();
265  NS_TEST_ASSERT_MSG_EQ(std::get<0>(t2), 2.99, "First element of tuple 2 not correctly set");
266  NS_TEST_ASSERT_MSG_EQ(std::get<1>(t2), 8, "Second element of tuple 2 not correctly set");
267  NS_TEST_ASSERT_MSG_EQ((std::get<2>(t2) == "LightSpeed"),
268  true,
269  "Third element of tuple 2 not correctly set");
270 
271  // Test that setting invalid values fails
272  ret1 = tupleObject->SetAttributeFailSafe("StringStringEnumTuple",
273  TupleValue<StringValue, StringValue>({"Get", "Back"}));
274  NS_TEST_ASSERT_MSG_EQ(ret1, false, "Too few values");
275  NS_TEST_ASSERT_MSG_EQ((tupleObject->GetTuple1() ==
276  std::make_tuple("Come", "Together", (int)(TupleObject::VALUE1))),
277  true,
278  "Tuple modified after failed assignment");
279 
280  ret1 = tupleObject->SetAttributeFailSafe(
281  "StringStringEnumTuple",
282  MakeTupleValue<TupleObject::Tuple1Pack>(
283  TupleObject::Tuple1{"Get", "Back", TupleObject::VALUE3}));
284  NS_TEST_ASSERT_MSG_EQ(ret1, false, "Invalid enum value");
285  NS_TEST_ASSERT_MSG_EQ((tupleObject->GetTuple1() ==
286  std::make_tuple("Come", "Together", (int)(TupleObject::VALUE1))),
287  true,
288  "Tuple modified after failed assignment");
289 
290  ret2 = tupleObject->SetAttributeFailSafe(
291  "DoubleUintStringTuple",
293  {4.83, 14, "Josephson", "constant"}));
294  NS_TEST_ASSERT_MSG_EQ(ret2, false, "Too many values");
295  NS_TEST_ASSERT_MSG_EQ((tupleObject->GetTuple2() == std::make_tuple(2.99, 8, "LightSpeed")),
296  true,
297  "Tuple modified after failed assignment");
298 
299  ret2 = tupleObject->SetAttributeFailSafe(
300  "DoubleUintStringTuple",
301  TupleValue<DoubleValue, UintegerValue, StringValue>({48.3, 13, "Josephson"}));
302  NS_TEST_ASSERT_MSG_EQ(ret2, false, "Double value out of range");
303  NS_TEST_ASSERT_MSG_EQ((tupleObject->GetTuple2() == std::make_tuple(2.99, 8, "LightSpeed")),
304  true,
305  "Tuple modified after failed assignment");
306 
307  ret2 = tupleObject->SetAttributeFailSafe(
308  "DoubleUintStringTuple",
309  TupleValue<DoubleValue, UintegerValue, StringValue>({4.83, 130, "Josephson"}));
310  NS_TEST_ASSERT_MSG_EQ(ret2, false, "Uinteger value out of range");
311  NS_TEST_ASSERT_MSG_EQ((tupleObject->GetTuple2() == std::make_tuple(2.99, 8, "LightSpeed")),
312  true,
313  "Tuple modified after failed assignment");
314 }
315 
318 {
319  public:
321 };
322 
324  : TestSuite("tuple-value-test-suite", UNIT)
325 {
326  AddTestCase(new TupleValueTestCase(), TestCase::QUICK);
327 }
328 
Object with attribute values storing tuples.
Tuple1 GetTuple1() const
Get tuple1.
void SetTuple1(const Tuple1 &tuple)
Set tuple1.
Tuple1Value::value_type Tuple1Pack
tuple of attribute values
Tuple2 m_tuple2
second tuple
std::tuple< double, uint16_t, std::string > Tuple2
Tuple2 typedef.
static TypeId GetTypeId()
Get the type ID.
Tuple2 GetTuple2() const
Get tuple2.
Tuple1 m_tuple1
first tuple
TupleTestEnum
Test enum type.
void SetTuple2(const Tuple2 &tuple)
Set tuple2.
Tuple1Value::result_type Tuple1
tuple of values
Test instantiation, initialization, access.
void DoRun() override
Implementation to actually run this TestCase.
A base class which provides memory management and object aggregation.
Definition: object.h:89
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
Hold objects of type std::tuple<Args...>.
Definition: tuple.h:69
std::tuple< Args... > value_type
Type of value stored in the TupleValue.
Definition: tuple.h:72
result_type Get() const
Get the stored values as a std::tuple.
Definition: tuple.h:311
std::tuple< std::invoke_result_t< decltype(&Args::Get), Args >... > result_type
Type returned by Get or passed in Set.
Definition: tuple.h:74
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:194
Ptr< const AttributeChecker > MakeStringChecker()
Definition: string.cc:30
static TupleValueTestSuite g_tupleValueTestSuite
Static variable for test initialization.