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