nodecontainer_test.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #include <gtest/gtest.h>
  2. #include <memory>
  3. #include <sstream>
  4. #include <tins/tins.h>
  5. #include "nodecontainer.hpp"
  6. #include "nodeinfo.hpp"
  7. class NodeContainerTest : public testing::Test
  8. {
  9. protected:
  10. // cppcheck-suppress duplInheritedMember
  11. static void SetUpTestSuite()
  12. {
  13. testing::Test::SetUpTestSuite();
  14. /* Container 1 */
  15. container1 = std::make_unique<NodeContainer>();
  16. c1_child_node1 = std::make_shared<NodeInfo>();
  17. c1_child_node1->set_hoplimit(20);
  18. c1_child_node1->set_mac_address(
  19. Tins::HWAddress<6>("52:54:00:b2:fa:7f"));
  20. c1_child_node1->add_address(Tins::IPv6Address("fd00::11"));
  21. c1_child_node1->add_address(Tins::IPv6Address("fd00::12"));
  22. container1->add_node(c1_child_node1);
  23. c1_child_node2 = std::make_shared<NodeInfo>();
  24. c1_child_node2->set_hoplimit(30);
  25. c1_child_node2->set_mac_address(
  26. Tins::HWAddress<6>("52:54:00:b2:fa:7e"));
  27. c1_child_node2->add_address(Tins::IPv6Address("fd00::21"));
  28. container1->add_node(c1_child_node2);
  29. c1_child_node3 = std::make_shared<NodeInfo>();
  30. c1_child_node3->set_mac_address(
  31. Tins::HWAddress<6>("52:54:00:b2:fa:7d"));
  32. c1_child_node3->add_address(Tins::IPv6Address("fd00::3"));
  33. c1_child_node3_child1 = std::make_shared<NodeInfo>();
  34. c1_child_node3_child1->add_address(Tins::IPv6Address("fd00::3:1"));
  35. c1_child_node3->add_node(c1_child_node3_child1);
  36. c1_child_node3_child2 = std::make_shared<NodeInfo>();
  37. c1_child_node3_child2->add_address(Tins::IPv6Address("fd00::3:2"));
  38. c1_child_node3_child2_child1 = std::make_shared<NodeInfo>();
  39. c1_child_node3_child2_child1->add_address(
  40. Tins::IPv6Address("fd00::3:2:1"));
  41. c1_child_node3_child2->add_node(c1_child_node3_child2_child1);
  42. c1_child_node3->add_node(c1_child_node3_child2);
  43. container1->add_node(c1_child_node3);
  44. /* Container 2 */
  45. container2 = std::make_unique<NodeContainer>();
  46. c2_child_node1 = std::make_shared<NodeInfo>();
  47. c2_child_node1->set_mac_address(
  48. Tins::HWAddress<6>("52:54:00:b2:fa:7f"));
  49. c2_child_node1->add_address(Tins::IPv6Address("fd01::"));
  50. container2->add_node(c2_child_node1);
  51. /* Container 3 */
  52. container3 = std::make_unique<NodeContainer>();
  53. }
  54. // NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)
  55. static std::unique_ptr<NodeContainer> container1;
  56. static std::shared_ptr<NodeInfo> c1_child_node1;
  57. static std::shared_ptr<NodeInfo> c1_child_node2;
  58. static std::shared_ptr<NodeInfo> c1_child_node3;
  59. static std::shared_ptr<NodeInfo> c1_child_node3_child1;
  60. static std::shared_ptr<NodeInfo> c1_child_node3_child2;
  61. static std::shared_ptr<NodeInfo> c1_child_node3_child2_child1;
  62. static std::unique_ptr<NodeContainer> container2;
  63. static std::shared_ptr<NodeInfo> c2_child_node1;
  64. static std::unique_ptr<NodeContainer> container3;
  65. // NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
  66. };
  67. // NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)
  68. std::unique_ptr<NodeContainer> NodeContainerTest::container1;
  69. std::shared_ptr<NodeInfo> NodeContainerTest::c1_child_node1;
  70. std::shared_ptr<NodeInfo> NodeContainerTest::c1_child_node2;
  71. std::shared_ptr<NodeInfo> NodeContainerTest::c1_child_node3;
  72. std::shared_ptr<NodeInfo> NodeContainerTest::c1_child_node3_child1;
  73. std::shared_ptr<NodeInfo> NodeContainerTest::c1_child_node3_child2;
  74. std::shared_ptr<NodeInfo> NodeContainerTest::c1_child_node3_child2_child1;
  75. std::unique_ptr<NodeContainer> NodeContainerTest::container2;
  76. std::shared_ptr<NodeInfo> NodeContainerTest::c2_child_node1;
  77. std::unique_ptr<NodeContainer> NodeContainerTest::container3;
  78. // NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
  79. TEST_F(NodeContainerTest, Print)
  80. {
  81. std::ostringstream test_output;
  82. container1->print(test_output);
  83. EXPECT_EQ(
  84. test_output.str(),
  85. "NodeContainer: 3 childnodes\nChilds:\n\tNodeInfo: hoplimit=20 "
  86. "fd00::11 fd00::12 52:54:00:b2:fa:7f\n\tNodeInfo: hoplimit=30 fd00::21 "
  87. "52:54:00:b2:fa:7e\n\tNodeInfo: hoplimit=64 fd00::3 "
  88. "52:54:00:b2:fa:7d\n\tChilds:\n\t\tNodeInfo: hoplimit=64 "
  89. "fd00::3:1\n\t\tNodeInfo: hoplimit=64 "
  90. "fd00::3:2\n\t\tChilds:\n\t\t\tNodeInfo: hoplimit=64 fd00::3:2:1\n");
  91. test_output.str("");
  92. container2->print(test_output);
  93. EXPECT_EQ(test_output.str(),
  94. "NodeContainer: 1 childnodes\nChilds:\n\tNodeInfo: hoplimit=64 "
  95. "fd01:: 52:54:00:b2:fa:7f\n");
  96. test_output.str("");
  97. container3->print(test_output);
  98. EXPECT_EQ(test_output.str(), "NodeContainer: 0 childnodes\n");
  99. }
  100. TEST_F(NodeContainerTest, Output)
  101. {
  102. std::ostringstream test_output;
  103. test_output << *container1;
  104. EXPECT_EQ(test_output.str(), "NodeContainer: 3 childnodes");
  105. test_output.str("");
  106. test_output << *container2;
  107. EXPECT_EQ(test_output.str(), "NodeContainer: 1 childnodes");
  108. test_output.str("");
  109. test_output << *container3;
  110. EXPECT_EQ(test_output.str(), "NodeContainer: 0 childnodes");
  111. }
  112. TEST_F(NodeContainerTest, MaxDepth)
  113. {
  114. EXPECT_EQ(container1->max_depth(), 3);
  115. EXPECT_EQ(container2->max_depth(), 1);
  116. EXPECT_EQ(container3->max_depth(), 0);
  117. }
  118. TEST_F(NodeContainerTest, Comparison)
  119. {
  120. NodeContainer container;
  121. auto c1_child_node1 = std::make_shared<NodeInfo>();
  122. c1_child_node1->set_hoplimit(20);
  123. c1_child_node1->set_mac_address(Tins::HWAddress<6>("52:54:00:b2:fa:7f"));
  124. c1_child_node1->add_address(Tins::IPv6Address("fd00::11"));
  125. c1_child_node1->add_address(Tins::IPv6Address("fd00::12"));
  126. container.add_node(c1_child_node1);
  127. auto c1_child_node2 = std::make_shared<NodeInfo>();
  128. c1_child_node2->set_hoplimit(30);
  129. c1_child_node2->set_mac_address(Tins::HWAddress<6>("52:54:00:b2:fa:7e"));
  130. c1_child_node2->add_address(Tins::IPv6Address("fd00::21"));
  131. container.add_node(c1_child_node2);
  132. auto c1_child_node3 = std::make_shared<NodeInfo>();
  133. c1_child_node3->set_mac_address(Tins::HWAddress<6>("52:54:00:b2:fa:7d"));
  134. c1_child_node3->add_address(Tins::IPv6Address("fd00::3"));
  135. auto c1_child_node3_child1 = std::make_shared<NodeInfo>();
  136. c1_child_node3_child1->add_address(Tins::IPv6Address("fd00::3:1"));
  137. c1_child_node3->add_node(c1_child_node3_child1);
  138. auto c1_child_node3_child2 = std::make_shared<NodeInfo>();
  139. c1_child_node3_child2->add_address(Tins::IPv6Address("fd00::3:2"));
  140. auto c1_child_node3_child2_child1 = std::make_shared<NodeInfo>();
  141. c1_child_node3_child2_child1->add_address(Tins::IPv6Address("fd00::3:2:1"));
  142. c1_child_node3_child2->add_node(c1_child_node3_child2_child1);
  143. c1_child_node3->add_node(c1_child_node3_child2);
  144. container.add_node(c1_child_node3);
  145. EXPECT_EQ(*container1, container);
  146. EXPECT_NE(*container2, container);
  147. EXPECT_NE(*container3, container);
  148. }
  149. Tins::EthernetII
  150. create_echo_request(const Tins::HWAddress<6>& source_mac,
  151. const Tins::HWAddress<6>& destination_mac,
  152. const Tins::IPv6Address& source_address,
  153. const Tins::IPv6Address& destination_address,
  154. const int hoplimit,
  155. const int icmp_identifier,
  156. const int icmp_sequence,
  157. const Tins::RawPDU::payload_type& payload)
  158. {
  159. Tins::EthernetII packet = Tins::EthernetII(destination_mac, source_mac) /
  160. Tins::IPv6(destination_address, source_address) /
  161. Tins::ICMPv6(Tins::ICMPv6::Types::ECHO_REQUEST);
  162. Tins::IPv6& inner_ipv6 = packet.rfind_pdu<Tins::IPv6>();
  163. inner_ipv6.hop_limit(hoplimit);
  164. Tins::ICMPv6& inner_icmpv6 = inner_ipv6.rfind_pdu<Tins::ICMPv6>();
  165. inner_icmpv6.identifier(icmp_identifier);
  166. inner_icmpv6.sequence(icmp_sequence);
  167. inner_icmpv6.inner_pdu(Tins::RawPDU(payload));
  168. const Tins::PDU::serialization_type serialized_packet = packet.serialize();
  169. const Tins::EthernetII final_packet(serialized_packet.data(),
  170. serialized_packet.size());
  171. return final_packet;
  172. }
  173. std::string create_echo_reply(const Tins::HWAddress<6>& source_mac,
  174. const Tins::HWAddress<6>& destination_mac,
  175. const Tins::IPv6Address& source_address,
  176. const Tins::IPv6Address& destination_address,
  177. const int hoplimit,
  178. const int icmp_identifier,
  179. const int icmp_sequence,
  180. const Tins::RawPDU::payload_type& payload)
  181. {
  182. Tins::EthernetII packet = Tins::EthernetII(destination_mac, source_mac) /
  183. Tins::IPv6(destination_address, source_address) /
  184. Tins::ICMPv6(Tins::ICMPv6::Types::ECHO_REPLY);
  185. Tins::IPv6& inner_ipv6 = packet.rfind_pdu<Tins::IPv6>();
  186. inner_ipv6.hop_limit(hoplimit);
  187. Tins::ICMPv6& inner_icmpv6 = inner_ipv6.rfind_pdu<Tins::ICMPv6>();
  188. inner_icmpv6.identifier(icmp_identifier);
  189. inner_icmpv6.sequence(icmp_sequence);
  190. inner_icmpv6.inner_pdu(Tins::RawPDU(payload));
  191. const Tins::PDU::serialization_type serialized_packet = packet.serialize();
  192. const std::string final_packet(serialized_packet.begin(),
  193. serialized_packet.end());
  194. return final_packet;
  195. }
  196. TEST_F(NodeContainerTest, GetReplyEchoRequest)
  197. {
  198. const Tins::HWAddress<6> source_mac("52:54:01:b2:fa:7f");
  199. const Tins::HWAddress<6> destination_mac("52:54:00:b2:fa:7d");
  200. const Tins::IPv6Address source_address("fd01::1");
  201. const Tins::IPv6Address destination_address("fd00::3:2:1");
  202. constexpr int hoplimit = 55;
  203. constexpr int icmp_identifier = 56;
  204. constexpr int icmp_sequence = 1;
  205. const Tins::RawPDU::payload_type payload = {8, 4, 5, 9, 255, 0, 0, 0, 0, 0};
  206. const Tins::EthernetII request_packet =
  207. create_echo_request(source_mac,
  208. destination_mac,
  209. source_address,
  210. destination_address,
  211. hoplimit,
  212. icmp_identifier,
  213. icmp_sequence,
  214. payload);
  215. const NodeRequest echo_request(request_packet);
  216. NodeReply echo_reply = container1->get_reply(echo_request);
  217. const std::string reply_packet = create_echo_reply(destination_mac,
  218. source_mac,
  219. destination_address,
  220. source_address,
  221. 62,
  222. icmp_identifier,
  223. icmp_sequence,
  224. payload);
  225. EXPECT_EQ(echo_reply.to_packet(), reply_packet);
  226. }