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