blob: f1121ea4dcbad5bad3444ec61aefb60200e0f877 [file] [log] [blame]
Yanbiao Li6704a4a2015-08-19 16:30:16 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Yanbiao Lidf846e52016-01-30 21:53:47 -08003 * Copyright (c) 2014-2016, 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
Davide Pesavento5f47aa62016-10-07 22:09:09 +020028#include "core/random.hpp"
Yanbiao Li6704a4a2015-08-19 16:30:16 -070029#include "face/face.hpp"
30#include "face/internal-face.hpp"
Davide Pesavento97210d52016-10-14 15:45:48 +020031#include "fw/strategy.hpp"
Yanbiao Li6704a4a2015-08-19 16:30:16 -070032#include "table/name-tree.hpp"
33#include "table/strategy-choice.hpp"
Junxiao Shia49a1ab2016-07-15 18:24:36 +000034
Davide Pesavento97210d52016-10-14 15:45:48 +020035#include "nfd-manager-common-fixture.hpp"
Junxiao Shi0e4a1f12016-12-24 02:39:01 +000036#include "../fw/dummy-strategy.hpp"
37#include "../fw/choose-strategy.hpp"
Yanbiao Li6704a4a2015-08-19 16:30:16 -070038
Junxiao Shi25c6ce42016-09-09 13:49:59 +000039#include <ndn-cxx/mgmt/nfd/strategy-choice.hpp>
Yanbiao Li6704a4a2015-08-19 16:30:16 -070040
41namespace nfd {
42namespace tests {
43
Yanbiao Lidf846e52016-01-30 21:53:47 -080044class StrategyChoiceManagerFixture : public NfdManagerCommonFixture
Yanbiao Li6704a4a2015-08-19 16:30:16 -070045{
46public:
47 StrategyChoiceManagerFixture()
48 : m_strategyChoice(m_forwarder.getStrategyChoice())
Junxiao Shi9ddf1b52016-08-22 03:58:55 +000049 , m_manager(m_strategyChoice, m_dispatcher, *m_authenticator)
Yanbiao Li6704a4a2015-08-19 16:30:16 -070050 {
Junxiao Shi9ddf1b52016-08-22 03:58:55 +000051 setTopPrefix();
Yanbiao Lidf846e52016-01-30 21:53:47 -080052 setPrivilege("strategy-choice");
Yanbiao Li6704a4a2015-08-19 16:30:16 -070053 }
54
55public:
56 void
Junxiao Shia49a1ab2016-07-15 18:24:36 +000057 installStrategy(const Name& strategyName)
Yanbiao Li6704a4a2015-08-19 16:30:16 -070058 {
Junxiao Shi0e4a1f12016-12-24 02:39:01 +000059 // install<DummyStrategy>(m_forwarder, strategyName);
Yanbiao Li6704a4a2015-08-19 16:30:16 -070060 }
61
62 const Name&
63 findStrategy(const Name& name)
64 {
Junxiao Shi0e4a1f12016-12-24 02:39:01 +000065 return m_strategyChoice.findEffectiveStrategy(name).getInstanceName();
Yanbiao Li6704a4a2015-08-19 16:30:16 -070066 }
67
68 ControlParameters
69 makeParameters(const Name& name, const Name& strategy)
70 {
71 return ControlParameters().setName(name).setStrategy(strategy);
72 }
73
74protected:
75 StrategyChoice& m_strategyChoice;
76 StrategyChoiceManager m_manager;
77};
78
Davide Pesavento97210d52016-10-14 15:45:48 +020079BOOST_AUTO_TEST_SUITE(Mgmt)
80BOOST_FIXTURE_TEST_SUITE(TestStrategyChoiceManager, StrategyChoiceManagerFixture)
Yanbiao Li6704a4a2015-08-19 16:30:16 -070081
Junxiao Shi0e4a1f12016-12-24 02:39:01 +000082///\todo #3868 rewrite test case after changing strategy versioning scheme
83BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(SetStrategy, 6)
Yanbiao Li6704a4a2015-08-19 16:30:16 -070084BOOST_AUTO_TEST_CASE(SetStrategy)
85{
86 auto testSetStrategy = [this] (const ControlParameters& parameters) -> Name {
87 m_responses.clear();
88 auto command = makeControlCommandRequest("/localhost/nfd/strategy-choice/set", parameters);
89 receiveInterest(command);
90 return command->getName();
91 };
92
93 installStrategy("/localhost/nfd/strategy/test-strategy-a");
94 installStrategy("/localhost/nfd/strategy/test-strategy-c/%FD%01"); // version 1
95 installStrategy("/localhost/nfd/strategy/test-strategy-c/%FD%02"); // version 2
96
97 auto parametersA = makeParameters("test", "/localhost/nfd/strategy/test-strategy-a");
98 auto parametersB = makeParameters("test", "/localhost/nfd/strategy/test-strategy-b");
99 auto parametersC1 = makeParameters("test", "/localhost/nfd/strategy/test-strategy-c/%FD%01");
100 auto parametersC = makeParameters("test", "/localhost/nfd/strategy/test-strategy-c");
101
102 auto commandNameA = testSetStrategy(parametersA); // succeed
103 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
104 BOOST_CHECK_EQUAL(checkResponse(0, commandNameA, makeResponse(200, "OK", parametersA)),
105 CheckResponseResult::OK);
106 BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-a");
107
108 auto commandNameB = testSetStrategy(parametersB); // not installed
109 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
110 BOOST_CHECK_EQUAL(checkResponse(0, commandNameB, ControlResponse(504, "Unsupported strategy")),
111 CheckResponseResult::OK);
112
113 auto commandNameC1 = testSetStrategy(parametersC1); // specified version
114 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
115 BOOST_CHECK_EQUAL(checkResponse(0, commandNameC1, makeResponse(200, "OK", parametersC1)),
116 CheckResponseResult::OK);
117 BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-c/%FD%01");
118
119 auto commandNameC = testSetStrategy(parametersC); // latest version
120 parametersC.setStrategy("/localhost/nfd/strategy/test-strategy-c/%FD%02"); // change to latest
121 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
122 BOOST_CHECK_EQUAL(checkResponse(0, commandNameC, makeResponse(200, "OK", parametersC)),
123 CheckResponseResult::OK);
124 BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-c/%FD%02");
125}
126
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000127///\todo #3868 rewrite test case after changing strategy versioning scheme
128BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(UnsetStrategy, 9)
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700129BOOST_AUTO_TEST_CASE(UnsetStrategy)
130{
131 auto testUnsetStrategy = [this] (const ControlParameters& parameters) -> Name {
132 m_responses.clear();
133 auto command = makeControlCommandRequest("/localhost/nfd/strategy-choice/unset", parameters);
134 receiveInterest(command);
135 return command->getName();
136 };
137
138 installStrategy("/localhost/nfd/strategy/test-strategy-a");
139 installStrategy("/localhost/nfd/strategy/test-strategy-b");
140 installStrategy("/localhost/nfd/strategy/test-strategy-c");
141
142 BOOST_CHECK(m_strategyChoice.insert("ndn:/", "/localhost/nfd/strategy/test-strategy-a")); // root
143 BOOST_CHECK(m_strategyChoice.insert("/test", "/localhost/nfd/strategy/test-strategy-b")); // test
144 BOOST_CHECK_EQUAL(findStrategy("/"), "/localhost/nfd/strategy/test-strategy-a");
145
146 auto parametersRoot = ControlParameters().setName("ndn:/"); // root prefix
147 auto parametersNone = ControlParameters().setName("/none"); // no such entry
148 auto parametersTest = ControlParameters().setName("/test"); // has such entry
149
150 BOOST_CHECK_EQUAL(findStrategy("/"), "/localhost/nfd/strategy/test-strategy-a"); // root
151 auto commandRootName = testUnsetStrategy(parametersRoot);
152 auto expectedResponse = ControlResponse(400, "failed in validating parameters");
153 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
154 BOOST_CHECK_EQUAL(checkResponse(0, commandRootName, expectedResponse), CheckResponseResult::OK);
155 BOOST_CHECK_EQUAL(findStrategy("/"), "/localhost/nfd/strategy/test-strategy-a"); // keep as root
156
157 BOOST_CHECK_EQUAL(findStrategy("/none"), "/localhost/nfd/strategy/test-strategy-a"); // root
158 auto commandNoneName = testUnsetStrategy(parametersNone);
159 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
160 BOOST_CHECK_EQUAL(checkResponse(0, commandNoneName, makeResponse(200, "OK", parametersNone)),
161 CheckResponseResult::OK);
162 BOOST_CHECK_EQUAL(findStrategy("/none"), "/localhost/nfd/strategy/test-strategy-a"); // root
163
164 BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-b"); // self
165 auto commandTestName = testUnsetStrategy(parametersTest);
166 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
167 BOOST_CHECK_EQUAL(checkResponse(0, commandTestName, makeResponse(200, "OK", parametersTest)),
168 CheckResponseResult::OK);
169 BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-a"); // parent
170}
171
172// @todo Remove when ndn::nfd::StrategyChoice implements operator!= and operator<<
173class StrategyChoice : public ndn::nfd::StrategyChoice
174{
175public:
176 StrategyChoice() = default;
177
178 StrategyChoice(const ndn::nfd::StrategyChoice& entry)
179 : ndn::nfd::StrategyChoice(entry)
180 {
181 }
182};
183
184bool
185operator!=(const StrategyChoice& left, const StrategyChoice& right)
186{
187 return left.getName() != right.getName() || left.getStrategy() != right.getStrategy();
188}
189
190std::ostream&
191operator<<(std::ostream &os, const StrategyChoice& entry)
192{
193 os << "[ " << entry.getName() << ", " << entry.getStrategy() << " ]";
194 return os;
195}
196
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000197///\todo #3868 rewrite test case after changing strategy versioning scheme
198BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(StrategyChoiceDataset, 4)
Davide Pesavento97210d52016-10-14 15:45:48 +0200199BOOST_AUTO_TEST_CASE(StrategyChoiceDataset)
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700200{
201 size_t nPreInsertedStrategies = m_strategyChoice.size(); // the best-route strategy
202 std::set<Name> actualNames, actualStrategies;
Davide Pesavento97210d52016-10-14 15:45:48 +0200203 for (const auto& entry : m_strategyChoice) {
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700204 actualNames.insert(entry.getPrefix());
Junxiao Shi4cb74312016-12-25 20:48:47 +0000205 actualStrategies.insert(entry.getStrategyInstanceName());
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700206 }
207
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200208 std::uniform_int_distribution<uint64_t> dist;
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700209 size_t nEntries = 1024;
210 for (size_t i = 0 ; i < nEntries ; i++) {
211 auto name = Name("test-name").appendSegment(i);
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200212 auto strategy = Name("test-strategy").appendSegment(dist(getGlobalRng()));
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700213 auto entry = ndn::nfd::StrategyChoice().setName(name).setStrategy(strategy);
214 actualNames.insert(name);
215 actualStrategies.insert(strategy);
216 installStrategy(strategy);
217 m_strategyChoice.insert(name, strategy);
218 }
219 nEntries += nPreInsertedStrategies;
220
221 receiveInterest(makeInterest("/localhost/nfd/strategy-choice/list"));
222
223 Block content;
224 BOOST_CHECK_NO_THROW(content = concatenateResponses());
225 BOOST_CHECK_NO_THROW(content.parse());
226 BOOST_CHECK_EQUAL(content.elements().size(), nEntries);
227
228 std::vector<StrategyChoice> receivedRecords, expectedRecords;
229 for (size_t idx = 0; idx < nEntries; ++idx) {
230 BOOST_TEST_MESSAGE("processing element: " << idx);
231
232 StrategyChoice decodedEntry;
Junxiao Shi0e4a1f12016-12-24 02:39:01 +0000233 //BOOST_REQUIRE_NO_THROW(decodedEntry.wireDecode(content.elements()[idx]));
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700234 receivedRecords.push_back(decodedEntry);
235
236 actualNames.erase(decodedEntry.getName());
237 actualStrategies.erase(decodedEntry.getStrategy());
238
239 auto result = m_strategyChoice.get(decodedEntry.getName());
240 BOOST_REQUIRE(result.first);
241
242 auto record = StrategyChoice().setName(decodedEntry.getName()).setStrategy(result.second);
243 expectedRecords.push_back(record);
244 }
245
246 BOOST_CHECK_EQUAL(actualNames.size(), 0);
247 BOOST_CHECK_EQUAL(actualStrategies.size(), 0);
Yanbiao Li6704a4a2015-08-19 16:30:16 -0700248 BOOST_CHECK_EQUAL_COLLECTIONS(receivedRecords.begin(), receivedRecords.end(),
249 expectedRecords.begin(), expectedRecords.end());
250}
251
252BOOST_AUTO_TEST_SUITE_END() // TestStrategyChoiceManager
253BOOST_AUTO_TEST_SUITE_END() // Mgmt
254
255} // namespace tests
256} // namespace nfd