You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.9 KiB
127 lines
3.9 KiB
/****************************************************************************** |
|
* |
|
* Copyright (C) 2017 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 <base/bind.h> |
|
#include <base/logging.h> |
|
#include <base/threading/thread.h> |
|
#include <gmock/gmock.h> |
|
#include <gtest/gtest.h> |
|
#include <semaphore.h> |
|
#include <time.h> |
|
#include <unistd.h> |
|
|
|
#include "btcore/include/module.h" |
|
#include "osi/include/alarm.h" |
|
#include "osi/include/fixed_queue.h" |
|
#include "osi/include/thread.h" |
|
#include "stack/include/btu.h" |
|
|
|
class TimeoutHelper { |
|
public: |
|
TimeoutHelper() { sem_init(&sem, 0, 0); } |
|
|
|
~TimeoutHelper() { sem_destroy(&sem); } |
|
|
|
void wait(int seconds, base::Closure callback) { |
|
struct timespec timeout; |
|
clock_gettime(CLOCK_REALTIME, &timeout); |
|
timeout.tv_sec += seconds; |
|
|
|
int semvalue; |
|
sem_getvalue(&sem, &semvalue); |
|
|
|
// Call the callback if timeout occured |
|
if (sem_timedwait(&sem, &timeout) == -1 && !callback.is_null()) { |
|
callback.Run(); |
|
} |
|
} |
|
|
|
void notify() { sem_post(&sem); } |
|
|
|
private: |
|
sem_t sem; |
|
}; |
|
|
|
TimeoutHelper helper; |
|
|
|
// External function definitions |
|
void btu_message_loop_run(void* context); |
|
void btu_task_start_up(void* context); |
|
void btu_task_shut_down(void* context); |
|
|
|
/* Below are methods and variables that must be implemented if we don't want to |
|
* compile the whole stack. They will be removed, or changed into mocks one by |
|
* one in the future, as the refactoring progresses */ |
|
void btif_transfer_context(void (*)(unsigned short, char*), uint16_t, char*, |
|
int, void (*)(unsigned short, char*, char*)) { |
|
helper.notify(); |
|
}; |
|
|
|
void btu_init_core(){}; |
|
void btif_init_ok(unsigned short, char*){}; |
|
void BTE_InitStack(){}; |
|
void bta_sys_init(){}; |
|
void bta_sys_free(){}; |
|
void btu_free_core(){}; |
|
const module_t* get_module(const char*) { return nullptr; }; |
|
bool module_init(module_t const*) { return true; }; |
|
void module_clean_up(module_t const*){}; |
|
|
|
thread_t* bt_workqueue_thread; |
|
|
|
class BtuMessageLoopTest : public testing::Test { |
|
public: |
|
MOCK_METHOD0(TestCallback, void(void)); |
|
base::MessageLoop* message_loop; |
|
|
|
virtual void SetUp() { |
|
// Initialize alarms to prevent btu_task_shut_down from crashing |
|
alarm_new("test alarm"); |
|
bt_workqueue_thread = thread_new("test alarm thread"); |
|
|
|
// btu_task_start_up calls btif_transfer_context to let the stack know |
|
// start up is finished |
|
btu_task_start_up(nullptr); |
|
helper.wait(5, base::Bind(&BtuMessageLoopTest::Fail, base::Unretained(this), |
|
"BTU startup timed out")); |
|
} |
|
|
|
virtual void TearDown() { |
|
btu_task_shut_down(nullptr); |
|
alarm_cleanup(); |
|
} |
|
|
|
void Fail(std::string message) { FAIL() << message; } |
|
}; |
|
|
|
TEST_F(BtuMessageLoopTest, send_message) { |
|
message_loop = get_message_loop(); |
|
EXPECT_FALSE(message_loop == nullptr); |
|
|
|
EXPECT_CALL(*this, TestCallback()).Times(1); |
|
message_loop->task_runner()->PostTask( |
|
FROM_HERE, |
|
base::Bind(&BtuMessageLoopTest::TestCallback, base::Unretained(this))); |
|
|
|
message_loop->task_runner()->PostTask( |
|
FROM_HERE, base::Bind(&TimeoutHelper::notify, base::Unretained(&helper))); |
|
|
|
// Prevent the test from ending before the message loop posts the function |
|
helper.wait(5, base::Bind(&BtuMessageLoopTest::Fail, base::Unretained(this), |
|
"Timed out waiting for callback")); |
|
}
|
|
|