1d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// Copyright 2009 Google Inc. All Rights Reserved.
2d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan//
3d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// Redistribution and use in source and binary forms, with or without
4d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// modification, are permitted provided that the following conditions are
5d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// met:
6d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan//
7d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan//     * Redistributions of source code must retain the above copyright
8d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// notice, this list of conditions and the following disclaimer.
9d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan//     * Redistributions in binary form must reproduce the above
10d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// copyright notice, this list of conditions and the following disclaimer
11d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// in the documentation and/or other materials provided with the
12d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// distribution.
13d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan//     * Neither the name of Google Inc. nor the names of its
14d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// contributors may be used to endorse or promote products derived from
15d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// this software without specific prior written permission.
16d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan//
17d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan//
29d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// Author: vladl@google.com (Vlad Losev)
30d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
31d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// This sample shows how to use Google Test listener API to implement
32d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// a primitive leak checker.
33d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
34d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan#include <stdio.h>
35d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan#include <stdlib.h>
36d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
372620c79810d4741922e9fa89050c0af564994f24zhanyong.wan#include "gtest/gtest.h"
38d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
39fff033497b70e96a5dcadb6ba9570c12b5921d74zhanyong.wanusing ::testing::EmptyTestEventListener;
40d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wanusing ::testing::InitGoogleTest;
41d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wanusing ::testing::Test;
42fff033497b70e96a5dcadb6ba9570c12b5921d74zhanyong.wanusing ::testing::TestCase;
43f6d087b78d230d875bf5d8281112662795044680zhanyong.wanusing ::testing::TestEventListeners;
44d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wanusing ::testing::TestInfo;
45d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wanusing ::testing::TestPartResult;
46d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wanusing ::testing::UnitTest;
47d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
48d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wannamespace {
49d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
50d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// We will track memory used by this class.
51d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wanclass Water {
52d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan public:
53d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  // Normal Water declarations go here.
54d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
55d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  // operator new and operator delete help us control water allocation.
56d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  void* operator new(size_t allocation_size) {
57d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    allocated_++;
58d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    return malloc(allocation_size);
59d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  }
60d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
61a6b964f85b615360d42aa68658621a0eaf9ec225zhanyong.wan  void operator delete(void* block, size_t /* allocation_size */) {
62d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    allocated_--;
63d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    free(block);
64d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  }
65d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
66d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  static int allocated() { return allocated_; }
67d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
68d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan private:
69d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  static int allocated_;
70d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan};
71d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
72d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wanint Water::allocated_ = 0;
73d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
74d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// This event listener monitors how many Water objects are created and
75d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// destroyed by each test, and reports a failure if a test leaks some Water
76d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// objects. It does this by comparing the number of live Water objects at
77d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// the beginning of a test and at the end of a test.
78d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wanclass LeakChecker : public EmptyTestEventListener {
79d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan private:
80d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  // Called before a test starts.
81a6b964f85b615360d42aa68658621a0eaf9ec225zhanyong.wan  virtual void OnTestStart(const TestInfo& /* test_info */) {
82d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    initially_allocated_ = Water::allocated();
83d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  }
84d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
85d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  // Called after a test ends.
86a6b964f85b615360d42aa68658621a0eaf9ec225zhanyong.wan  virtual void OnTestEnd(const TestInfo& /* test_info */) {
87d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    int difference = Water::allocated() - initially_allocated_;
88d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
89d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // You can generate a failure in any event handler except
90d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // OnTestPartResult. Just use an appropriate Google Test assertion to do
91d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // it.
9293fed47dbf8e6bc3d39d3f769cb5039551747257vladlosev    EXPECT_LE(difference, 0) << "Leaked " << difference << " unit(s) of Water!";
93d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  }
94d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
95d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  int initially_allocated_;
96d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan};
97d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
98d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wanTEST(ListenersTest, DoesNotLeak) {
99d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  Water* water = new Water;
100d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  delete water;
101d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan}
102d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
103d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// This should fail when the --check_for_leaks command line flag is
104d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan// specified.
105d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wanTEST(ListenersTest, LeaksWater) {
106d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  Water* water = new Water;
107d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  EXPECT_TRUE(water != NULL);
108d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan}
109d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
110d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan}  // namespace
111d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
112d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wanint main(int argc, char **argv) {
113d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  InitGoogleTest(&argc, argv);
114d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
115d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  bool check_for_leaks = false;
116d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0 )
117d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    check_for_leaks = true;
118d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  else
119d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    printf("%s\n", "Run this program with --check_for_leaks to enable "
120d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan           "custom leak checking in the tests.");
121d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
122d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  // If we are given the --check_for_leaks command line flag, installs the
123d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  // leak checker.
124d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  if (check_for_leaks) {
125f6d087b78d230d875bf5d8281112662795044680zhanyong.wan    TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
126d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan
127d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // Adds the leak checker to the end of the test event listener list,
128d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // after the default text output printer and the default XML report
129d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // generator.
130d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    //
131d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // The order is important - it ensures that failures generated in the
132d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // leak checker's OnTestEnd() method are processed by the text and XML
133d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // printers *before* their OnTestEnd() methods are called, such that
134d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // they are attributed to the right test. Remember that a listener
135d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // receives an OnXyzStart event *after* listeners preceding it in the
136d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // list received that event, and receives an OnXyzEnd event *before*
137d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // listeners preceding it.
138d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    //
139d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // We don't need to worry about deleting the new listener later, as
140d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    // Google Test will do it.
141d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan    listeners.Append(new LeakChecker);
142d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  }
143d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan  return RUN_ALL_TESTS();
144d541f0259d2f6857df769f581363f84e8c4b2899zhanyong.wan}
145