base: Add unit test for debug.hh
Add unit tests for the functions and classes in debug.hh. breakpoint() is not being tested. Change-Id: I1ae7318a043aa9dc479d4f970c1fd6c9946f4357 Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/38710 Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Daniel Carvalho
parent
a4657f1b84
commit
3f0cd995bf
@@ -40,6 +40,7 @@ Source('channel_addr.cc')
|
||||
Source('cprintf.cc', add_tags='gtest lib')
|
||||
GTest('cprintf.test', 'cprintf.test.cc')
|
||||
Source('debug.cc')
|
||||
GTest('debug.test', 'debug.test.cc', 'debug.cc')
|
||||
if env['USE_FENV']:
|
||||
Source('fenv.c')
|
||||
if env['USE_PNG']:
|
||||
|
||||
@@ -94,8 +94,7 @@ Flag::Flag(const char *name, const char *desc)
|
||||
std::pair<FlagsMap::iterator, bool> result =
|
||||
allFlags().insert(std::make_pair(name, this));
|
||||
|
||||
if (!result.second)
|
||||
panic("Flag %s already defined!", name);
|
||||
panic_if(!result.second, "Flag %s already defined!", name);
|
||||
|
||||
++allFlagsVersion;
|
||||
|
||||
|
||||
293
src/base/debug.test.cc
Normal file
293
src/base/debug.test.cc
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Daniel R. Carvalho
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "base/debug.hh"
|
||||
|
||||
/** Test assignment of names and descriptions. */
|
||||
TEST(DebugFlagTest, NameDesc)
|
||||
{
|
||||
Debug::SimpleFlag flag_a("FlagNameDescTestKidA", "Kid A");
|
||||
EXPECT_EQ("FlagNameDescTestKidA", flag_a.name());
|
||||
EXPECT_EQ("Kid A", flag_a.desc());
|
||||
|
||||
Debug::SimpleFlag flag_b("FlagNameDescTestKidB", "Kid B");
|
||||
EXPECT_EQ("FlagNameDescTestKidB", flag_b.name());
|
||||
EXPECT_EQ("Kid B", flag_b.desc());
|
||||
|
||||
Debug::CompoundFlag compound_flag("FlagNameDescTest", "Compound Flag",
|
||||
{&flag_a, &flag_b});
|
||||
EXPECT_EQ("FlagNameDescTest", compound_flag.name());
|
||||
EXPECT_EQ("Compound Flag", compound_flag.desc());
|
||||
}
|
||||
|
||||
/** Test that names are unique. */
|
||||
TEST(DebugFlagDeathTest, UniqueNames)
|
||||
{
|
||||
Debug::SimpleFlag flag("FlagUniqueNamesTest", "A");
|
||||
testing::internal::CaptureStderr();
|
||||
EXPECT_ANY_THROW(Debug::SimpleFlag("FlagUniqueNamesTest", "B"));
|
||||
const std::string expected = "panic: panic condition !result.second "
|
||||
"occurred: Flag FlagUniqueNamesTest already defined!\n";
|
||||
std::string actual = testing::internal::GetCapturedStderr().substr();
|
||||
actual = actual.substr(actual.find(":", actual.find(":") + 1) + 2);
|
||||
EXPECT_EQ(expected, actual);
|
||||
}
|
||||
|
||||
/** Test enabling and disabling simple flags, as well as the global enabler. */
|
||||
TEST(DebugSimpleFlagTest, Status)
|
||||
{
|
||||
Debug::Flag::globalDisable();
|
||||
Debug::SimpleFlag flag("SimpleFlagStatusTest", "");
|
||||
|
||||
// By default flags are initialized disabled
|
||||
ASSERT_FALSE(flag.status());
|
||||
|
||||
// Flags must be globally enabled before individual flags are enabled
|
||||
flag.enable();
|
||||
ASSERT_FALSE(flag.status());
|
||||
Debug::Flag::globalEnable();
|
||||
ASSERT_TRUE(flag.status());
|
||||
|
||||
// Verify that the global enabler works
|
||||
Debug::Flag::globalDisable();
|
||||
ASSERT_FALSE(flag.status());
|
||||
Debug::Flag::globalEnable();
|
||||
ASSERT_TRUE(flag.status());
|
||||
|
||||
// Test disabling the flag with global enabled
|
||||
flag.disable();
|
||||
ASSERT_FALSE(flag.status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that manipulate the status of the compound flag to change the status
|
||||
* of the kids.
|
||||
*/
|
||||
TEST(DebugCompoundFlagTest, Status)
|
||||
{
|
||||
Debug::Flag::globalDisable();
|
||||
Debug::SimpleFlag flag_a("CompoundFlagStatusTestKidA", "");
|
||||
Debug::SimpleFlag flag_b("CompoundFlagStatusTestKidB", "");
|
||||
Debug::CompoundFlag flag("CompoundFlagStatusTest", "", {&flag_a, &flag_b});
|
||||
|
||||
// By default flags are initialized disabled
|
||||
ASSERT_FALSE(flag.status());
|
||||
|
||||
// Flags must be globally enabled before individual flags are enabled
|
||||
flag.enable();
|
||||
ASSERT_FALSE(flag_a.status());
|
||||
ASSERT_FALSE(flag_b.status());
|
||||
ASSERT_FALSE(flag.status());
|
||||
Debug::Flag::globalEnable();
|
||||
for (auto &kid : flag.kids()) {
|
||||
ASSERT_TRUE(kid->status());
|
||||
}
|
||||
ASSERT_TRUE(flag_a.status());
|
||||
ASSERT_TRUE(flag_b.status());
|
||||
ASSERT_TRUE(flag.status());
|
||||
|
||||
// Test disabling the flag with global enabled
|
||||
flag.disable();
|
||||
for (auto &kid : flag.kids()) {
|
||||
ASSERT_FALSE(kid->status());
|
||||
}
|
||||
ASSERT_FALSE(flag_a.status());
|
||||
ASSERT_FALSE(flag_b.status());
|
||||
ASSERT_FALSE(flag.status());
|
||||
}
|
||||
|
||||
/** Test that the conversion operator matches the status. */
|
||||
TEST(DebugFlagTest, ConversionOperator)
|
||||
{
|
||||
Debug::Flag::globalEnable();
|
||||
Debug::SimpleFlag flag("FlagConversionOperatorTest", "");
|
||||
|
||||
ASSERT_EQ(flag, flag.status());
|
||||
flag.enable();
|
||||
ASSERT_EQ(flag, flag.status());
|
||||
flag.disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that manipulate the kids to change the status of the compound flag.
|
||||
*/
|
||||
TEST(DebugCompoundFlagTest, StatusKids)
|
||||
{
|
||||
Debug::Flag::globalEnable();
|
||||
Debug::SimpleFlag flag_a("CompoundFlagStatusKidsTestKidA", "");
|
||||
Debug::SimpleFlag flag_b("CompoundFlagStatusKidsTestKidB", "");
|
||||
Debug::CompoundFlag flag("CompoundFlagStatusKidsTest", "",
|
||||
{&flag_a, &flag_b});
|
||||
|
||||
// Test enabling only flag A
|
||||
ASSERT_FALSE(flag_a.status());
|
||||
ASSERT_FALSE(flag_b.status());
|
||||
ASSERT_FALSE(flag.status());
|
||||
flag_a.enable();
|
||||
ASSERT_TRUE(flag_a.status());
|
||||
ASSERT_FALSE(flag_b.status());
|
||||
ASSERT_FALSE(flag.status());
|
||||
|
||||
// Test that enabling both flags enables the compound flag
|
||||
ASSERT_TRUE(flag_a.status());
|
||||
ASSERT_FALSE(flag_b.status());
|
||||
ASSERT_FALSE(flag.status());
|
||||
flag_b.enable();
|
||||
ASSERT_TRUE(flag_a.status());
|
||||
ASSERT_TRUE(flag_b.status());
|
||||
ASSERT_TRUE(flag.status());
|
||||
|
||||
// Test that disabling one of the flags disables the compound flag
|
||||
flag_a.disable();
|
||||
ASSERT_FALSE(flag_a.status());
|
||||
ASSERT_TRUE(flag_b.status());
|
||||
ASSERT_FALSE(flag.status());
|
||||
}
|
||||
|
||||
/** Search for existent and non-existent flags. */
|
||||
TEST(DebugFlagTest, FindFlag)
|
||||
{
|
||||
Debug::Flag::globalEnable();
|
||||
Debug::SimpleFlag flag_a("FlagFindFlagTestA", "");
|
||||
Debug::SimpleFlag flag_b("FlagFindFlagTestB", "");
|
||||
|
||||
// Enable the found flags and verify that the original flags are
|
||||
// enabled too
|
||||
Debug::Flag *flag;
|
||||
EXPECT_TRUE(flag = Debug::findFlag("FlagFindFlagTestA"));
|
||||
ASSERT_FALSE(flag_a.status());
|
||||
flag->enable();
|
||||
ASSERT_TRUE(flag_a.status());
|
||||
EXPECT_TRUE(flag = Debug::findFlag("FlagFindFlagTestB"));
|
||||
ASSERT_FALSE(flag_b.status());
|
||||
flag->enable();
|
||||
ASSERT_TRUE(flag_b.status());
|
||||
|
||||
// Search for a non-existent flag
|
||||
EXPECT_FALSE(Debug::findFlag("FlagFindFlagTestC"));
|
||||
}
|
||||
|
||||
/** Test changing flag status. */
|
||||
TEST(DebugFlagTest, ChangeFlag)
|
||||
{
|
||||
Debug::Flag::globalEnable();
|
||||
Debug::SimpleFlag flag_a("FlagChangeFlagTestA", "");
|
||||
Debug::SimpleFlag flag_b("FlagChangeFlagTestB", "");
|
||||
|
||||
// Enable the found flags and verify that the original flags are
|
||||
// enabled too
|
||||
ASSERT_FALSE(flag_a.status());
|
||||
EXPECT_TRUE(Debug::changeFlag("FlagChangeFlagTestA", true));
|
||||
ASSERT_TRUE(flag_a.status());
|
||||
EXPECT_TRUE(Debug::changeFlag("FlagChangeFlagTestA", false));
|
||||
ASSERT_FALSE(flag_a.status());
|
||||
|
||||
// Disable and enable a flag
|
||||
ASSERT_FALSE(flag_b.status());
|
||||
EXPECT_TRUE(Debug::changeFlag("FlagChangeFlagTestB", false));
|
||||
ASSERT_FALSE(flag_b.status());
|
||||
EXPECT_TRUE(Debug::changeFlag("FlagChangeFlagTestB", true));
|
||||
ASSERT_TRUE(flag_b.status());
|
||||
|
||||
// Change a non-existent flag
|
||||
ASSERT_FALSE(Debug::changeFlag("FlagChangeFlagTestC", true));
|
||||
}
|
||||
|
||||
/** Test changing flag status with aux functions. */
|
||||
TEST(DebugFlagTest, SetClearDebugFlag)
|
||||
{
|
||||
Debug::Flag::globalEnable();
|
||||
Debug::SimpleFlag flag_a("FlagSetClearDebugFlagTestA", "");
|
||||
Debug::SimpleFlag flag_b("FlagSetClearDebugFlagTestB", "");
|
||||
|
||||
// Enable and disable a flag
|
||||
ASSERT_FALSE(flag_a.status());
|
||||
setDebugFlag("FlagSetClearDebugFlagTestA");
|
||||
ASSERT_TRUE(flag_a.status());
|
||||
clearDebugFlag("FlagSetClearDebugFlagTestA");
|
||||
ASSERT_FALSE(flag_a.status());
|
||||
|
||||
// Disable and enable a flag
|
||||
ASSERT_FALSE(flag_b.status());
|
||||
clearDebugFlag("FlagSetClearDebugFlagTestB");
|
||||
ASSERT_FALSE(flag_b.status());
|
||||
setDebugFlag("FlagSetClearDebugFlagTestB");
|
||||
ASSERT_TRUE(flag_b.status());
|
||||
|
||||
// Change a non-existent flag
|
||||
setDebugFlag("FlagSetClearDebugFlagTestC");
|
||||
clearDebugFlag("FlagSetClearDebugFlagTestC");
|
||||
}
|
||||
|
||||
/** Test dumping no enabled debug flags. */
|
||||
TEST(DebugFlagTest, NoDumpDebugFlags)
|
||||
{
|
||||
Debug::Flag::globalEnable();
|
||||
Debug::SimpleFlag flag("FlagDumpDebugFlagTest", "");
|
||||
|
||||
// Verify that the names of the enabled flags are printed
|
||||
testing::internal::CaptureStdout();
|
||||
dumpDebugFlags();
|
||||
std::string output = testing::internal::GetCapturedStdout();
|
||||
EXPECT_EQ(output, "");
|
||||
ASSERT_FALSE(flag.status());
|
||||
}
|
||||
|
||||
/** Test dumping enabled debug flags with a larger set of flags. */
|
||||
TEST(DebugFlagTest, DumpDebugFlags)
|
||||
{
|
||||
Debug::Flag::globalEnable();
|
||||
Debug::SimpleFlag flag_a("FlagDumpDebugFlagTestA", "");
|
||||
Debug::SimpleFlag flag_b("FlagDumpDebugFlagTestB", "");
|
||||
Debug::SimpleFlag flag_c("FlagDumpDebugFlagTestC", "");
|
||||
Debug::SimpleFlag flag_d("FlagDumpDebugFlagTestD", "");
|
||||
Debug::SimpleFlag flag_e("FlagDumpDebugFlagTestE", "");
|
||||
Debug::CompoundFlag compound_flag_a("CompoundFlagDumpDebugFlagTestA", "",
|
||||
{&flag_d});
|
||||
Debug::CompoundFlag compound_flag_b("CompoundFlagDumpDebugFlagTestB", "",
|
||||
{&flag_e});
|
||||
|
||||
// Enable a few flags
|
||||
ASSERT_FALSE(flag_a.status());
|
||||
ASSERT_FALSE(flag_b.status());
|
||||
ASSERT_FALSE(flag_c.status());
|
||||
ASSERT_FALSE(flag_d.status());
|
||||
ASSERT_FALSE(flag_e.status());
|
||||
flag_a.enable();
|
||||
flag_c.enable();
|
||||
compound_flag_b.enable();
|
||||
|
||||
// Verify that the names of the enabled flags are printed
|
||||
testing::internal::CaptureStdout();
|
||||
dumpDebugFlags();
|
||||
std::string output = testing::internal::GetCapturedStdout();
|
||||
EXPECT_EQ(output, "FlagDumpDebugFlagTestA\nFlagDumpDebugFlagTestC\n" \
|
||||
"FlagDumpDebugFlagTestE\n");
|
||||
}
|
||||
Reference in New Issue
Block a user