blob: 3553cfd4c0bd2524ff2e61ce2300e292655f5b51 [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 Pesavento2c9d2ca2024-01-27 16:36:51 -05003 * Copyright (c) 2014-2024, 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
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040034namespace nfd::tests {
Yanbiao Li6704a4a2015-08-19 16:30:16 -070035
Davide Pesavento78ddcab2019-02-28 22:00:03 -050036class StrategyChoiceManagerFixture : public ManagerFixtureWithAuthenticator
Yanbiao Li6704a4a2015-08-19 16:30:16 -070037{
38public:
39 StrategyChoiceManagerFixture()
Junxiao Shi7d30d852017-01-22 03:29:26 +000040 : sc(m_forwarder.getStrategyChoice())
41 , manager(sc, m_dispatcher, *m_authenticator)
Eric Newberry358414d2021-03-21 20:56:42 -070042 , strategyNameP(Name("/strategy-choice-manager-P").appendVersion(2))
Yanbiao Li6704a4a2015-08-19 16:30:16 -070043 {
Junxiao Shi7d30d852017-01-22 03:29:26 +000044 VersionedDummyStrategy<2>::registerAs(strategyNameP);
45
Junxiao Shi9ddf1b52016-08-22 03:58:55 +000046 setTopPrefix();
Yanbiao Lidf846e52016-01-30 21:53:47 -080047 setPrivilege("strategy-choice");
Yanbiao Li6704a4a2015-08-19 16:30:16 -070048 }
49
50public:
Junxiao Shi7d30d852017-01-22 03:29:26 +000051 /** \return whether exact-match StrategyChoice entry exists
52 */
53 bool
54 hasEntry(const Name& name) const
Yanbiao Li6704a4a2015-08-19 16:30:16 -070055 {
Junxiao Shi7d30d852017-01-22 03:29:26 +000056 return sc.get(name).first;
Yanbiao Li6704a4a2015-08-19 16:30:16 -070057 }
58
Junxiao Shi7d30d852017-01-22 03:29:26 +000059 /** \return strategy instance name from an exact-match StrategyChoice entry
60 */
61 Name
62 getInstanceName(const Name& name) const
Yanbiao Li6704a4a2015-08-19 16:30:16 -070063 {
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040064 auto [hasEntry, instanceName] = sc.get(name);
65 return hasEntry ? instanceName : Name("/no-StrategyChoice-entry-at").append(name);
Yanbiao Li6704a4a2015-08-19 16:30:16 -070066 }
67
68protected:
Junxiao Shi7d30d852017-01-22 03:29:26 +000069 StrategyChoice& sc;
70 StrategyChoiceManager manager;
71
72 const Name strategyNameP;
Yanbiao Li6704a4a2015-08-19 16:30:16 -070073};
74
Davide Pesavento97210d52016-10-14 15:45:48 +020075BOOST_AUTO_TEST_SUITE(Mgmt)
76BOOST_FIXTURE_TEST_SUITE(TestStrategyChoiceManager, StrategyChoiceManagerFixture)
Yanbiao Li6704a4a2015-08-19 16:30:16 -070077
Junxiao Shi7d30d852017-01-22 03:29:26 +000078BOOST_AUTO_TEST_CASE(SetSuccess)
Yanbiao Li6704a4a2015-08-19 16:30:16 -070079{
Junxiao Shi7d30d852017-01-22 03:29:26 +000080 ControlParameters reqParams;
81 reqParams.setName("/A")
82 .setStrategy(strategyNameP.getPrefix(-1)); // use unversioned strategy name in request
83 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/set", reqParams);
84 receiveInterest(req);
Yanbiao Li6704a4a2015-08-19 16:30:16 -070085
Junxiao Shi7d30d852017-01-22 03:29:26 +000086 ControlParameters expectedParams;
87 expectedParams.setName("/A")
88 .setStrategy(strategyNameP); // response should have versioned strategy name
89 ControlResponse expectedResp;
90 expectedResp.setCode(200)
91 .setText("OK")
92 .setBody(expectedParams.wireEncode());
Junxiao Shi8a1f1702017-07-03 00:05:08 +000093 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Yanbiao Li6704a4a2015-08-19 16:30:16 -070094 CheckResponseResult::OK);
95
Junxiao Shi7d30d852017-01-22 03:29:26 +000096 BOOST_CHECK_EQUAL(getInstanceName("/A"), strategyNameP);
Yanbiao Li6704a4a2015-08-19 16:30:16 -070097
Junxiao Shi7d30d852017-01-22 03:29:26 +000098 // Strategy versioning and parameters are not tested here because they are covered by
99 // Table/TestStrategyChoice test suite.
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700100}
101
Junxiao Shi7d30d852017-01-22 03:29:26 +0000102BOOST_AUTO_TEST_CASE(SetUnknownStrategy)
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700103{
Junxiao Shi7d30d852017-01-22 03:29:26 +0000104 ControlParameters reqParams;
105 reqParams.setName("/A")
106 .setStrategy("/strategy-choice-manager-unknown");
107 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/set", reqParams);
108 receiveInterest(req);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700109
Junxiao Shi7d30d852017-01-22 03:29:26 +0000110 ControlResponse expectedResp;
111 expectedResp.setCode(404)
112 .setText("Strategy not registered");
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000113 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700114 CheckResponseResult::OK);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700115
Junxiao Shi7d30d852017-01-22 03:29:26 +0000116 BOOST_CHECK_EQUAL(hasEntry("/A"), false);
117}
118
Junxiao Shi332783b2018-02-04 23:52:46 +0000119BOOST_AUTO_TEST_CASE(SetNameTooLong)
120{
121 Name prefix;
Davide Pesavento2cae8ca2019-04-18 20:48:05 -0400122 while (prefix.size() <= NameTree::getMaxDepth()) {
Junxiao Shi332783b2018-02-04 23:52:46 +0000123 prefix.append("A");
124 }
125 ControlParameters reqParams;
126 reqParams.setName(prefix)
127 .setStrategy(strategyNameP);
128 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/set", reqParams);
129 receiveInterest(req);
130
131 ControlResponse expectedResp;
132 expectedResp.setCode(414)
133 .setText("Prefix has too many components (limit is " +
Davide Pesavento2c9d2ca2024-01-27 16:36:51 -0500134 std::to_string(NameTree::getMaxDepth()) + ")");
Junxiao Shi332783b2018-02-04 23:52:46 +0000135 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
136 CheckResponseResult::OK);
137
138 BOOST_CHECK_EQUAL(hasEntry(prefix), false);
139}
140
Junxiao Shi7d30d852017-01-22 03:29:26 +0000141BOOST_AUTO_TEST_CASE(UnsetSuccess)
142{
143 auto insertRes = sc.insert("/A", strategyNameP);
144 BOOST_REQUIRE(insertRes);
145
146 ControlParameters reqParams;
147 reqParams.setName("/A");
148 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/unset", reqParams);
149 receiveInterest(req);
150
151 ControlParameters expectedParams(reqParams);
152 ControlResponse expectedResp;
153 expectedResp.setCode(200)
154 .setText("OK")
155 .setBody(expectedParams.wireEncode());
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000156 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700157 CheckResponseResult::OK);
Junxiao Shi7d30d852017-01-22 03:29:26 +0000158
159 BOOST_CHECK_EQUAL(hasEntry("/A"), false);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700160}
161
Junxiao Shi7d30d852017-01-22 03:29:26 +0000162BOOST_AUTO_TEST_CASE(UnsetNoop)
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700163{
Junxiao Shi7d30d852017-01-22 03:29:26 +0000164 ControlParameters reqParams;
165 reqParams.setName("/A");
166 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/unset", reqParams);
167 receiveInterest(req);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700168
Junxiao Shi7d30d852017-01-22 03:29:26 +0000169 ControlParameters expectedParams(reqParams);
170 ControlResponse expectedResp;
171 expectedResp.setCode(200)
172 .setText("OK")
173 .setBody(expectedParams.wireEncode());
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000174 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Junxiao Shi7d30d852017-01-22 03:29:26 +0000175 CheckResponseResult::OK);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700176
Junxiao Shi7d30d852017-01-22 03:29:26 +0000177 BOOST_CHECK_EQUAL(hasEntry("/A"), false);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700178}
179
Junxiao Shi7d30d852017-01-22 03:29:26 +0000180BOOST_AUTO_TEST_CASE(UnsetRootForbidden)
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700181{
Junxiao Shi7d30d852017-01-22 03:29:26 +0000182 ControlParameters reqParams;
183 reqParams.setName("/");
184 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/unset", reqParams);
185 receiveInterest(req);
186
187 ControlResponse expectedResp;
188 expectedResp.setCode(400)
189 .setText("failed in validating parameters");
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000190 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Junxiao Shi7d30d852017-01-22 03:29:26 +0000191 CheckResponseResult::OK);
192
193 BOOST_CHECK_EQUAL(hasEntry("/"), true);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700194}
195
Davide Pesavento97210d52016-10-14 15:45:48 +0200196BOOST_AUTO_TEST_CASE(StrategyChoiceDataset)
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700197{
Junxiao Shi7d30d852017-01-22 03:29:26 +0000198 std::map<Name, Name> expected; // namespace => strategy instance name
199 for (const strategy_choice::Entry& entry : sc) {
200 expected[entry.getPrefix()] = entry.getStrategyInstanceName();
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700201 }
202
Davide Pesavento28181322018-11-08 16:44:50 -0500203 for (size_t i = expected.size(); i < 1024; ++i) {
Junxiao Shi7d30d852017-01-22 03:29:26 +0000204 Name name("/SC");
205 name.appendNumber(i);
206 Name strategy = DummyStrategy::getStrategyName(i);
207
208 auto insertRes = sc.insert(name, strategy);
209 BOOST_CHECK(insertRes);
210 expected[name] = strategy;
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700211 }
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700212
Davide Pesavento28181322018-11-08 16:44:50 -0500213 receiveInterest(Interest("/localhost/nfd/strategy-choice/list").setCanBePrefix(true));
214
Junxiao Shi7d30d852017-01-22 03:29:26 +0000215 Block dataset = concatenateResponses();
216 dataset.parse();
217 BOOST_CHECK_EQUAL(dataset.elements_size(), expected.size());
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700218
Junxiao Shi7d30d852017-01-22 03:29:26 +0000219 for (auto i = dataset.elements_begin(); i != dataset.elements_end(); ++i) {
220 ndn::nfd::StrategyChoice record(*i);
Davide Pesaventod7083a52023-10-19 17:51:16 -0400221 BOOST_TEST_INFO_SCOPE(record);
Junxiao Shi7d30d852017-01-22 03:29:26 +0000222 auto found = expected.find(record.getName());
223 if (found == expected.end()) {
224 BOOST_ERROR("record has unexpected namespace " << record.getName());
225 }
226 else {
Davide Pesaventod7083a52023-10-19 17:51:16 -0400227 BOOST_TEST(record.getStrategy() == found->second);
Junxiao Shi7d30d852017-01-22 03:29:26 +0000228 expected.erase(found);
229 }
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700230 }
231
Junxiao Shi7d30d852017-01-22 03:29:26 +0000232 for (const auto& pair : expected) {
233 BOOST_ERROR("record for " << pair.first << " is missing");
234 }
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700235}
236
237BOOST_AUTO_TEST_SUITE_END() // TestStrategyChoiceManager
238BOOST_AUTO_TEST_SUITE_END() // Mgmt
239
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400240} // namespace nfd::tests