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/common.h>
35 #include <google/protobuf/stubs/strutil.h>
36 #include <google/protobuf/stubs/substitute.h>
37 
38 #include <google/protobuf/testing/googletest.h>
39 #include <gtest/gtest.h>
40 
41 #include "config.h"
42 
43 namespace google {
44 namespace protobuf {
45 namespace {
46 
47 // TODO(kenton):  More tests.
48 
49 #ifdef PACKAGE_VERSION  // only defined when using automake, not MSVC
50 
TEST(VersionTest,VersionMatchesConfig)51 TEST(VersionTest, VersionMatchesConfig) {
52   // Verify that the version string specified in config.h matches the one
53   // in common.h.  The config.h version is a string which may have a suffix
54   // like "beta" or "rc1", so we remove that.
55   string version = PACKAGE_VERSION;
56   int pos = 0;
57   while (pos < version.size() &&
58          (ascii_isdigit(version[pos]) || version[pos] == '.')) {
59     ++pos;
60   }
61   version.erase(pos);
62 
63   EXPECT_EQ(version, internal::VersionString(GOOGLE_PROTOBUF_VERSION));
64 }
65 
66 #endif  // PACKAGE_VERSION
67 
TEST(CommonTest,IntMinMaxConstants)68 TEST(CommonTest, IntMinMaxConstants) {
69   // kint32min was declared incorrectly in the first release of protobufs.
70   // Ugh.
71   EXPECT_LT(kint32min, kint32max);
72   EXPECT_EQ(static_cast<uint32>(kint32min), static_cast<uint32>(kint32max) + 1);
73   EXPECT_LT(kint64min, kint64max);
74   EXPECT_EQ(static_cast<uint64>(kint64min), static_cast<uint64>(kint64max) + 1);
75   EXPECT_EQ(0, kuint32max + 1);
76   EXPECT_EQ(0, kuint64max + 1);
77 }
78 
79 vector<string> captured_messages_;
80 
CaptureLog(LogLevel level,const char * filename,int line,const string & message)81 void CaptureLog(LogLevel level, const char* filename, int line,
82                 const string& message) {
83   captured_messages_.push_back(
84     strings::Substitute("$0 $1:$2: $3",
85       implicit_cast<int>(level), filename, line, message));
86 }
87 
TEST(LoggingTest,DefaultLogging)88 TEST(LoggingTest, DefaultLogging) {
89   CaptureTestStderr();
90   int line = __LINE__;
91   GOOGLE_LOG(INFO   ) << "A message.";
92   GOOGLE_LOG(WARNING) << "A warning.";
93   GOOGLE_LOG(ERROR  ) << "An error.";
94 
95   string text = GetCapturedTestStderr();
96   EXPECT_EQ(
97     "[libprotobuf INFO "__FILE__":" + SimpleItoa(line + 1) + "] A message.\n"
98     "[libprotobuf WARNING "__FILE__":" + SimpleItoa(line + 2) + "] A warning.\n"
99     "[libprotobuf ERROR "__FILE__":" + SimpleItoa(line + 3) + "] An error.\n",
100     text);
101 }
102 
TEST(LoggingTest,NullLogging)103 TEST(LoggingTest, NullLogging) {
104   LogHandler* old_handler = SetLogHandler(NULL);
105 
106   CaptureTestStderr();
107   GOOGLE_LOG(INFO   ) << "A message.";
108   GOOGLE_LOG(WARNING) << "A warning.";
109   GOOGLE_LOG(ERROR  ) << "An error.";
110 
111   EXPECT_TRUE(SetLogHandler(old_handler) == NULL);
112 
113   string text = GetCapturedTestStderr();
114   EXPECT_EQ("", text);
115 }
116 
TEST(LoggingTest,CaptureLogging)117 TEST(LoggingTest, CaptureLogging) {
118   captured_messages_.clear();
119 
120   LogHandler* old_handler = SetLogHandler(&CaptureLog);
121 
122   int start_line = __LINE__;
123   GOOGLE_LOG(ERROR) << "An error.";
124   GOOGLE_LOG(WARNING) << "A warning.";
125 
126   EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
127 
128   ASSERT_EQ(2, captured_messages_.size());
129   EXPECT_EQ(
130     "2 "__FILE__":" + SimpleItoa(start_line + 1) + ": An error.",
131     captured_messages_[0]);
132   EXPECT_EQ(
133     "1 "__FILE__":" + SimpleItoa(start_line + 2) + ": A warning.",
134     captured_messages_[1]);
135 }
136 
TEST(LoggingTest,SilenceLogging)137 TEST(LoggingTest, SilenceLogging) {
138   captured_messages_.clear();
139 
140   LogHandler* old_handler = SetLogHandler(&CaptureLog);
141 
142   int line1 = __LINE__; GOOGLE_LOG(INFO) << "Visible1";
143   LogSilencer* silencer1 = new LogSilencer;
144   GOOGLE_LOG(INFO) << "Not visible.";
145   LogSilencer* silencer2 = new LogSilencer;
146   GOOGLE_LOG(INFO) << "Not visible.";
147   delete silencer1;
148   GOOGLE_LOG(INFO) << "Not visible.";
149   delete silencer2;
150   int line2 = __LINE__; GOOGLE_LOG(INFO) << "Visible2";
151 
152   EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
153 
154   ASSERT_EQ(2, captured_messages_.size());
155   EXPECT_EQ(
156     "0 "__FILE__":" + SimpleItoa(line1) + ": Visible1",
157     captured_messages_[0]);
158   EXPECT_EQ(
159     "0 "__FILE__":" + SimpleItoa(line2) + ": Visible2",
160     captured_messages_[1]);
161 }
162 
163 class ClosureTest : public testing::Test {
164  public:
SetA123Method()165   void SetA123Method()   { a_ = 123; }
SetA123Function()166   static void SetA123Function() { current_instance_->a_ = 123; }
167 
SetAMethod(int a)168   void SetAMethod(int a)         { a_ = a; }
SetCMethod(string c)169   void SetCMethod(string c)      { c_ = c; }
170 
SetAFunction(int a)171   static void SetAFunction(int a)         { current_instance_->a_ = a; }
SetCFunction(string c)172   static void SetCFunction(string c)      { current_instance_->c_ = c; }
173 
SetABMethod(int a,const char * b)174   void SetABMethod(int a, const char* b)  { a_ = a; b_ = b; }
SetABFunction(int a,const char * b)175   static void SetABFunction(int a, const char* b) {
176     current_instance_->a_ = a;
177     current_instance_->b_ = b;
178   }
179 
SetUp()180   virtual void SetUp() {
181     current_instance_ = this;
182     a_ = 0;
183     b_ = NULL;
184     c_.clear();
185     permanent_closure_ = NULL;
186   }
187 
DeleteClosureInCallback()188   void DeleteClosureInCallback() {
189     delete permanent_closure_;
190   }
191 
192   int a_;
193   const char* b_;
194   string c_;
195   Closure* permanent_closure_;
196 
197   static ClosureTest* current_instance_;
198 };
199 
200 ClosureTest* ClosureTest::current_instance_ = NULL;
201 
TEST_F(ClosureTest,TestClosureFunction0)202 TEST_F(ClosureTest, TestClosureFunction0) {
203   Closure* closure = NewCallback(&SetA123Function);
204   EXPECT_NE(123, a_);
205   closure->Run();
206   EXPECT_EQ(123, a_);
207 }
208 
TEST_F(ClosureTest,TestClosureMethod0)209 TEST_F(ClosureTest, TestClosureMethod0) {
210   Closure* closure = NewCallback(current_instance_,
211                                  &ClosureTest::SetA123Method);
212   EXPECT_NE(123, a_);
213   closure->Run();
214   EXPECT_EQ(123, a_);
215 }
216 
TEST_F(ClosureTest,TestClosureFunction1)217 TEST_F(ClosureTest, TestClosureFunction1) {
218   Closure* closure = NewCallback(&SetAFunction, 456);
219   EXPECT_NE(456, a_);
220   closure->Run();
221   EXPECT_EQ(456, a_);
222 }
223 
TEST_F(ClosureTest,TestClosureMethod1)224 TEST_F(ClosureTest, TestClosureMethod1) {
225   Closure* closure = NewCallback(current_instance_,
226                                  &ClosureTest::SetAMethod, 456);
227   EXPECT_NE(456, a_);
228   closure->Run();
229   EXPECT_EQ(456, a_);
230 }
231 
TEST_F(ClosureTest,TestClosureFunction1String)232 TEST_F(ClosureTest, TestClosureFunction1String) {
233   Closure* closure = NewCallback(&SetCFunction, string("test"));
234   EXPECT_NE("test", c_);
235   closure->Run();
236   EXPECT_EQ("test", c_);
237 }
238 
TEST_F(ClosureTest,TestClosureMethod1String)239 TEST_F(ClosureTest, TestClosureMethod1String) {
240   Closure* closure = NewCallback(current_instance_,
241                                  &ClosureTest::SetCMethod, string("test"));
242   EXPECT_NE("test", c_);
243   closure->Run();
244   EXPECT_EQ("test", c_);
245 }
246 
TEST_F(ClosureTest,TestClosureFunction2)247 TEST_F(ClosureTest, TestClosureFunction2) {
248   const char* cstr = "hello";
249   Closure* closure = NewCallback(&SetABFunction, 789, cstr);
250   EXPECT_NE(789, a_);
251   EXPECT_NE(cstr, b_);
252   closure->Run();
253   EXPECT_EQ(789, a_);
254   EXPECT_EQ(cstr, b_);
255 }
256 
TEST_F(ClosureTest,TestClosureMethod2)257 TEST_F(ClosureTest, TestClosureMethod2) {
258   const char* cstr = "hello";
259   Closure* closure = NewCallback(current_instance_,
260                                  &ClosureTest::SetABMethod, 789, cstr);
261   EXPECT_NE(789, a_);
262   EXPECT_NE(cstr, b_);
263   closure->Run();
264   EXPECT_EQ(789, a_);
265   EXPECT_EQ(cstr, b_);
266 }
267 
268 // Repeat all of the above with NewPermanentCallback()
269 
TEST_F(ClosureTest,TestPermanentClosureFunction0)270 TEST_F(ClosureTest, TestPermanentClosureFunction0) {
271   Closure* closure = NewPermanentCallback(&SetA123Function);
272   EXPECT_NE(123, a_);
273   closure->Run();
274   EXPECT_EQ(123, a_);
275   a_ = 0;
276   closure->Run();
277   EXPECT_EQ(123, a_);
278   delete closure;
279 }
280 
TEST_F(ClosureTest,TestPermanentClosureMethod0)281 TEST_F(ClosureTest, TestPermanentClosureMethod0) {
282   Closure* closure = NewPermanentCallback(current_instance_,
283                                           &ClosureTest::SetA123Method);
284   EXPECT_NE(123, a_);
285   closure->Run();
286   EXPECT_EQ(123, a_);
287   a_ = 0;
288   closure->Run();
289   EXPECT_EQ(123, a_);
290   delete closure;
291 }
292 
TEST_F(ClosureTest,TestPermanentClosureFunction1)293 TEST_F(ClosureTest, TestPermanentClosureFunction1) {
294   Closure* closure = NewPermanentCallback(&SetAFunction, 456);
295   EXPECT_NE(456, a_);
296   closure->Run();
297   EXPECT_EQ(456, a_);
298   a_ = 0;
299   closure->Run();
300   EXPECT_EQ(456, a_);
301   delete closure;
302 }
303 
TEST_F(ClosureTest,TestPermanentClosureMethod1)304 TEST_F(ClosureTest, TestPermanentClosureMethod1) {
305   Closure* closure = NewPermanentCallback(current_instance_,
306                                           &ClosureTest::SetAMethod, 456);
307   EXPECT_NE(456, a_);
308   closure->Run();
309   EXPECT_EQ(456, a_);
310   a_ = 0;
311   closure->Run();
312   EXPECT_EQ(456, a_);
313   delete closure;
314 }
315 
TEST_F(ClosureTest,TestPermanentClosureFunction2)316 TEST_F(ClosureTest, TestPermanentClosureFunction2) {
317   const char* cstr = "hello";
318   Closure* closure = NewPermanentCallback(&SetABFunction, 789, cstr);
319   EXPECT_NE(789, a_);
320   EXPECT_NE(cstr, b_);
321   closure->Run();
322   EXPECT_EQ(789, a_);
323   EXPECT_EQ(cstr, b_);
324   a_ = 0;
325   b_ = NULL;
326   closure->Run();
327   EXPECT_EQ(789, a_);
328   EXPECT_EQ(cstr, b_);
329   delete closure;
330 }
331 
TEST_F(ClosureTest,TestPermanentClosureMethod2)332 TEST_F(ClosureTest, TestPermanentClosureMethod2) {
333   const char* cstr = "hello";
334   Closure* closure = NewPermanentCallback(current_instance_,
335                                           &ClosureTest::SetABMethod, 789, cstr);
336   EXPECT_NE(789, a_);
337   EXPECT_NE(cstr, b_);
338   closure->Run();
339   EXPECT_EQ(789, a_);
340   EXPECT_EQ(cstr, b_);
341   a_ = 0;
342   b_ = NULL;
343   closure->Run();
344   EXPECT_EQ(789, a_);
345   EXPECT_EQ(cstr, b_);
346   delete closure;
347 }
348 
TEST_F(ClosureTest,TestPermanentClosureDeleteInCallback)349 TEST_F(ClosureTest, TestPermanentClosureDeleteInCallback) {
350   permanent_closure_ = NewPermanentCallback((ClosureTest*) this,
351       &ClosureTest::DeleteClosureInCallback);
352   permanent_closure_->Run();
353 }
354 
355 }  // anonymous namespace
356 }  // namespace protobuf
357 }  // namespace google
358