blob: 5041fb3f307cd5202db1951a067f88a5f5c39a9f [file] [log] [blame]
Junxiao Shi38f4ce92016-08-04 10:01:52 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento87fc0f82018-04-11 23:43:51 -04002/*
Davide Pesavento3dade002019-03-19 11:29:56 -06003 * Copyright (c) 2014-2019, Regents of the University of California,
Junxiao Shi38f4ce92016-08-04 10:01:52 +00004 * 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
Junxiao Shi1f481fa2017-01-26 15:14:43 +000028#include "status-fixture.hpp"
Junxiao Shi38f4ce92016-08-04 10:01:52 +000029
30namespace nfd {
31namespace tools {
Junxiao Shi331ade72016-08-19 14:07:19 +000032namespace nfdc {
Junxiao Shi38f4ce92016-08-04 10:01:52 +000033namespace tests {
34
35const std::string STATUS_XML = stripXmlSpaces(R"XML(
36 <?xml version="1.0"?>
37 <nfdStatus xmlns="ndn:/localhost/nfd/status/1">
38 <module1/>
39 <module2/>
40 </nfdStatus>
41)XML");
42
43const std::string STATUS_TEXT = std::string(R"TEXT(
44module1
45module2
46)TEXT").substr(1);
47
48class DummyModule : public Module
49{
50public:
Davide Pesavento3dade002019-03-19 11:29:56 -060051 DummyModule(const std::string& moduleName, boost::asio::io_service& io)
Junxiao Shi38f4ce92016-08-04 10:01:52 +000052 : m_moduleName(moduleName)
Davide Pesavento3dade002019-03-19 11:29:56 -060053 , m_scheduler(io)
Junxiao Shi38f4ce92016-08-04 10:01:52 +000054 , m_res(0)
Davide Pesavento14e71f02019-03-28 17:35:25 -040055 , m_delay(1_ms)
Junxiao Shi38f4ce92016-08-04 10:01:52 +000056 {
57 }
58
59 /** \brief cause fetchStatus to succeed or fail
60 * \param res zero to succeed, non-zero to fail with specific code
61 * \param delay duration from fetchStatus invocation to succeed or fail; must be positive
62 */
63 void
64 setResult(uint32_t res, time::nanoseconds delay)
65 {
66 BOOST_ASSERT(delay > time::nanoseconds::zero());
67 m_res = res;
68 m_delay = delay;
69 }
70
Davide Pesavento87fc0f82018-04-11 23:43:51 -040071 void
Davide Pesavento3dade002019-03-19 11:29:56 -060072 fetchStatus(Controller&,
Davide Pesavento87fc0f82018-04-11 23:43:51 -040073 const std::function<void()>& onSuccess,
Junxiao Shi29b41282016-08-22 03:47:02 +000074 const Controller::DatasetFailCallback& onFailure,
Davide Pesavento3dade002019-03-19 11:29:56 -060075 const CommandOptions&) final
Junxiao Shi38f4ce92016-08-04 10:01:52 +000076 {
77 ++nFetchStatusCalls;
Davide Pesavento3dade002019-03-19 11:29:56 -060078 m_scheduler.schedule(m_delay, [=] {
Junxiao Shi38f4ce92016-08-04 10:01:52 +000079 if (m_res == 0) {
80 onSuccess();
81 }
82 else {
83 onFailure(m_res, m_moduleName + " fails with code " + to_string(m_res));
84 }
85 });
86 }
87
Davide Pesavento87fc0f82018-04-11 23:43:51 -040088 void
89 formatStatusXml(std::ostream& os) const final
Junxiao Shi38f4ce92016-08-04 10:01:52 +000090 {
91 os << '<' << m_moduleName << "/>";
92 }
93
Davide Pesavento87fc0f82018-04-11 23:43:51 -040094 void
95 formatStatusText(std::ostream& os) const final
Junxiao Shi38f4ce92016-08-04 10:01:52 +000096 {
97 os << m_moduleName << '\n';
98 }
99
100public:
101 int nFetchStatusCalls = 0;
102
103private:
104 std::string m_moduleName;
Davide Pesavento3dade002019-03-19 11:29:56 -0600105 Scheduler m_scheduler;
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000106 uint32_t m_res;
107 time::nanoseconds m_delay;
108};
109
110class StatusReportTester : public StatusReport
111{
112private:
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400113 void
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000114 processEvents(Face&) override
115 {
116 processEventsFunc();
117 }
118
119public:
120 std::function<void()> processEventsFunc;
121};
122
Davide Pesaventob7703ad2019-03-23 21:12:56 -0400123class StatusReportModulesFixture : public ClockFixture, public KeyChainFixture
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000124{
125protected:
126 StatusReportModulesFixture()
Davide Pesaventob7703ad2019-03-23 21:12:56 -0400127 : ClockFixture(m_io)
128 , face(m_io, m_keyChain)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000129 , controller(face, m_keyChain, validator)
130 , res(0)
131 {
132 }
133
134 DummyModule&
135 addModule(const std::string& moduleName)
136 {
Davide Pesaventob7703ad2019-03-23 21:12:56 -0400137 report.sections.push_back(make_unique<DummyModule>(moduleName, m_io));
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000138 return static_cast<DummyModule&>(*report.sections.back());
139 }
140
141 void
142 collect(time::nanoseconds tick, size_t nTicks)
143 {
144 report.processEventsFunc = [=] {
145 this->advanceClocks(tick, nTicks);
146 };
147 res = report.collect(face, m_keyChain, validator, CommandOptions());
148
149 if (res == 0) {
150 statusXml.str("");
151 report.formatXml(statusXml);
152 statusText.str("");
153 report.formatText(statusText);
154 }
155 }
156
Davide Pesaventob7703ad2019-03-23 21:12:56 -0400157private:
158 boost::asio::io_service m_io;
159
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000160protected:
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000161 ndn::util::DummyClientFace face;
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000162 ValidatorNull validator;
163 Controller controller;
164 StatusReportTester report;
165
166 uint32_t res;
167 output_test_stream statusXml;
168 output_test_stream statusText;
169};
170
Junxiao Shi331ade72016-08-19 14:07:19 +0000171BOOST_AUTO_TEST_SUITE(Nfdc)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000172BOOST_FIXTURE_TEST_SUITE(TestStatusReport, StatusReportModulesFixture)
173
174BOOST_AUTO_TEST_CASE(Normal)
175{
176 DummyModule& m1 = addModule("module1");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400177 m1.setResult(0, 10_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000178 DummyModule& m2 = addModule("module2");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400179 m2.setResult(0, 20_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000180
Davide Pesavento14e71f02019-03-28 17:35:25 -0400181 this->collect(5_ms, 6);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000182
183 BOOST_CHECK_EQUAL(m1.nFetchStatusCalls, 1);
184 BOOST_CHECK_EQUAL(m2.nFetchStatusCalls, 1);
185
186 BOOST_CHECK_EQUAL(res, 0);
187 BOOST_CHECK(statusXml.is_equal(STATUS_XML));
188 BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
189}
190
191BOOST_AUTO_TEST_CASE(Reorder)
192{
193 DummyModule& m1 = addModule("module1");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400194 m1.setResult(0, 20_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000195 DummyModule& m2 = addModule("module2");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400196 m2.setResult(0, 10_ms); // module2 completes earlier than module1
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000197
Davide Pesavento14e71f02019-03-28 17:35:25 -0400198 this->collect(5_ms, 6);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000199
200 BOOST_CHECK_EQUAL(res, 0);
201 BOOST_CHECK(statusXml.is_equal(STATUS_XML)); // output is still in order
202 BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
203}
204
205BOOST_AUTO_TEST_CASE(Error)
206{
207 DummyModule& m1 = addModule("module1");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400208 m1.setResult(0, 20_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000209 DummyModule& m2 = addModule("module2");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400210 m2.setResult(500, 10_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000211
Davide Pesavento14e71f02019-03-28 17:35:25 -0400212 this->collect(5_ms, 6);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000213
214 BOOST_CHECK_EQUAL(res, 1000500);
215}
216
Junxiao Shi8c39bf02016-08-28 23:54:13 +0000217BOOST_AUTO_TEST_SUITE_END() // TestStatusReport
Junxiao Shi331ade72016-08-19 14:07:19 +0000218BOOST_AUTO_TEST_SUITE_END() // Nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000219
220} // namespace tests
Junxiao Shi331ade72016-08-19 14:07:19 +0000221} // namespace nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000222} // namespace tools
223} // namespace nfd