blob: 2ab5c3e6cf9e86117f1ef1dcc9f434e0e13f3628 [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 Pesavento21353752020-11-20 00:43:44 -05003 * Copyright (c) 2014-2020, 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 Pesavento21353752020-11-20 00:43:44 -0500123class StatusReportModulesFixture : public IoFixture, public KeyChainFixture
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000124{
125protected:
126 StatusReportModulesFixture()
Davide Pesavento21353752020-11-20 00:43:44 -0500127 : face(m_io, m_keyChain)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000128 , controller(face, m_keyChain, validator)
129 , res(0)
130 {
131 }
132
133 DummyModule&
134 addModule(const std::string& moduleName)
135 {
Davide Pesaventob7703ad2019-03-23 21:12:56 -0400136 report.sections.push_back(make_unique<DummyModule>(moduleName, m_io));
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000137 return static_cast<DummyModule&>(*report.sections.back());
138 }
139
140 void
141 collect(time::nanoseconds tick, size_t nTicks)
142 {
Davide Pesavento21353752020-11-20 00:43:44 -0500143 report.processEventsFunc = [=] { advanceClocks(tick, nTicks); };
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000144 res = report.collect(face, m_keyChain, validator, CommandOptions());
145
146 if (res == 0) {
147 statusXml.str("");
148 report.formatXml(statusXml);
149 statusText.str("");
150 report.formatText(statusText);
151 }
152 }
153
154protected:
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000155 ndn::util::DummyClientFace face;
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000156 ValidatorNull validator;
157 Controller controller;
158 StatusReportTester report;
159
160 uint32_t res;
161 output_test_stream statusXml;
162 output_test_stream statusText;
163};
164
Junxiao Shi331ade72016-08-19 14:07:19 +0000165BOOST_AUTO_TEST_SUITE(Nfdc)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000166BOOST_FIXTURE_TEST_SUITE(TestStatusReport, StatusReportModulesFixture)
167
168BOOST_AUTO_TEST_CASE(Normal)
169{
170 DummyModule& m1 = addModule("module1");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400171 m1.setResult(0, 10_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000172 DummyModule& m2 = addModule("module2");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400173 m2.setResult(0, 20_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000174
Davide Pesavento14e71f02019-03-28 17:35:25 -0400175 this->collect(5_ms, 6);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000176
177 BOOST_CHECK_EQUAL(m1.nFetchStatusCalls, 1);
178 BOOST_CHECK_EQUAL(m2.nFetchStatusCalls, 1);
179
180 BOOST_CHECK_EQUAL(res, 0);
181 BOOST_CHECK(statusXml.is_equal(STATUS_XML));
182 BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
183}
184
185BOOST_AUTO_TEST_CASE(Reorder)
186{
187 DummyModule& m1 = addModule("module1");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400188 m1.setResult(0, 20_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000189 DummyModule& m2 = addModule("module2");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400190 m2.setResult(0, 10_ms); // module2 completes earlier than module1
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000191
Davide Pesavento14e71f02019-03-28 17:35:25 -0400192 this->collect(5_ms, 6);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000193
194 BOOST_CHECK_EQUAL(res, 0);
195 BOOST_CHECK(statusXml.is_equal(STATUS_XML)); // output is still in order
196 BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
197}
198
199BOOST_AUTO_TEST_CASE(Error)
200{
201 DummyModule& m1 = addModule("module1");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400202 m1.setResult(0, 20_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000203 DummyModule& m2 = addModule("module2");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400204 m2.setResult(500, 10_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000205
Davide Pesavento14e71f02019-03-28 17:35:25 -0400206 this->collect(5_ms, 6);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000207
208 BOOST_CHECK_EQUAL(res, 1000500);
209}
210
Junxiao Shi8c39bf02016-08-28 23:54:13 +0000211BOOST_AUTO_TEST_SUITE_END() // TestStatusReport
Junxiao Shi331ade72016-08-19 14:07:19 +0000212BOOST_AUTO_TEST_SUITE_END() // Nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000213
214} // namespace tests
Junxiao Shi331ade72016-08-19 14:07:19 +0000215} // namespace nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000216} // namespace tools
217} // namespace nfd