113481Sgiacomo.travaglini@arm.com// Copyright 2009 Google Inc. All Rights Reserved.
213481Sgiacomo.travaglini@arm.com//
313481Sgiacomo.travaglini@arm.com// Redistribution and use in source and binary forms, with or without
413481Sgiacomo.travaglini@arm.com// modification, are permitted provided that the following conditions are
513481Sgiacomo.travaglini@arm.com// met:
613481Sgiacomo.travaglini@arm.com//
713481Sgiacomo.travaglini@arm.com//     * Redistributions of source code must retain the above copyright
813481Sgiacomo.travaglini@arm.com// notice, this list of conditions and the following disclaimer.
913481Sgiacomo.travaglini@arm.com//     * Redistributions in binary form must reproduce the above
1013481Sgiacomo.travaglini@arm.com// copyright notice, this list of conditions and the following disclaimer
1113481Sgiacomo.travaglini@arm.com// in the documentation and/or other materials provided with the
1213481Sgiacomo.travaglini@arm.com// distribution.
1313481Sgiacomo.travaglini@arm.com//     * Neither the name of Google Inc. nor the names of its
1413481Sgiacomo.travaglini@arm.com// contributors may be used to endorse or promote products derived from
1513481Sgiacomo.travaglini@arm.com// this software without specific prior written permission.
1613481Sgiacomo.travaglini@arm.com//
1713481Sgiacomo.travaglini@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1813481Sgiacomo.travaglini@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1913481Sgiacomo.travaglini@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2013481Sgiacomo.travaglini@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2113481Sgiacomo.travaglini@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2213481Sgiacomo.travaglini@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2313481Sgiacomo.travaglini@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2413481Sgiacomo.travaglini@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2513481Sgiacomo.travaglini@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2613481Sgiacomo.travaglini@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2713481Sgiacomo.travaglini@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2813481Sgiacomo.travaglini@arm.com//
2913481Sgiacomo.travaglini@arm.com// Author: vladl@google.com (Vlad Losev)
3013481Sgiacomo.travaglini@arm.com
3113481Sgiacomo.travaglini@arm.com// This sample shows how to use Google Test listener API to implement
3213481Sgiacomo.travaglini@arm.com// a primitive leak checker.
3313481Sgiacomo.travaglini@arm.com
3413481Sgiacomo.travaglini@arm.com#include <stdio.h>
3513481Sgiacomo.travaglini@arm.com#include <stdlib.h>
3613481Sgiacomo.travaglini@arm.com
3713481Sgiacomo.travaglini@arm.com#include "gtest/gtest.h"
3813481Sgiacomo.travaglini@arm.com
3913481Sgiacomo.travaglini@arm.comusing ::testing::EmptyTestEventListener;
4013481Sgiacomo.travaglini@arm.comusing ::testing::InitGoogleTest;
4113481Sgiacomo.travaglini@arm.comusing ::testing::Test;
4213481Sgiacomo.travaglini@arm.comusing ::testing::TestCase;
4313481Sgiacomo.travaglini@arm.comusing ::testing::TestEventListeners;
4413481Sgiacomo.travaglini@arm.comusing ::testing::TestInfo;
4513481Sgiacomo.travaglini@arm.comusing ::testing::TestPartResult;
4613481Sgiacomo.travaglini@arm.comusing ::testing::UnitTest;
4713481Sgiacomo.travaglini@arm.com
4813481Sgiacomo.travaglini@arm.comnamespace {
4913481Sgiacomo.travaglini@arm.com
5013481Sgiacomo.travaglini@arm.com// We will track memory used by this class.
5113481Sgiacomo.travaglini@arm.comclass Water {
5213481Sgiacomo.travaglini@arm.com public:
5313481Sgiacomo.travaglini@arm.com  // Normal Water declarations go here.
5413481Sgiacomo.travaglini@arm.com
5513481Sgiacomo.travaglini@arm.com  // operator new and operator delete help us control water allocation.
5613481Sgiacomo.travaglini@arm.com  void* operator new(size_t allocation_size) {
5713481Sgiacomo.travaglini@arm.com    allocated_++;
5813481Sgiacomo.travaglini@arm.com    return malloc(allocation_size);
5913481Sgiacomo.travaglini@arm.com  }
6013481Sgiacomo.travaglini@arm.com
6113481Sgiacomo.travaglini@arm.com  void operator delete(void* block, size_t /* allocation_size */) {
6213481Sgiacomo.travaglini@arm.com    allocated_--;
6313481Sgiacomo.travaglini@arm.com    free(block);
6413481Sgiacomo.travaglini@arm.com  }
6513481Sgiacomo.travaglini@arm.com
6613481Sgiacomo.travaglini@arm.com  static int allocated() { return allocated_; }
6713481Sgiacomo.travaglini@arm.com
6813481Sgiacomo.travaglini@arm.com private:
6913481Sgiacomo.travaglini@arm.com  static int allocated_;
7013481Sgiacomo.travaglini@arm.com};
7113481Sgiacomo.travaglini@arm.com
7213481Sgiacomo.travaglini@arm.comint Water::allocated_ = 0;
7313481Sgiacomo.travaglini@arm.com
7413481Sgiacomo.travaglini@arm.com// This event listener monitors how many Water objects are created and
7513481Sgiacomo.travaglini@arm.com// destroyed by each test, and reports a failure if a test leaks some Water
7613481Sgiacomo.travaglini@arm.com// objects. It does this by comparing the number of live Water objects at
7713481Sgiacomo.travaglini@arm.com// the beginning of a test and at the end of a test.
7813481Sgiacomo.travaglini@arm.comclass LeakChecker : public EmptyTestEventListener {
7913481Sgiacomo.travaglini@arm.com private:
8013481Sgiacomo.travaglini@arm.com  // Called before a test starts.
8113481Sgiacomo.travaglini@arm.com  virtual void OnTestStart(const TestInfo& /* test_info */) {
8213481Sgiacomo.travaglini@arm.com    initially_allocated_ = Water::allocated();
8313481Sgiacomo.travaglini@arm.com  }
8413481Sgiacomo.travaglini@arm.com
8513481Sgiacomo.travaglini@arm.com  // Called after a test ends.
8613481Sgiacomo.travaglini@arm.com  virtual void OnTestEnd(const TestInfo& /* test_info */) {
8713481Sgiacomo.travaglini@arm.com    int difference = Water::allocated() - initially_allocated_;
8813481Sgiacomo.travaglini@arm.com
8913481Sgiacomo.travaglini@arm.com    // You can generate a failure in any event handler except
9013481Sgiacomo.travaglini@arm.com    // OnTestPartResult. Just use an appropriate Google Test assertion to do
9113481Sgiacomo.travaglini@arm.com    // it.
9213481Sgiacomo.travaglini@arm.com    EXPECT_LE(difference, 0) << "Leaked " << difference << " unit(s) of Water!";
9313481Sgiacomo.travaglini@arm.com  }
9413481Sgiacomo.travaglini@arm.com
9513481Sgiacomo.travaglini@arm.com  int initially_allocated_;
9613481Sgiacomo.travaglini@arm.com};
9713481Sgiacomo.travaglini@arm.com
9813481Sgiacomo.travaglini@arm.comTEST(ListenersTest, DoesNotLeak) {
9913481Sgiacomo.travaglini@arm.com  Water* water = new Water;
10013481Sgiacomo.travaglini@arm.com  delete water;
10113481Sgiacomo.travaglini@arm.com}
10213481Sgiacomo.travaglini@arm.com
10313481Sgiacomo.travaglini@arm.com// This should fail when the --check_for_leaks command line flag is
10413481Sgiacomo.travaglini@arm.com// specified.
10513481Sgiacomo.travaglini@arm.comTEST(ListenersTest, LeaksWater) {
10613481Sgiacomo.travaglini@arm.com  Water* water = new Water;
10713481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(water != NULL);
10813481Sgiacomo.travaglini@arm.com}
10913481Sgiacomo.travaglini@arm.com
11013481Sgiacomo.travaglini@arm.com}  // namespace
11113481Sgiacomo.travaglini@arm.com
11213481Sgiacomo.travaglini@arm.comint main(int argc, char **argv) {
11313481Sgiacomo.travaglini@arm.com  InitGoogleTest(&argc, argv);
11413481Sgiacomo.travaglini@arm.com
11513481Sgiacomo.travaglini@arm.com  bool check_for_leaks = false;
11613481Sgiacomo.travaglini@arm.com  if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0 )
11713481Sgiacomo.travaglini@arm.com    check_for_leaks = true;
11813481Sgiacomo.travaglini@arm.com  else
11913481Sgiacomo.travaglini@arm.com    printf("%s\n", "Run this program with --check_for_leaks to enable "
12013481Sgiacomo.travaglini@arm.com           "custom leak checking in the tests.");
12113481Sgiacomo.travaglini@arm.com
12213481Sgiacomo.travaglini@arm.com  // If we are given the --check_for_leaks command line flag, installs the
12313481Sgiacomo.travaglini@arm.com  // leak checker.
12413481Sgiacomo.travaglini@arm.com  if (check_for_leaks) {
12513481Sgiacomo.travaglini@arm.com    TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
12613481Sgiacomo.travaglini@arm.com
12713481Sgiacomo.travaglini@arm.com    // Adds the leak checker to the end of the test event listener list,
12813481Sgiacomo.travaglini@arm.com    // after the default text output printer and the default XML report
12913481Sgiacomo.travaglini@arm.com    // generator.
13013481Sgiacomo.travaglini@arm.com    //
13113481Sgiacomo.travaglini@arm.com    // The order is important - it ensures that failures generated in the
13213481Sgiacomo.travaglini@arm.com    // leak checker's OnTestEnd() method are processed by the text and XML
13313481Sgiacomo.travaglini@arm.com    // printers *before* their OnTestEnd() methods are called, such that
13413481Sgiacomo.travaglini@arm.com    // they are attributed to the right test. Remember that a listener
13513481Sgiacomo.travaglini@arm.com    // receives an OnXyzStart event *after* listeners preceding it in the
13613481Sgiacomo.travaglini@arm.com    // list received that event, and receives an OnXyzEnd event *before*
13713481Sgiacomo.travaglini@arm.com    // listeners preceding it.
13813481Sgiacomo.travaglini@arm.com    //
13913481Sgiacomo.travaglini@arm.com    // We don't need to worry about deleting the new listener later, as
14013481Sgiacomo.travaglini@arm.com    // Google Test will do it.
14113481Sgiacomo.travaglini@arm.com    listeners.Append(new LeakChecker);
14213481Sgiacomo.travaglini@arm.com  }
14313481Sgiacomo.travaglini@arm.com  return RUN_ALL_TESTS();
14413481Sgiacomo.travaglini@arm.com}
145