blob: a1dd69465a40794b3690d5346b5fe0c9cffdc597 [file] [log] [blame]
Junxiao Shi1f481fa2017-01-26 15:14:43 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2017, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#ifndef NFD_TESTS_TOOLS_NFDC_MOCK_NFD_MGMT_FIXTURE_HPP
27#define NFD_TESTS_TOOLS_NFDC_MOCK_NFD_MGMT_FIXTURE_HPP
28
29#include <ndn-cxx/util/dummy-client-face.hpp>
30
31#include "tests/test-common.hpp"
32#include "tests/identity-management-fixture.hpp"
33
34namespace nfd {
35namespace tools {
36namespace nfdc {
37namespace tests {
38
39using namespace nfd::tests;
40
41/** \brief fixture to emulate NFD management
42 */
43class MockNfdMgmtFixture : public IdentityManagementTimeFixture
44{
45protected:
46 MockNfdMgmtFixture()
47 : face(g_io, m_keyChain,
48 {true, false, bind(&MockNfdMgmtFixture::processEventsOverride, this, _1)})
49 {
50 face.onSendInterest.connect([=] (const Interest& interest) {
51 g_io.post([=] {
52 if (processInterest != nullptr) {
53 processInterest(interest);
54 }
55 });
56 });
57 }
58
59protected: // status fetching
60 /** \brief send an empty dataset in reply to StatusDataset request
61 * \param prefix dataset prefix without version and segment
62 * \pre Interest for dataset has been expressed, sendDataset has not been invoked
63 */
64 void
65 sendEmptyDataset(const Name& prefix)
66 {
67 this->sendDatasetReply(prefix, nullptr, 0);
68 }
69
70 /** \brief send one WireEncodable in reply to StatusDataset request
71 * \param prefix dataset prefix without version and segment
72 * \param payload payload block
73 * \note payload must fit in one Data
74 * \pre Interest for dataset has been expressed, sendDataset has not been invoked
75 */
76 template<typename T>
77 void
78 sendDataset(const Name& prefix, const T& payload)
79 {
80 BOOST_CONCEPT_ASSERT((ndn::WireEncodable<T>));
81
82 this->sendDatasetReply(prefix, payload.wireEncode());
83 }
84
85 /** \brief send two WireEncodables in reply to StatusDataset request
86 * \param prefix dataset prefix without version and segment
87 * \param payload1 first vector item
88 * \param payload2 second vector item
89 * \note all payloads must fit in one Data
90 * \pre Interest for dataset has been expressed, sendDataset has not been invoked
91 */
92 template<typename T1, typename T2>
93 void
94 sendDataset(const Name& prefix, const T1& payload1, const T2& payload2)
95 {
96 BOOST_CONCEPT_ASSERT((ndn::WireEncodable<T1>));
97 BOOST_CONCEPT_ASSERT((ndn::WireEncodable<T2>));
98
99 ndn::encoding::EncodingBuffer buffer;
100 payload2.wireEncode(buffer);
101 payload1.wireEncode(buffer);
102
103 this->sendDatasetReply(prefix, buffer.buf(), buffer.size());
104 }
105
106private:
107 virtual void
108 processEventsOverride(time::milliseconds timeout)
109 {
110 if (timeout <= time::milliseconds::zero()) {
111 // give enough time to finish execution
112 timeout = time::seconds(30);
113 }
114 this->advanceClocks(time::milliseconds(100), timeout);
115 }
116
117 /** \brief send a payload in reply to StatusDataset request
118 * \param name dataset prefix without version and segment
119 * \param contentArgs passed to Data::setContent
120 */
121 template<typename ...ContentArgs>
122 void
123 sendDatasetReply(Name name, ContentArgs&&... contentArgs)
124 {
125 name.appendVersion().appendSegment(0);
126
127 // These warnings assist in debugging when nfdc does not receive StatusDataset.
128 // They usually indicate a misspelled prefix or incorrect timing in the test case.
129 if (face.sentInterests.empty()) {
130 BOOST_WARN_MESSAGE(false, "no Interest expressed");
131 }
132 else {
133 BOOST_WARN_MESSAGE(face.sentInterests.back().getName().isPrefixOf(name),
134 "last Interest " << face.sentInterests.back().getName() <<
135 " cannot be satisfied by this Data " << name);
136 }
137
138 auto data = make_shared<Data>(name);
139 data->setFinalBlockId(name[-1]);
140 data->setContent(std::forward<ContentArgs>(contentArgs)...);
141 this->signDatasetReply(*data);
142 face.receive(*data);
143 }
144
145 virtual void
146 signDatasetReply(Data& data)
147 {
148 signData(data);
149 }
150
151protected:
152 ndn::util::DummyClientFace face;
153 std::function<void(const Interest&)> processInterest;
154};
155
156} // namespace tests
157} // namespace nfdc
158} // namespace tools
159} // namespace nfd
160
161#endif // NFD_TESTS_TOOLS_NFDC_MOCK_NFD_MGMT_FIXTURE_HPP