test: Add test cases for network manager

Resolves openbmc/openbmc#1462

Change-Id: Ib4cb6fc52dca05c9af38fe5197d9d7dff2031af7
Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
diff --git a/test/Makefile.am b/test/Makefile.am
index 5899847..b2fbced 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,11 +1,13 @@
-AM_CPPFLAGS = -I${top_srcdir}
+AM_CPPFLAGS = -I${top_srcdir} -I${top_builddir}
 
 TESTS = $(check_PROGRAMS)
 
 check_PROGRAMS = test
 
 test_SOURCES = \
-	test_util.cpp
+	test_util.cpp \
+	mock_syscall.cpp \
+	test_network_manager.cpp
 
 test_CPPFLAGS = -Igtest $(GTEST_CPPFLAGS) $(AM_CPPFLAGS)
 test_CXXFLAGS = $(PTHREAD_CFLAGS)
@@ -13,6 +15,13 @@
 test_LDFLAGS =	-lgtest_main -lgtest -lstdc++fs \
 				$(OESDK_TESTCASE_FLAGS) \
 				$(SYSTEMD_LIBS) \
-				$(SDBUSPLUS_LIBS)
+				$(SDBUSPLUS_LIBS) \
+				$(PHOSPHOR_DBUS_INTERFACES_LIBS)
 
