stack_btu_test.cc revision 47616530ceea2ea6432ffb35cd8a3fc0a56365b5
1/****************************************************************************** 2 * 3 * Copyright (C) 2017 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19#include <base/bind.h> 20#include <base/logging.h> 21#include <base/threading/thread.h> 22#include <gmock/gmock.h> 23#include <gtest/gtest.h> 24#include <semaphore.h> 25#include <time.h> 26#include <unistd.h> 27 28#include "btcore/include/module.h" 29#include "osi/include/alarm.h" 30#include "osi/include/fixed_queue.h" 31#include "osi/include/thread.h" 32#include "stack/include/btu.h" 33 34class TimeoutHelper { 35 public: 36 TimeoutHelper() { sem_init(&sem, 0, 0); } 37 38 ~TimeoutHelper() { sem_destroy(&sem); } 39 40 void wait(int seconds, base::Closure callback) { 41 struct timespec timeout; 42 clock_gettime(CLOCK_REALTIME, &timeout); 43 timeout.tv_sec += seconds; 44 45 int semvalue; 46 sem_getvalue(&sem, &semvalue); 47 48 // Call the callback if timeout occured 49 if (sem_timedwait(&sem, &timeout) == -1 && !callback.is_null()) { 50 callback.Run(); 51 } 52 } 53 54 void notify() { sem_post(&sem); } 55 56 private: 57 sem_t sem; 58}; 59 60TimeoutHelper helper; 61 62// External function definitions 63void btu_message_loop_run(void* context); 64void btu_task_start_up(void* context); 65void btu_task_shut_down(void* context); 66 67/* Below are methods and variables that must be implemented if we don't want to 68 * compile the whole stack. They will be removed, or changed into mocks one by 69 * one in the future, as the refactoring progresses */ 70void btif_transfer_context(void (*)(unsigned short, char*), uint16_t, char*, 71 int, void (*)(unsigned short, char*, char*)) { 72 helper.notify(); 73}; 74 75void btu_init_core(){}; 76void btif_init_ok(unsigned short, char*){}; 77void BTE_InitStack(){}; 78void bta_sys_init(){}; 79void bta_sys_free(){}; 80void btu_free_core(){}; 81const module_t* get_module(const char*) { return nullptr; }; 82bool module_init(module_t const*) { return true; }; 83void module_clean_up(module_t const*){}; 84 85thread_t* bt_workqueue_thread; 86 87class BtuMessageLoopTest : public testing::Test { 88 public: 89 MOCK_METHOD0(TestCallback, void(void)); 90 base::MessageLoop* message_loop; 91 92 virtual void SetUp() { 93 // Initialize alarms to prevent btu_task_shut_down from crashing 94 alarm_new("test alarm"); 95 bt_workqueue_thread = thread_new("test alarm thread"); 96 97 // btu_task_start_up calls btif_transfer_context to let the stack know 98 // start up is finished 99 btu_task_start_up(nullptr); 100 helper.wait(5, base::Bind(&BtuMessageLoopTest::Fail, base::Unretained(this), 101 "BTU startup timed out")); 102 } 103 104 virtual void TearDown() { 105 btu_task_shut_down(nullptr); 106 alarm_cleanup(); 107 } 108 109 void Fail(std::string message) { FAIL() << message; } 110}; 111 112TEST_F(BtuMessageLoopTest, send_message) { 113 message_loop = get_message_loop(); 114 EXPECT_FALSE(message_loop == nullptr); 115 116 EXPECT_CALL(*this, TestCallback()).Times(1); 117 message_loop->task_runner()->PostTask( 118 FROM_HERE, 119 base::Bind(&BtuMessageLoopTest::TestCallback, base::Unretained(this))); 120 121 message_loop->task_runner()->PostTask( 122 FROM_HERE, base::Bind(&TimeoutHelper::notify, base::Unretained(&helper))); 123 124 // Prevent the test from ending before the message loop posts the function 125 helper.wait(5, base::Bind(&BtuMessageLoopTest::Fail, base::Unretained(this), 126 "Timed out waiting for callback")); 127} 128