1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2016 Tom Henderson
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18 
19 #include "ns3/core-module.h"
20 
21 /**
22  * \defgroup string-value-formatting
23  * Check that StringValue parses complex values correctly.
24  */
25 
26 /**
27  * \file
28  * \ingroup core-examples
29  * \ingroup string-value-formatting
30  * Check that StringValue parses complex values correctly.
31  * \todo This should really be turned into a TestSuite
32  */
33 
34 using namespace ns3;
35 
36 NS_LOG_COMPONENT_DEFINE ("TestStringValueFormatting");
37 
38 namespace {
39 
40 /**
41  * \ingroup string-value-formatting
42  *
43  * StringValue formatting example test object.
44  *
45  * We use an attribute containing a pointer to a random variable
46  * to stress StringValue.
47  */
48 class FormattingTestObject : public Object
49 {
50 public:
51   /**
52    * \brief Register this type and get the TypeId.
53    * \return the object TypeId
54    */
55   static TypeId GetTypeId (void);
56   /** Default constructor */
57   FormattingTestObject ();
58   /**
59    * Get the test variable
60    * \returns the test variable
61    */
62   Ptr<RandomVariableStream> GetTestVariable (void) const;
63 
64 private:
65   Ptr<RandomVariableStream> m_testVariable; //!< The test variable
66 };
67 
68 NS_OBJECT_ENSURE_REGISTERED (FormattingTestObject);
69 
70 TypeId
GetTypeId(void)71 FormattingTestObject::GetTypeId (void)
72 {
73   static TypeId tid = TypeId ("ns3::FormattingTestObject")
74     .SetParent<Object> ()
75     .AddConstructor<FormattingTestObject> ()
76     .AddAttribute ("OnTime", "A RandomVariableStream used to pick the duration of the 'On' state.",
77                    StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"),
78                    MakePointerAccessor (&FormattingTestObject::m_testVariable),
79                    MakePointerChecker <RandomVariableStream>())
80   ;
81   return tid;
82 }
83 
FormattingTestObject()84 FormattingTestObject::FormattingTestObject ()
85 {}
86 
87 Ptr<RandomVariableStream>
GetTestVariable(void) const88 FormattingTestObject::GetTestVariable (void) const
89 {
90   return m_testVariable;
91 }
92 
93 /**
94  * \ingroup string-value-formatting
95  *
96  * StringValue formatting example test helper class.
97  */
98 class FormattingTestObjectHelper
99 {
100 public:
101   /** Default constructor */
102   FormattingTestObjectHelper ();
103   /**
104    * Set an attribute by name
105    * \param name the attribute
106    * \param value the attribute value
107    */
108   void SetAttribute (std::string name, const AttributeValue &value);
109   /**
110    * Create an Object as configured by SetAttribute
111    * \returns the newly created Object
112    */
113   Ptr<Object> CreateFromFactory (void);
114 
115 private:
116   ObjectFactory m_factory; //!< Object factory
117 };
118 
FormattingTestObjectHelper()119 FormattingTestObjectHelper::FormattingTestObjectHelper ()
120 {
121   m_factory.SetTypeId (FormattingTestObject::GetTypeId ());
122 }
123 
124 void
SetAttribute(std::string name,const AttributeValue & value)125 FormattingTestObjectHelper::SetAttribute (std::string name, const AttributeValue &value)
126 {
127   m_factory.Set (name, value);
128 }
129 
130 Ptr<Object>
CreateFromFactory(void)131 FormattingTestObjectHelper::CreateFromFactory (void)
132 {
133   return m_factory.Create ();
134 }
135 
136 }  // unnamed namespace
137 
138 
139 int
main(int argc,char * argv[])140 main (int argc, char *argv[])
141 {
142   // CreateObject parsing
143   Ptr<FormattingTestObject> obj = CreateObject<FormattingTestObject> ();
144   obj->SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable"));
145   obj->SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable[Min=0.]"));
146   obj->SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable[Min=0.|Max=1.]"));
147   obj->SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable[Min=50.|Max=100.]"));
148 
149   Ptr<RandomVariableStream> rvStream = obj->GetTestVariable ();
150   // Either GetObject () or DynamicCast may be used to get subclass pointer
151   Ptr<UniformRandomVariable> uniformStream = rvStream->GetObject<UniformRandomVariable> ();
152   NS_ASSERT (uniformStream);
153 
154   // Check that the last setting of Min to 50 and Max to 100 worked
155   DoubleValue val;
156   uniformStream->GetAttribute ("Min", val);
157   NS_ASSERT_MSG (val.Get () == 50, "Minimum not set to 50");
158   uniformStream->GetAttribute ("Max", val);
159   NS_ASSERT_MSG (val.Get () == 100, "Maximum not set to 100");
160 
161 
162   // The following malformed values should result in an error exit
163   // if uncommented
164 
165   // Attribute doesn't exist
166   //obj->SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable[A=0.]"));
167   // Missing right bracket
168   //obj->SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable[Min=0."));
169   // Comma delimiter fails
170   //obj->SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable[Min=0.,Max=1.]"));
171   // Incomplete specification
172   //obj->SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable[Min=0.|Max=]"));
173   // Incomplete specification
174   //obj->SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable[Min=0.|Max]"));
175 
176   // ObjectFactory parsing
177   FormattingTestObjectHelper formattingHelper;
178   formattingHelper.SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable[Min=30.|Max=60.0]"));
179   // Attribute doesn't exist
180   //formattingHelper.SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable[A=0.]"));
181   // Missing right bracket
182   //formattingHelper.SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable[Min=30."));
183   // Comma delimiter fails
184   //formattingHelper.SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable[Min=30.,Max=60.]"));
185   // Incomplete specification
186   //formattingHelper.SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable[Min=30.|Max=]"));
187   // Incomplete specification
188   //formattingHelper.SetAttribute ("OnTime", StringValue ("ns3::UniformRandomVariable[Min=30.|Max]"));
189 
190   // verify that creation occurs correctly
191   Ptr<Object> outputObj = formattingHelper.CreateFromFactory ();
192   Ptr<FormattingTestObject> fto = DynamicCast<FormattingTestObject> (outputObj);
193   NS_ASSERT_MSG (fto, "object creation failed");
194   rvStream = fto->GetTestVariable ();
195   uniformStream = rvStream->GetObject<UniformRandomVariable> ();
196   NS_ASSERT (uniformStream);
197   // Check that the last setting of Min to 30 and Max to 60 worked
198   uniformStream->GetAttribute ("Min", val);
199   NS_ASSERT_MSG (val.Get () == 30, "Minimum not set to 30");
200   uniformStream->GetAttribute ("Max", val);
201   NS_ASSERT_MSG (val.Get () == 60, "Maximum not set to 60");
202 }
203