blob: 365f91df8247609402f1bad6781f01a7e690ca46 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/lib/testing/loop_fixture/real_loop_fixture.h"
#include "sync_manager.h"
#define WAIT_FOR_OK(ok) ASSERT_TRUE(RunLoopWithTimeoutOrUntil([&ok]() { return ok; }, zx::sec(2)))
#define WAIT_FOR_OK_AND_RESET(ok) \
WAIT_FOR_OK(ok); \
ok = false
namespace netemul {
namespace testing {
static const char* kMainTestBarrier = "test-barrier";
static const char* kAltTestBarrier = "alt-barrier";
class BarrierTest : public gtest::RealLoopFixture {
public:
using SyncManagerPtr = fidl::InterfacePtr<SyncManager::FSyncManager>;
BarrierTest() : svc_(std::make_unique<SyncManager>()) {}
protected:
void GetSyncManager(fidl::InterfaceRequest<SyncManager::FSyncManager> manager) {
svc_->GetHandler()(std::move(manager));
}
std::unique_ptr<SyncManager> svc_;
};
TEST_F(BarrierTest, FulfillBarrier) {
SyncManagerPtr sm;
GetSyncManager(sm.NewRequest());
bool got_callback = false;
// waiting on a count of 1 will always fullfill immediately:
sm->WaitForBarrierThreshold(kMainTestBarrier, 1, zx::msec(0).to_nsecs(),
[&got_callback](bool result) {
EXPECT_TRUE(result);
got_callback = true;
});
WAIT_FOR_OK_AND_RESET(got_callback);
}
TEST_F(BarrierTest, TimeoutBarrier) {
SyncManagerPtr sm;
GetSyncManager(sm.NewRequest());
bool got_callback = false;
// wait and timeout:
sm->WaitForBarrierThreshold(kMainTestBarrier, 2, zx::msec(15).to_nsecs(),
[&got_callback](bool result) {
EXPECT_FALSE(result);
got_callback = true;
});
WAIT_FOR_OK_AND_RESET(got_callback);
}
TEST_F(BarrierTest, DestroyWithPending) {
SyncManagerPtr sm;
GetSyncManager(sm.NewRequest());
// wait and timeout:
sm->WaitForBarrierThreshold(kMainTestBarrier, 2, zx::msec(0).to_nsecs(),
[](bool result) { FAIL() << "Shouldn't call callback"; });
}
TEST_F(BarrierTest, ManyWaits) {
SyncManagerPtr sm;
GetSyncManager(sm.NewRequest());
bool got_callback1 = false;
bool got_callback2 = false;
bool got_callback3 = false;
bool got_callback4 = false;
sm->WaitForBarrierThreshold(kMainTestBarrier, 4, zx::msec(0).to_nsecs(),
[&got_callback1](bool result) {
EXPECT_TRUE(result);
got_callback1 = true;
});
sm->WaitForBarrierThreshold(kMainTestBarrier, 4, zx::msec(0).to_nsecs(),
[&got_callback2](bool result) {
EXPECT_TRUE(result);
got_callback2 = true;
});
sm->WaitForBarrierThreshold(kMainTestBarrier, 4, zx::msec(0).to_nsecs(),
[&got_callback3](bool result) {
EXPECT_TRUE(result);
got_callback3 = true;
});
// Wait for 5. Will trigger the others, but will timeout on itself.
sm->WaitForBarrierThreshold(kMainTestBarrier, 5, zx::msec(15).to_nsecs(),
[&got_callback4](bool result) {
EXPECT_FALSE(result);
got_callback4 = true;
});
ASSERT_TRUE(RunLoopWithTimeoutOrUntil(
[&]() { return got_callback1 && got_callback2 && got_callback3 && got_callback4; },
zx::sec(2)));
}
TEST_F(BarrierTest, DifferentBarriers) {
SyncManagerPtr sm;
GetSyncManager(sm.NewRequest());
bool got_callback1 = false;
bool got_callback2 = false;
bool got_callback3 = false;
sm->WaitForBarrierThreshold(kMainTestBarrier, 2, zx::msec(0).to_nsecs(),
[&got_callback1](bool result) {
EXPECT_TRUE(result);
got_callback1 = true;
});
sm->WaitForBarrierThreshold(kMainTestBarrier, 2, zx::msec(0).to_nsecs(),
[&got_callback2](bool result) {
EXPECT_TRUE(result);
got_callback2 = true;
});
// wait on different barrier. Should timeout.
sm->WaitForBarrierThreshold(kAltTestBarrier, 2, zx::msec(10).to_nsecs(),
[&got_callback3](bool result) {
EXPECT_FALSE(result);
got_callback3 = true;
});
ASSERT_TRUE(RunLoopWithTimeoutOrUntil(
[&]() { return got_callback1 && got_callback2 && got_callback3; }, zx::sec(2)));
}
} // namespace testing
} // namespace netemul