blob: 5323dea080de3cdecac48c5ff0c2741bb96f4335 [file] [log] [blame]
John Park398c74a2018-10-20 21:17:39 -07001#include "aos/complex_thread_local.h"
Brian Silverman2fa99cb2014-09-06 00:53:00 -04002
3#include <atomic>
Kai Tinkessbf1385d2020-01-18 14:18:49 -08004#include <thread>
Brian Silverman2fa99cb2014-09-06 00:53:00 -04005
6#include "gtest/gtest.h"
7
Brian Silverman2fa99cb2014-09-06 00:53:00 -04008namespace aos {
9namespace testing {
10
11class ComplexThreadLocalTest : public ::testing::Test {
12 protected:
13 struct TraceableObject {
14 TraceableObject(int data = 0) : data(data) { ++constructions; }
15 ~TraceableObject() { ++destructions; }
16
17 static ::std::atomic<int> constructions, destructions;
18
19 int data;
20 };
21 ComplexThreadLocal<TraceableObject> local;
22
23 private:
24 void SetUp() override {
25 local.Clear();
26 EXPECT_EQ(TraceableObject::constructions, TraceableObject::destructions)
27 << "There should be no way to create and destroy different numbers.";
28 TraceableObject::constructions = TraceableObject::destructions = 0;
29 }
30};
31::std::atomic<int> ComplexThreadLocalTest::TraceableObject::constructions;
32::std::atomic<int> ComplexThreadLocalTest::TraceableObject::destructions;
33
34TEST_F(ComplexThreadLocalTest, Basic) {
35 EXPECT_EQ(0, TraceableObject::constructions);
36 EXPECT_EQ(0, TraceableObject::destructions);
37 EXPECT_FALSE(local.created());
38 EXPECT_EQ(nullptr, local.get());
39
40 local.Create(971);
41 EXPECT_EQ(1, TraceableObject::constructions);
42 EXPECT_EQ(0, TraceableObject::destructions);
43 EXPECT_TRUE(local.created());
44 EXPECT_EQ(971, local->data);
45
46 local.Create(254);
47 EXPECT_EQ(1, TraceableObject::constructions);
48 EXPECT_EQ(0, TraceableObject::destructions);
49 EXPECT_TRUE(local.created());
50 EXPECT_EQ(971, local->data);
51
52 local.Clear();
53 EXPECT_EQ(1, TraceableObject::constructions);
54 EXPECT_EQ(1, TraceableObject::destructions);
55 EXPECT_FALSE(local.created());
56 EXPECT_EQ(nullptr, local.get());
57
58 local.Create(973);
59 EXPECT_EQ(2, TraceableObject::constructions);
60 EXPECT_EQ(1, TraceableObject::destructions);
61 EXPECT_TRUE(local.created());
62 EXPECT_EQ(973, local->data);
63}
64
65TEST_F(ComplexThreadLocalTest, AnotherThread) {
66 EXPECT_FALSE(local.created());
Kai Tinkessbf1385d2020-01-18 14:18:49 -080067 std::thread t1([this]() {
Brian Silverman2fa99cb2014-09-06 00:53:00 -040068 EXPECT_FALSE(local.created());
69 local.Create(971);
70 EXPECT_TRUE(local.created());
71 EXPECT_EQ(971, local->data);
72 EXPECT_EQ(1, TraceableObject::constructions);
73 EXPECT_EQ(0, TraceableObject::destructions);
74 });
Kai Tinkessbf1385d2020-01-18 14:18:49 -080075 t1.join();
Brian Silverman2fa99cb2014-09-06 00:53:00 -040076 EXPECT_EQ(1, TraceableObject::constructions);
77 EXPECT_EQ(1, TraceableObject::destructions);
78 EXPECT_FALSE(local.created());
79}
80
81TEST_F(ComplexThreadLocalTest, TwoThreads) {
Kai Tinkessbf1385d2020-01-18 14:18:49 -080082 std::thread thread([this]() {
Brian Silverman2fa99cb2014-09-06 00:53:00 -040083 local.Create(971);
84 EXPECT_EQ(971, local->data);
85 EXPECT_EQ(0, TraceableObject::destructions);
86 });
Brian Silverman2fa99cb2014-09-06 00:53:00 -040087 local.Create(973);
88 EXPECT_EQ(973, local->data);
Kai Tinkessbf1385d2020-01-18 14:18:49 -080089 thread.join();
Brian Silverman2fa99cb2014-09-06 00:53:00 -040090 EXPECT_TRUE(local.created());
91 EXPECT_EQ(2, TraceableObject::constructions);
92 EXPECT_EQ(1, TraceableObject::destructions);
93 local.Clear();
94 EXPECT_EQ(2, TraceableObject::constructions);
95 EXPECT_EQ(2, TraceableObject::destructions);
96 EXPECT_FALSE(local.created());
97}
98
99} // namespace testing
100} // namespace aos