blob: e6ff7065d2e5d435f29d7de75d0ff0edcdafa638 [file] [log] [blame]
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#ifndef NFD_TESTS_MGMT_FACE_STATUS_PUBLISHER_COMMON_HPP
8#define NFD_TESTS_MGMT_FACE_STATUS_PUBLISHER_COMMON_HPP
9
10#include "mgmt/face-status-publisher.hpp"
11#include "mgmt/app-face.hpp"
12#include "mgmt/internal-face.hpp"
13#include "fw/forwarder.hpp"
14#include "../face/dummy-face.hpp"
15
16#include "tests/test-common.hpp"
17
18#include <ndn-cpp-dev/encoding/tlv.hpp>
19
20namespace nfd {
21namespace tests {
22
23class TestCountersFace : public DummyFace
24{
25public:
26
27 TestCountersFace()
28 {
29 }
30
31 virtual
32 ~TestCountersFace()
33 {
34 }
35
36 void
37 setCounters(FaceCounter inInterest,
38 FaceCounter inData,
39 FaceCounter outInterest,
40 FaceCounter outData)
41 {
42 FaceCounters& counters = getMutableCounters();
43 counters.getInInterest() = inInterest;
44 counters.getInData() = inData;
45 counters.getOutInterest() = outInterest;
46 counters.getOutData() = outData;
47 }
48
49
50};
51
52static inline uint64_t
53readNonNegativeIntegerType(const Block& block,
54 uint32_t type)
55{
56 if (block.type() == type)
57 {
58 return readNonNegativeInteger(block);
59 }
60 std::stringstream error;
61 error << "expected type " << type << " got " << block.type();
62 throw ndn::Tlv::Error(error.str());
63}
64
65static inline uint64_t
66checkedReadNonNegativeIntegerType(Block::element_const_iterator& i,
67 Block::element_const_iterator end,
68 uint32_t type)
69{
70 if (i != end)
71 {
72 const Block& block = *i;
73 ++i;
74 return readNonNegativeIntegerType(block, type);
75 }
76 throw ndn::Tlv::Error("Unexpected end of FaceStatus");
77}
78
79class FaceStatusPublisherFixture : public BaseFixture
80{
81public:
82
83 FaceStatusPublisherFixture()
84 : m_table(m_forwarder)
85 , m_face(make_shared<InternalFace>())
86 , m_publisher(m_table, m_face, "/localhost/nfd/FaceStatusPublisherFixture")
87 , m_finished(false)
88 {
89
90 }
91
92 virtual
93 ~FaceStatusPublisherFixture()
94 {
95
96 }
97
98 void
99 add(shared_ptr<Face> face)
100 {
101 m_table.add(face);
102 }
103
104 void
105 validateFaceStatus(const Block& status, const shared_ptr<Face>& reference)
106 {
107 const FaceCounters& counters = reference->getCounters();
108
109 FaceId faceId = INVALID_FACEID;
110 std::string uri;
111 FaceCounter inInterest = 0;
112 FaceCounter inData = 0;
113 FaceCounter outInterest = 0;
114 FaceCounter outData = 0;
115
116 status.parse();
117
118 for (Block::element_const_iterator i = status.elements_begin();
119 i != status.elements_end();
120 ++i)
121 {
122 // parse a full set of FaceStatus sub-blocks
123 faceId =
124 checkedReadNonNegativeIntegerType(i,
125 status.elements_end(),
126 ndn::tlv::nfd::FaceId);
127
128 BOOST_REQUIRE_EQUAL(faceId, reference->getId());
129
130 BOOST_REQUIRE(i->type() == ndn::tlv::nfd::Uri);
131
132 uri.append(reinterpret_cast<const char*>(i->value()), i->value_size());
133 ++i;
134
135 BOOST_REQUIRE(i != status.elements_end());
136
137 BOOST_REQUIRE_EQUAL(uri, reference->getUri().toString());
138
139 inInterest =
140 checkedReadNonNegativeIntegerType(i,
141 status.elements_end(),
142 ndn::tlv::nfd::TotalIncomingInterestCounter);
143
144 BOOST_REQUIRE_EQUAL(inInterest, counters.getInInterest());
145
146 inData =
147 checkedReadNonNegativeIntegerType(i,
148 status.elements_end(),
149 ndn::tlv::nfd::TotalIncomingDataCounter);
150
151 BOOST_REQUIRE_EQUAL(inData, counters.getInData());
152
153 outInterest =
154 checkedReadNonNegativeIntegerType(i,
155 status.elements_end(),
156 ndn::tlv::nfd::TotalOutgoingInterestCounter);
157 BOOST_REQUIRE_EQUAL(outInterest, counters.getOutInterest());
158
159 outData =
160 readNonNegativeIntegerType(*i,
161 ndn::tlv::nfd::TotalOutgoingDataCounter);
162
163 BOOST_REQUIRE_EQUAL(outData, counters.getOutData());
164 }
165 }
166
167 void
168 decodeFaceStatusBlock(const Data& data)
169 {
170 Block payload = data.getContent();
171
172 m_buffer.appendByteArray(payload.value(), payload.value_size());
173
174 uint64_t segmentNo = data.getName()[-1].toSegment();
175 if (data.getFinalBlockId() != data.getName()[-1])
176 {
177 return;
178 }
179
180 // wrap the Face Statuses in a single Content TLV for easy parsing
181 m_buffer.prependVarNumber(m_buffer.size());
182 m_buffer.prependVarNumber(ndn::Tlv::Content);
183
184 ndn::Block parser(m_buffer.buf(), m_buffer.size());
185 parser.parse();
186
187 BOOST_REQUIRE_EQUAL(parser.elements_size(), m_referenceFaces.size());
188
189 std::list<shared_ptr<Face> >::const_iterator iReference = m_referenceFaces.begin();
190 for (Block::element_const_iterator i = parser.elements_begin();
191 i != parser.elements_end();
192 ++i)
193 {
194 if (i->type() != ndn::tlv::nfd::FaceStatus)
195 {
196 BOOST_FAIL("expected face status, got type #" << i->type());
197 }
198 validateFaceStatus(*i, *iReference);
199 ++iReference;
200 }
201 m_finished = true;
202 }
203
204protected:
205 Forwarder m_forwarder;
206 FaceTable m_table;
207 shared_ptr<InternalFace> m_face;
208 FaceStatusPublisher m_publisher;
209 ndn::EncodingBuffer m_buffer;
210 std::list<shared_ptr<Face> > m_referenceFaces;
211
212protected:
213 bool m_finished;
214};
215
216} // namespace tests
217} // namespace nfd
218
219#endif // NFD_TESTS_MGMT_FACE_STATUS_PUBLISHER_COMMON_HPP