blob: c3637a319353b5ba10f93a186206ff2940f2f63d [file] [log] [blame]
Junxiao Shi38f4ce92016-08-04 10:01:52 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2016, 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
Junxiao Shi331ade72016-08-19 14:07:19 +000026#include "nfdc/status-report.hpp"
Junxiao Shi38f4ce92016-08-04 10:01:52 +000027#include "core/scheduler.hpp"
28
29#include "module-fixture.hpp"
30
31namespace nfd {
32namespace tools {
Junxiao Shi331ade72016-08-19 14:07:19 +000033namespace nfdc {
Junxiao Shi38f4ce92016-08-04 10:01:52 +000034namespace tests {
35
36const std::string STATUS_XML = stripXmlSpaces(R"XML(
37 <?xml version="1.0"?>
38 <nfdStatus xmlns="ndn:/localhost/nfd/status/1">
39 <module1/>
40 <module2/>
41 </nfdStatus>
42)XML");
43
44const std::string STATUS_TEXT = std::string(R"TEXT(
45module1
46module2
47)TEXT").substr(1);
48
49class DummyModule : public Module
50{
51public:
52 explicit
53 DummyModule(const std::string& moduleName)
54 : m_moduleName(moduleName)
55 , m_res(0)
56 , m_delay(time::milliseconds(1))
57 {
58 }
59
60 /** \brief cause fetchStatus to succeed or fail
61 * \param res zero to succeed, non-zero to fail with specific code
62 * \param delay duration from fetchStatus invocation to succeed or fail; must be positive
63 */
64 void
65 setResult(uint32_t res, time::nanoseconds delay)
66 {
67 BOOST_ASSERT(delay > time::nanoseconds::zero());
68 m_res = res;
69 m_delay = delay;
70 }
71
72 virtual void
73 fetchStatus(Controller& controller,
74 const function<void()>& onSuccess,
Junxiao Shi29b41282016-08-22 03:47:02 +000075 const Controller::DatasetFailCallback& onFailure,
Junxiao Shi38f4ce92016-08-04 10:01:52 +000076 const CommandOptions& options) override
77 {
78 ++nFetchStatusCalls;
79 scheduler::schedule(m_delay, [=] {
80 if (m_res == 0) {
81 onSuccess();
82 }
83 else {
84 onFailure(m_res, m_moduleName + " fails with code " + to_string(m_res));
85 }
86 });
87 }
88
89 virtual void
90 formatStatusXml(std::ostream& os) const override
91 {
92 os << '<' << m_moduleName << "/>";
93 }
94
95 virtual void
96 formatStatusText(std::ostream& os) const override
97 {
98 os << m_moduleName << '\n';
99 }
100
101public:
102 int nFetchStatusCalls = 0;
103
104private:
105 std::string m_moduleName;
106 uint32_t m_res;
107 time::nanoseconds m_delay;
108};
109
110class StatusReportTester : public StatusReport
111{
112private:
113 virtual void
114 processEvents(Face&) override
115 {
116 processEventsFunc();
117 }
118
119public:
120 std::function<void()> processEventsFunc;
121};
122
123class StatusReportModulesFixture : public IdentityManagementTimeFixture
124{
125protected:
126 StatusReportModulesFixture()
127 : face(g_io, m_keyChain)
128 , controller(face, m_keyChain, validator)
129 , res(0)
130 {
131 }
132
133 DummyModule&
134 addModule(const std::string& moduleName)
135 {
136 report.sections.push_back(make_unique<DummyModule>(moduleName));
137 return static_cast<DummyModule&>(*report.sections.back());
138 }
139
140 void
141 collect(time::nanoseconds tick, size_t nTicks)
142 {
143 report.processEventsFunc = [=] {
144 this->advanceClocks(tick, nTicks);
145 };
146 res = report.collect(face, m_keyChain, validator, CommandOptions());
147
148 if (res == 0) {
149 statusXml.str("");
150 report.formatXml(statusXml);
151 statusText.str("");
152 report.formatText(statusText);
153 }
154 }
155
156protected:
157 DummyClientFace face;
158 ValidatorNull validator;
159 Controller controller;
160 StatusReportTester report;
161
162 uint32_t res;
163 output_test_stream statusXml;
164 output_test_stream statusText;
165};
166
167
Junxiao Shi331ade72016-08-19 14:07:19 +0000168BOOST_AUTO_TEST_SUITE(Nfdc)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000169BOOST_FIXTURE_TEST_SUITE(TestStatusReport, StatusReportModulesFixture)
170
171BOOST_AUTO_TEST_CASE(Normal)
172{
173 DummyModule& m1 = addModule("module1");
174 m1.setResult(0, time::milliseconds(10));
175 DummyModule& m2 = addModule("module2");
176 m2.setResult(0, time::milliseconds(20));
177
178 this->collect(time::milliseconds(5), 6);
179
180 BOOST_CHECK_EQUAL(m1.nFetchStatusCalls, 1);
181 BOOST_CHECK_EQUAL(m2.nFetchStatusCalls, 1);
182
183 BOOST_CHECK_EQUAL(res, 0);
184 BOOST_CHECK(statusXml.is_equal(STATUS_XML));
185 BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
186}
187
188BOOST_AUTO_TEST_CASE(Reorder)
189{
190 DummyModule& m1 = addModule("module1");
191 m1.setResult(0, time::milliseconds(20));
192 DummyModule& m2 = addModule("module2");
193 m2.setResult(0, time::milliseconds(10)); // module2 completes earlier than module1
194
195 this->collect(time::milliseconds(5), 6);
196
197 BOOST_CHECK_EQUAL(res, 0);
198 BOOST_CHECK(statusXml.is_equal(STATUS_XML)); // output is still in order
199 BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
200}
201
202BOOST_AUTO_TEST_CASE(Error)
203{
204 DummyModule& m1 = addModule("module1");
205 m1.setResult(0, time::milliseconds(20));
206 DummyModule& m2 = addModule("module2");
207 m2.setResult(500, time::milliseconds(10));
208
209 this->collect(time::milliseconds(5), 6);
210
211 BOOST_CHECK_EQUAL(res, 1000500);
212}
213
Junxiao Shi8c39bf02016-08-28 23:54:13 +0000214BOOST_AUTO_TEST_SUITE_END() // TestStatusReport
Junxiao Shi331ade72016-08-19 14:07:19 +0000215BOOST_AUTO_TEST_SUITE_END() // Nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000216
217} // namespace tests
Junxiao Shi331ade72016-08-19 14:07:19 +0000218} // namespace nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000219} // namespace tools
220} // namespace nfd