1 #include "types.hpp" 2 #include "rtnetlink_server.hpp" 3 #include "network_manager.hpp" 4 #include "mock_syscall.hpp" 5 #include "timer.hpp" 6 #include "types.hpp" 7 8 9 #include <gtest/gtest.h> 10 #include <sdbusplus/bus.hpp> 11 12 #include <net/if.h> 13 #include <linux/rtnetlink.h> 14 15 namespace phosphor 16 { 17 18 namespace network 19 { 20 sdbusplus::bus::bus bus(sdbusplus::bus::new_default()); 21 std::unique_ptr<Manager> manager = nullptr; 22 std::unique_ptr<Timer> refreshObjectTimer = nullptr; 23 std::unique_ptr<Timer> restartTimer = nullptr; 24 EventPtr eventPtr = nullptr; 25 26 /** @brief refresh the network objects. */ 27 void refreshObjects() 28 { 29 30 if (manager) 31 { 32 manager->createChildObjects(); 33 } 34 } 35 36 void initializeTimers() 37 { 38 std::function<void()> refreshFunc( 39 std::bind(&refreshObjects)); 40 41 refreshObjectTimer = 42 std::make_unique<Timer>(refreshFunc); 43 44 } 45 46 class TestRtNetlink : public testing::Test 47 { 48 49 public: 50 std::string confDir; 51 phosphor::Descriptor smartSock; 52 53 54 55 TestRtNetlink() 56 { 57 manager = 58 std::make_unique<Manager>(bus, 59 "/xyz/openbmc_test/bcd", 60 "/tmp"); 61 sd_event* events; 62 sd_event_default(&events); 63 eventPtr.reset(events); 64 events = nullptr; 65 setConfDir(); 66 initializeTimers(); 67 createNetLinkSocket(); 68 bus.attach_event(eventPtr.get(), SD_EVENT_PRIORITY_NORMAL); 69 rtnetlink::Server svr(eventPtr, smartSock); 70 } 71 72 ~TestRtNetlink() 73 { 74 if (confDir.empty()) 75 { 76 fs::remove_all(confDir); 77 } 78 } 79 80 void setConfDir() 81 { 82 char tmp[] = "/tmp/NetworkManager.XXXXXX"; 83 confDir = mkdtemp(tmp); 84 manager->setConfDir(confDir); 85 } 86 87 bool isInterfaceAdded(std::string intf) 88 { 89 return manager->interfaces.find(intf) != manager->interfaces.end()? 90 true : 91 false; 92 } 93 94 void createNetLinkSocket() 95 { 96 //RtnetLink socket 97 auto fd = socket(PF_NETLINK, SOCK_RAW | SOCK_NONBLOCK, 98 NETLINK_ROUTE); 99 smartSock.set(fd); 100 } 101 }; 102 103 104 TEST_F(TestRtNetlink, WithSingleInterface) 105 { 106 using namespace std::chrono; 107 // Adds the following ip in the getifaddrs list. 108 mock_addIP("igb5", "127.0.0.1", "255.255.255.128", 109 IFF_UP | IFF_RUNNING); 110 constexpr auto BUFSIZE = 4096; 111 std::array<char, BUFSIZE> msgBuf = {0}; 112 113 // point the header and the msg structure pointers into the buffer. 114 auto nlMsg = reinterpret_cast<nlmsghdr*>(msgBuf.data()); 115 // Length of message 116 nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(rtmsg)); 117 nlMsg->nlmsg_type = RTM_GETADDR; 118 nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; 119 nlMsg->nlmsg_seq = 0; 120 nlMsg->nlmsg_pid = getpid(); 121 122 EXPECT_EQ(false, isInterfaceAdded("igb5")); 123 // Send the request 124 send(smartSock(), nlMsg, nlMsg->nlmsg_len, 0); 125 126 int i = 3; 127 while (i--) 128 { 129 //wait for timer to expire 130 std::this_thread::sleep_for( 131 std::chrono::milliseconds(refreshTimeout)); 132 sd_event_run(eventPtr.get(), 10); 133 }; 134 135 EXPECT_EQ(true, isInterfaceAdded("igb5")); 136 } 137 138 }// namespce network 139 }// namespace phosphor 140