blob: 95ef1462b58c52469a7231a1f352b6bf9676d78e [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 Pesavento2c9d2ca2024-01-27 16:36:51 -05003 * Copyright (c) 2014-2024, 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
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040030namespace nfd::tools::nfdc::tests {
Junxiao Shi38f4ce92016-08-04 10:01:52 +000031
32const std::string STATUS_XML = stripXmlSpaces(R"XML(
33 <?xml version="1.0"?>
34 <nfdStatus xmlns="ndn:/localhost/nfd/status/1">
35 <module1/>
36 <module2/>
37 </nfdStatus>
38)XML");
39
40const std::string STATUS_TEXT = std::string(R"TEXT(
41module1
42module2
43)TEXT").substr(1);
44
45class DummyModule : public Module
46{
47public:
Davide Pesaventoa9e1ab22023-10-02 22:10:45 -040048 DummyModule(const std::string& moduleName, boost::asio::io_context& io)
Junxiao Shi38f4ce92016-08-04 10:01:52 +000049 : m_moduleName(moduleName)
Davide Pesavento3dade002019-03-19 11:29:56 -060050 , m_scheduler(io)
Junxiao Shi38f4ce92016-08-04 10:01:52 +000051 , m_res(0)
Davide Pesavento14e71f02019-03-28 17:35:25 -040052 , m_delay(1_ms)
Junxiao Shi38f4ce92016-08-04 10:01:52 +000053 {
54 }
55
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040056 /** \brief Cause fetchStatus() to succeed or fail.
Junxiao Shi38f4ce92016-08-04 10:01:52 +000057 * \param res zero to succeed, non-zero to fail with specific code
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040058 * \param delay duration from fetchStatus() invocation to succeed or fail; must be positive
Junxiao Shi38f4ce92016-08-04 10:01:52 +000059 */
60 void
61 setResult(uint32_t res, time::nanoseconds delay)
62 {
Davide Pesavento63b3ae82023-03-24 23:53:24 -040063 BOOST_ASSERT(delay > 0_ns);
Junxiao Shi38f4ce92016-08-04 10:01:52 +000064 m_res = res;
65 m_delay = delay;
66 }
67
Davide Pesavento87fc0f82018-04-11 23:43:51 -040068 void
Davide Pesavento63b3ae82023-03-24 23:53:24 -040069 fetchStatus(ndn::nfd::Controller&,
Davide Pesavento87fc0f82018-04-11 23:43:51 -040070 const std::function<void()>& onSuccess,
Davide Pesavento63b3ae82023-03-24 23:53:24 -040071 const ndn::nfd::DatasetFailureCallback& onFailure,
Davide Pesavento3dade002019-03-19 11:29:56 -060072 const CommandOptions&) final
Junxiao Shi38f4ce92016-08-04 10:01:52 +000073 {
74 ++nFetchStatusCalls;
Davide Pesavento3dade002019-03-19 11:29:56 -060075 m_scheduler.schedule(m_delay, [=] {
Junxiao Shi38f4ce92016-08-04 10:01:52 +000076 if (m_res == 0) {
77 onSuccess();
78 }
79 else {
Davide Pesavento2c9d2ca2024-01-27 16:36:51 -050080 onFailure(m_res, m_moduleName + " fails with code " + std::to_string(m_res));
Junxiao Shi38f4ce92016-08-04 10:01:52 +000081 }
82 });
83 }
84
Davide Pesavento87fc0f82018-04-11 23:43:51 -040085 void
86 formatStatusXml(std::ostream& os) const final
Junxiao Shi38f4ce92016-08-04 10:01:52 +000087 {
88 os << '<' << m_moduleName << "/>";
89 }
90
Davide Pesavento87fc0f82018-04-11 23:43:51 -040091 void
92 formatStatusText(std::ostream& os) const final
Junxiao Shi38f4ce92016-08-04 10:01:52 +000093 {
94 os << m_moduleName << '\n';
95 }
96
97public:
98 int nFetchStatusCalls = 0;
99
100private:
101 std::string m_moduleName;
Davide Pesavento2c9d2ca2024-01-27 16:36:51 -0500102 ndn::Scheduler m_scheduler;
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000103 uint32_t m_res;
104 time::nanoseconds m_delay;
105};
106
107class StatusReportTester : public StatusReport
108{
109private:
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400110 void
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000111 processEvents(Face&) override
112 {
113 processEventsFunc();
114 }
115
116public:
117 std::function<void()> processEventsFunc;
118};
119
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400120class StatusReportModulesFixture : public nfd::tests::IoFixture, public nfd::tests::KeyChainFixture
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000121{
122protected:
123 StatusReportModulesFixture()
Davide Pesavento21353752020-11-20 00:43:44 -0500124 : face(m_io, m_keyChain)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000125 , controller(face, m_keyChain, validator)
126 , res(0)
127 {
128 }
129
130 DummyModule&
131 addModule(const std::string& moduleName)
132 {
Davide Pesaventob7703ad2019-03-23 21:12:56 -0400133 report.sections.push_back(make_unique<DummyModule>(moduleName, m_io));
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000134 return static_cast<DummyModule&>(*report.sections.back());
135 }
136
137 void
138 collect(time::nanoseconds tick, size_t nTicks)
139 {
Davide Pesavento21353752020-11-20 00:43:44 -0500140 report.processEventsFunc = [=] { advanceClocks(tick, nTicks); };
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000141 res = report.collect(face, m_keyChain, validator, CommandOptions());
142
143 if (res == 0) {
144 statusXml.str("");
145 report.formatXml(statusXml);
146 statusText.str("");
147 report.formatText(statusText);
148 }
149 }
150
151protected:
Davide Pesaventoae430302023-05-11 01:42:46 -0400152 ndn::DummyClientFace face;
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000153 ValidatorNull validator;
Davide Pesavento63b3ae82023-03-24 23:53:24 -0400154 ndn::nfd::Controller controller;
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000155 StatusReportTester report;
156
157 uint32_t res;
158 output_test_stream statusXml;
159 output_test_stream statusText;
160};
161
Junxiao Shi331ade72016-08-19 14:07:19 +0000162BOOST_AUTO_TEST_SUITE(Nfdc)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000163BOOST_FIXTURE_TEST_SUITE(TestStatusReport, StatusReportModulesFixture)
164
165BOOST_AUTO_TEST_CASE(Normal)
166{
167 DummyModule& m1 = addModule("module1");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400168 m1.setResult(0, 10_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000169 DummyModule& m2 = addModule("module2");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400170 m2.setResult(0, 20_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000171
Davide Pesavento14e71f02019-03-28 17:35:25 -0400172 this->collect(5_ms, 6);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000173
174 BOOST_CHECK_EQUAL(m1.nFetchStatusCalls, 1);
175 BOOST_CHECK_EQUAL(m2.nFetchStatusCalls, 1);
176
177 BOOST_CHECK_EQUAL(res, 0);
178 BOOST_CHECK(statusXml.is_equal(STATUS_XML));
179 BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
180}
181
182BOOST_AUTO_TEST_CASE(Reorder)
183{
184 DummyModule& m1 = addModule("module1");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400185 m1.setResult(0, 20_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000186 DummyModule& m2 = addModule("module2");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400187 m2.setResult(0, 10_ms); // module2 completes earlier than module1
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000188
Davide Pesavento14e71f02019-03-28 17:35:25 -0400189 this->collect(5_ms, 6);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000190
191 BOOST_CHECK_EQUAL(res, 0);
192 BOOST_CHECK(statusXml.is_equal(STATUS_XML)); // output is still in order
193 BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
194}
195
196BOOST_AUTO_TEST_CASE(Error)
197{
198 DummyModule& m1 = addModule("module1");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400199 m1.setResult(0, 20_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000200 DummyModule& m2 = addModule("module2");
Davide Pesavento14e71f02019-03-28 17:35:25 -0400201 m2.setResult(500, 10_ms);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000202
Davide Pesavento14e71f02019-03-28 17:35:25 -0400203 this->collect(5_ms, 6);
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000204
205 BOOST_CHECK_EQUAL(res, 1000500);
206}
207
Junxiao Shi8c39bf02016-08-28 23:54:13 +0000208BOOST_AUTO_TEST_SUITE_END() // TestStatusReport
Junxiao Shi331ade72016-08-19 14:07:19 +0000209BOOST_AUTO_TEST_SUITE_END() // Nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000210
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400211} // namespace nfd::tools::nfdc::tests