blob: ae963527ddecdfaf03b5232354332301ae8068d9 [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 Pesavento78ddcab2019-02-28 22:00:03 -05003 * Copyright (c) 2014-2019, 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)
43 , strategyNameP("/strategy-choice-manager-P/%FD%02")
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 {
Junxiao Shi7d30d852017-01-22 03:29:26 +000065 bool hasEntry = false;
66 Name instanceName;
67 std::tie(hasEntry, instanceName) = sc.get(name);
68 return hasEntry ?
69 instanceName :
70 Name("/no-StrategyChoice-entry-at").append(name);
Yanbiao Li6704a4a2015-08-19 16:30:16 -070071 }
72
73protected:
Junxiao Shi7d30d852017-01-22 03:29:26 +000074 StrategyChoice& sc;
75 StrategyChoiceManager manager;
76
77 const Name strategyNameP;
Yanbiao Li6704a4a2015-08-19 16:30:16 -070078};
79
Davide Pesavento97210d52016-10-14 15:45:48 +020080BOOST_AUTO_TEST_SUITE(Mgmt)
81BOOST_FIXTURE_TEST_SUITE(TestStrategyChoiceManager, StrategyChoiceManagerFixture)
Yanbiao Li6704a4a2015-08-19 16:30:16 -070082
Junxiao Shi7d30d852017-01-22 03:29:26 +000083BOOST_AUTO_TEST_CASE(SetSuccess)
Yanbiao Li6704a4a2015-08-19 16:30:16 -070084{
Junxiao Shi7d30d852017-01-22 03:29:26 +000085 ControlParameters reqParams;
86 reqParams.setName("/A")
87 .setStrategy(strategyNameP.getPrefix(-1)); // use unversioned strategy name in request
88 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/set", reqParams);
89 receiveInterest(req);
Yanbiao Li6704a4a2015-08-19 16:30:16 -070090
Junxiao Shi7d30d852017-01-22 03:29:26 +000091 ControlParameters expectedParams;
92 expectedParams.setName("/A")
93 .setStrategy(strategyNameP); // response should have versioned strategy name
94 ControlResponse expectedResp;
95 expectedResp.setCode(200)
96 .setText("OK")
97 .setBody(expectedParams.wireEncode());
Junxiao Shi8a1f1702017-07-03 00:05:08 +000098 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Yanbiao Li6704a4a2015-08-19 16:30:16 -070099 CheckResponseResult::OK);
100
Junxiao Shi7d30d852017-01-22 03:29:26 +0000101 BOOST_CHECK_EQUAL(getInstanceName("/A"), strategyNameP);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700102
Junxiao Shi7d30d852017-01-22 03:29:26 +0000103 // Strategy versioning and parameters are not tested here because they are covered by
104 // Table/TestStrategyChoice test suite.
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700105}
106
Junxiao Shi7d30d852017-01-22 03:29:26 +0000107BOOST_AUTO_TEST_CASE(SetUnknownStrategy)
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700108{
Junxiao Shi7d30d852017-01-22 03:29:26 +0000109 ControlParameters reqParams;
110 reqParams.setName("/A")
111 .setStrategy("/strategy-choice-manager-unknown");
112 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/set", reqParams);
113 receiveInterest(req);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700114
Junxiao Shi7d30d852017-01-22 03:29:26 +0000115 ControlResponse expectedResp;
116 expectedResp.setCode(404)
117 .setText("Strategy not registered");
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000118 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700119 CheckResponseResult::OK);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700120
Junxiao Shi7d30d852017-01-22 03:29:26 +0000121 BOOST_CHECK_EQUAL(hasEntry("/A"), false);
122}
123
Junxiao Shi332783b2018-02-04 23:52:46 +0000124BOOST_AUTO_TEST_CASE(SetNameTooLong)
125{
126 Name prefix;
Davide Pesavento2cae8ca2019-04-18 20:48:05 -0400127 while (prefix.size() <= NameTree::getMaxDepth()) {
Junxiao Shi332783b2018-02-04 23:52:46 +0000128 prefix.append("A");
129 }
130 ControlParameters reqParams;
131 reqParams.setName(prefix)
132 .setStrategy(strategyNameP);
133 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/set", reqParams);
134 receiveInterest(req);
135
136 ControlResponse expectedResp;
137 expectedResp.setCode(414)
138 .setText("Prefix has too many components (limit is " +
139 to_string(NameTree::getMaxDepth()) + ")");
140 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
141 CheckResponseResult::OK);
142
143 BOOST_CHECK_EQUAL(hasEntry(prefix), false);
144}
145
Junxiao Shi7d30d852017-01-22 03:29:26 +0000146BOOST_AUTO_TEST_CASE(UnsetSuccess)
147{
148 auto insertRes = sc.insert("/A", strategyNameP);
149 BOOST_REQUIRE(insertRes);
150
151 ControlParameters reqParams;
152 reqParams.setName("/A");
153 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/unset", reqParams);
154 receiveInterest(req);
155
156 ControlParameters expectedParams(reqParams);
157 ControlResponse expectedResp;
158 expectedResp.setCode(200)
159 .setText("OK")
160 .setBody(expectedParams.wireEncode());
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000161 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700162 CheckResponseResult::OK);
Junxiao Shi7d30d852017-01-22 03:29:26 +0000163
164 BOOST_CHECK_EQUAL(hasEntry("/A"), false);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700165}
166
Junxiao Shi7d30d852017-01-22 03:29:26 +0000167BOOST_AUTO_TEST_CASE(UnsetNoop)
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700168{
Junxiao Shi7d30d852017-01-22 03:29:26 +0000169 ControlParameters reqParams;
170 reqParams.setName("/A");
171 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/unset", reqParams);
172 receiveInterest(req);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700173
Junxiao Shi7d30d852017-01-22 03:29:26 +0000174 ControlParameters expectedParams(reqParams);
175 ControlResponse expectedResp;
176 expectedResp.setCode(200)
177 .setText("OK")
178 .setBody(expectedParams.wireEncode());
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000179 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Junxiao Shi7d30d852017-01-22 03:29:26 +0000180 CheckResponseResult::OK);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700181
Junxiao Shi7d30d852017-01-22 03:29:26 +0000182 BOOST_CHECK_EQUAL(hasEntry("/A"), false);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700183}
184
Junxiao Shi7d30d852017-01-22 03:29:26 +0000185BOOST_AUTO_TEST_CASE(UnsetRootForbidden)
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700186{
Junxiao Shi7d30d852017-01-22 03:29:26 +0000187 ControlParameters reqParams;
188 reqParams.setName("/");
189 auto req = makeControlCommandRequest("/localhost/nfd/strategy-choice/unset", reqParams);
190 receiveInterest(req);
191
192 ControlResponse expectedResp;
193 expectedResp.setCode(400)
194 .setText("failed in validating parameters");
Junxiao Shi8a1f1702017-07-03 00:05:08 +0000195 BOOST_CHECK_EQUAL(checkResponse(0, req.getName(), expectedResp),
Junxiao Shi7d30d852017-01-22 03:29:26 +0000196 CheckResponseResult::OK);
197
198 BOOST_CHECK_EQUAL(hasEntry("/"), true);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700199}
200
Davide Pesavento97210d52016-10-14 15:45:48 +0200201BOOST_AUTO_TEST_CASE(StrategyChoiceDataset)
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700202{
Junxiao Shi7d30d852017-01-22 03:29:26 +0000203 std::map<Name, Name> expected; // namespace => strategy instance name
204 for (const strategy_choice::Entry& entry : sc) {
205 expected[entry.getPrefix()] = entry.getStrategyInstanceName();
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700206 }
207
Davide Pesavento28181322018-11-08 16:44:50 -0500208 for (size_t i = expected.size(); i < 1024; ++i) {
Junxiao Shi7d30d852017-01-22 03:29:26 +0000209 Name name("/SC");
210 name.appendNumber(i);
211 Name strategy = DummyStrategy::getStrategyName(i);
212
213 auto insertRes = sc.insert(name, strategy);
214 BOOST_CHECK(insertRes);
215 expected[name] = strategy;
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700216 }
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700217
Davide Pesavento28181322018-11-08 16:44:50 -0500218 receiveInterest(Interest("/localhost/nfd/strategy-choice/list").setCanBePrefix(true));
219
Junxiao Shi7d30d852017-01-22 03:29:26 +0000220 Block dataset = concatenateResponses();
221 dataset.parse();
222 BOOST_CHECK_EQUAL(dataset.elements_size(), expected.size());
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700223
Junxiao Shi7d30d852017-01-22 03:29:26 +0000224 for (auto i = dataset.elements_begin(); i != dataset.elements_end(); ++i) {
225 ndn::nfd::StrategyChoice record(*i);
226 auto found = expected.find(record.getName());
227 if (found == expected.end()) {
228 BOOST_ERROR("record has unexpected namespace " << record.getName());
229 }
230 else {
231 BOOST_CHECK_MESSAGE(record.getStrategy() == found->second,
232 "record for " << record.getName() << " has wrong strategy " << record.getStrategy() <<
233 ", should be " << found->second);
234 expected.erase(found);
235 }
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700236 }
237
Junxiao Shi7d30d852017-01-22 03:29:26 +0000238 for (const auto& pair : expected) {
239 BOOST_ERROR("record for " << pair.first << " is missing");
240 }
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700241}
242
243BOOST_AUTO_TEST_SUITE_END() // TestStrategyChoiceManager
244BOOST_AUTO_TEST_SUITE_END() // Mgmt
245
246} // namespace tests
247} // namespace nfd