summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/unittests
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/unittests')
-rw-r--r--clang-tools-extra/unittests/clangd/CMakeLists.txt1
-rw-r--r--clang-tools-extra/unittests/clangd/ClangdTests.cpp40
-rw-r--r--clang-tools-extra/unittests/clangd/TUSchedulerTests.cpp14
-rw-r--r--clang-tools-extra/unittests/clangd/ThreadingTests.cpp65
4 files changed, 82 insertions, 38 deletions
diff --git a/clang-tools-extra/unittests/clangd/CMakeLists.txt b/clang-tools-extra/unittests/clangd/CMakeLists.txt
index 8f6125e192d..c0cba6c817f 100644
--- a/clang-tools-extra/unittests/clangd/CMakeLists.txt
+++ b/clang-tools-extra/unittests/clangd/CMakeLists.txt
@@ -21,6 +21,7 @@ add_extra_unittest(ClangdTests
JSONExprTests.cpp
URITests.cpp
TestFS.cpp
+ ThreadingTests.cpp
TraceTests.cpp
TUSchedulerTests.cpp
SourceCodeTests.cpp
diff --git a/clang-tools-extra/unittests/clangd/ClangdTests.cpp b/clang-tools-extra/unittests/clangd/ClangdTests.cpp
index 4d5c588609e..ac2459c7ba3 100644
--- a/clang-tools-extra/unittests/clangd/ClangdTests.cpp
+++ b/clang-tools-extra/unittests/clangd/ClangdTests.cpp
@@ -539,7 +539,6 @@ int d;
unsigned RequestsWithErrors = 0;
bool LastContentsHadErrors = false;
bool FileIsRemoved = true;
- std::future<void> LastRequestFuture;
};
std::vector<RequestStats> ReqStats;
@@ -565,8 +564,7 @@ int d;
std::uniform_int_distribution<int> ColumnDist(0, MaxColumnForFileRequests);
// Some helpers.
- auto UpdateStatsOnAddDocument = [&](unsigned FileIndex, bool HadErrors,
- std::future<void> Future) {
+ auto UpdateStatsOnAddDocument = [&](unsigned FileIndex, bool HadErrors) {
auto &Stats = ReqStats[FileIndex];
if (HadErrors)
@@ -575,22 +573,17 @@ int d;
++Stats.RequestsWithoutErrors;
Stats.LastContentsHadErrors = HadErrors;
Stats.FileIsRemoved = false;
- Stats.LastRequestFuture = std::move(Future);
};
- auto UpdateStatsOnRemoveDocument = [&](unsigned FileIndex,
- std::future<void> Future) {
+ auto UpdateStatsOnRemoveDocument = [&](unsigned FileIndex) {
auto &Stats = ReqStats[FileIndex];
Stats.FileIsRemoved = true;
- Stats.LastRequestFuture = std::move(Future);
};
- auto UpdateStatsOnForceReparse = [&](unsigned FileIndex,
- std::future<void> Future) {
+ auto UpdateStatsOnForceReparse = [&](unsigned FileIndex) {
auto &Stats = ReqStats[FileIndex];
- Stats.LastRequestFuture = std::move(Future);
if (Stats.LastContentsHadErrors)
++Stats.RequestsWithErrors;
else
@@ -599,10 +592,10 @@ int d;
auto AddDocument = [&](unsigned FileIndex) {
bool ShouldHaveErrors = ShouldHaveErrorsDist(RandGen);
- auto Future = Server.addDocument(
- FilePaths[FileIndex], ShouldHaveErrors ? SourceContentsWithErrors
- : SourceContentsWithoutErrors);
- UpdateStatsOnAddDocument(FileIndex, ShouldHaveErrors, std::move(Future));
+ Server.addDocument(FilePaths[FileIndex],
+ ShouldHaveErrors ? SourceContentsWithErrors
+ : SourceContentsWithoutErrors);
+ UpdateStatsOnAddDocument(FileIndex, ShouldHaveErrors);
};
// Various requests that we would randomly run.
@@ -617,8 +610,8 @@ int d;
if (ReqStats[FileIndex].FileIsRemoved)
AddDocument(FileIndex);
- auto Future = Server.forceReparse(FilePaths[FileIndex]);
- UpdateStatsOnForceReparse(FileIndex, std::move(Future));
+ Server.forceReparse(FilePaths[FileIndex]);
+ UpdateStatsOnForceReparse(FileIndex);
};
auto RemoveDocumentRequest = [&]() {
@@ -627,8 +620,8 @@ int d;
if (ReqStats[FileIndex].FileIsRemoved)
AddDocument(FileIndex);
- auto Future = Server.removeDocument(FilePaths[FileIndex]);
- UpdateStatsOnRemoveDocument(FileIndex, std::move(Future));
+ Server.removeDocument(FilePaths[FileIndex]);
+ UpdateStatsOnRemoveDocument(FileIndex);
};
auto CodeCompletionRequest = [&]() {
@@ -681,17 +674,6 @@ int d;
BlockingRequests[RequestIndex]();
}
}
-
- // Wait for last requests to finish.
- for (auto &ReqStat : ReqStats) {
- if (!ReqStat.LastRequestFuture.valid())
- continue; // We never ran any requests for this file.
-
- // Future should be ready much earlier than in 5 seconds, the timeout is
- // there to check we won't wait indefinitely.
- ASSERT_EQ(ReqStat.LastRequestFuture.wait_for(std::chrono::seconds(5)),
- std::future_status::ready);
- }
} // Wait for ClangdServer to shutdown before proceeding.
// Check some invariants about the state of the program.
diff --git a/clang-tools-extra/unittests/clangd/TUSchedulerTests.cpp b/clang-tools-extra/unittests/clangd/TUSchedulerTests.cpp
index 34b6f25ce06..b18f04ed39c 100644
--- a/clang-tools-extra/unittests/clangd/TUSchedulerTests.cpp
+++ b/clang-tools-extra/unittests/clangd/TUSchedulerTests.cpp
@@ -65,10 +65,8 @@ TEST_F(TUSchedulerTests, MissingFiles) {
ASSERT_FALSE(bool(Preamble));
ignoreError(Preamble.takeError());
});
- S.remove(Missing, [&](llvm::Error Err) {
- EXPECT_TRUE(bool(Err));
- ignoreError(std::move(Err));
- });
+ // remove() shouldn't crash on missing files.
+ S.remove(Missing);
// Assert there aren't any errors for added file.
S.runWithAST(
@@ -76,7 +74,7 @@ TEST_F(TUSchedulerTests, MissingFiles) {
S.runWithPreamble(Added, [&](llvm::Expected<InputsAndPreamble> Preamble) {
EXPECT_TRUE(bool(Preamble));
});
- S.remove(Added, [&](llvm::Error Err) { EXPECT_FALSE(bool(Err)); });
+ S.remove(Added);
// Assert that all operations fail after removing the file.
S.runWithAST(Added, [&](llvm::Expected<InputsAndAST> AST) {
@@ -87,10 +85,8 @@ TEST_F(TUSchedulerTests, MissingFiles) {
ASSERT_FALSE(bool(Preamble));
ignoreError(Preamble.takeError());
});
- S.remove(Added, [&](llvm::Error Err) {
- EXPECT_TRUE(bool(Err));
- ignoreError(std::move(Err));
- });
+ // remove() shouldn't crash on missing files.
+ S.remove(Added);
}
TEST_F(TUSchedulerTests, ManyUpdates) {
diff --git a/clang-tools-extra/unittests/clangd/ThreadingTests.cpp b/clang-tools-extra/unittests/clangd/ThreadingTests.cpp
new file mode 100644
index 00000000000..84e6512fe43
--- /dev/null
+++ b/clang-tools-extra/unittests/clangd/ThreadingTests.cpp
@@ -0,0 +1,65 @@
+//===-- ThreadingTests.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Threading.h"
+#include "gtest/gtest.h"
+#include <mutex>
+
+namespace clang {
+namespace clangd {
+class ThreadingTest : public ::testing::Test {};
+
+TEST_F(ThreadingTest, TaskRunner) {
+ const int TasksCnt = 100;
+ // This should be const, but MSVC does not allow to use const vars in lambdas
+ // without capture. On the other hand, clang gives a warning that capture of
+ // const var is not required.
+ // Making it non-const makes both compilers happy.
+ int IncrementsPerTask = 1000;
+
+ std::mutex Mutex;
+ int Counter(0); /* GUARDED_BY(Mutex) */
+ {
+ AsyncTaskRunner Tasks;
+ auto scheduleIncrements = [&]() {
+ for (int TaskI = 0; TaskI < TasksCnt; ++TaskI) {
+ Tasks.runAsync([&Counter, &Mutex, IncrementsPerTask]() {
+ for (int Increment = 0; Increment < IncrementsPerTask; ++Increment) {
+ std::lock_guard<std::mutex> Lock(Mutex);
+ ++Counter;
+ }
+ });
+ }
+ };
+
+ {
+ // Make sure runAsync is not running tasks synchronously on the same
+ // thread by locking the Mutex used for increments.
+ std::lock_guard<std::mutex> Lock(Mutex);
+ scheduleIncrements();
+ }
+
+ Tasks.waitForAll();
+ {
+ std::lock_guard<std::mutex> Lock(Mutex);
+ ASSERT_EQ(Counter, TasksCnt * IncrementsPerTask);
+ }
+
+ {
+ std::lock_guard<std::mutex> Lock(Mutex);
+ Counter = 0;
+ scheduleIncrements();
+ }
+ }
+ // Check that destructor has waited for tasks to finish.
+ std::lock_guard<std::mutex> Lock(Mutex);
+ ASSERT_EQ(Counter, TasksCnt * IncrementsPerTask);
+}
+} // namespace clangd
+} // namespace clang
OpenPOWER on IntegriCloud