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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
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>
26 using namespace folly;
28 class TestData : public RequestData {
30 explicit TestData(int data) : data_(data) {}
31 ~TestData() override {}
32 void onSet() override {
35 void onUnset() override {
38 int set_ = 0, unset_ = 0;
42 TEST(RequestContext, SimpleTest) {
46 // There should always be a default context with get()
47 EXPECT_TRUE(RequestContext::get() != nullptr);
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);
57 EXPECT_EQ(nullptr, RequestContext::get()->getContextData("test"));
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_;
66 base.terminateLoopSoon();
68 auto th = std::thread([&](){
72 EXPECT_TRUE(RequestContext::get() != nullptr);
73 auto a = dynamic_cast<TestData*>(
74 RequestContext::get()->getContextData("test"));
78 RequestContext::setContext(std::shared_ptr<RequestContext>());
79 // There should always be a default context
80 EXPECT_TRUE(nullptr != RequestContext::get());
83 TEST(RequestContext, setIfAbsentTest) {
84 EXPECT_TRUE(RequestContext::get() != nullptr);
86 RequestContext::get()->setContextData(
87 "test", folly::make_unique<TestData>(10));
88 EXPECT_FALSE(RequestContext::get()->setContextDataIfAbsent(
89 "test", folly::make_unique<TestData>(20)));
91 dynamic_cast<TestData*>(
92 RequestContext::get()->getContextData("test"))->data_);
94 EXPECT_TRUE(RequestContext::get()->setContextDataIfAbsent(
95 "test2", folly::make_unique<TestData>(20)));
97 dynamic_cast<TestData*>(
98 RequestContext::get()->getContextData("test2"))->data_);
100 RequestContext::setContext(std::shared_ptr<RequestContext>());
101 EXPECT_TRUE(nullptr != RequestContext::get());
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"));
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"));
116 // Check ctx1->onUnset was called
117 EXPECT_EQ(0, testData1->set_);
118 EXPECT_EQ(1, testData1->unset_);
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_);
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_);
133 TEST(RequestContext, deadlockTest) {
134 class DeadlockTestData : public RequestData {
136 explicit DeadlockTestData(const std::string& val) : val_(val) {}
138 virtual ~DeadlockTestData() {
139 RequestContext::get()->setContextData(
140 val_, folly::make_unique<TestData>(1));
143 void onSet() override {}
145 void onUnset() override {}
150 RequestContext::get()->setContextData(
151 "test", folly::make_unique<DeadlockTestData>("test2"));
152 RequestContext::get()->clearContextData("test");