From 2b0f7c321cd286913d63a4815e805ef55fa28e2d Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Thu, 9 Jan 2014 17:48:48 +0000 Subject: Convert Checksum test to DEF_TEST() macro. BUG=None TEST=tests R=mtklein@google.com, bungeman@google.com Author: tfarina@chromium.org Review URL: https://codereview.chromium.org/126743003 git-svn-id: http://skia.googlecode.com/svn/trunk@12996 2bbb7eff-a529-9590-31e7-b0007b416f81 --- tests/ChecksumTest.cpp | 175 ++++++++++++------------------------------------- 1 file changed, 43 insertions(+), 132 deletions(-) (limited to 'tests/ChecksumTest.cpp') diff --git a/tests/ChecksumTest.cpp b/tests/ChecksumTest.cpp index c2f2be2ae6..478f8435f9 100644 --- a/tests/ChecksumTest.cpp +++ b/tests/ChecksumTest.cpp @@ -1,142 +1,53 @@ - /* * Copyright 2012 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -#include "Test.h" #include "SkChecksum.h" - -// Word size that is large enough to hold results of any checksum type. -typedef uint64_t checksum_result; - -namespace skiatest { - class ChecksumTestClass : public Test { - public: - static Test* Factory(void*) {return SkNEW(ChecksumTestClass); } - protected: - virtual void onGetName(SkString* name) { name->set("Checksum"); } - virtual void onRun(Reporter* reporter) { - this->fReporter = reporter; - RunTest(); - } - private: - enum Algorithm { - kSkChecksum, - kMurmur3, - }; - - // Call Compute(data, size) on the appropriate checksum algorithm, - // depending on this->fWhichAlgorithm. - checksum_result ComputeChecksum(const char *data, size_t size) { - switch(fWhichAlgorithm) { - case kSkChecksum: - REPORTER_ASSERT_MESSAGE(fReporter, - reinterpret_cast(data) % 4 == 0, - "test data pointer is not 32-bit aligned"); - REPORTER_ASSERT_MESSAGE(fReporter, SkIsAlign4(size), - "test data size is not 32-bit aligned"); - return SkChecksum::Compute(reinterpret_cast(data), size); - case kMurmur3: - REPORTER_ASSERT_MESSAGE(fReporter, - reinterpret_cast(data) % 4 == 0, - "test data pointer is not 32-bit aligned"); - REPORTER_ASSERT_MESSAGE(fReporter, SkIsAlign4(size), - "test data size is not 32-bit aligned"); - return SkChecksum::Murmur3(reinterpret_cast(data), size); - default: - SkString message("fWhichAlgorithm has unknown value "); - message.appendf("%d", fWhichAlgorithm); - fReporter->reportFailed(message); - } - // we never get here - return 0; - } - - // Confirm that the checksum algorithm (specified by fWhichAlgorithm) - // generates the same results if called twice over the same data. - void TestChecksumSelfConsistency(size_t buf_size) { - SkAutoMalloc storage(buf_size); - char* ptr = reinterpret_cast(storage.get()); - - REPORTER_ASSERT(fReporter, - GetTestDataChecksum(8, 0) == - GetTestDataChecksum(8, 0)); - REPORTER_ASSERT(fReporter, - GetTestDataChecksum(8, 0) != - GetTestDataChecksum(8, 1)); - - sk_bzero(ptr, buf_size); - checksum_result prev = 0; - - // assert that as we change values (from 0 to non-zero) in - // our buffer, we get a different value - for (size_t i = 0; i < buf_size; ++i) { - ptr[i] = (i & 0x7f) + 1; // need some non-zero value here - - // Try checksums of different-sized chunks, but always - // 32-bit aligned and big enough to contain all the - // nonzero bytes. (Remaining bytes will still be zero - // from the initial sk_bzero() call.) - size_t checksum_size = (((i/4)+1)*4); - REPORTER_ASSERT(fReporter, checksum_size <= buf_size); - - checksum_result curr = ComputeChecksum(ptr, checksum_size); - REPORTER_ASSERT(fReporter, prev != curr); - checksum_result again = ComputeChecksum(ptr, checksum_size); - REPORTER_ASSERT(fReporter, again == curr); - prev = curr; - } - } - - // Return the checksum of a buffer of bytes 'len' long. - // The pattern of values within the buffer will be consistent - // for every call, based on 'seed'. - checksum_result GetTestDataChecksum(size_t len, char seed=0) { - SkAutoMalloc storage(len); - char* start = reinterpret_cast(storage.get()); - char* ptr = start; - for (size_t i = 0; i < len; ++i) { - *ptr++ = ((seed+i) & 0x7f); - } - checksum_result result = ComputeChecksum(start, len); - return result; - } - - void RunTest() { - const Algorithm algorithms[] = { kSkChecksum, kMurmur3 }; - for (size_t i = 0; i < SK_ARRAY_COUNT(algorithms); i++) { - fWhichAlgorithm = algorithms[i]; - - // Test self-consistency of checksum algorithms. - TestChecksumSelfConsistency(128); - - // Test checksum results that should be consistent across - // versions and platforms. - REPORTER_ASSERT(fReporter, ComputeChecksum(NULL, 0) == 0); - - const bool colision1 = GetTestDataChecksum(128) == GetTestDataChecksum(256); - const bool colision2 = GetTestDataChecksum(132) == GetTestDataChecksum(260); - if (fWhichAlgorithm == kSkChecksum) { - // TODO: note the weakness exposed by these collisions... - // We need to improve the SkChecksum algorithm. - // We would prefer that these asserts FAIL! - // Filed as https://code.google.com/p/skia/issues/detail?id=981 - // ('SkChecksum algorithm allows for way too many collisions') - REPORTER_ASSERT(fReporter, colision1); - REPORTER_ASSERT(fReporter, colision2); - } else { - REPORTER_ASSERT(fReporter, !colision1); - REPORTER_ASSERT(fReporter, !colision2); - } - } +#include "SkRandom.h" +#include "Test.h" +#include "TestClassDef.h" + + +// Murmur3 has an optional third seed argument, so we wrap it to fit a uniform type. +static uint32_t murmur_noseed(const uint32_t* d, size_t l) { return SkChecksum::Murmur3(d, l); } + +#define ASSERT(x) REPORTER_ASSERT(r, x) + +DEF_TEST(Checksum, r) { + // Algorithms to test. They're currently all uint32_t(const uint32_t*, size_t). + typedef uint32_t(*algorithmProc)(const uint32_t*, size_t); + const algorithmProc kAlgorithms[] = { &SkChecksum::Compute, &murmur_noseed }; + + // Put 128 random bytes into two identical buffers. Any multiple of 4 will do. + const size_t kBytes = SkAlign4(128); + SkRandom rand; + uint32_t data[kBytes/4], tweaked[kBytes/4]; + for (size_t i = 0; i < SK_ARRAY_COUNT(tweaked); ++i) { + data[i] = tweaked[i] = rand.nextU(); + } + + // Test each algorithm. + for (size_t i = 0; i < SK_ARRAY_COUNT(kAlgorithms); ++i) { + const algorithmProc algorithm = kAlgorithms[i]; + + // Hash of NULL is always 0. + ASSERT(algorithm(NULL, 0) == 0); + + const uint32_t hash = algorithm(data, kBytes); + // Should be deterministic. + ASSERT(hash == algorithm(data, kBytes)); + + // Changing any single element should change the hash. + for (size_t j = 0; j < SK_ARRAY_COUNT(tweaked); ++j) { + const uint32_t saved = tweaked[j]; + tweaked[j] = rand.nextU(); + const uint32_t tweakedHash = algorithm(tweaked, kBytes); + ASSERT(tweakedHash != hash); + ASSERT(tweakedHash == algorithm(tweaked, kBytes)); + tweaked[j] = saved; } - - Reporter* fReporter; - Algorithm fWhichAlgorithm; - }; - - static TestRegistry gReg(ChecksumTestClass::Factory); + } } -- cgit v1.2.3