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("test", std::make_unique<TestData>(10));
60 base.runInEventBaseThread([&](){
61 EXPECT_TRUE(RequestContext::get() != nullptr);
62 auto data = dynamic_cast<TestData*>(
63 RequestContext::get()->getContextData("test"))->data_;
65 base.terminateLoopSoon();
67 auto th = std::thread([&](){
71 EXPECT_TRUE(RequestContext::get() != nullptr);
72 auto a = dynamic_cast<TestData*>(
73 RequestContext::get()->getContextData("test"));
77 RequestContext::setContext(std::shared_ptr<RequestContext>());
78 // There should always be a default context
79 EXPECT_TRUE(nullptr != RequestContext::get());
82 TEST(RequestContext, setIfAbsentTest) {
83 EXPECT_TRUE(RequestContext::get() != nullptr);
85 RequestContext::get()->setContextData("test", std::make_unique<TestData>(10));
86 EXPECT_FALSE(RequestContext::get()->setContextDataIfAbsent(
87 "test", std::make_unique<TestData>(20)));
89 dynamic_cast<TestData*>(
90 RequestContext::get()->getContextData("test"))->data_);
92 EXPECT_TRUE(RequestContext::get()->setContextDataIfAbsent(
93 "test2", std::make_unique<TestData>(20)));
95 dynamic_cast<TestData*>(
96 RequestContext::get()->getContextData("test2"))->data_);
98 RequestContext::setContext(std::shared_ptr<RequestContext>());
99 EXPECT_TRUE(nullptr != RequestContext::get());
102 TEST(RequestContext, testSetUnset) {
103 RequestContext::create();
104 auto ctx1 = RequestContext::saveContext();
105 ctx1->setContextData("test", std::make_unique<TestData>(10));
106 auto testData1 = dynamic_cast<TestData*>(ctx1->getContextData("test"));
108 // Override RequestContext
109 RequestContext::create();
110 auto ctx2 = RequestContext::saveContext();
111 ctx2->setContextData("test", std::make_unique<TestData>(20));
112 auto testData2 = dynamic_cast<TestData*>(ctx2->getContextData("test"));
114 // Check ctx1->onUnset was called
115 EXPECT_EQ(0, testData1->set_);
116 EXPECT_EQ(1, testData1->unset_);
118 RequestContext::setContext(ctx1);
119 EXPECT_EQ(1, testData1->set_);
120 EXPECT_EQ(1, testData1->unset_);
121 EXPECT_EQ(0, testData2->set_);
122 EXPECT_EQ(1, testData2->unset_);
124 RequestContext::setContext(ctx2);
125 EXPECT_EQ(1, testData1->set_);
126 EXPECT_EQ(2, testData1->unset_);
127 EXPECT_EQ(1, testData2->set_);
128 EXPECT_EQ(1, testData2->unset_);
131 TEST(RequestContext, deadlockTest) {
132 class DeadlockTestData : public RequestData {
134 explicit DeadlockTestData(const std::string& val) : val_(val) {}
136 virtual ~DeadlockTestData() {
137 RequestContext::get()->setContextData(
138 val_, std::make_unique<TestData>(1));
141 void onSet() override {}
143 void onUnset() override {}
148 RequestContext::get()->setContextData(
149 "test", std::make_unique<DeadlockTestData>("test2"));
150 RequestContext::get()->clearContextData("test");