[NETD-BPF#1] Move libnetdutils to framework/libs/net/...

libnetdutils is referenced by netd.c and TrafficController.cpp, which
are going to be mainlined. Therefore, move libnetdutils to a common
place where both mainline module and platform code (Netd) can refer to.

Bug: 202086915
Test: build; flash; cd system/netd; atest
No-Typo-Check: Clean code move with no other changes.
BYPASS_INCLUSIVE_LANGUAGE_REASON=Clean code move with no other changes.

Merged-In: I645bfe35f6543149c9a9f894cd4158d27a481abe
Change-Id: I645bfe35f6543149c9a9f894cd4158d27a481abe
diff --git a/staticlibs/netd/libnetdutils/SyscallsTest.cpp b/staticlibs/netd/libnetdutils/SyscallsTest.cpp
new file mode 100644
index 0000000..78ffab5
--- /dev/null
+++ b/staticlibs/netd/libnetdutils/SyscallsTest.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <array>
+#include <cstdint>
+#include <memory>
+
+#include <gtest/gtest.h>
+
+#include "netdutils/Handle.h"
+#include "netdutils/Math.h"
+#include "netdutils/MockSyscalls.h"
+#include "netdutils/Netfilter.h"
+#include "netdutils/Netlink.h"
+#include "netdutils/Slice.h"
+#include "netdutils/Status.h"
+#include "netdutils/StatusOr.h"
+#include "netdutils/Syscalls.h"
+
+using testing::_;
+using testing::ByMove;
+using testing::Invoke;
+using testing::Return;
+using testing::StrictMock;
+
+namespace android {
+namespace netdutils {
+
+class SyscallsTest : public testing::Test {
+  protected:
+    StrictMock<ScopedMockSyscalls> mSyscalls;
+};
+
+TEST(syscalls, scopedMock) {
+    auto& old = sSyscalls.get();
+    {
+        StrictMock<ScopedMockSyscalls> s;
+        EXPECT_EQ(&s, &sSyscalls.get());
+    }
+    EXPECT_EQ(&old, &sSyscalls.get());
+}
+
+TEST_F(SyscallsTest, open) {
+    const char kPath[] = "/test/path/please/ignore";
+    constexpr Fd kFd(40);
+    constexpr int kFlags = 883;
+    constexpr mode_t kMode = 37373;
+    const auto& sys = sSyscalls.get();
+    EXPECT_CALL(mSyscalls, open(kPath, kFlags, kMode)).WillOnce(Return(ByMove(UniqueFd(kFd))));
+    EXPECT_CALL(mSyscalls, close(kFd)).WillOnce(Return(status::ok));
+    auto result = sys.open(kPath, kFlags, kMode);
+    EXPECT_EQ(status::ok, result.status());
+    EXPECT_EQ(kFd, result.value());
+}
+
+TEST_F(SyscallsTest, getsockname) {
+    constexpr Fd kFd(40);
+    sockaddr_nl expected = {};
+    auto& sys = sSyscalls.get();
+
+    // Success
+    EXPECT_CALL(mSyscalls, getsockname(kFd, _, _))
+        .WillOnce(Invoke([expected](Fd, sockaddr* addr, socklen_t* addrlen) {
+            memcpy(addr, &expected, sizeof(expected));
+            EXPECT_EQ(*addrlen, static_cast<socklen_t>(sizeof(expected)));
+            return status::ok;
+        }));
+    const auto result = sys.getsockname<sockaddr_nl>(kFd);
+    EXPECT_TRUE(isOk(result));
+    EXPECT_EQ(expected, result.value());
+
+    // Failure
+    const Status kError = statusFromErrno(EINVAL, "test");
+    EXPECT_CALL(mSyscalls, getsockname(kFd, _, _)).WillOnce(Return(kError));
+    EXPECT_EQ(kError, sys.getsockname<sockaddr_nl>(kFd).status());
+}
+
+TEST_F(SyscallsTest, setsockopt) {
+    constexpr Fd kFd(40);
+    constexpr int kLevel = 50;
+    constexpr int kOptname = 70;
+    sockaddr_nl expected = {};
+    auto& sys = sSyscalls.get();
+
+    // Success
+    EXPECT_CALL(mSyscalls, setsockopt(kFd, kLevel, kOptname, &expected, sizeof(expected)))
+        .WillOnce(Return(status::ok));
+    EXPECT_EQ(status::ok, sys.setsockopt(kFd, kLevel, kOptname, expected));
+
+    // Failure
+    const Status kError = statusFromErrno(EINVAL, "test");
+    EXPECT_CALL(mSyscalls, setsockopt(kFd, kLevel, kOptname, &expected, sizeof(expected)))
+        .WillOnce(Return(kError));
+    EXPECT_EQ(kError, sys.setsockopt(kFd, kLevel, kOptname, expected));
+}
+
+TEST_F(SyscallsTest, getsockopt) {
+    constexpr Fd kFd(40);
+    constexpr int kLevel = 50;
+    constexpr int kOptname = 70;
+    sockaddr_nl expected = {};
+    socklen_t optLen = 0;
+    auto& sys = sSyscalls.get();
+
+    // Success
+    EXPECT_CALL(mSyscalls, getsockopt(kFd, kLevel, kOptname, &expected, &optLen))
+        .WillOnce(Return(status::ok));
+    EXPECT_EQ(status::ok, sys.getsockopt(kFd, kLevel, kOptname, &expected, &optLen));
+
+    // Failure
+    const Status kError = statusFromErrno(EINVAL, "test");
+    EXPECT_CALL(mSyscalls, getsockopt(kFd, kLevel, kOptname, &expected, &optLen))
+        .WillOnce(Return(kError));
+    EXPECT_EQ(kError, sys.getsockopt(kFd, kLevel, kOptname, &expected, &optLen));
+}
+
+TEST_F(SyscallsTest, bind) {
+    constexpr Fd kFd(40);
+    sockaddr_nl expected = {};
+    auto& sys = sSyscalls.get();
+
+    // Success
+    EXPECT_CALL(mSyscalls, bind(kFd, asSockaddrPtr(&expected), sizeof(expected)))
+        .WillOnce(Return(status::ok));
+    EXPECT_EQ(status::ok, sys.bind(kFd, expected));
+
+    // Failure
+    const Status kError = statusFromErrno(EINVAL, "test");
+    EXPECT_CALL(mSyscalls, bind(kFd, asSockaddrPtr(&expected), sizeof(expected)))
+        .WillOnce(Return(kError));
+    EXPECT_EQ(kError, sys.bind(kFd, expected));
+}
+
+TEST_F(SyscallsTest, connect) {
+    constexpr Fd kFd(40);
+    sockaddr_nl expected = {};
+    auto& sys = sSyscalls.get();
+
+    // Success
+    EXPECT_CALL(mSyscalls, connect(kFd, asSockaddrPtr(&expected), sizeof(expected)))
+        .WillOnce(Return(status::ok));
+    EXPECT_EQ(status::ok, sys.connect(kFd, expected));
+
+    // Failure
+    const Status kError = statusFromErrno(EINVAL, "test");
+    EXPECT_CALL(mSyscalls, connect(kFd, asSockaddrPtr(&expected), sizeof(expected)))
+        .WillOnce(Return(kError));
+    EXPECT_EQ(kError, sys.connect(kFd, expected));
+}
+
+TEST_F(SyscallsTest, sendto) {
+    constexpr Fd kFd(40);
+    constexpr int kFlags = 0;
+    std::array<char, 10> payload;
+    const auto slice = makeSlice(payload);
+    sockaddr_nl expected = {};
+    auto& sys = sSyscalls.get();
+
+    // Success
+    EXPECT_CALL(mSyscalls, sendto(kFd, slice, kFlags, asSockaddrPtr(&expected), sizeof(expected)))
+        .WillOnce(Return(slice.size()));
+    EXPECT_EQ(status::ok, sys.sendto(kFd, slice, kFlags, expected));
+}
+
+TEST_F(SyscallsTest, recvfrom) {
+    constexpr Fd kFd(40);
+    constexpr int kFlags = 0;
+    std::array<char, 10> payload;
+    const auto dst = makeSlice(payload);
+    const auto used = take(dst, 8);
+    sockaddr_nl expected = {};
+    auto& sys = sSyscalls.get();
+
+    // Success
+    EXPECT_CALL(mSyscalls, recvfrom(kFd, dst, kFlags, _, _))
+            .WillOnce(Invoke(
+                    [expected, used](Fd, const Slice, int, sockaddr* src, socklen_t* srclen) {
+                        *srclen = sizeof(expected);
+                        memcpy(src, &expected, *srclen);
+                        return used;
+                    }));
+    auto result = sys.recvfrom<sockaddr_nl>(kFd, dst, kFlags);
+    EXPECT_EQ(status::ok, result.status());
+    EXPECT_EQ(used, result.value().first);
+    EXPECT_EQ(expected, result.value().second);
+}
+
+}  // namespace netdutils
+}  // namespace android