brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.4 KiB · ed98d8f Raw
91 lines · cpp
1#include "support/Cancellation.h"2#include "support/Context.h"3#include "support/Threading.h"4#include "gmock/gmock.h"5#include "gtest/gtest.h"6#include <atomic>7#include <memory>8#include <optional>9#include <thread>10 11namespace clang {12namespace clangd {13namespace {14 15TEST(CancellationTest, CancellationTest) {16  auto Task = cancelableTask();17  WithContext ContextWithCancellation(std::move(Task.first));18  EXPECT_FALSE(isCancelled());19  Task.second();20  EXPECT_TRUE(isCancelled());21}22 23TEST(CancellationTest, CancelerDiesContextLives) {24  std::optional<WithContext> ContextWithCancellation;25  {26    auto Task = cancelableTask();27    ContextWithCancellation.emplace(std::move(Task.first));28    EXPECT_FALSE(isCancelled());29    Task.second();30    EXPECT_TRUE(isCancelled());31  }32  EXPECT_TRUE(isCancelled());33}34 35TEST(CancellationTest, TaskContextDiesHandleLives) {36  auto Task = cancelableTask();37  {38    WithContext ContextWithCancellation(std::move(Task.first));39    EXPECT_FALSE(isCancelled());40    Task.second();41    EXPECT_TRUE(isCancelled());42  }43  // Still should be able to cancel without any problems.44  Task.second();45}46 47struct NestedTasks {48  enum { OuterReason = 1, InnerReason = 2 };49  std::pair<Context, Canceler> Outer, Inner;50  NestedTasks() {51    Outer = cancelableTask(OuterReason);52    {53      WithContext WithOuter(Outer.first.clone());54      Inner = cancelableTask(InnerReason);55    }56  }57};58 59TEST(CancellationTest, Nested) {60  // Cancelling inner task works but leaves outer task unaffected.61  NestedTasks CancelInner;62  CancelInner.Inner.second();63  EXPECT_EQ(NestedTasks::InnerReason, isCancelled(CancelInner.Inner.first));64  EXPECT_FALSE(isCancelled(CancelInner.Outer.first));65  // Cancellation of outer task is inherited by inner task.66  NestedTasks CancelOuter;67  CancelOuter.Outer.second();68  EXPECT_EQ(NestedTasks::OuterReason, isCancelled(CancelOuter.Inner.first));69  EXPECT_EQ(NestedTasks::OuterReason, isCancelled(CancelOuter.Outer.first));70}71 72TEST(CancellationTest, AsynCancellationTest) {73  std::atomic<bool> HasCancelled(false);74  Notification Cancelled;75  auto TaskToBeCancelled = [&](Context Ctx) {76    WithContext ContextGuard(std::move(Ctx));77    Cancelled.wait();78    HasCancelled = isCancelled();79  };80  auto Task = cancelableTask();81  std::thread AsyncTask(TaskToBeCancelled, std::move(Task.first));82  Task.second();83  Cancelled.notify();84  AsyncTask.join();85 86  EXPECT_TRUE(HasCancelled);87}88} // namespace89} // namespace clangd90} // namespace clang91