shared_network_unittest.cc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. // Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #include <config.h>
  7. #include <asiolink/io_address.h>
  8. #include <dhcpsrv/shared_network.h>
  9. #include <dhcpsrv/subnet.h>
  10. #include <dhcpsrv/subnet_id.h>
  11. #include <dhcpsrv/triplet.h>
  12. #include <exceptions/exceptions.h>
  13. #include <testutils/test_to_element.h>
  14. #include <gtest/gtest.h>
  15. #include <cstdint>
  16. #include <vector>
  17. using namespace isc;
  18. using namespace isc::asiolink;
  19. using namespace isc::dhcp;
  20. namespace {
  21. // This test verifies that shared network can be given a name and that
  22. // this name can be retrieved.
  23. TEST(SharedNetwork4Test, getName) {
  24. // Create shared network with an initial name "dog".
  25. SharedNetwork4Ptr network(new SharedNetwork4("frog"));
  26. EXPECT_EQ("frog", network->getName());
  27. // Override the name.
  28. network->setName("dog");
  29. EXPECT_EQ("dog", network->getName());
  30. }
  31. // This test verifies that an IPv4 subnet can be added to a shared network.
  32. // It also verifies that two subnets with the same ID can't be added to
  33. // a shared network and that a single subnet can't be added to two different
  34. // shared subnets.
  35. TEST(SharedNetwork4Test, addSubnet4) {
  36. // First, create a network.
  37. SharedNetwork4Ptr network(new SharedNetwork4("frog"));
  38. // Try to add null pointer. It should throw.
  39. Subnet4Ptr subnet;
  40. ASSERT_THROW(network->add(subnet), BadValue);
  41. // Create a valid subnet. It should now be added successfully.
  42. subnet.reset(new Subnet4(IOAddress("10.0.0.0"), 8, 10, 20, 30,
  43. SubnetID(15)));
  44. ASSERT_NO_THROW(network->add(subnet));
  45. ASSERT_EQ(1, network->getAllSubnets()->size());
  46. // Retrieve the subnet from the network and make sure it is returned
  47. // as expected.
  48. Subnet4Ptr returned_subnet = network->getAllSubnets()->front();
  49. ASSERT_TRUE(returned_subnet);
  50. EXPECT_EQ(subnet->getID(), returned_subnet->getID());
  51. SharedNetwork4Ptr network1;
  52. subnet->getSharedNetwork(network1);
  53. ASSERT_TRUE(network1);
  54. EXPECT_TRUE(network1 == network);
  55. // Create another subnet with the same ID. Adding a network with the
  56. // same ID should cause an error.
  57. Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.0"), 24, 10, 20, 30,
  58. SubnetID(15)));
  59. ASSERT_THROW(network->add(subnet), DuplicateSubnetID);
  60. // Create another network and try to add a subnet to it. It should fail
  61. // because the subnet is already associated with the first network.
  62. SharedNetwork4Ptr network2(new SharedNetwork4("dog"));
  63. ASSERT_THROW(network2->add(subnet), InvalidOperation);
  64. }
  65. // This test verifies that it is possible to remove a specified subnet.
  66. TEST(SharedNetwork4Test, delSubnet4) {
  67. // Create two subnets and add them to the shared network.
  68. Subnet4Ptr subnet1(new Subnet4(IOAddress("10.0.0.0"), 8, 10, 20, 30,
  69. SubnetID(1)));
  70. Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.0"), 24, 10, 20, 30,
  71. SubnetID(2)));
  72. SharedNetwork4Ptr network(new SharedNetwork4("frog"));
  73. ASSERT_NO_THROW(network->add(subnet1));
  74. ASSERT_NO_THROW(network->add(subnet2));
  75. // Make sure they have been added successfully.
  76. ASSERT_EQ(2, network->getAllSubnets()->size());
  77. // Try to remove a subnet that doesn't exist in this shared network.
  78. // It should cause an error.
  79. ASSERT_THROW(network->del(SubnetID(5)), BadValue);
  80. // Now delete the subnet that exists.
  81. ASSERT_NO_THROW(network->del(subnet1->getID()));
  82. // We should be left with only one subnet.
  83. ASSERT_EQ(1, network->getAllSubnets()->size());
  84. Subnet4Ptr subnet_returned = network->getAllSubnets()->front();
  85. ASSERT_TRUE(subnet_returned);
  86. EXPECT_EQ(subnet2->getID(), subnet_returned->getID());
  87. // Check that shared network has been cleared for the removed subnet.
  88. SharedNetwork4Ptr network1;
  89. subnet1->getSharedNetwork(network1);
  90. EXPECT_FALSE(network1);
  91. // Remove another subnet and make sure there are no subnets left.
  92. ASSERT_NO_THROW(network->del(subnet2->getID()));
  93. EXPECT_EQ(0, network->getAllSubnets()->size());
  94. // The network pointer should be cleared for this second subnet too.
  95. SharedNetwork4Ptr network2;
  96. subnet1->getSharedNetwork(network2);
  97. EXPECT_FALSE(network2);
  98. }
  99. // This test verifies that it is possible to iterate over the subnets
  100. // associated with a particular shared network.
  101. TEST(SharedNetwork4Test, getNextSubnet) {
  102. SharedNetwork4Ptr network(new SharedNetwork4("frog"));
  103. // Create three subnets.
  104. Subnet4Ptr subnet1(new Subnet4(IOAddress("10.0.0.0"), 8, 10, 20, 30,
  105. SubnetID(1)));
  106. Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.0"), 24, 10, 20, 30,
  107. SubnetID(2)));
  108. Subnet4Ptr subnet3(new Subnet4(IOAddress("172.16.25.0"), 24, 10, 20, 30,
  109. SubnetID(3)));
  110. std::vector<Subnet4Ptr> subnets;
  111. subnets.push_back(subnet1);
  112. subnets.push_back(subnet2);
  113. subnets.push_back(subnet3);
  114. // Subnets have unique IDs so they should successfully be added to the
  115. // network.
  116. for (auto i = 0; i < subnets.size(); ++i) {
  117. ASSERT_NO_THROW(network->add(subnets[i]))
  118. << "failed to add subnet with id " << subnets[i]->getID()
  119. << " to shared network";
  120. }
  121. // Collect networks associated with our subnets in the vector.
  122. std::vector<SharedNetwork4Ptr> networks;
  123. for (auto i = 0; i < subnets.size(); ++i) {
  124. SharedNetwork4Ptr network;
  125. subnets[i]->getSharedNetwork(network);
  126. ASSERT_TRUE(network) << "failed to retrieve shared network for a"
  127. << " subnet id " << subnets[i]->getID();
  128. networks.push_back(network);
  129. }
  130. // All subnets should be associated with the same network.
  131. for (auto i = 1; i < networks.size(); ++i) {
  132. EXPECT_TRUE(networks[0] == networks[i]);
  133. }
  134. // Perform the test 3 times where each subnet belonging to the shared
  135. // network is treated as a "first" subnet in the call to getNextSubnet.
  136. for (auto i = 0; i < subnets.size(); ++i) {
  137. Subnet4Ptr s = subnets[i];
  138. // Iterate over the subnets starting from the subnet with index i.
  139. for (auto j = 0; j < subnets.size(); ++j) {
  140. // Get next subnet (following the one currently in s).
  141. s = networks[0]->getNextSubnet(subnets[i], s->getID());
  142. // The last iteration should return empty pointer to indicate end of
  143. // the subnets within shared network. If we're not at last iteration
  144. // check that the subnet identifier of the returned subnet is valid.
  145. if (j < subnets.size() - 1) {
  146. ASSERT_TRUE(s) << "retrieving next subnet failed for pair of"
  147. " indexes (i, j) = (" << i << ", " << j << ")";
  148. const auto expected_subnet_id = (i + j + 1) % subnets.size() + 1;
  149. EXPECT_EQ(expected_subnet_id, s->getID());
  150. } else {
  151. // Null subnet returned for a last iteration.
  152. ASSERT_FALSE(s) << "expected null pointer to be returned as"
  153. " next subnet for pair of indexes (i, j) = ("
  154. << i << ", " << j << ")";
  155. }
  156. }
  157. }
  158. }
  159. // This test verifies that unparsing shared network returns valid structure.
  160. TEST(SharedNetwork4Test, unparse) {
  161. SharedNetwork4Ptr network(new SharedNetwork4("frog"));
  162. // Set interface name.
  163. network->setIface("eth1");
  164. network->setT1(100);
  165. network->setT2(150);
  166. network->setValid(200);
  167. network->setMatchClientId(false);
  168. // Add several subnets.
  169. Subnet4Ptr subnet1(new Subnet4(IOAddress("10.0.0.0"), 8, 10, 20, 30,
  170. SubnetID(1)));
  171. Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.0"), 24, 10, 20, 30,
  172. SubnetID(2)));
  173. network->add(subnet1);
  174. network->add(subnet2);
  175. std::string expected = "{\n"
  176. " \"interface\": \"eth1\",\n"
  177. " \"match-client-id\": false,\n"
  178. " \"name\": \"frog\",\n"
  179. " \"option-data\": [ ],\n"
  180. " \"rebind-timer\": 150,\n"
  181. " \"relay\": {\n"
  182. " \"ip-address\": \"0.0.0.0\"\n"
  183. " },\n"
  184. " \"renew-timer\": 100,\n"
  185. " \"reservation-mode\": \"all\","
  186. " \"subnet4\": [\n"
  187. " {\n"
  188. " \"4o6-interface\": \"\",\n"
  189. " \"4o6-interface-id\": \"\",\n"
  190. " \"4o6-subnet\": \"\",\n"
  191. " \"id\": 1,\n"
  192. " \"match-client-id\": true,\n"
  193. " \"next-server\": \"0.0.0.0\",\n"
  194. " \"option-data\": [ ],\n"
  195. " \"pools\": [ ],\n"
  196. " \"rebind-timer\": 20,\n"
  197. " \"relay\": {\n"
  198. " \"ip-address\": \"0.0.0.0\"\n"
  199. " },\n"
  200. " \"renew-timer\": 10,\n"
  201. " \"reservation-mode\": \"all\",\n"
  202. " \"subnet\": \"10.0.0.0/8\",\n"
  203. " \"valid-lifetime\": 30\n"
  204. " },\n"
  205. " {\n"
  206. " \"4o6-interface\": \"\",\n"
  207. " \"4o6-interface-id\": \"\",\n"
  208. " \"4o6-subnet\": \"\",\n"
  209. " \"id\": 2,\n"
  210. " \"match-client-id\": true,\n"
  211. " \"next-server\": \"0.0.0.0\",\n"
  212. " \"option-data\": [ ],\n"
  213. " \"pools\": [ ],\n"
  214. " \"rebind-timer\": 20,\n"
  215. " \"relay\": {\n"
  216. " \"ip-address\": \"0.0.0.0\"\n"
  217. " },\n"
  218. " \"renew-timer\": 10,\n"
  219. " \"reservation-mode\": \"all\",\n"
  220. " \"subnet\": \"192.0.2.0/24\",\n"
  221. " \"valid-lifetime\": 30\n"
  222. " }\n"
  223. " ],\n"
  224. " \"valid-lifetime\": 200\n"
  225. "}\n";
  226. test::runToElementTest<SharedNetwork4>(expected, *network);
  227. }
  228. // This test verifies that when the shared network object is destroyed,
  229. // the subnets belonging to this shared network will not hold the pointer
  230. // to the destroyed network.
  231. TEST(SharedNetwork4Test, destructSharedNetwork) {
  232. // Create a network and add a subnet to it.
  233. SharedNetwork4Ptr network(new SharedNetwork4("frog"));
  234. Subnet4Ptr subnet(new Subnet4(IOAddress("10.0.0.0"), 8, 10, 20, 30,
  235. SubnetID(1)));
  236. ASSERT_NO_THROW(network->add(subnet));
  237. // Get the pointer to the network from subnet.
  238. SharedNetwork4Ptr subnet_to_network;
  239. subnet->getSharedNetwork(subnet_to_network);
  240. ASSERT_TRUE(subnet_to_network);
  241. // Reset the pointer to not hold the reference to the shared network.
  242. subnet_to_network.reset();
  243. // Destroy the network object.
  244. network.reset();
  245. // The reference to the network from the subnet should be lost.
  246. subnet->getSharedNetwork(subnet_to_network);
  247. ASSERT_FALSE(subnet_to_network);
  248. }
  249. // This test verifies that shared network can be given a name and that
  250. // this name can be retrieved.
  251. TEST(SharedNetwork6Test, getName) {
  252. // Create shared network with an initial name "frog".
  253. SharedNetwork6Ptr network(new SharedNetwork6("frog"));
  254. EXPECT_EQ("frog", network->getName());
  255. // Override the name.
  256. network->setName("dog");
  257. EXPECT_EQ("dog", network->getName());
  258. }
  259. // This test verifies that an IPv6 subnet can be added to a shared network.
  260. // It also verifies that two subnets with the same ID can't be added to
  261. // a shared network and that a single subnet can't be added to two different
  262. // shared subnets.
  263. TEST(SharedNetwork6Test, addSubnet6) {
  264. // First, create a network.
  265. SharedNetwork6Ptr network(new SharedNetwork6("frog"));
  266. // Try to add null pointer. It should throw.
  267. Subnet6Ptr subnet;
  268. ASSERT_THROW(network->add(subnet), BadValue);
  269. // Create a valid subnet. It should now be added successfully.
  270. subnet.reset(new Subnet6(IOAddress("2001:db8:1::"), 64, 10, 20, 30, 40,
  271. SubnetID(15)));
  272. ASSERT_NO_THROW(network->add(subnet));
  273. ASSERT_EQ(1, network->getAllSubnets()->size());
  274. // Retrieve the subnet from the network and make sure it is returned
  275. // as expected.
  276. Subnet6Ptr returned_subnet = network->getAllSubnets()->front();
  277. ASSERT_TRUE(returned_subnet);
  278. EXPECT_EQ(subnet->getID(), returned_subnet->getID());
  279. SharedNetwork6Ptr network1;
  280. subnet->getSharedNetwork(network1);
  281. ASSERT_TRUE(network1);
  282. EXPECT_TRUE(network1 == network);
  283. // Create another subnet with the same ID. Adding a network with the
  284. // same ID should cause an error.
  285. Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 16, 10, 20, 30, 40,
  286. SubnetID(15)));
  287. ASSERT_THROW(network->add(subnet), DuplicateSubnetID);
  288. // Create another network and try to add a subnet to it. It should fail
  289. // because the subnet is already associated with the first network.
  290. SharedNetwork6Ptr network2(new SharedNetwork6("dog"));
  291. ASSERT_THROW(network2->add(subnet), InvalidOperation);
  292. }
  293. // This test verifies that it is possible to remove a specified subnet.
  294. TEST(SharedNetwork6Test, delSubnet6) {
  295. // Create two subnets and add them to the shared network.
  296. Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 64, 10, 20, 30,
  297. 40, SubnetID(1)));
  298. Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 16, 10, 20, 30, 40,
  299. SubnetID(2)));
  300. SharedNetwork6Ptr network(new SharedNetwork6("frog"));
  301. ASSERT_NO_THROW(network->add(subnet1));
  302. ASSERT_NO_THROW(network->add(subnet2));
  303. // Make sure they have been added successfully.
  304. ASSERT_EQ(2, network->getAllSubnets()->size());
  305. // Try to remove a subnet that doesn't exist in this shared network.
  306. // It should cause an error.
  307. ASSERT_THROW(network->del(SubnetID(5)), BadValue);
  308. // Now delete the subnet that exists.
  309. ASSERT_NO_THROW(network->del(subnet1->getID()));
  310. // We should be left with only one subnet.
  311. ASSERT_EQ(1, network->getAllSubnets()->size());
  312. Subnet6Ptr subnet_returned = network->getAllSubnets()->front();
  313. ASSERT_TRUE(subnet_returned);
  314. EXPECT_EQ(subnet2->getID(), subnet_returned->getID());
  315. // Check that shared network has been cleared for the removed subnet.
  316. SharedNetwork6Ptr network1;
  317. subnet1->getSharedNetwork(network1);
  318. EXPECT_FALSE(network1);
  319. // Remove another subnet and make sure there are no subnets left.
  320. ASSERT_NO_THROW(network->del(subnet2->getID()));
  321. EXPECT_EQ(0, network->getAllSubnets()->size());
  322. // The network pointer should be cleared for this second subnet too.
  323. SharedNetwork6Ptr network2;
  324. subnet1->getSharedNetwork(network2);
  325. EXPECT_FALSE(network2);
  326. }
  327. // This test verifies that it is possible to iterate over the subnets
  328. // associated with a particular shared network.
  329. TEST(SharedNetwork6Test, getNextSubnet) {
  330. SharedNetwork6Ptr network(new SharedNetwork6("frog"));
  331. // Create three subnets.
  332. Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 64, 10, 20, 30,
  333. 40, SubnetID(1)));
  334. Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 16, 10, 20, 30, 40,
  335. SubnetID(2)));
  336. Subnet6Ptr subnet3(new Subnet6(IOAddress("2001:db8:2::"), 64, 10, 20, 30,
  337. 40, SubnetID(3)));
  338. std::vector<Subnet6Ptr> subnets;
  339. subnets.push_back(subnet1);
  340. subnets.push_back(subnet2);
  341. subnets.push_back(subnet3);
  342. // Subnets have unique IDs so they should successfully be added to the
  343. // network.
  344. for (auto i = 0; i < subnets.size(); ++i) {
  345. ASSERT_NO_THROW(network->add(subnets[i]))
  346. << "failed to add subnet with id " << subnets[i]->getID()
  347. << " to shared network";
  348. }
  349. // Collect networks associated with our subnets in the vector.
  350. std::vector<SharedNetwork6Ptr> networks;
  351. for (auto i = 0; i < subnets.size(); ++i) {
  352. SharedNetwork6Ptr network;
  353. subnets[i]->getSharedNetwork(network);
  354. ASSERT_TRUE(network) << "failed to retrieve shared network for a"
  355. << " subnet id " << subnets[i]->getID();
  356. networks.push_back(network);
  357. }
  358. // All subnets should be associated with the same network.
  359. for (auto i = 1; i < networks.size(); ++i) {
  360. EXPECT_TRUE(networks[0] == networks[i]);
  361. }
  362. // Perform the test 3 times where each subnet belonging to the shared
  363. // network is treated as a "first" subnet in the call to getNextSubnet.
  364. for (auto i = 0; i < subnets.size(); ++i) {
  365. Subnet6Ptr s = subnets[i];
  366. // Iterate over the subnets starting from the subnet with index i.
  367. for (auto j = 0; j < subnets.size(); ++j) {
  368. // Get next subnet (following the one currently in s).
  369. s = networks[0]->getNextSubnet(subnets[i], s->getID());
  370. // The last iteration should return empty pointer to indicate end of
  371. // the subnets within shared network. If we're not at last iteration
  372. // check that the subnet identifier of the returned subnet is valid.
  373. if (j < subnets.size() - 1) {
  374. ASSERT_TRUE(s) << "retrieving next subnet failed for pair of"
  375. " indexes (i, j) = (" << i << ", " << j << ")";
  376. const auto expected_subnet_id = (i + j + 1) % subnets.size() + 1;
  377. EXPECT_EQ(expected_subnet_id, s->getID());
  378. } else {
  379. // Null subnet returned for a last iteration.
  380. ASSERT_FALSE(s) << "expected null pointer to be returned as"
  381. " next subnet for pair of indexes (i, j) = ("
  382. << i << ", " << j << ")";
  383. }
  384. }
  385. }
  386. }
  387. // This test verifies that unparsing shared network returns valid structure.
  388. TEST(SharedNetwork6Test, unparse) {
  389. SharedNetwork6Ptr network(new SharedNetwork6("frog"));
  390. network->setIface("eth1");
  391. network->setT1(100);
  392. network->setT2(150);
  393. network->setPreferred(200);
  394. network->setValid(300);
  395. network->setRapidCommit(true);
  396. // Add several subnets.
  397. Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 64, 10, 20, 30,
  398. 40, SubnetID(1)));
  399. Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 16, 10, 20, 30, 40,
  400. SubnetID(2)));
  401. network->add(subnet1);
  402. network->add(subnet2);
  403. std::string expected = "{\n"
  404. " \"interface\": \"eth1\",\n"
  405. " \"name\": \"frog\",\n"
  406. " \"option-data\": [ ],\n"
  407. " \"preferred-lifetime\": 200,\n"
  408. " \"rapid-commit\": true,\n"
  409. " \"rebind-timer\": 150,\n"
  410. " \"relay\": {\n"
  411. " \"ip-address\": \"::\"\n"
  412. " },\n"
  413. " \"renew-timer\": 100,\n"
  414. " \"reservation-mode\": \"all\","
  415. " \"subnet6\": [\n"
  416. " {\n"
  417. " \"id\": 1,\n"
  418. " \"option-data\": [ ],\n"
  419. " \"pd-pools\": [ ],\n"
  420. " \"pools\": [ ],\n"
  421. " \"preferred-lifetime\": 30,\n"
  422. " \"rapid-commit\": false,\n"
  423. " \"rebind-timer\": 20,\n"
  424. " \"relay\": {\n"
  425. " \"ip-address\": \"::\"\n"
  426. " },\n"
  427. " \"renew-timer\": 10,\n"
  428. " \"reservation-mode\": \"all\",\n"
  429. " \"subnet\": \"2001:db8:1::/64\",\n"
  430. " \"valid-lifetime\": 40\n"
  431. " },\n"
  432. " {\n"
  433. " \"id\": 2,\n"
  434. " \"option-data\": [ ],\n"
  435. " \"pd-pools\": [ ],\n"
  436. " \"pools\": [ ],\n"
  437. " \"preferred-lifetime\": 30,\n"
  438. " \"rapid-commit\": false,\n"
  439. " \"rebind-timer\": 20,\n"
  440. " \"relay\": {\n"
  441. " \"ip-address\": \"::\"\n"
  442. " },\n"
  443. " \"renew-timer\": 10,\n"
  444. " \"reservation-mode\": \"all\",\n"
  445. " \"subnet\": \"3000::/16\",\n"
  446. " \"valid-lifetime\": 40\n"
  447. " }\n"
  448. " ],\n"
  449. " \"valid-lifetime\": 300\n"
  450. "}\n";
  451. test::runToElementTest<SharedNetwork6>(expected, *network);
  452. }
  453. // This test verifies that when the shared network object is destroyed,
  454. // the subnets belonging to this shared network will not hold the pointer
  455. // to the destroyed network.
  456. TEST(SharedNetwork6Test, destructSharedNetwork) {
  457. // Create a network and add a subnet to it.
  458. SharedNetwork6Ptr network(new SharedNetwork6("frog"));
  459. Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 64, 10, 20, 30,
  460. 40, SubnetID(1)));
  461. ASSERT_NO_THROW(network->add(subnet));
  462. // Get the pointer to the network from subnet.
  463. SharedNetwork6Ptr subnet_to_network;
  464. subnet->getSharedNetwork(subnet_to_network);
  465. ASSERT_TRUE(subnet_to_network);
  466. // Reset the pointer to not hold the reference to the shared network.
  467. subnet_to_network.reset();
  468. // Destroy the network object.
  469. network.reset();
  470. // The reference to the network from the subnet should be lost.
  471. subnet->getSharedNetwork(subnet_to_network);
  472. ASSERT_FALSE(subnet_to_network);
  473. }
  474. } // end of anonymous namespace