summaryrefslogtreecommitdiff
path: root/tests/main_loop_unittest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/main_loop_unittest.cpp')
-rw-r--r--tests/main_loop_unittest.cpp135
1 files changed, 135 insertions, 0 deletions
diff --git a/tests/main_loop_unittest.cpp b/tests/main_loop_unittest.cpp
new file mode 100644
index 0000000..db04027
--- /dev/null
+++ b/tests/main_loop_unittest.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2016, 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 <cerrno>
+#include <memory>
+#include <tuple>
+#include <utility>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+#include "wifilogd/tests/mock_command_processor.h"
+#include "wifilogd/tests/mock_os.h"
+
+#include "wifilogd/main_loop.h"
+#include "wifilogd/protocol.h"
+
+namespace android {
+namespace wifilogd {
+namespace {
+
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::Ge;
+using ::testing::Return;
+using ::testing::StrictMock;
+
+constexpr int kControlSocketFd = 100;
+constexpr char kFakeSocketName[] = "fake-socket";
+
+class MainLoopTest : public ::testing::Test {
+ public:
+ MainLoopTest()
+ : os_(new StrictMock<MockOs>()),
+ command_processor_(new StrictMock<MockCommandProcessor>()) {
+ EXPECT_CALL(*os_, GetControlSocket(kFakeSocketName))
+ .WillOnce(Return(std::tuple<size_t, Os::Errno>{kControlSocketFd, 0}));
+ main_loop_ = std::make_unique<MainLoop>(
+ kFakeSocketName, std::unique_ptr<Os>{os_},
+ std::unique_ptr<CommandProcessor>{command_processor_});
+ }
+
+ protected:
+ std::unique_ptr<MainLoop> main_loop_;
+ // We use raw pointers to access the mocks, since ownership passes
+ // to |main_loop_|.
+ StrictMock<MockOs>* os_;
+ StrictMock<MockCommandProcessor>* command_processor_;
+};
+
+} // namespace
+
+TEST_F(MainLoopTest, RunOnceReadsFromCorrectSocket) {
+ EXPECT_CALL(*os_, ReceiveDatagram(kControlSocketFd, _, _));
+ EXPECT_CALL(*command_processor_, ProcessCommand(_, _, _)).Times(AnyNumber());
+ main_loop_->RunOnce();
+}
+
+TEST_F(MainLoopTest, RunOnceReadsWithSufficientlyLargeBuffer) {
+ EXPECT_CALL(*os_, ReceiveDatagram(_, _, Ge(protocol::kMaxMessageSize)));
+ EXPECT_CALL(*command_processor_, ProcessCommand(_, _, _)).Times(AnyNumber());
+ main_loop_->RunOnce();
+}
+
+TEST_F(MainLoopTest, RunOncePassesSmallestValidMessageToCommandProcessor) {
+ EXPECT_CALL(*os_, ReceiveDatagram(_, _, _))
+ .WillOnce(
+ Return(std::tuple<size_t, Os::Errno>{sizeof(protocol::Command), 0}));
+ EXPECT_CALL(*command_processor_,
+ ProcessCommand(_, sizeof(protocol::Command), _));
+ main_loop_->RunOnce();
+}
+
+TEST_F(MainLoopTest, RunOncePassesLargestValidMessageToCommandProcessor) {
+ EXPECT_CALL(*os_, ReceiveDatagram(_, _, _))
+ .WillOnce(
+ Return(std::tuple<size_t, Os::Errno>{protocol::kMaxMessageSize, 0}));
+ EXPECT_CALL(*command_processor_,
+ ProcessCommand(_, protocol::kMaxMessageSize, _));
+ main_loop_->RunOnce();
+}
+
+TEST_F(MainLoopTest, RunOncePassesRuntMessageToCommandProcessor) {
+ EXPECT_CALL(*os_, ReceiveDatagram(_, _, _))
+ .WillOnce(Return(std::tuple<size_t, Os::Errno>{0, 0}));
+ EXPECT_CALL(*command_processor_, ProcessCommand(_, 0, _));
+ main_loop_->RunOnce();
+}
+
+TEST_F(MainLoopTest, RunOnceLimitsMaxSizeReportedToCommandProcessor) {
+ EXPECT_CALL(*os_, ReceiveDatagram(_, _, _))
+ .WillOnce(Return(
+ std::tuple<size_t, Os::Errno>{protocol::kMaxMessageSize + 1, 0}));
+ EXPECT_CALL(*command_processor_,
+ ProcessCommand(_, protocol::kMaxMessageSize, _));
+ main_loop_->RunOnce();
+}
+
+TEST_F(MainLoopTest, RunOnceDoesNotPassDataToCommandProcessorOnError) {
+ EXPECT_CALL(*os_, ReceiveDatagram(_, _, protocol::kMaxMessageSize))
+ .WillOnce(Return(std::tuple<size_t, Os::Errno>{0, EINTR}));
+ EXPECT_CALL(*command_processor_, ProcessCommand(_, _, _)).Times(0);
+ main_loop_->RunOnce();
+}
+
+// Per
+// github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#death-tests,
+// death tests should be specially named.
+using MainLoopDeathTest = MainLoopTest;
+
+TEST_F(MainLoopDeathTest, CtorFailureToFetchControlSocketCausesDeath) {
+ auto os = std::make_unique<StrictMock<MockOs>>();
+ auto command_processor = std::make_unique<StrictMock<MockCommandProcessor>>();
+ ON_CALL(*os, GetControlSocket(kFakeSocketName))
+ .WillByDefault(Return(std::tuple<size_t, Os::Errno>{-1, ERANGE}));
+ EXPECT_DEATH(
+ MainLoop(kFakeSocketName, std::move(os), std::move(command_processor)),
+ "Failed to get control socket");
+}
+
+} // namespace wifilogd
+} // namespace android