79dbe6ff935bf4a40f8c8af5d663749c683ec71a
[folly.git] / folly / io / async / test / ScopedEventBaseThreadTest.cpp
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <folly/io/async/ScopedEventBaseThread.h>
18
19 #include <chrono>
20 #include <string>
21
22 #include <folly/Baton.h>
23 #include <folly/Optional.h>
24 #include <folly/ThreadName.h>
25 #include <folly/io/async/EventBaseManager.h>
26 #include <folly/portability/GTest.h>
27
28 using namespace std;
29 using namespace std::chrono;
30 using namespace folly;
31
32 class ScopedEventBaseThreadTest : public testing::Test {};
33
34 TEST_F(ScopedEventBaseThreadTest, example) {
35   ScopedEventBaseThread sebt;
36
37   Baton<> done;
38   sebt.getEventBase()->runInEventBaseThread([&] { done.post(); });
39   ASSERT_TRUE(done.timed_wait(seconds(1)));
40 }
41
42 TEST_F(ScopedEventBaseThreadTest, named_example) {
43   static constexpr StringPiece kThreadName{"named_example"};
44
45   Optional<std::string> createdThreadName;
46   Baton<> done;
47
48   ScopedEventBaseThread sebt{kThreadName};
49   sebt.getEventBase()->runInEventBaseThread([&] {
50     createdThreadName = folly::getCurrentThreadName();
51     done.post();
52   });
53
54   ASSERT_TRUE(done.timed_wait(seconds(1)));
55   if (createdThreadName) {
56     ASSERT_EQ(kThreadName.toString(), createdThreadName.value());
57   }
58 }
59
60 TEST_F(ScopedEventBaseThreadTest, default_manager) {
61   auto ebm = EventBaseManager::get();
62   ScopedEventBaseThread sebt;
63   auto sebt_eb = sebt.getEventBase();
64   auto ebm_eb = static_cast<EventBase*>(nullptr);
65   sebt_eb->runInEventBaseThreadAndWait([&] { ebm_eb = ebm->getEventBase(); });
66   EXPECT_EQ(uintptr_t(sebt_eb), uintptr_t(ebm_eb));
67 }
68
69 TEST_F(ScopedEventBaseThreadTest, custom_manager) {
70   EventBaseManager ebm;
71   ScopedEventBaseThread sebt(&ebm);
72   auto sebt_eb = sebt.getEventBase();
73   auto ebm_eb = static_cast<EventBase*>(nullptr);
74   sebt_eb->runInEventBaseThreadAndWait([&] { ebm_eb = ebm.getEventBase(); });
75   EXPECT_EQ(uintptr_t(sebt_eb), uintptr_t(ebm_eb));
76 }
77
78 TEST_F(ScopedEventBaseThreadTest, eb_dtor_in_io_thread) {
79   Optional<ScopedEventBaseThread> sebt;
80   sebt.emplace();
81   auto const io_thread_id = sebt->getThreadId();
82   EXPECT_NE(this_thread::get_id(), io_thread_id) << "sanity";
83
84   auto const eb = sebt->getEventBase();
85   thread::id eb_dtor_thread_id;
86   eb->runOnDestruction(new EventBase::FunctionLoopCallback(
87       [&] { eb_dtor_thread_id = this_thread::get_id(); }));
88   sebt.clear();
89   EXPECT_EQ(io_thread_id, eb_dtor_thread_id);
90 }