-test_LDADD = $(top_builddir)/util.cpp
+test_LDADD = $(top_builddir)/ethernet_interface.cpp \
+			$(top_builddir)/network_manager.cpp \
+			$(top_builddir)/network_config.cpp \
+			$(top_builddir)/ipaddress.cpp \
+			$(top_builddir)/util.cpp \
+			$(top_builddir)/xyz/openbmc_project/Network/VLAN/Create/phosphor_network_manager-server.o \
+			$(top_builddir)/xyz/openbmc_project/Network/IP/Create/phosphor_network_manager-server.o
diff --git a/test/mock_syscall.cpp b/test/mock_syscall.cpp
new file mode 100644
index 0000000..173b67f
--- /dev/null
+++ b/test/mock_syscall.cpp
@@ -0,0 +1,71 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <ifaddrs.h>
+
+#define MAX_IFADDRS 5
+
+int debugging = false;
+
+/* Data for mocking getifaddrs */
+struct ifaddr_storage {
+    struct ifaddrs ifaddr;
+    struct sockaddr_storage addr;
+    struct sockaddr_storage mask;
+    struct sockaddr_storage bcast;
+} mock_ifaddr_storage[MAX_IFADDRS];
+
+struct ifaddrs *mock_ifaddrs = nullptr;
+
+int ifaddr_count = 0;
+
+/* Stub library functions */
+void freeifaddrs(ifaddrs *ifp)
+{
+    return ;
+}
+
+void mock_addIP(const char* name, const char* addr, const char* mask,
+                unsigned int flags)
+{
+    struct ifaddrs *ifaddr = &mock_ifaddr_storage[ifaddr_count].ifaddr;
+
+    struct sockaddr_in *in = reinterpret_cast<sockaddr_in*>
+                    (&mock_ifaddr_storage[ifaddr_count].addr);
+    struct sockaddr_in *mask_in = reinterpret_cast<sockaddr_in*>
+                    (&mock_ifaddr_storage[ifaddr_count].mask);
+
+    in->sin_family = AF_INET;
+    in->sin_port = 0;
+    in->sin_addr.s_addr = inet_addr(addr);
+
+    mask_in->sin_family = AF_INET;
+    mask_in->sin_port = 0;
+    mask_in->sin_addr.s_addr = inet_addr(mask);
+
+    ifaddr->ifa_next = nullptr;
+    ifaddr->ifa_name = const_cast<char*>(name);
+    ifaddr->ifa_flags = flags;
+    ifaddr->ifa_addr = reinterpret_cast<struct sockaddr*>(in);
+    ifaddr->ifa_netmask = reinterpret_cast<struct sockaddr*>(mask_in);
+    ifaddr->ifa_data = nullptr;
+
+    if (ifaddr_count > 0)
+        mock_ifaddr_storage[ifaddr_count - 1].ifaddr.ifa_next = ifaddr;
+    ifaddr_count++;
+    mock_ifaddrs = &mock_ifaddr_storage[0].ifaddr;
+
+}
+
+int getifaddrs(ifaddrs **ifap)
+{
+    *ifap = mock_ifaddrs;
+    if (mock_ifaddrs == nullptr)
+        return -1;
+    return (0);
+}
+
diff --git a/test/mock_syscall.hpp b/test/mock_syscall.hpp
new file mode 100644
index 0000000..d219999
--- /dev/null
+++ b/test/mock_syscall.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+/** @brief Adds the given interface and addr info
+ *         into the ifaddr list.
+ *  @param[in] name - Interface name.
+ *  @param[in] addr - IP address.
+ *  @param[in] mask - subnet mask.
+ *  @param[in] flags - Interface flags.
+ */
+
+void mock_addIP(const char* name, const char* addr, const char* mask,
+                unsigned int flags);
diff --git a/test/test_network_manager.cpp b/test/test_network_manager.cpp
new file mode 100644
index 0000000..3382e38
--- /dev/null
+++ b/test/test_network_manager.cpp
@@ -0,0 +1,113 @@
+#include "network_manager.hpp"
+#include "mock_syscall.hpp"
+
+#include "xyz/openbmc_project/Common/error.hpp"
+#include <phosphor-logging/elog-errors.hpp>
+
+#include <gtest/gtest.h>
+#include <sdbusplus/bus.hpp>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <exception>
+
+namespace phosphor
+{
+namespace network
+{
+
+class TestNetworkManager : public testing::Test
+{
+    public:
+
+        sdbusplus::bus::bus bus;
+        Manager manager;
+
+        TestNetworkManager()
+            : bus(sdbusplus::bus::new_default()),
+              manager(bus, "xyz/openbmc_test/abc")
+        {
+
+        }
+
+        void createInterfaces()
+        {
+            manager.createInterfaces();
+        }
+
+        int getSize()
+        {
+            return manager.interfaces.size();
+        }
+
+        bool isInterfaceAdded(std::string intf)
+        {
+            return manager.interfaces.find(intf) != manager.interfaces.end() ?
+                   true :
+                   false;
+        }
+};
+
+// getifaddrs will not return any interface
+TEST_F(TestNetworkManager, NoInterface)
+{
+    using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+    bool caughtException = false;
+    try
+    {
+        createInterfaces();
+    }
+    catch (InternalFailure& e)
+    {
+        caughtException = true;
+    }
+
+    EXPECT_EQ(true, caughtException);
+}
+
+// getifaddrs returns single interface.
+TEST_F(TestNetworkManager, WithSingleInterface)
+{
+    bool caughtException = false;
+    try
+    {
+        // Adds the following ip in the getifaddrs list.
+        mock_addIP("igb1", "192.0.2.3", "255.255.255.128",
+                   IFF_UP | IFF_RUNNING);
+
+        // Now create the interfaces which will call the mocked getifaddrs
+        // which returns the above interface detail.
+        createInterfaces();
+        EXPECT_EQ(1, getSize());
+        EXPECT_EQ(true, isInterfaceAdded("igb1"));
+    }
+    catch (std::exception& e)
+    {
+        caughtException = true;
+    }
+    EXPECT_EQ(false, caughtException);
+}
+
+// getifaddrs returns two interfaces.
+TEST_F(TestNetworkManager, WithMultipleInterfaces)
+{
+    try
+    {
+        mock_addIP("igb0", "192.0.2.2", "255.255.255.128",
+                   IFF_UP | IFF_RUNNING);
+
+        mock_addIP("igb1", "192.0.2.3", "255.255.255.128",
+                   IFF_UP | IFF_RUNNING);
+
+        createInterfaces();
+        EXPECT_EQ(2, getSize());
+        EXPECT_EQ(true, isInterfaceAdded("igb0"));
+    }
+    catch (std::exception& e)
+    {
+    }
+}
+
+}// namespce network
+}// namespace phosphor