blob: 5915e3e083de99a4d867160174c5e8b766179b1b [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 Lidf846e52016-01-30 21:53:47 -080027#include "nfd-manager-common-fixture.hpp"
Yanbiao Li6704a4a2015-08-19 16:30:16 -070028
29#include "face/face.hpp"
30#include "face/internal-face.hpp"
31#include "table/name-tree.hpp"
32#include "table/strategy-choice.hpp"
33#include "fw/strategy.hpp"
Junxiao Shia49a1ab2016-07-15 18:24:36 +000034
Yanbiao Li6704a4a2015-08-19 16:30:16 -070035#include "tests/daemon/face/dummy-face.hpp"
36#include "tests/daemon/fw/dummy-strategy.hpp"
Junxiao Shia49a1ab2016-07-15 18:24:36 +000037#include "tests/daemon/fw/install-strategy.hpp"
Yanbiao Li6704a4a2015-08-19 16:30:16 -070038
39#include <ndn-cxx/util/random.hpp>
40#include <ndn-cxx/management/nfd-strategy-choice.hpp>
41
42namespace nfd {
43namespace tests {
44
Yanbiao Lidf846e52016-01-30 21:53:47 -080045class StrategyChoiceManagerFixture : public NfdManagerCommonFixture
Yanbiao Li6704a4a2015-08-19 16:30:16 -070046{
47public:
48 StrategyChoiceManagerFixture()
49 : m_strategyChoice(m_forwarder.getStrategyChoice())
50 , m_manager(m_strategyChoice, m_dispatcher, m_validator)
51 {
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 Shia49a1ab2016-07-15 18:24:36 +000059 install<DummyStrategy>(m_forwarder, strategyName);
Yanbiao Li6704a4a2015-08-19 16:30:16 -070060 }
61
62 const Name&
63 findStrategy(const Name& name)
64 {
65 return m_strategyChoice.findEffectiveStrategy(name).getName();
66 }
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
79BOOST_FIXTURE_TEST_SUITE(Mgmt, StrategyChoiceManagerFixture)
80BOOST_AUTO_TEST_SUITE(TestStrategyChoiceManager)
81
82BOOST_AUTO_TEST_CASE(SetStrategy)
83{
84 auto testSetStrategy = [this] (const ControlParameters& parameters) -> Name {
85 m_responses.clear();
86 auto command = makeControlCommandRequest("/localhost/nfd/strategy-choice/set", parameters);
87 receiveInterest(command);
88 return command->getName();
89 };
90
91 installStrategy("/localhost/nfd/strategy/test-strategy-a");
92 installStrategy("/localhost/nfd/strategy/test-strategy-c/%FD%01"); // version 1
93 installStrategy("/localhost/nfd/strategy/test-strategy-c/%FD%02"); // version 2
94
95 auto parametersA = makeParameters("test", "/localhost/nfd/strategy/test-strategy-a");
96 auto parametersB = makeParameters("test", "/localhost/nfd/strategy/test-strategy-b");
97 auto parametersC1 = makeParameters("test", "/localhost/nfd/strategy/test-strategy-c/%FD%01");
98 auto parametersC = makeParameters("test", "/localhost/nfd/strategy/test-strategy-c");
99
100 auto commandNameA = testSetStrategy(parametersA); // succeed
101 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
102 BOOST_CHECK_EQUAL(checkResponse(0, commandNameA, makeResponse(200, "OK", parametersA)),
103 CheckResponseResult::OK);
104 BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-a");
105
106 auto commandNameB = testSetStrategy(parametersB); // not installed
107 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
108 BOOST_CHECK_EQUAL(checkResponse(0, commandNameB, ControlResponse(504, "Unsupported strategy")),
109 CheckResponseResult::OK);
110
111 auto commandNameC1 = testSetStrategy(parametersC1); // specified version
112 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
113 BOOST_CHECK_EQUAL(checkResponse(0, commandNameC1, makeResponse(200, "OK", parametersC1)),
114 CheckResponseResult::OK);
115 BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-c/%FD%01");
116
117 auto commandNameC = testSetStrategy(parametersC); // latest version
118 parametersC.setStrategy("/localhost/nfd/strategy/test-strategy-c/%FD%02"); // change to latest
119 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
120 BOOST_CHECK_EQUAL(checkResponse(0, commandNameC, makeResponse(200, "OK", parametersC)),
121 CheckResponseResult::OK);
122 BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-c/%FD%02");
123}
124
125BOOST_AUTO_TEST_CASE(UnsetStrategy)
126{
127 auto testUnsetStrategy = [this] (const ControlParameters& parameters) -> Name {
128 m_responses.clear();
129 auto command = makeControlCommandRequest("/localhost/nfd/strategy-choice/unset", parameters);
130 receiveInterest(command);
131 return command->getName();
132 };
133
134 installStrategy("/localhost/nfd/strategy/test-strategy-a");
135 installStrategy("/localhost/nfd/strategy/test-strategy-b");
136 installStrategy("/localhost/nfd/strategy/test-strategy-c");
137
138 BOOST_CHECK(m_strategyChoice.insert("ndn:/", "/localhost/nfd/strategy/test-strategy-a")); // root
139 BOOST_CHECK(m_strategyChoice.insert("/test", "/localhost/nfd/strategy/test-strategy-b")); // test
140 BOOST_CHECK_EQUAL(findStrategy("/"), "/localhost/nfd/strategy/test-strategy-a");
141
142 auto parametersRoot = ControlParameters().setName("ndn:/"); // root prefix
143 auto parametersNone = ControlParameters().setName("/none"); // no such entry
144 auto parametersTest = ControlParameters().setName("/test"); // has such entry
145
146 BOOST_CHECK_EQUAL(findStrategy("/"), "/localhost/nfd/strategy/test-strategy-a"); // root
147 auto commandRootName = testUnsetStrategy(parametersRoot);
148 auto expectedResponse = ControlResponse(400, "failed in validating parameters");
149 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
150 BOOST_CHECK_EQUAL(checkResponse(0, commandRootName, expectedResponse), CheckResponseResult::OK);
151 BOOST_CHECK_EQUAL(findStrategy("/"), "/localhost/nfd/strategy/test-strategy-a"); // keep as root
152
153 BOOST_CHECK_EQUAL(findStrategy("/none"), "/localhost/nfd/strategy/test-strategy-a"); // root
154 auto commandNoneName = testUnsetStrategy(parametersNone);
155 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
156 BOOST_CHECK_EQUAL(checkResponse(0, commandNoneName, makeResponse(200, "OK", parametersNone)),
157 CheckResponseResult::OK);
158 BOOST_CHECK_EQUAL(findStrategy("/none"), "/localhost/nfd/strategy/test-strategy-a"); // root
159
160 BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-b"); // self
161 auto commandTestName = testUnsetStrategy(parametersTest);
162 BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
163 BOOST_CHECK_EQUAL(checkResponse(0, commandTestName, makeResponse(200, "OK", parametersTest)),
164 CheckResponseResult::OK);
165 BOOST_CHECK_EQUAL(findStrategy("/test"), "/localhost/nfd/strategy/test-strategy-a"); // parent
166}
167
168// @todo Remove when ndn::nfd::StrategyChoice implements operator!= and operator<<
169class StrategyChoice : public ndn::nfd::StrategyChoice
170{
171public:
172 StrategyChoice() = default;
173
174 StrategyChoice(const ndn::nfd::StrategyChoice& entry)
175 : ndn::nfd::StrategyChoice(entry)
176 {
177 }
178};
179
180bool
181operator!=(const StrategyChoice& left, const StrategyChoice& right)
182{
183 return left.getName() != right.getName() || left.getStrategy() != right.getStrategy();
184}
185
186std::ostream&
187operator<<(std::ostream &os, const StrategyChoice& entry)
188{
189 os << "[ " << entry.getName() << ", " << entry.getStrategy() << " ]";
190 return os;
191}
192
193BOOST_AUTO_TEST_CASE(ListChoices)
194{
195 size_t nPreInsertedStrategies = m_strategyChoice.size(); // the best-route strategy
196 std::set<Name> actualNames, actualStrategies;
197 for (auto&& entry : m_strategyChoice) {
198 actualNames.insert(entry.getPrefix());
199 actualStrategies.insert(entry.getStrategyName());
200 }
201
202 size_t nEntries = 1024;
203 for (size_t i = 0 ; i < nEntries ; i++) {
204 auto name = Name("test-name").appendSegment(i);
205 auto strategy = Name("test-strategy").appendSegment(ndn::random::generateWord64());
206 auto entry = ndn::nfd::StrategyChoice().setName(name).setStrategy(strategy);
207 actualNames.insert(name);
208 actualStrategies.insert(strategy);
209 installStrategy(strategy);
210 m_strategyChoice.insert(name, strategy);
211 }
212 nEntries += nPreInsertedStrategies;
213
214 receiveInterest(makeInterest("/localhost/nfd/strategy-choice/list"));
215
216 Block content;
217 BOOST_CHECK_NO_THROW(content = concatenateResponses());
218 BOOST_CHECK_NO_THROW(content.parse());
219 BOOST_CHECK_EQUAL(content.elements().size(), nEntries);
220
221 std::vector<StrategyChoice> receivedRecords, expectedRecords;
222 for (size_t idx = 0; idx < nEntries; ++idx) {
223 BOOST_TEST_MESSAGE("processing element: " << idx);
224
225 StrategyChoice decodedEntry;
226 BOOST_REQUIRE_NO_THROW(decodedEntry.wireDecode(content.elements()[idx]));
227 receivedRecords.push_back(decodedEntry);
228
229 actualNames.erase(decodedEntry.getName());
230 actualStrategies.erase(decodedEntry.getStrategy());
231
232 auto result = m_strategyChoice.get(decodedEntry.getName());
233 BOOST_REQUIRE(result.first);
234
235 auto record = StrategyChoice().setName(decodedEntry.getName()).setStrategy(result.second);
236 expectedRecords.push_back(record);
237 }
238
239 BOOST_CHECK_EQUAL(actualNames.size(), 0);
240 BOOST_CHECK_EQUAL(actualStrategies.size(), 0);
241
242 BOOST_CHECK_EQUAL_COLLECTIONS(receivedRecords.begin(), receivedRecords.end(),
243 expectedRecords.begin(), expectedRecords.end());
244}
245
246BOOST_AUTO_TEST_SUITE_END() // TestStrategyChoiceManager
247BOOST_AUTO_TEST_SUITE_END() // Mgmt
248
249} // namespace tests
250} // namespace nfd