Use the GTest portability headers
[folly.git] / folly / io / async / test / RequestContextTest.cpp
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 #include <thread>
20
21 #include <folly/Memory.h>
22 #include <folly/io/async/EventBase.h>
23 #include <folly/io/async/Request.h>
24 #include <folly/portability/GTest.h>
25
26 using namespace folly;
27
28 class TestData : public RequestData {
29  public:
30   explicit TestData(int data) : data_(data) {}
31   ~TestData() override {}
32   void onSet() override {
33     set_++;
34   }
35   void onUnset() override {
36     unset_++;
37   }
38   int set_ = 0, unset_ = 0;
39   int data_;
40 };
41
42 TEST(RequestContext, SimpleTest) {
43   EventBase base;
44
45
46   // There should always be a default context with get()
47   EXPECT_TRUE(RequestContext::get() != nullptr);
48
49
50   // but not with saveContext()
51   EXPECT_EQ(RequestContext::saveContext(), nullptr);
52   RequestContext::create();
53   EXPECT_NE(RequestContext::saveContext(), nullptr);
54   RequestContext::create();
55   EXPECT_NE(RequestContext::saveContext(), nullptr);
56
57   EXPECT_EQ(nullptr, RequestContext::get()->getContextData("test"));
58
59   RequestContext::get()->setContextData(
60       "test", folly::make_unique<TestData>(10));
61   base.runInEventBaseThread([&](){
62       EXPECT_TRUE(RequestContext::get() != nullptr);
63       auto data = dynamic_cast<TestData*>(
64         RequestContext::get()->getContextData("test"))->data_;
65       EXPECT_EQ(10, data);
66       base.terminateLoopSoon();
67     });
68   auto th = std::thread([&](){
69       base.loopForever();
70   });
71   th.join();
72   EXPECT_TRUE(RequestContext::get() != nullptr);
73   auto a = dynamic_cast<TestData*>(
74     RequestContext::get()->getContextData("test"));
75   auto data = a->data_;
76   EXPECT_EQ(10, data);
77
78   RequestContext::setContext(std::shared_ptr<RequestContext>());
79   // There should always be a default context
80   EXPECT_TRUE(nullptr != RequestContext::get());
81 }
82
83 TEST(RequestContext, setIfAbsentTest) {
84   EXPECT_TRUE(RequestContext::get() != nullptr);
85
86   RequestContext::get()->setContextData(
87       "test", folly::make_unique<TestData>(10));
88   EXPECT_FALSE(RequestContext::get()->setContextDataIfAbsent(
89       "test", folly::make_unique<TestData>(20)));
90   EXPECT_EQ(10,
91             dynamic_cast<TestData*>(
92                 RequestContext::get()->getContextData("test"))->data_);
93
94   EXPECT_TRUE(RequestContext::get()->setContextDataIfAbsent(
95       "test2", folly::make_unique<TestData>(20)));
96   EXPECT_EQ(20,
97             dynamic_cast<TestData*>(
98                 RequestContext::get()->getContextData("test2"))->data_);
99
100   RequestContext::setContext(std::shared_ptr<RequestContext>());
101   EXPECT_TRUE(nullptr != RequestContext::get());
102 }
103
104 TEST(RequestContext, testSetUnset) {
105   RequestContext::create();
106   auto ctx1 = RequestContext::saveContext();
107   ctx1->setContextData("test", folly::make_unique<TestData>(10));
108   auto testData1 = dynamic_cast<TestData*>(ctx1->getContextData("test"));
109
110   // Override RequestContext
111   RequestContext::create();
112   auto ctx2 = RequestContext::saveContext();
113   ctx2->setContextData("test", folly::make_unique<TestData>(20));
114   auto testData2 = dynamic_cast<TestData*>(ctx2->getContextData("test"));
115
116   // Check ctx1->onUnset was called
117   EXPECT_EQ(0, testData1->set_);
118   EXPECT_EQ(1, testData1->unset_);
119
120   RequestContext::setContext(ctx1);
121   EXPECT_EQ(1, testData1->set_);
122   EXPECT_EQ(1, testData1->unset_);
123   EXPECT_EQ(0, testData2->set_);
124   EXPECT_EQ(1, testData2->unset_);
125
126   RequestContext::setContext(ctx2);
127   EXPECT_EQ(1, testData1->set_);
128   EXPECT_EQ(2, testData1->unset_);
129   EXPECT_EQ(1, testData2->set_);
130   EXPECT_EQ(1, testData2->unset_);
131 }