1bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 2bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Copyright (C) 2015 The Android Open Source Project 3bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 4bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Licensed under the Apache License, Version 2.0 (the "License"); 5bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// you may not use this file except in compliance with the License. 6bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// You may obtain a copy of the License at 7bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 8bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// http://www.apache.org/licenses/LICENSE-2.0 9bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 10bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Unless required by applicable law or agreed to in writing, software 11bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// distributed under the License is distributed on an "AS IS" BASIS, 12bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// See the License for the specific language governing permissions and 14bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// limitations under the License. 15bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 1680c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 1780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include "trunks/background_command_transceiver.h" 1880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 1980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include <base/bind.h> 2080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include <base/logging.h> 2180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include <base/message_loop/message_loop.h> 2280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include <base/run_loop.h> 2380c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include <base/threading/platform_thread.h> 2480c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include <base/threading/thread.h> 2580c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include <gmock/gmock.h> 2680c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include <gtest/gtest.h> 2780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 2880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include "trunks/command_transceiver.h" 2980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include "trunks/mock_command_transceiver.h" 3080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 3180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnusing testing::_; 3280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnusing testing::Invoke; 3380c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnusing testing::InvokeWithoutArgs; 3480c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnusing testing::WithArgs; 3580c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 3680c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnnamespace { 3780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 3880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnconst char kTestThreadName[] = "test_thread"; 3980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 4080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnstd::string GetThreadName() { 4180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn return std::string(base::PlatformThread::GetName()); 4280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn} 4380c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 4480c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnvoid GetThreadNameAndCall( 4580c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn const trunks::CommandTransceiver::ResponseCallback& callback) { 4680c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn callback.Run(GetThreadName()); 4780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn} 4880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 4980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnvoid Assign(std::string* to, const std::string& from) { 5080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn *to = from; 5180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn} 5280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 5380c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnvoid SendCommandAndWaitAndAssign(trunks::CommandTransceiver* transceiver, 5480c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn std::string* output) { 5580c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn *output = transceiver->SendCommandAndWait("test"); 5680c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn} 5780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 5880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn} // namespace 5980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 6080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnnamespace trunks { 6180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 6280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnclass BackgroundTransceiverTest : public testing::Test { 6380c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn public: 6480c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn BackgroundTransceiverTest() : test_thread_(kTestThreadName) { 6580c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn EXPECT_CALL(next_transceiver_, SendCommand(_, _)) 6680c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn .WillRepeatedly(WithArgs<1>(Invoke(GetThreadNameAndCall))); 6780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn EXPECT_CALL(next_transceiver_, SendCommandAndWait(_)) 6880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn .WillRepeatedly(InvokeWithoutArgs(GetThreadName)); 6980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn CHECK(test_thread_.Start()); 7080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn } 7180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 72295e851b66fb19c05a14401e834337962a58c493Darren Krahn ~BackgroundTransceiverTest() override {} 7380c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 7480c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn protected: 7580c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn base::MessageLoopForIO message_loop_; 7680c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn base::Thread test_thread_; 7780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn MockCommandTransceiver next_transceiver_; 7880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn}; 7980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 8080c739e10fd606b24e2656cad6e566c66bb218d4Darren KrahnTEST_F(BackgroundTransceiverTest, Asynchronous) { 8180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn trunks::BackgroundCommandTransceiver background_transceiver( 824dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &next_transceiver_, test_thread_.task_runner()); 8380c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn std::string output = "not_assigned"; 8480c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn background_transceiver.SendCommand("test", base::Bind(Assign, &output)); 8580c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn do { 8680c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn base::RunLoop run_loop; 8780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn run_loop.RunUntilIdle(); 8880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn } while (output == "not_assigned"); 8980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn // The call to our mock should have happened on the background thread. 9080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn EXPECT_EQ(std::string(kTestThreadName), output); 9180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn} 9280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 9380c739e10fd606b24e2656cad6e566c66bb218d4Darren KrahnTEST_F(BackgroundTransceiverTest, Synchronous) { 9480c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn trunks::BackgroundCommandTransceiver background_transceiver( 954dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &next_transceiver_, test_thread_.task_runner()); 9680c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn std::string output = "not_assigned"; 9780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn // Post a synchronous call to be run when we start pumping the loop. 9880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn message_loop_.PostTask(FROM_HERE, 9980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn base::Bind(SendCommandAndWaitAndAssign, 1004dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn &background_transceiver, &output)); 10180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn base::RunLoop run_loop; 10280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn run_loop.RunUntilIdle(); 10380c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn // The call to our mock should have happened on the background thread. 10480c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn EXPECT_EQ(std::string("test_thread"), output); 10580c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn} 10680c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 10780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn} // namespace trunks 108