# HG changeset patch # User Tom Henderson # Date 1313534945 25200 # Node ID 3aeb5ac5af6237e3f02b26bc0e5de256b52db5b7 # Parent 8dc11dc385fe7c7fe637066e10ed11191ce5654d Add config-store example and update documentation diff -r 8dc11dc385fe -r 3aeb5ac5af62 doc/manual/source/attributes.rst --- a/doc/manual/source/attributes.rst Tue Aug 16 12:58:50 2011 -0700 +++ b/doc/manual/source/attributes.rst Tue Aug 16 15:49:05 2011 -0700 @@ -640,38 +640,67 @@ ConfigStore *********** -**Feedback requested:** This is an experimental feature of |ns3|. It is found -in ``src/config-store``. If you like this feature and -would like to provide feedback on it, please email us. +The ConfigStore is a specialized database for attribute values and +default values. Although it is a separately maintained module in +``src/config-store/`` directory, we document it here because of its +sole dependency on |ns3| core module and attributes. Values for |ns3| attributes can be stored in an ASCII or XML text file and loaded into a future simulation. This feature is known as the -|ns3| ConfigStore. The ConfigStore code is in ``src/config-store/model``. -It is still considered as unstable code, because we are seeking some -user feedback and experience with this. +|ns3| ConfigStore. We can explore this system by using an example from +``src/config-store/examples/config-store-save.cc``. -We can explore this system by using an example. Copy the ``csma-bridge.cc`` -file to the scratch directory::: - - cp examples/csma-bridge.cc scratch/ - ./waf - -Let's edit it to add the ConfigStore feature. First, add an include statement to -include the contrib module, and then add these lines::: +First, all users must include the following statement::: #include "ns3/config-store-module.h" - ... - int main (...) + +Next, this program adds a sample object A to show how the system +is extended::: + + class A : public Object { - // setup topology + public: + static TypeId GetTypeId (void) { + static TypeId tid = TypeId ("ns3::A") + .SetParent () + .AddAttribute ("TestInt16", "help text", + IntegerValue (-2), + MakeIntegerAccessor (&A::m_int16), + MakeIntegerChecker ()) + ; + return tid; + } + int16_t m_int16; + }; + + NS_OBJECT_ENSURE_REGISTERED (A); - // Invoke just before entering Simulator::Run () - ConfigStore config; - config.ConfigureDefaults (); - config.ConfigureAttributes (); +Next, we use the Config subsystem to override the defaults in a couple of +ways::: + + Config::SetDefault ("ns3::A::TestInt16", IntegerValue (-5)); + + Ptr a_obj = CreateObject (); + NS_ABORT_MSG_UNLESS (a_obj->m_int16 == -5, "Cannot set A's integer attribute via Config::SetDefault"); + + Ptr a2_obj = CreateObject (); + a2_obj->SetAttribute ("TestInt16", IntegerValue (-3)); + IntegerValue iv; + a2_obj->GetAttribute ("TestInt16", iv); + NS_ABORT_MSG_UNLESS (iv.Get () == -3, "Cannot set A's integer attribute via SetAttribute"); + +The next statement is necessary to make sure that (one of) the objects +created is rooted in the configuration namespace as an object instance. +This normally happens when you aggregate objects to ns3::Node or ns3::Channel +but here, since we are working at the core level, we need to create a +new root namespace object::: - Simulator::Run (); - } + Config::RegisterRootNamespaceObject (a2_obj); + +Next, we want to output the configuration store. The examples show how +to do it in two formats, XML and raw text. In practice, one should perform +this step just before calling ``Simulator::Run ()``; it will allow the +configuration to be saved just before running the simulation. There are three attributes that govern the behavior of the ConfigStore: "Mode", "Filename", and "FileFormat". The Mode (default "None") configures whether @@ -681,28 +710,88 @@ (default "RawText") governs whether the ConfigStore format is Xml or RawText format. -So, using the above modified program, try executing the following waf command -and :: +The example shows::: + + Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("output-attributes.xml")); + Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("Xml")); + Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save")); + ConfigStore outputConfig; + outputConfig.ConfigureDefaults (); + outputConfig.ConfigureAttributes (); + + // Output config store to txt format + Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("output-attributes.txt")); + Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("RawText")); + Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save")); + ConfigStore outputConfig2; + outputConfig2.ConfigureDefaults (); + outputConfig2.ConfigureAttributes (); + + Simulator::Run (); + + Simulator::Destroy (); + +After running, you can open the output-attributes.txt file and see::: - ./waf --command-template="%s --ns3::ConfigStore::Filename=csma-bridge-config.xml - --ns3::ConfigStore::Mode=Save --ns3::ConfigStore::FileFormat=Xml" --run scratch/csma-bridge + default ns3::RealtimeSimulatorImpl::SynchronizationMode "BestEffort" + default ns3::RealtimeSimulatorImpl::HardLimit "+100000000.0ns" + default ns3::PcapFileWrapper::CaptureSize "65535" + default ns3::PacketSocket::RcvBufSize "131072" + default ns3::ErrorModel::IsEnabled "true" + default ns3::RateErrorModel::ErrorUnit "EU_BYTE" + default ns3::RateErrorModel::ErrorRate "0" + default ns3::RateErrorModel::RanVar "Uniform:0:1" + default ns3::DropTailQueue::Mode "Packets" + default ns3::DropTailQueue::MaxPackets "100" + default ns3::DropTailQueue::MaxBytes "6553500" + default ns3::Application::StartTime "+0.0ns" + default ns3::Application::StopTime "+0.0ns" + default ns3::ConfigStore::Mode "Save" + default ns3::ConfigStore::Filename "output-attributes.txt" + default ns3::ConfigStore::FileFormat "RawText" + default ns3::A::TestInt16 "-5" + global RngSeed "1" + global RngRun "1" + global SimulatorImplementationType "ns3::DefaultSimulatorImpl" + global SchedulerType "ns3::MapScheduler" + global ChecksumEnabled "false" + value /$ns3::A/TestInt16 "-3" -After running, you can open the csma-bridge-config.xml file and it will -display the configuration that was applied to your simulation; e.g.:: +In the above, all of the default values for attributes for the core +module are shown. Then, all the values for the |ns3| global values +are recorded. Finally, the value of the instance of A that was rooted +in the configuration namespace is shown. In a real ns-3 program, many +more models, attributes, and defaults would be shown. + +An XML version also exists in ``output-attributes.xml``::: - - - - - - - - - - ... - + + + + + + + + + + + + + + + + + + + + + + + + + This file can be archived with your simulation script and output data. While it is possible to generate a sample config file and lightly edit it to @@ -796,4 +885,3 @@ * save a unique version number with date and time at start of file * save rng initial seed somewhere. * make each RandomVariable serialize its own initial seed and re-read it later -* add the default values diff -r 8dc11dc385fe -r 3aeb5ac5af62 src/config-store/doc/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/config-store/doc/README Tue Aug 16 15:49:05 2011 -0700 @@ -0,0 +1,2 @@ +The Sphinx documentation for config-store is maintained as a section +in doc/manual/source/attributes.rst diff -r 8dc11dc385fe -r 3aeb5ac5af62 src/config-store/examples/config-store-save.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/config-store/examples/config-store-save.cc Tue Aug 16 15:49:05 2011 -0700 @@ -0,0 +1,71 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +#include "ns3/core-module.h" +#include "ns3/config-store-module.h" + +#include + +using namespace ns3; + +class A : public Object +{ +public: + static TypeId GetTypeId (void) { + static TypeId tid = TypeId ("ns3::A") + .SetParent () + .AddAttribute ("TestInt16", "help text", + IntegerValue (-2), + MakeIntegerAccessor (&A::m_int16), + MakeIntegerChecker ()) + ; + return tid; + } + int16_t m_int16; +}; + +NS_OBJECT_ENSURE_REGISTERED (A); + +// Assign a new default value to A::TestInt16 (-5) +// Configure a TestInt16 value for a special instance of A (to -3) +// View the output from the config store +// +int main (int argc, char *argv[]) +{ + Config::SetDefault ("ns3::A::TestInt16", IntegerValue (-5)); + + Ptr a_obj = CreateObject (); + NS_ABORT_MSG_UNLESS (a_obj->m_int16 == -5, "Cannot set A's integer attribute via Config::SetDefault"); + + Ptr a2_obj = CreateObject (); + a2_obj->SetAttribute ("TestInt16", IntegerValue (-3)); + IntegerValue iv; + a2_obj->GetAttribute ("TestInt16", iv); + NS_ABORT_MSG_UNLESS (iv.Get () == -3, "Cannot set A's integer attribute via SetAttribute"); + + // These test objects are not rooted in any ns-3 configuration namespace. + // This is usually done automatically for ns3 nodes and channels, but + // we can establish a new root and anchor one of them there (note; we + // can't use two objects of the same type as roots). Rooting one of these + // is necessary for it to show up in the config namespace so that + // ConfigureAttributes() will work below. + Config::RegisterRootNamespaceObject (a2_obj); + + // Output config store to XML format + Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("output-attributes.xml")); + Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("Xml")); + Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save")); + ConfigStore outputConfig; + outputConfig.ConfigureDefaults (); + outputConfig.ConfigureAttributes (); + + // Output config store to txt format + Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("output-attributes.txt")); + Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("RawText")); + Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save")); + ConfigStore outputConfig2; + outputConfig2.ConfigureDefaults (); + outputConfig2.ConfigureAttributes (); + + Simulator::Run (); + + Simulator::Destroy (); +} diff -r 8dc11dc385fe -r 3aeb5ac5af62 src/config-store/examples/wscript --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/config-store/examples/wscript Tue Aug 16 15:49:05 2011 -0700 @@ -0,0 +1,6 @@ +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +def build(bld): + + obj = bld.create_ns3_program('config-store-save', ['core', 'config-store']) + obj.source = 'config-store-save.cc' diff -r 8dc11dc385fe -r 3aeb5ac5af62 src/config-store/test/examples-to-run.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/config-store/test/examples-to-run.py Tue Aug 16 15:49:05 2011 -0700 @@ -0,0 +1,12 @@ +#! /usr/bin/env python +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +# A list of C++ examples to run in order to ensure that they remain +# buildable and runnable over time. Each tuple in the list contains +# +# (example_name, do_run, do_valgrind_run). +# +# See test.py for more information. +cpp_examples = [ + ("config-store-save", "True", "True"), +] diff -r 8dc11dc385fe -r 3aeb5ac5af62 src/config-store/wscript --- a/src/config-store/wscript Tue Aug 16 12:58:50 2011 -0700 +++ b/src/config-store/wscript Tue Aug 16 15:49:05 2011 -0700 @@ -52,4 +52,7 @@ else: module.uselib = 'LIBXML2' + if bld.env['ENABLE_EXAMPLES']: + bld.add_subdirs('examples') + bld.ns3_python_bindings()