diff options
Diffstat (limited to 'tests/main_loop_unittest.cpp')
-rw-r--r-- | tests/main_loop_unittest.cpp | 135 |
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 |