From 8f6b3cf1ab2c645bc6448c697edbc9c5fd1a27bb Mon Sep 17 00:00:00 2001 From: Viktor Stanchev Date: Fri, 4 Apr 2014 10:11:41 +0800 Subject: [PATCH] Bug 986160 - Create unit tests for the Gecko Profiler. r=benwa --HG-- extra : rebase_source : b73d3af33ddbf032a01067c9d92ea6a6e441cdba --- tools/profiler/ProfileEntry.h | 11 +++ tools/profiler/moz.build | 3 + .../tests/gtest/ThreadProfileTest.cpp | 69 +++++++++++++++++++ tools/profiler/tests/gtest/moz.build | 19 +++++ 4 files changed, 102 insertions(+) create mode 100644 tools/profiler/tests/gtest/ThreadProfileTest.cpp create mode 100644 tools/profiler/tests/gtest/moz.build diff --git a/tools/profiler/ProfileEntry.h b/tools/profiler/ProfileEntry.h index e866b4368ff6..765831a87cf8 100644 --- a/tools/profiler/ProfileEntry.h +++ b/tools/profiler/ProfileEntry.h @@ -12,6 +12,7 @@ #include "platform.h" #include "ProfilerBacktrace.h" #include "mozilla/Mutex.h" +#include "gtest/gtest.h" class ThreadProfile; @@ -45,6 +46,11 @@ public: char getTagName() const { return mTagName; } private: + FRIEND_TEST(ThreadProfile, InsertOneTag); + FRIEND_TEST(ThreadProfile, InsertOneTagWithTinyBuffer); + FRIEND_TEST(ThreadProfile, InsertTagsNoWrap); + FRIEND_TEST(ThreadProfile, InsertTagsWrap); + FRIEND_TEST(ThreadProfile, MemoryMeasure); friend class ThreadProfile; union { const char* mTagData; @@ -99,6 +105,11 @@ public: void* GetStackTop() const { return mStackTop; } void DuplicateLastSample(); private: + FRIEND_TEST(ThreadProfile, InsertOneTag); + FRIEND_TEST(ThreadProfile, InsertOneTagWithTinyBuffer); + FRIEND_TEST(ThreadProfile, InsertTagsNoWrap); + FRIEND_TEST(ThreadProfile, InsertTagsWrap); + FRIEND_TEST(ThreadProfile, MemoryMeasure); // Circular buffer 'Keep One Slot Open' implementation // for simplicity ProfileEntry* mEntries; diff --git a/tools/profiler/moz.build b/tools/profiler/moz.build index 4710841e7be9..7041db04ac8f 100644 --- a/tools/profiler/moz.build +++ b/tools/profiler/moz.build @@ -7,6 +7,9 @@ if CONFIG['MOZ_ENABLE_PROFILER_SPS']: FAIL_ON_WARNINGS = not CONFIG['_MSC_VER'] + if CONFIG['ENABLE_TESTS']: + DIRS += ['tests/gtest'] + XPIDL_MODULE = 'profiler' XPIDL_SOURCES += [ 'nsIProfiler.idl', diff --git a/tools/profiler/tests/gtest/ThreadProfileTest.cpp b/tools/profiler/tests/gtest/ThreadProfileTest.cpp new file mode 100644 index 000000000000..9c5d66871b36 --- /dev/null +++ b/tools/profiler/tests/gtest/ThreadProfileTest.cpp @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" + +#include "ProfileEntry.h" + +// Make sure we can initialize our ThreadProfile +TEST(ThreadProfile, Initialization) { + PseudoStack stack; + Thread::tid_t tid = 1000; + ThreadProfile tp("testThread", 10, &stack, tid, nullptr, true, nullptr); +} + +// Make sure we can record one tag and read it +TEST(ThreadProfile, InsertOneTag) { + PseudoStack stack; + Thread::tid_t tid = 1000; + ThreadProfile tp("testThread", 10, &stack, tid, nullptr, true, nullptr); + tp.addTag(ProfileEntry('t', 123.1f)); + ASSERT_TRUE(tp.mEntries != nullptr); + ASSERT_TRUE(tp.mEntries[tp.mReadPos].mTagName == 't'); + ASSERT_TRUE(tp.mEntries[tp.mReadPos].mTagFloat == 123.1f); +} + +// See if we can insert some tags +TEST(ThreadProfile, InsertTagsNoWrap) { + PseudoStack stack; + Thread::tid_t tid = 1000; + ThreadProfile tp("testThread", 100, &stack, tid, nullptr, true, nullptr); + int test_size = 50; + for (int i = 0; i < test_size; i++) { + tp.addTag(ProfileEntry('t', i)); + } + ASSERT_TRUE(tp.mEntries != nullptr); + int readPos = tp.mReadPos; + while (readPos != tp.mWritePos) { + ASSERT_TRUE(tp.mEntries[readPos].mTagName == 't'); + ASSERT_TRUE(tp.mEntries[readPos].mTagLine == readPos); + readPos = (readPos + 1) % tp.mEntrySize; + } +} + +// See if wrapping works as it should in the basic case +TEST(ThreadProfile, InsertTagsWrap) { + PseudoStack stack; + Thread::tid_t tid = 1000; + // we can fit only 24 tags in this buffer because of the empty slot + int tags = 24; + int buffer_size = tags + 1; + ThreadProfile tp("testThread", buffer_size, &stack, tid, nullptr, true, nullptr); + int test_size = 43; + for (int i = 0; i < test_size; i++) { + tp.addTag(ProfileEntry('t', i)); + } + ASSERT_TRUE(tp.mEntries != nullptr); + int readPos = tp.mReadPos; + int ctr = 0; + while (readPos != tp.mWritePos) { + ASSERT_TRUE(tp.mEntries[readPos].mTagName == 't'); + // the first few tags were discarded when we wrapped + ASSERT_TRUE(tp.mEntries[readPos].mTagLine == ctr + (test_size - tags)); + ctr++; + readPos = (readPos + 1) % tp.mEntrySize; + } +} + diff --git a/tools/profiler/tests/gtest/moz.build b/tools/profiler/tests/gtest/moz.build new file mode 100644 index 000000000000..c247d286b9b3 --- /dev/null +++ b/tools/profiler/tests/gtest/moz.build @@ -0,0 +1,19 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +LIBRARY_NAME = 'profilertest' + +UNIFIED_SOURCES = [ + "ThreadProfileTest.cpp", +] + +EXPORT_LIBRARY = True + +LOCAL_INCLUDES += [ + '/tools/profiler/', +] + +FINAL_LIBRARY = 'xul-gtest'