blob: 3e42d1c8ba1663d39da1d1a98257941ae9e9ccab [file] [log] [blame]
Yanbiao Li6704a4a2015-08-19 16:30:16 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi332783b2018-02-04 23:52:46 +00002/*
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -04003 * Copyright (c) 2014-2022, Regents of the University of California,
Yanbiao Li6704a4a2015-08-19 16:30:16 -07004 * 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#include "mgmt/strategy-choice-manager.hpp"
Yanbiao Li6704a4a2015-08-19 16:30:16 -070027#include "table/strategy-choice.hpp"
Junxiao Shia49a1ab2016-07-15 18:24:36 +000028
Davide Pesavento78ddcab2019-02-28 22:00:03 -050029#include "manager-common-fixture.hpp"
30#include "tests/daemon/fw/dummy-strategy.hpp"
Davide Pesavento28181322018-11-08 16:44:50 -050031
Junxiao Shi25c6ce42016-09-09 13:49:59 +000032#include <ndn-cxx/mgmt/nfd/strategy-choice.hpp>
Yanbiao Li6704a4a2015-08-19 16:30:16 -070033
34namespace nfd {
35namespace tests {
36
Davide Pesavento78ddcab2019-02-28 22:00:03 -050037class StrategyChoiceManagerFixture : public ManagerFixtureWithAuthenticator
Yanbiao Li6704a4a2015-08-19 16:30:16 -070038{
39public:
40 StrategyChoiceManagerFixture()
Junxiao Shi7d30d852017-01-22 03:29:26 +000041 : sc(m_forwarder.getStrategyChoice())
42 , manager(sc, m_dispatcher, *m_authenticator)
Eric Newberry358414d2021-03-21 20:56:42 -070043 , strategyNameP(Name("/strategy-choice-manager-P").appendVersion(2))
Yanbiao Li6704a4a2015-08-19 16:30:16 -070044 {
Junxiao Shi7d30d852017-01-22 03:29:26 +000045 VersionedDummyStrategy<2>::registerAs(strategyNameP);
46
Junxiao Shi9ddf1b52016-08-22 03:58:55 +000047 setTopPrefix();
Yanbiao Lidf846e52016-01-30 21:53:47 -080048 setPrivilege("strategy-choice");
Yanbiao Li6704a4a2015-08-19 16:30:16 -070049 }
50
51public:
Junxiao Shi7d30d852017-01-22 03:29:26 +000052 /** \return whether exact-match StrategyChoice entry exists
53 */
54 bool
55 hasEntry(const Name& name) const
Yanbiao Li6704a4a2015-08-19 16:30:16 -070056 {
Junxiao Shi7d30d852017-01-22 03:29:26 +000057 return sc.get(name).first;
Yanbiao Li6704a4a2015-08-19 16:30:16 -070058 }
59
Junxiao Shi7d30d852017-01-22 03:29:26 +000060 /** \return strategy instance name from an exact-match StrategyChoice entry
61 */
62 Name
63 getInstanceName(const Name& name) const
Yanbiao Li6704a4a2015-08-19 16:30:16 -070064 {
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040065 auto [hasEntry, instanceName] = sc.get(name);
66 return hasEntry ? instanceName : Name("/no-StrategyChoice-entry-at").append(name);
Yanbiao Li6704a4a2015-08-19 16:30:16 -070067 }
68
69protected:
Junxiao Shi7d30d852017-01-22 03:29:26 +000070 StrategyChoice& sc;
71 StrategyChoiceManager manager;
72
73 const Name strategyNameP;
Yanbiao Li6704a4a2015-08-19 16:30:16 -070074};
75
Davide Pesavento97210d52016-10-14 15:45:48 +020076BOOST_AUTO_TEST_SUITE(Mgmt)
77BOOST_FIXTURE_TEST_SUITE(TestStrategyChoiceManager, StrategyChoiceManagerFixture)
Yanbiao Li6704a4a2015-08-19 16:30:16 -070078
Junxiao Shi7d30d852017-01-22 03:29:26 +000079BOOST_AUTO_TEST_CASE(SetSuccess)
Yanbiao Li6704a4a2015-08-19 16:30:16 -070080{
Junxiao Shi7d30d852017-01-22 03:29:26 +000081 ControlParameters reqParams;
82 reqParams.setName("/A")
83 .setStrategy(strategyNameP.getPrefix(-1)); // use unversioned strategy name in request
84 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/set", reqParams);
85 receiveInterest(req);
Yanbiao Li6704a4a2015-08-19 16:30:16 -070086
Junxiao Shi7d30d852017-01-22 03:29:26 +000087 ControlParameters expectedParams;
88 expectedParams.setName("/A")
89 .setStrategy(strategyNameP); // response should have versioned strategy name
90 ControlResponse expectedResp;
91 expectedResp.setCode(200)
92 .setText("OK")
93 .setBody(expectedParams.wireEncode());
Junxiao Shi8a1f1702017-07-03 00:05:08 +000094 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Yanbiao Li6704a4a2015-08-19 16:30:16 -070095 CheckResponseResult::OK);
96
Junxiao Shi7d30d852017-01-22 03:29:26 +000097 BOOST_CHECK_EQUAL(getInstanceName("/A"), strategyNameP);
Yanbiao Li6704a4a2015-08-19 16:30:16 -070098
Junxiao Shi7d30d852017-01-22 03:29:26 +000099 // Strategy versioning and parameters are not tested here because they are covered by
100 // Table/TestStrategyChoice test suite.
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700101}
102
Junxiao Shi7d30d852017-01-22 03:29:26 +0000103BOOST_AUTO_TEST_CASE(SetUnknownStrategy)
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700104{
Junxiao Shi7d30d852017-01-22 03:29:26 +0000105 ControlParameters reqParams;
106 reqParams.setName("/A")
107 .setStrategy("/strategy-choice-manager-unknown");
108 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/set", reqParams);
109 receiveInterest(req);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700110
Junxiao Shi7d30d852017-01-22 03:29:26 +0000111 ControlResponse expectedResp;
112 expectedResp.setCode(404)
113 .setText("Strategy not registered");
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000114 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700115 CheckResponseResult::OK);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700116
Junxiao Shi7d30d852017-01-22 03:29:26 +0000117 BOOST_CHECK_EQUAL(hasEntry("/A"), false);
118}
119
Junxiao Shi332783b2018-02-04 23:52:46 +0000120BOOST_AUTO_TEST_CASE(SetNameTooLong)
121{
122 Name prefix;
Davide Pesavento2cae8ca2019-04-18 20:48:05 -0400123 while (prefix.size() <= NameTree::getMaxDepth()) {
Junxiao Shi332783b2018-02-04 23:52:46 +0000124 prefix.append("A");
125 }
126 ControlParameters reqParams;
127 reqParams.setName(prefix)
128 .setStrategy(strategyNameP);
129 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/set", reqParams);
130 receiveInterest(req);
131
132 ControlResponse expectedResp;
133 expectedResp.setCode(414)
134 .setText("Prefix has too many components (limit is " +
135 to_string(NameTree::getMaxDepth()) + ")");
136 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
137 CheckResponseResult::OK);
138
139 BOOST_CHECK_EQUAL(hasEntry(prefix), false);
140}
141
Junxiao Shi7d30d852017-01-22 03:29:26 +0000142BOOST_AUTO_TEST_CASE(UnsetSuccess)
143{
144 auto insertRes = sc.insert("/A", strategyNameP);
145 BOOST_REQUIRE(insertRes);
146
147 ControlParameters reqParams;
148 reqParams.setName("/A");
149 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/unset", reqParams);
150 receiveInterest(req);
151
152 ControlParameters expectedParams(reqParams);
153 ControlResponse expectedResp;
154 expectedResp.setCode(200)
155 .setText("OK")
156 .setBody(expectedParams.wireEncode());
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000157 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700158 CheckResponseResult::OK);
Junxiao Shi7d30d852017-01-22 03:29:26 +0000159
160 BOOST_CHECK_EQUAL(hasEntry("/A"), false);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700161}
162
Junxiao Shi7d30d852017-01-22 03:29:26 +0000163BOOST_AUTO_TEST_CASE(UnsetNoop)
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700164{
Junxiao Shi7d30d852017-01-22 03:29:26 +0000165 ControlParameters reqParams;
166 reqParams.setName("/A");
167 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/unset", reqParams);
168 receiveInterest(req);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700169
Junxiao Shi7d30d852017-01-22 03:29:26 +0000170 ControlParameters expectedParams(reqParams);
171 ControlResponse expectedResp;
172 expectedResp.setCode(200)
173 .setText("OK")
174 .setBody(expectedParams.wireEncode());
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000175 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Junxiao Shi7d30d852017-01-22 03:29:26 +0000176 CheckResponseResult::OK);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700177
Junxiao Shi7d30d852017-01-22 03:29:26 +0000178 BOOST_CHECK_EQUAL(hasEntry("/A"), false);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700179}
180
Junxiao Shi7d30d852017-01-22 03:29:26 +0000181BOOST_AUTO_TEST_CASE(UnsetRootForbidden)
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700182{
Junxiao Shi7d30d852017-01-22 03:29:26 +0000183 ControlParameters reqParams;
184 reqParams.setName("/");
185 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/unset", reqParams);
186 receiveInterest(req);
187
188 ControlResponse expectedResp;
189 expectedResp.setCode(400)
190 .setText("failed in validating parameters");
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000191 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Junxiao Shi7d30d852017-01-22 03:29:26 +0000192 CheckResponseResult::OK);
193
194 BOOST_CHECK_EQUAL(hasEntry("/"), true);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700195}
196
Davide Pesavento97210d52016-10-14 15:45:48 +0200197BOOST_AUTO_TEST_CASE(StrategyChoiceDataset)
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700198{
Junxiao Shi7d30d852017-01-22 03:29:26 +0000199 std::map<Name, Name> expected; // namespace => strategy instance name
200 for (const strategy_choice::Entry& entry : sc) {
201 expected[entry.getPrefix()] = entry.getStrategyInstanceName();
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700202 }
203
Davide Pesavento28181322018-11-08 16:44:50 -0500204 for (size_t i = expected.size(); i < 1024; ++i) {
Junxiao Shi7d30d852017-01-22 03:29:26 +0000205 Name name("/SC");
206 name.appendNumber(i);
207 Name strategy = DummyStrategy::getStrategyName(i);
208
209 auto insertRes = sc.insert(name, strategy);
210 BOOST_CHECK(insertRes);
211 expected[name] = strategy;
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700212 }
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700213
Davide Pesavento28181322018-11-08 16:44:50 -0500214 receiveInterest(Interest("/localhost/nfd/strategy-choice/list").setCanBePrefix(true));
215
Junxiao Shi7d30d852017-01-22 03:29:26 +0000216 Block dataset = concatenateResponses();
217 dataset.parse();
218 BOOST_CHECK_EQUAL(dataset.elements_size(), expected.size());
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700219
Junxiao Shi7d30d852017-01-22 03:29:26 +0000220 for (auto i = dataset.elements_begin(); i != dataset.elements_end(); ++i) {
221 ndn::nfd::StrategyChoice record(*i);
222 auto found = expected.find(record.getName());
223 if (found == expected.end()) {
224 BOOST_ERROR("record has unexpected namespace " << record.getName());
225 }
226 else {
227 BOOST_CHECK_MESSAGE(record.getStrategy() == found->second,
228 "record for " << record.getName() << " has wrong strategy " << record.getStrategy() <<
229 ", should be " << found->second);
230 expected.erase(found);
231 }
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700232 }
233
Junxiao Shi7d30d852017-01-22 03:29:26 +0000234 for (const auto& pair : expected) {
235 BOOST_ERROR("record for " << pair.first << " is missing");
236 }
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700237}
238
239BOOST_AUTO_TEST_SUITE_END() // TestStrategyChoiceManager
240BOOST_AUTO_TEST_SUITE_END() // Mgmt
241
242} // namespace tests
243} // namespace nfd