A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
36using namespace ns3;
37
38NS_LOG_COMPONENT_DEFINE("TupleTestSuite");
39
40/** Object with attribute values storing tuples */
41class TupleObject : public Object
42{
43 public:
44 /**
45 * Test enum type
46 */
48 {
51 VALUE3
52 };
53
55 ~TupleObject() override;
56
57 /**
58 * \brief Get the type ID.
59 * \return the object TypeId
60 */
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
67 using Tuple1 = Tuple1Value::result_type; //!< tuple of values
68 using Tuple1Pack = Tuple1Value::value_type; //!< tuple of attribute values
69
70 using Tuple2 = std::tuple<double, uint16_t, std::string>; //!< Tuple2 typedef
71
72 /**
73 * Set tuple1
74 * \param tuple tuple value
75 */
76 void SetTuple1(const Tuple1& tuple);
77 /**
78 * Get tuple1
79 * \return tuple1
80 */
81 Tuple1 GetTuple1() const;
82 /**
83 * Set tuple2
84 * \param tuple tuple value
85 */
86 void SetTuple2(const Tuple2& tuple);
87 /**
88 * Get tuple2
89 * \return tuple2
90 */
91 Tuple2 GetTuple2() const;
92
93 private:
94 Tuple1 m_tuple1; //!< first tuple
95 Tuple2 m_tuple2; //!< second tuple
96};
97
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),
125 return tid;
126}
127
129{
130}
131
133{
134}
135
136void
138{
139 m_tuple1 = tuple;
140}
141
144{
145 return m_tuple1;
146}
147
148void
150{
151 m_tuple2 = tuple;
152}
153
156{
157 return m_tuple2;
158}
159
160/** Test instantiation, initialization, access */
162{
163 public:
165
167 {
168 }
169
170 private:
171 void DoRun() override;
172};
173
175 : TestCase("test TupleValue attribute value")
176{
177}
178
179void
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>(
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",
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",
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
316/** Test suite */
318{
319 public:
321};
322
324 : TestSuite("tuple-value-test-suite", Type::UNIT)
325{
326 AddTestCase(new TupleValueTestCase(), TestCase::Duration::QUICK);
327}
328
329static TupleValueTestSuite g_tupleValueTestSuite; //!< Static variable for test initialization
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:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
AttributeValue implementation for Tuple.
Definition: tuple.h:78
std::tuple< Args... > value_type
Type of value stored in the TupleValue.
Definition: tuple.h:81
result_type Get() const
Get the stored values as a std::tuple.
Definition: tuple.h:333
std::tuple< std::invoke_result_t< decltype(&Args::Get), Args >... > result_type
Type returned by Get or passed in Set.
Definition: tuple.h:83
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Ptr< const AttributeChecker > MakeStringChecker()
Definition: string.cc:30
#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:145
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:189
static TupleValueTestSuite g_tupleValueTestSuite
Static variable for test initialization.