141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Copyright 2009 Google Inc. All Rights Reserved.
241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot//
341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Redistribution and use in source and binary forms, with or without
441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// modification, are permitted provided that the following conditions are
541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// met:
641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot//
741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot//     * Redistributions of source code must retain the above copyright
841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// notice, this list of conditions and the following disclaimer.
941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot//     * Redistributions in binary form must reproduce the above
1041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// copyright notice, this list of conditions and the following disclaimer
1141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// in the documentation and/or other materials provided with the
1241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// distribution.
1341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot//     * Neither the name of Google Inc. nor the names of its
1441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// contributors may be used to endorse or promote products derived from
1541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// this software without specific prior written permission.
1641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot//
1741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot//
2941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// Author: vladl@google.com (Vlad Losev)
3041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
3141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// This sample shows how to use Google Test listener API to implement
3241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// a primitive leak checker.
3341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
3441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#include <stdio.h>
3541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#include <stdlib.h>
3641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
3741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot#include "gtest/gtest.h"
3841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
3941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotusing ::testing::EmptyTestEventListener;
4041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotusing ::testing::InitGoogleTest;
4141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotusing ::testing::Test;
4241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotusing ::testing::TestCase;
4341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotusing ::testing::TestEventListeners;
4441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotusing ::testing::TestInfo;
4541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotusing ::testing::TestPartResult;
4641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotusing ::testing::UnitTest;
4741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
4841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotnamespace {
4941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
5041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// We will track memory used by this class.
5141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotclass Water {
5241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot public:
5341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  // Normal Water declarations go here.
5441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
5541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  // operator new and operator delete help us control water allocation.
5641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  void* operator new(size_t allocation_size) {
5741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    allocated_++;
5841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    return malloc(allocation_size);
5941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  }
6041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
6141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  void operator delete(void* block, size_t /* allocation_size */) {
6241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    allocated_--;
6341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    free(block);
6441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  }
6541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
6641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  static int allocated() { return allocated_; }
6741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
6841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot private:
6941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  static int allocated_;
7041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot};
7141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
7241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotint Water::allocated_ = 0;
7341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
7441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// This event listener monitors how many Water objects are created and
7541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// destroyed by each test, and reports a failure if a test leaks some Water
7641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// objects. It does this by comparing the number of live Water objects at
7741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// the beginning of a test and at the end of a test.
7841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotclass LeakChecker : public EmptyTestEventListener {
7941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot private:
8041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  // Called before a test starts.
8141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  virtual void OnTestStart(const TestInfo& /* test_info */) {
8241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    initially_allocated_ = Water::allocated();
8341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  }
8441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
8541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  // Called after a test ends.
8641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  virtual void OnTestEnd(const TestInfo& /* test_info */) {
8741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    int difference = Water::allocated() - initially_allocated_;
8841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
8941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // You can generate a failure in any event handler except
9041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // OnTestPartResult. Just use an appropriate Google Test assertion to do
9141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // it.
9241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    EXPECT_TRUE(difference <= 0)
9341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot        << "Leaked " << difference << " unit(s) of Water!";
9441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  }
9541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
9641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  int initially_allocated_;
9741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot};
9841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
9941d0579e8de9ef4ff178fc4991043c61a19943f7Brett ChabotTEST(ListenersTest, DoesNotLeak) {
10041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  Water* water = new Water;
10141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  delete water;
10241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot}
10341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
10441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// This should fail when the --check_for_leaks command line flag is
10541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot// specified.
10641d0579e8de9ef4ff178fc4991043c61a19943f7Brett ChabotTEST(ListenersTest, LeaksWater) {
10741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  Water* water = new Water;
10841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  EXPECT_TRUE(water != NULL);
10941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot}
11041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
11141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot}  // namespace
11241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
11341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabotint main(int argc, char **argv) {
11441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  InitGoogleTest(&argc, argv);
11541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
11641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  bool check_for_leaks = false;
11741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0 )
11841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    check_for_leaks = true;
11941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  else
12041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    printf("%s\n", "Run this program with --check_for_leaks to enable "
12141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot           "custom leak checking in the tests.");
12241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
12341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  // If we are given the --check_for_leaks command line flag, installs the
12441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  // leak checker.
12541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  if (check_for_leaks) {
12641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
12741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot
12841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // Adds the leak checker to the end of the test event listener list,
12941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // after the default text output printer and the default XML report
13041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // generator.
13141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    //
13241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // The order is important - it ensures that failures generated in the
13341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // leak checker's OnTestEnd() method are processed by the text and XML
13441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // printers *before* their OnTestEnd() methods are called, such that
13541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // they are attributed to the right test. Remember that a listener
13641d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // receives an OnXyzStart event *after* listeners preceding it in the
13741d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // list received that event, and receives an OnXyzEnd event *before*
13841d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // listeners preceding it.
13941d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    //
14041d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // We don't need to worry about deleting the new listener later, as
14141d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    // Google Test will do it.
14241d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot    listeners.Append(new LeakChecker);
14341d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  }
14441d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot  return RUN_ALL_TESTS();
14541d0579e8de9ef4ff178fc4991043c61a19943f7Brett Chabot}
146