1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 
33 #include <vector>
34 #include <google/protobuf/stubs/callback.h>
35 #include <google/protobuf/stubs/casts.h>
36 #include <google/protobuf/stubs/common.h>
37 #include <google/protobuf/stubs/logging.h>
38 #include <google/protobuf/stubs/strutil.h>
39 #include <google/protobuf/stubs/substitute.h>
40 
41 #include <google/protobuf/testing/googletest.h>
42 #include <gtest/gtest.h>
43 
44 namespace google {
45 namespace protobuf {
46 namespace {
47 
48 // TODO(kenton):  More tests.
49 
50 #ifdef PACKAGE_VERSION  // only defined when using automake, not MSVC
51 
TEST(VersionTest,VersionMatchesConfig)52 TEST(VersionTest, VersionMatchesConfig) {
53   // Verify that the version string specified in config.h matches the one
54   // in common.h.  The config.h version is a string which may have a suffix
55   // like "beta" or "rc1", so we remove that.
56   std::string version = PACKAGE_VERSION;
57   int pos = 0;
58   while (pos < version.size() &&
59          (ascii_isdigit(version[pos]) || version[pos] == '.')) {
60     ++pos;
61   }
62   version.erase(pos);
63 
64   EXPECT_EQ(version, internal::VersionString(GOOGLE_PROTOBUF_VERSION));
65 }
66 
67 #endif  // PACKAGE_VERSION
68 
TEST(CommonTest,IntMinMaxConstants)69 TEST(CommonTest, IntMinMaxConstants) {
70   // kint32min was declared incorrectly in the first release of protobufs.
71   // Ugh.
72   EXPECT_LT(kint32min, kint32max);
73   EXPECT_EQ(static_cast<uint32>(kint32min), static_cast<uint32>(kint32max) + 1);
74   EXPECT_LT(kint64min, kint64max);
75   EXPECT_EQ(static_cast<uint64>(kint64min), static_cast<uint64>(kint64max) + 1);
76   EXPECT_EQ(0, kuint32max + 1);
77   EXPECT_EQ(0, kuint64max + 1);
78 }
79 
80 std::vector<std::string> captured_messages_;
81 
CaptureLog(LogLevel level,const char * filename,int line,const std::string & message)82 void CaptureLog(LogLevel level, const char* filename, int line,
83                 const std::string& message) {
84   captured_messages_.push_back(
85     strings::Substitute("$0 $1:$2: $3",
86       implicit_cast<int>(level), filename, line, message));
87 }
88 
TEST(LoggingTest,DefaultLogging)89 TEST(LoggingTest, DefaultLogging) {
90   CaptureTestStderr();
91   int line = __LINE__;
92   GOOGLE_LOG(INFO   ) << "A message.";
93   GOOGLE_LOG(WARNING) << "A warning.";
94   GOOGLE_LOG(ERROR  ) << "An error.";
95 
96   std::string text = GetCapturedTestStderr();
97   EXPECT_EQ(
98     "[libprotobuf INFO " __FILE__ ":" + SimpleItoa(line + 1) + "] A message.\n"
99     "[libprotobuf WARNING " __FILE__ ":" + SimpleItoa(line + 2) + "] A warning.\n"
100     "[libprotobuf ERROR " __FILE__ ":" + SimpleItoa(line + 3) + "] An error.\n",
101     text);
102 }
103 
TEST(LoggingTest,NullLogging)104 TEST(LoggingTest, NullLogging) {
105   LogHandler* old_handler = SetLogHandler(nullptr);
106 
107   CaptureTestStderr();
108   GOOGLE_LOG(INFO   ) << "A message.";
109   GOOGLE_LOG(WARNING) << "A warning.";
110   GOOGLE_LOG(ERROR  ) << "An error.";
111 
112   EXPECT_TRUE(SetLogHandler(old_handler) == nullptr);
113 
114   std::string text = GetCapturedTestStderr();
115   EXPECT_EQ("", text);
116 }
117 
TEST(LoggingTest,CaptureLogging)118 TEST(LoggingTest, CaptureLogging) {
119   captured_messages_.clear();
120 
121   LogHandler* old_handler = SetLogHandler(&CaptureLog);
122 
123   int start_line = __LINE__;
124   GOOGLE_LOG(ERROR) << "An error.";
125   GOOGLE_LOG(WARNING) << "A warning.";
126 
127   EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
128 
129   ASSERT_EQ(2, captured_messages_.size());
130   EXPECT_EQ(
131     "2 " __FILE__ ":" + SimpleItoa(start_line + 1) + ": An error.",
132     captured_messages_[0]);
133   EXPECT_EQ(
134     "1 " __FILE__ ":" + SimpleItoa(start_line + 2) + ": A warning.",
135     captured_messages_[1]);
136 }
137 
TEST(LoggingTest,SilenceLogging)138 TEST(LoggingTest, SilenceLogging) {
139   captured_messages_.clear();
140 
141   LogHandler* old_handler = SetLogHandler(&CaptureLog);
142 
143   int line1 = __LINE__; GOOGLE_LOG(INFO) << "Visible1";
144   LogSilencer* silencer1 = new LogSilencer;
145   GOOGLE_LOG(INFO) << "Not visible.";
146   LogSilencer* silencer2 = new LogSilencer;
147   GOOGLE_LOG(INFO) << "Not visible.";
148   delete silencer1;
149   GOOGLE_LOG(INFO) << "Not visible.";
150   delete silencer2;
151   int line2 = __LINE__; GOOGLE_LOG(INFO) << "Visible2";
152 
153   EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
154 
155   ASSERT_EQ(2, captured_messages_.size());
156   EXPECT_EQ(
157     "0 " __FILE__ ":" + SimpleItoa(line1) + ": Visible1",
158     captured_messages_[0]);
159   EXPECT_EQ(
160     "0 " __FILE__ ":" + SimpleItoa(line2) + ": Visible2",
161     captured_messages_[1]);
162 }
163 
164 class ClosureTest : public testing::Test {
165  public:
SetA123Method()166   void SetA123Method()   { a_ = 123; }
SetA123Function()167   static void SetA123Function() { current_instance_->a_ = 123; }
168 
SetAMethod(int a)169   void SetAMethod(int a)         { a_ = a; }
SetCMethod(std::string c)170   void SetCMethod(std::string c) { c_ = c; }
171 
SetAFunction(int a)172   static void SetAFunction(int a)         { current_instance_->a_ = a; }
SetCFunction(std::string c)173   static void SetCFunction(std::string c) { current_instance_->c_ = c; }
174 
SetABMethod(int a,const char * b)175   void SetABMethod(int a, const char* b)  { a_ = a; b_ = b; }
SetABFunction(int a,const char * b)176   static void SetABFunction(int a, const char* b) {
177     current_instance_->a_ = a;
178     current_instance_->b_ = b;
179   }
180 
SetUp()181   virtual void SetUp() {
182     current_instance_ = this;
183     a_ = 0;
184     b_ = nullptr;
185     c_.clear();
186     permanent_closure_ = nullptr;
187   }
188 
DeleteClosureInCallback()189   void DeleteClosureInCallback() {
190     delete permanent_closure_;
191   }
192 
193   int a_;
194   const char* b_;
195   std::string c_;
196   Closure* permanent_closure_;
197 
198   static ClosureTest* current_instance_;
199 };
200 
201 ClosureTest* ClosureTest::current_instance_ = nullptr;
202 
TEST_F(ClosureTest,TestClosureFunction0)203 TEST_F(ClosureTest, TestClosureFunction0) {
204   Closure* closure = NewCallback(&SetA123Function);
205   EXPECT_NE(123, a_);
206   closure->Run();
207   EXPECT_EQ(123, a_);
208 }
209 
TEST_F(ClosureTest,TestClosureMethod0)210 TEST_F(ClosureTest, TestClosureMethod0) {
211   Closure* closure = NewCallback(current_instance_,
212                                  &ClosureTest::SetA123Method);
213   EXPECT_NE(123, a_);
214   closure->Run();
215   EXPECT_EQ(123, a_);
216 }
217 
TEST_F(ClosureTest,TestClosureFunction1)218 TEST_F(ClosureTest, TestClosureFunction1) {
219   Closure* closure = NewCallback(&SetAFunction, 456);
220   EXPECT_NE(456, a_);
221   closure->Run();
222   EXPECT_EQ(456, a_);
223 }
224 
TEST_F(ClosureTest,TestClosureMethod1)225 TEST_F(ClosureTest, TestClosureMethod1) {
226   Closure* closure = NewCallback(current_instance_,
227                                  &ClosureTest::SetAMethod, 456);
228   EXPECT_NE(456, a_);
229   closure->Run();
230   EXPECT_EQ(456, a_);
231 }
232 
TEST_F(ClosureTest,TestClosureFunction1String)233 TEST_F(ClosureTest, TestClosureFunction1String) {
234   Closure* closure = NewCallback(&SetCFunction, std::string("test"));
235   EXPECT_NE("test", c_);
236   closure->Run();
237   EXPECT_EQ("test", c_);
238 }
239 
TEST_F(ClosureTest,TestClosureMethod1String)240 TEST_F(ClosureTest, TestClosureMethod1String) {
241   Closure* closure = NewCallback(current_instance_, &ClosureTest::SetCMethod,
242                                  std::string("test"));
243   EXPECT_NE("test", c_);
244   closure->Run();
245   EXPECT_EQ("test", c_);
246 }
247 
TEST_F(ClosureTest,TestClosureFunction2)248 TEST_F(ClosureTest, TestClosureFunction2) {
249   const char* cstr = "hello";
250   Closure* closure = NewCallback(&SetABFunction, 789, cstr);
251   EXPECT_NE(789, a_);
252   EXPECT_NE(cstr, b_);
253   closure->Run();
254   EXPECT_EQ(789, a_);
255   EXPECT_EQ(cstr, b_);
256 }
257 
TEST_F(ClosureTest,TestClosureMethod2)258 TEST_F(ClosureTest, TestClosureMethod2) {
259   const char* cstr = "hello";
260   Closure* closure = NewCallback(current_instance_,
261                                  &ClosureTest::SetABMethod, 789, cstr);
262   EXPECT_NE(789, a_);
263   EXPECT_NE(cstr, b_);
264   closure->Run();
265   EXPECT_EQ(789, a_);
266   EXPECT_EQ(cstr, b_);
267 }
268 
269 // Repeat all of the above with NewPermanentCallback()
270 
TEST_F(ClosureTest,TestPermanentClosureFunction0)271 TEST_F(ClosureTest, TestPermanentClosureFunction0) {
272   Closure* closure = NewPermanentCallback(&SetA123Function);
273   EXPECT_NE(123, a_);
274   closure->Run();
275   EXPECT_EQ(123, a_);
276   a_ = 0;
277   closure->Run();
278   EXPECT_EQ(123, a_);
279   delete closure;
280 }
281 
TEST_F(ClosureTest,TestPermanentClosureMethod0)282 TEST_F(ClosureTest, TestPermanentClosureMethod0) {
283   Closure* closure = NewPermanentCallback(current_instance_,
284                                           &ClosureTest::SetA123Method);
285   EXPECT_NE(123, a_);
286   closure->Run();
287   EXPECT_EQ(123, a_);
288   a_ = 0;
289   closure->Run();
290   EXPECT_EQ(123, a_);
291   delete closure;
292 }
293 
TEST_F(ClosureTest,TestPermanentClosureFunction1)294 TEST_F(ClosureTest, TestPermanentClosureFunction1) {
295   Closure* closure = NewPermanentCallback(&SetAFunction, 456);
296   EXPECT_NE(456, a_);
297   closure->Run();
298   EXPECT_EQ(456, a_);
299   a_ = 0;
300   closure->Run();
301   EXPECT_EQ(456, a_);
302   delete closure;
303 }
304 
TEST_F(ClosureTest,TestPermanentClosureMethod1)305 TEST_F(ClosureTest, TestPermanentClosureMethod1) {
306   Closure* closure = NewPermanentCallback(current_instance_,
307                                           &ClosureTest::SetAMethod, 456);
308   EXPECT_NE(456, a_);
309   closure->Run();
310   EXPECT_EQ(456, a_);
311   a_ = 0;
312   closure->Run();
313   EXPECT_EQ(456, a_);
314   delete closure;
315 }
316 
TEST_F(ClosureTest,TestPermanentClosureFunction2)317 TEST_F(ClosureTest, TestPermanentClosureFunction2) {
318   const char* cstr = "hello";
319   Closure* closure = NewPermanentCallback(&SetABFunction, 789, cstr);
320   EXPECT_NE(789, a_);
321   EXPECT_NE(cstr, b_);
322   closure->Run();
323   EXPECT_EQ(789, a_);
324   EXPECT_EQ(cstr, b_);
325   a_ = 0;
326   b_ = nullptr;
327   closure->Run();
328   EXPECT_EQ(789, a_);
329   EXPECT_EQ(cstr, b_);
330   delete closure;
331 }
332 
TEST_F(ClosureTest,TestPermanentClosureMethod2)333 TEST_F(ClosureTest, TestPermanentClosureMethod2) {
334   const char* cstr = "hello";
335   Closure* closure = NewPermanentCallback(current_instance_,
336                                           &ClosureTest::SetABMethod, 789, cstr);
337   EXPECT_NE(789, a_);
338   EXPECT_NE(cstr, b_);
339   closure->Run();
340   EXPECT_EQ(789, a_);
341   EXPECT_EQ(cstr, b_);
342   a_ = 0;
343   b_ = nullptr;
344   closure->Run();
345   EXPECT_EQ(789, a_);
346   EXPECT_EQ(cstr, b_);
347   delete closure;
348 }
349 
TEST_F(ClosureTest,TestPermanentClosureDeleteInCallback)350 TEST_F(ClosureTest, TestPermanentClosureDeleteInCallback) {
351   permanent_closure_ = NewPermanentCallback((ClosureTest*) this,
352       &ClosureTest::DeleteClosureInCallback);
353   permanent_closure_->Run();
354 }
355 
356 }  // anonymous namespace
357 }  // namespace protobuf
358 }  // namespace google
359