From e50eec0a04e448c06e36090bb39c72a341ab1da0 Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Thu, 10 Oct 2019 11:13:36 -0700 Subject: [PATCH] tests: Added GTests for base/chunk_generator.hh Change-Id: Ic6ededfc7fed1f91a75e48a0933e61b4670e5af1 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21679 Tested-by: kokoro Reviewed-by: Nikos Nikoleris Maintainer: Bobby R. Bruce --- src/base/SConscript | 1 + src/base/chunk_generator.test.cc | 224 +++++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 src/base/chunk_generator.test.cc diff --git a/src/base/SConscript b/src/base/SConscript index 661a21911..09bcf3f86 100644 --- a/src/base/SConscript +++ b/src/base/SConscript @@ -102,6 +102,7 @@ GTest('circular_queue.test', 'circular_queue.test.cc') GTest('sat_counter.test', 'sat_counter.test.cc') GTest('refcnt.test','refcnt.test.cc') GTest('condcodes.test', 'condcodes.test.cc') +GTest('chunk_generator.test', 'chunk_generator.test.cc') DebugFlag('Annotate', "State machine annotation debugging") DebugFlag('AnnotateQ', "State machine annotation queue debugging") diff --git a/src/base/chunk_generator.test.cc b/src/base/chunk_generator.test.cc new file mode 100644 index 000000000..5e8209df8 --- /dev/null +++ b/src/base/chunk_generator.test.cc @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2019 The Regents of the University of California + * 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. + * + * Authors: Bobby R. Bruce + */ + +#include + +#include "chunk_generator.hh" + + +/* + * A test to ensure the object is in a sane state after initialization. + */ +TEST(ChunkGeneratorTest, StartingConditions) +{ + ChunkGenerator chunk_generator(0, 1024, 8); + EXPECT_EQ(0, chunk_generator.addr()); + EXPECT_EQ(8, chunk_generator.size()); + EXPECT_EQ(0, chunk_generator.complete()); + EXPECT_FALSE(chunk_generator.done()); + EXPECT_FALSE(chunk_generator.last()); +} + +/* + * A simple test to check the move to the next chunk under normal conditions. + */ +TEST(ChunkGeneratorTest, AdvanceToNextChunk) +{ + ChunkGenerator chunk_generator(0, 1024, 8); + EXPECT_EQ(0, chunk_generator.addr()); + EXPECT_TRUE(chunk_generator.next()); + EXPECT_EQ(8, chunk_generator.addr()); + EXPECT_EQ(8, chunk_generator.size()); + EXPECT_EQ(8, chunk_generator.complete()); + EXPECT_FALSE(chunk_generator.done()); + EXPECT_FALSE(chunk_generator.last()); +} + +/* + * A test to consume chunks until the last chunk. + */ +TEST(ChunkGeneratorTest, AdvanceToLastChunk) +{ + ChunkGenerator chunk_generator(0, 32, 8); + EXPECT_EQ(0, chunk_generator.addr()); + EXPECT_TRUE(chunk_generator.next()); + EXPECT_EQ(8, chunk_generator.addr()); + EXPECT_TRUE(chunk_generator.next()); + EXPECT_EQ(16, chunk_generator.addr()); + EXPECT_TRUE(chunk_generator.next()); + EXPECT_EQ(24, chunk_generator.addr()); + EXPECT_EQ(8, chunk_generator.size()); + EXPECT_EQ(24, chunk_generator.complete()); + EXPECT_FALSE(chunk_generator.done()); + EXPECT_TRUE(chunk_generator.last()); +} + +/* + * A test to consume chunks, inclusive of the last chunk. + */ +TEST(ChunkGeneratorTest, AdvanceToTheEnd) +{ + ChunkGenerator chunk_generator(0, 32, 8); + EXPECT_EQ(0, chunk_generator.addr()); + EXPECT_TRUE(chunk_generator.next()); + EXPECT_EQ(8, chunk_generator.addr()); + EXPECT_TRUE(chunk_generator.next()); + EXPECT_EQ(16, chunk_generator.addr()); + EXPECT_TRUE(chunk_generator.next()); + EXPECT_EQ(24, chunk_generator.addr()); + /* The following returns false because we cannot advance to the next to + * the next chunk (it does not exist). However, we still process the last + * chunk. It is therefore not indicative of failure to change the + * state of the object. + */ + EXPECT_FALSE(chunk_generator.next()); + EXPECT_EQ(24, chunk_generator.addr()); + EXPECT_EQ(0, chunk_generator.size()); + EXPECT_EQ(24, chunk_generator.complete()); + EXPECT_TRUE(chunk_generator.done()); + EXPECT_TRUE(chunk_generator.last()); +} + +/* + * A region does is not necessisarily divisable by the chunk size. This will + * will result in the final chunk being smaller than the rest. + */ +TEST(ChunkGeneratorTest, SmallerLastChunk) +{ + // There are two chunks. The last will be 6 bytes. + ChunkGenerator chunk_generator(0, 14, 8); + EXPECT_EQ(0, chunk_generator.addr()); + EXPECT_TRUE(chunk_generator.next()); + EXPECT_EQ(8, chunk_generator.addr()); + EXPECT_EQ(6, chunk_generator.size()); + EXPECT_EQ(8, chunk_generator.complete()); + EXPECT_FALSE(chunk_generator.done()); + EXPECT_TRUE(chunk_generator.last()); +} + +/* + * When a chunk size is greater than the total size, the chunk size + * is effectively that of the region size. This test will verify this + * corner-case. + */ +TEST(ChunkGeneratorTest, ChunkSizeGreaterThanTotalSize) +{ + ChunkGenerator chunk_generator(0, 32, 64); + EXPECT_EQ(0, chunk_generator.addr()); + EXPECT_EQ(32, chunk_generator.size()); + EXPECT_EQ(0, chunk_generator.complete()); + EXPECT_FALSE(chunk_generator.done()); + EXPECT_TRUE(chunk_generator.last()); + + // Process the entire region. + EXPECT_FALSE(chunk_generator.next()); + EXPECT_EQ(0, chunk_generator.addr()); + EXPECT_EQ(0, chunk_generator.size()); + EXPECT_EQ(0, chunk_generator.complete()); + EXPECT_TRUE(chunk_generator.done()); + EXPECT_TRUE(chunk_generator.last()); +} + +/* + * As a special case, we assume there is no chunking when the chunk size is + * zero. Processing a chunk (i.e., execution of "next()"). should progress to + * the end of the region. + */ +TEST(ChunkGeneratorTest, ChunkSizeZero) +{ + ChunkGenerator chunk_generator(0, 64, 0); + EXPECT_EQ(0, chunk_generator.addr()); + EXPECT_EQ(64, chunk_generator.size()); + EXPECT_EQ(0, chunk_generator.complete()); + EXPECT_FALSE(chunk_generator.done()); + EXPECT_TRUE(chunk_generator.last()); + + //Process the entire region. + EXPECT_FALSE(chunk_generator.next()); + EXPECT_EQ(0, chunk_generator.addr()); + EXPECT_EQ(0, chunk_generator.size()); + EXPECT_EQ(0, chunk_generator.complete()); + EXPECT_TRUE(chunk_generator.done()); + EXPECT_TRUE(chunk_generator.last()); +} + +/* + * A test to ensure a non-zero start functions correctly. + */ +TEST(ChunkGeneratorTest, StartAtNonZero) +{ + ChunkGenerator chunk_generator(4, 32, 8); //End address: 36. + EXPECT_EQ(4, chunk_generator.addr()); + EXPECT_EQ(4, chunk_generator.size()); + EXPECT_EQ(0, chunk_generator.complete()); + EXPECT_FALSE(chunk_generator.done()); + EXPECT_FALSE(chunk_generator.last()); + + /* + * As the starting position is 4, moving to the next bit should move to + * 8 (i.e., process the remainder of the first chunk in the region). + */ + EXPECT_TRUE(chunk_generator.next()); + EXPECT_EQ(8, chunk_generator.addr()); + EXPECT_EQ(8, chunk_generator.size()); + EXPECT_EQ(4, chunk_generator.complete()); + EXPECT_FALSE(chunk_generator.done()); + EXPECT_FALSE(chunk_generator.last()); + + // Process the rest of the region. + EXPECT_TRUE(chunk_generator.next()); + EXPECT_EQ(16, chunk_generator.addr()); + EXPECT_EQ(8, chunk_generator.size()); + EXPECT_EQ(12, chunk_generator.complete()); + EXPECT_FALSE(chunk_generator.done()); + EXPECT_FALSE(chunk_generator.last()); + + EXPECT_TRUE(chunk_generator.next()); + EXPECT_EQ(24, chunk_generator.addr()); + EXPECT_EQ(8, chunk_generator.size()); + EXPECT_EQ(20, chunk_generator.complete()); + EXPECT_FALSE(chunk_generator.done()); + EXPECT_FALSE(chunk_generator.last()); + + // The last chunk is also only 4 bytes. + EXPECT_TRUE(chunk_generator.next()); + EXPECT_EQ(32, chunk_generator.addr()); + EXPECT_EQ(4, chunk_generator.size()); + EXPECT_EQ(28, chunk_generator.complete()); + EXPECT_FALSE(chunk_generator.done()); + EXPECT_TRUE(chunk_generator.last()); + + EXPECT_FALSE(chunk_generator.next()); + EXPECT_EQ(32, chunk_generator.addr()); + EXPECT_EQ(0, chunk_generator.size()); + EXPECT_EQ(28, chunk_generator.complete()); + EXPECT_TRUE(chunk_generator.done()); + EXPECT_TRUE(chunk_generator.last()); +} \ No newline at end of file -- 2.30.2