#include <gtest/gtest.h>
#include <hardware/hardware.h>
#include <chrono>
#include "worker.h"
using android::Worker;
struct TestWorker : public Worker {
TestWorker()
: Worker("test-worker", HAL_PRIORITY_URGENT_DISPLAY),
value(0),
enabled_(false) {
}
int Init() {
return InitWorker();
}
void Routine() {
Lock();
if (!enabled_) {
int ret = WaitForSignalOrExitLocked();
if (ret == -EINTR) {
Unlock();
return;
}
// should only reached here if it was enabled
if (!enabled_)
printf("Shouldn't reach here while disabled %d %d\n", value, ret);
}
value++;
Unlock();
}
void Control(bool enable) {
bool changed = false;
Lock();
if (enabled_ != enable) {
enabled_ = enable;
changed = true;
}
Unlock();
if (enable && changed)
Signal();
}
int value;
private:
bool enabled_;
};
struct WorkerTest : public testing::Test {
TestWorker worker;
virtual void SetUp() {
worker.Init();
}
void small_delay() {
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
};
TEST_F(WorkerTest, test_worker) {
// already isInitialized so should fail
ASSERT_TRUE(worker.initialized());
int val = worker.value;
small_delay();
// value shouldn't change when isInitialized
ASSERT_EQ(val, worker.value);
worker.Control(true);
small_delay();
// while locked, value shouldn't be changing
worker.Lock();
val = worker.value;
small_delay();
ASSERT_EQ(val, worker.value);
worker.Unlock();
small_delay();
// value should be different now
ASSERT_NE(val, worker.value);
worker.Control(false);
worker.Lock();
val = worker.value;
worker.Unlock();
small_delay();
// value should be same
ASSERT_EQ(val, worker.value);
worker.Exit();
ASSERT_FALSE(worker.initialized());
}
TEST_F(WorkerTest, exit_while_running) {
worker.Control(true);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
worker.Exit();
}