OpenVPN 3 Core Library
Loading...
Searching...
No Matches
test_rc.cpp
Go to the documentation of this file.
1#include "test_common.hpp"
2
3#include <iostream>
4#include <string>
5#include <functional>
7
8using namespace openvpn;
9
10template <typename BASE>
11class TestType : public BASE
12{
13 public:
16 typedef BASE Base;
17
18 TestType(const std::string &name_arg)
19 : name(name_arg)
20 {
21 OPENVPN_LOG(name << "()");
22 }
23
25 {
26 OPENVPN_LOG("~" << name << "()");
27 }
28
29 void go(const char *title)
30 {
31 OPENVPN_LOG(title << ": " << name);
32 }
33
34 std::string name;
35};
36
37template <typename Base>
38class TestParentType : public TestType<Base>
39{
40 public:
43
44 TestParentType(const std::string &name_arg)
45 : TestType<Base>(name_arg)
46 {
47 parent_name = std::string("parent of ") + TestType<Base>::name;
48 }
49
50 std::string parent_name;
51};
52
53const char *expected_output = "*** TEST1\n"
54 "Test1()\n"
55 "~Test1()\n"
56 "*** TEST2\n"
57 "Test2()\n"
58 "t1a: Test2\n"
59 "t2a: Test2\n"
60 "t1b: Test2\n"
61 "t2b: Test2\n"
62 "tz: Test2\n"
63 "w1z=3 w2z=3\n"
64 "~Test2()\n"
65 "*** TEST3\n"
66 "Test3()\n"
67 "N#3: Test3\n"
68 "NOTIFY #3\n"
69 "N#2: Test3\n"
70 "NOTIFY #2\n"
71 "N#1: Test3\n"
72 "NOTIFY #1\n"
73 "~Test3()\n"
74 "*** TEST4\n"
75 "Test4()\n"
76 "parent of Test4\n"
77 "~Test4()\n";
78
79template <typename Test>
80void test()
81{
83 typedef TestParentType<typename Test::Base> TestParent;
84
85 {
86 OPENVPN_LOG("*** TEST1");
87 typename Test::Ptr t1 = new Test("Test1");
88 typename Test::Ptr t2(t1);
89 typename Test::Ptr t3(t2);
90 }
91 {
92 OPENVPN_LOG("*** TEST2");
93
94 typename Test::WPtr w1z;
95 typename Test::WPtr w2z;
96
97 {
98 typename Test::Ptr t1 = new Test("Test2");
99 typename Test::WPtr w1 = t1;
101 w1z.reset(t1);
102 w2z.reset(t1.get());
103
104 typename Test::Ptr t1a = w1.lock();
105 typename Test::Ptr t2a = w2.lock();
106
107 t1a->go("t1a");
108 t2a->go("t2a");
109
110 t1a = w1z.lock();
111 t2a = w2z.lock();
112
113 t1a->go("t1b");
114 t2a->go("t2b");
115
116 typename Test::WPtr z;
117 z.swap(w1);
118 typename Test::Ptr tz = z.lock();
119 tz->go("tz");
120
121 tz = w1.lock();
122 ASSERT_FALSE(tz) << "BUG ALERT #1";
123
124 z.reset();
125 tz = z.lock();
126 ASSERT_FALSE(tz) << "BUG ALERT #2";
127
128 OPENVPN_LOG("w1z=" << w1z.use_count() << " w2z=" << w2z.use_count());
129 }
130
131 typename Test::Ptr x = w1z.lock();
132 typename Test::Ptr y = w2z.lock();
133 ASSERT_FALSE(x || y || !w1z.expired() || !w2z.expired()) << "BUG ALERT #3";
134 w1z = w2z;
135 }
136 {
137 OPENVPN_LOG("*** TEST3");
138 typename Test::Ptr t1 = new Test("Test3");
139 typename Test::Ptr t2(t1);
140 typename Test::Ptr t3(t2);
141
142 t1->rc_release_notify([obj = t1.get()]()
143 {
144 obj->go("N#1");
145 OPENVPN_LOG("NOTIFY #1"); });
146 t2->rc_release_notify([obj = t2.get()]()
147 {
148 obj->go("N#2");
149 OPENVPN_LOG("NOTIFY #2"); });
150 t3->rc_release_notify([obj = t3.get()]()
151 {
152 obj->go("N#3");
153 OPENVPN_LOG("NOTIFY #3"); });
154 }
155 {
156 OPENVPN_LOG("*** TEST4");
157 typename TestParent::Ptr t1 = new TestParent("Test4");
158 typename Test::Ptr t2(t1);
159 typename TestParent::Ptr t3 = t2.template dynamic_pointer_cast<TestParent>();
160 OPENVPN_LOG(t3->parent_name);
161 }
163}
164
165TEST(misc, RCthreadUnsafe)
166{
167 test<TestType<RCWeak<thread_unsafe_refcount>>>();
168}
169
170TEST(misc, RCthreadSafe)
171{
172 test<TestType<RCWeak<thread_safe_refcount>>>();
173}
std::string parent_name
Definition test_rc.cpp:50
TestParentType(const std::string &name_arg)
Definition test_rc.cpp:44
RCPtr< TestParentType > Ptr
Definition test_rc.cpp:41
RCWeakPtr< TestParentType > WPtr
Definition test_rc.cpp:42
~TestType()
Definition test_rc.cpp:24
BASE Base
Definition test_rc.cpp:16
RCPtr< TestType > Ptr
Definition test_rc.cpp:14
TestType(const std::string &name_arg)
Definition test_rc.cpp:18
std::string name
Definition test_rc.cpp:34
void go(const char *title)
Definition test_rc.cpp:29
RCWeakPtr< TestType > WPtr
Definition test_rc.cpp:15
The smart pointer class.
Definition rc.hpp:119
void swap(RCPtr &rhs) noexcept
swaps the contents of two RCPtr<T>
Definition rc.hpp:311
implements a weak pointer for reference counted objects.
Definition rc.hpp:451
Strong lock() const noexcept
Tries to upgrade the weak reference to a strong reference and returns that result.
Definition rc.hpp:583
void reset(const Strong &p) noexcept
Reassign this weak ptr to the object referenced by the given strong (RCPtr) pointer.
Definition rc.hpp:508
openvpn::LogOutputCollector * testLog
#define OPENVPN_LOG(args)
Support deferred server-side state creation when client connects.
Definition ovpncli.cpp:95
const char * expected_output
Definition test_rc.cpp:53
void test()
Definition test_rc.cpp:80
TEST(misc, RCthreadUnsafe)
Definition test_rc.cpp:165