Index: third_party/mojo/src/mojo/edk/system/thread_annotations_unittest.cc |
diff --git a/third_party/mojo/src/mojo/edk/system/thread_annotations_unittest.cc b/third_party/mojo/src/mojo/edk/system/thread_annotations_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d56814fa6ba97ed5a2993045ce0e36ccacc32bbb |
--- /dev/null |
+++ b/third_party/mojo/src/mojo/edk/system/thread_annotations_unittest.cc |
@@ -0,0 +1,124 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// Tests of the static thread annotation macros. These fall into two categories, |
+// positive tests (testing that correct code compiles and works) and negative |
+// tests (testing that incorrect code does not compile). |
+// |
+// Unfortunately, we don't have systematic/automated negative compilation tests. |
+// So instead we have some cheesy macros that you can define to enable |
+// individual compilation failures. |
+ |
+#include "mojo/edk/system/thread_annotations.h" |
+ |
+#include "mojo/edk/system/mutex.h" |
+#include "mojo/public/cpp/system/macros.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+// Uncomment these to enable particular compilation failure tests. |
+// #define NC_GUARDED_BY |
+// TODO(vtl): |ACQUIRED_{BEFORE,AFTER}()| are currently unimplemented in clang |
+// as of 2015-07-06 ("To be fixed in a future update."). So this actually |
+// compiles! |
+// #define NC_ACQUIRED_BEFORE |
+ |
+namespace mojo { |
+namespace system { |
+namespace { |
+ |
+// Test MOJO_GUARDED_BY -------------------------------------------------------- |
+ |
+class GuardedByClass { |
+ public: |
+ GuardedByClass() : x_() {} |
+ ~GuardedByClass() {} |
+ |
+ void GoodSet(int x) { |
+ mu_.Lock(); |
+ x_ = x; |
+ mu_.Unlock(); |
+ } |
+ |
+#ifdef NC_GUARDED_BY |
+ void BadSet(int x) { x_ = x; } |
+#endif |
+ |
+ private: |
+ Mutex mu_; |
+ int x_ MOJO_GUARDED_BY(mu_); |
+ |
+ MOJO_DISALLOW_COPY_AND_ASSIGN(GuardedByClass); |
+}; |
+ |
+TEST(ThreadAnnotationsTest, GuardedBy) { |
+ GuardedByClass c; |
+ c.GoodSet(123); |
+} |
+ |
+// Test MOJO_ACQUIRED_BEFORE --------------------------------------------------- |
+ |
+class AcquiredBeforeClass2; |
+ |
+class AcquiredBeforeClass1 { |
+ public: |
+ AcquiredBeforeClass1() {} |
+ ~AcquiredBeforeClass1() {} |
+ |
+ void NoOp() { |
+ mu_.Lock(); |
+ mu_.Unlock(); |
+ } |
+ |
+#ifdef NC_ACQUIRED_BEFORE |
+ void BadMethod(AcquiredBeforeClass2* c2) { |
+ mu_.Lock(); |
+ c2->NoOp(); |
+ mu_.Unlock(); |
+ } |
+#endif |
+ |
+ private: |
+ friend class AcquiredBeforeClass2; |
+ |
+ Mutex mu_; |
+ |
+ MOJO_DISALLOW_COPY_AND_ASSIGN(AcquiredBeforeClass1); |
+}; |
+ |
+class AcquiredBeforeClass2 { |
+ public: |
+ AcquiredBeforeClass2() {} |
+ ~AcquiredBeforeClass2() {} |
+ |
+ void NoOp() { |
+ mu_.Lock(); |
+ mu_.Unlock(); |
+ } |
+ |
+ void GoodMethod(AcquiredBeforeClass1* c1) { |
+ mu_.Lock(); |
+ c1->NoOp(); |
+ mu_.Unlock(); |
+ } |
+ |
+ private: |
+ Mutex mu_ MOJO_ACQUIRED_BEFORE(AcquiredBeforeClass1::mu_); |
+ |
+ MOJO_DISALLOW_COPY_AND_ASSIGN(AcquiredBeforeClass2); |
+}; |
+ |
+TEST(ThreadAnnotationsTest, AcquiredBefore) { |
+ AcquiredBeforeClass1 c1; |
+ AcquiredBeforeClass2 c2; |
+ c2.GoodMethod(&c1); |
+#ifdef NC_ACQUIRED_BEFORE |
+ c1.BadMethod(&c2); |
+#endif |
+} |
+ |
+// TODO(vtl): Test more things. |
+ |
+} // namespace |
+} // namespace system |
+} // namespace mojo |