1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google Inc. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 //
8 #include <cstdlib>
9 #include <string>
10
11 #include <gmock/gmock.h>
12 #include <gtest/gtest.h>
13 #include "google/protobuf/port.h"
14
15 // Must be included last.
16 #include "google/protobuf/port_def.inc"
17
18 namespace {
19
20 using testing::AllOf;
21 using testing::ExitedWithCode;
22 using testing::HasSubstr;
23 using testing::Not;
24
MatchOutput(bool expect_output)25 auto MatchOutput(bool expect_output) {
26 const auto header = HasSubstr("Protobuf debug counters:");
27 const auto foo = HasSubstr("Foo :");
28 const auto bar = HasSubstr("Bar : 1 (33.33%)");
29 const auto baz = HasSubstr("Baz : 2 (66.67%)");
30 const auto total = HasSubstr("Total : 3");
31 return expect_output ? testing::Matcher<const std::string&>(
32 AllOf(header, foo, bar, baz, total))
33 : testing::Matcher<const std::string&>(Not(header));
34 }
35
36 #ifdef GTEST_HAS_DEATH_TEST
TEST(DebugCounterTest,RealProvidesReportAtExit)37 TEST(DebugCounterTest, RealProvidesReportAtExit) {
38 EXPECT_EXIT(
39 {
40 static google::protobuf::internal::RealDebugCounter counter1("Foo.Bar");
41 static google::protobuf::internal::RealDebugCounter counter2("Foo.Baz");
42 counter1.Inc();
43 counter2.Inc();
44 counter2.Inc();
45 exit(0);
46 },
47 ExitedWithCode(0), MatchOutput(true));
48 }
49
TEST(DebugCounterTest,NoopDoesNotProvidesReportAtExit)50 TEST(DebugCounterTest, NoopDoesNotProvidesReportAtExit) {
51 EXPECT_EXIT(
52 {
53 static google::protobuf::internal::NoopDebugCounter counter1;
54 static google::protobuf::internal::NoopDebugCounter counter2;
55 counter1.Inc();
56 counter2.Inc();
57 counter2.Inc();
58 exit(0);
59 },
60 ExitedWithCode(0), MatchOutput(false));
61
62 // and test that the operations have no side effects.
63 static_assert((google::protobuf::internal::NoopDebugCounter().Inc(), true), "");
64 }
65
TEST(DebugCounterTest,MacroProvidesReportAtExitDependingOnBuild)66 TEST(DebugCounterTest, MacroProvidesReportAtExitDependingOnBuild) {
67 #if defined(PROTOBUF_INTERNAL_ENABLE_DEBUG_COUNTERS)
68 constexpr bool match_output = true;
69 #else
70 constexpr bool match_output = false;
71
72 // and test that the operations have no side effects.
73 static_assert((PROTOBUF_DEBUG_COUNTER("Foo.Bar").Inc(), true), "");
74 #endif
75
76 EXPECT_EXIT(
77 {
78 PROTOBUF_DEBUG_COUNTER("Foo.Bar").Inc();
79 for (int i = 0; i < 2; ++i) {
80 PROTOBUF_DEBUG_COUNTER("Foo.Baz").Inc();
81 }
82 exit(0);
83 },
84 ExitedWithCode(0), MatchOutput(match_output));
85 }
86 #endif // GTEST_HAS_DEATH_TEST
87
88 } // namespace
89
90 #include "google/protobuf/port_undef.inc"
91