diff options
author | abarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-13 02:01:03 +0000 |
---|---|---|
committer | abarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-13 02:01:03 +0000 |
commit | 0b9c840bb55c2c9914ccb44b66274b38c74872a1 (patch) | |
tree | f464f1283529b4644df4a22e22c14c1032979fc6 /content | |
parent | 0a29063eef78157e35da84f60c7c12043f40f29d (diff) | |
download | chromium_src-0b9c840bb55c2c9914ccb44b66274b38c74872a1.zip chromium_src-0b9c840bb55c2c9914ccb44b66274b38c74872a1.tar.gz chromium_src-0b9c840bb55c2c9914ccb44b66274b38c74872a1.tar.bz2 |
Move image decoder unit tests to content_unittests
We're deleting the concept of a webcore_unit_test from Chromium. I would prefer
to move these tests into the WebKit repository, but they depend on test data in
src-internal. Instead, this CL moves them into content_unittests.
BUG=184276
Review URL: https://chromiumcodereview.appspot.com/12725006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@187745 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/content_tests.gypi | 4 | ||||
-rw-r--r-- | content/renderer/bmp_image_decoder_unittest.cc | 30 | ||||
-rw-r--r-- | content/renderer/ico_image_decoder_unittest.cc | 36 | ||||
-rw-r--r-- | content/test/image_decoder_test.cc | 225 | ||||
-rw-r--r-- | content/test/image_decoder_test.h | 86 |
5 files changed, 381 insertions, 0 deletions
diff --git a/content/content_tests.gypi b/content/content_tests.gypi index ad5bae8..2a3d515 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -369,10 +369,12 @@ 'renderer/active_notification_tracker_unittest.cc', 'renderer/android/email_detector_unittest.cc', 'renderer/android/phone_number_detector_unittest.cc', + 'renderer/bmp_image_decoder_unittest.cc', 'renderer/date_time_formatter_unittest.cc', 'renderer/disambiguation_popup_helper_unittest.cc', 'renderer/gpu/input_event_filter_unittest.cc', 'renderer/hyphenator/hyphenator_unittest.cc', + 'renderer/ico_image_decoder_unittest.cc', 'renderer/media/audio_message_filter_unittest.cc', 'renderer/media/audio_renderer_mixer_manager_unittest.cc', 'renderer/media/video_capture_impl_unittest.cc', @@ -384,6 +386,8 @@ 'renderer/v8_value_converter_impl_unittest.cc', 'test/gpu/gpu_test_config_unittest.cc', 'test/gpu/gpu_test_expectations_parser_unittest.cc', + 'test/image_decoder_test.cc', + 'test/image_decoder_test.h', 'test/run_all_unittests.cc', '../webkit/appcache/manifest_parser_unittest.cc', '../webkit/appcache/appcache_unittest.cc', diff --git a/content/renderer/bmp_image_decoder_unittest.cc b/content/renderer/bmp_image_decoder_unittest.cc new file mode 100644 index 0000000..7171e7f --- /dev/null +++ b/content/renderer/bmp_image_decoder_unittest.cc @@ -0,0 +1,30 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/test/image_decoder_test.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebImageDecoder.h" + +class BMPImageDecoderTest : public ImageDecoderTest { + public: + BMPImageDecoderTest() : ImageDecoderTest("bmp") { } + + protected: + virtual WebKit::WebImageDecoder* CreateWebKitImageDecoder() const OVERRIDE { + return new WebKit::WebImageDecoder(WebKit::WebImageDecoder::TypeBMP); + } + + // The BMPImageDecoderTest tests are really slow under Valgrind. + // Thus it is split into fast and slow versions. The threshold is + // set to 10KB because the fast test can finish under Valgrind in + // less than 30 seconds. + static const int64 kThresholdSize = 10240; +}; + +TEST_F(BMPImageDecoderTest, DecodingFast) { + TestDecoding(TEST_SMALLER, kThresholdSize); +} + +TEST_F(BMPImageDecoderTest, DecodingSlow) { + TestDecoding(TEST_BIGGER, kThresholdSize); +} diff --git a/content/renderer/ico_image_decoder_unittest.cc b/content/renderer/ico_image_decoder_unittest.cc new file mode 100644 index 0000000..3b02874 --- /dev/null +++ b/content/renderer/ico_image_decoder_unittest.cc @@ -0,0 +1,36 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/file_util.h" +#include "base/files/file_path.h" +#include "content/test/image_decoder_test.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebImageDecoder.h" + +using WebKit::WebImageDecoder; + +class ICOImageDecoderTest : public ImageDecoderTest { + public: + ICOImageDecoderTest() : ImageDecoderTest("ico") { } + + protected: + virtual WebKit::WebImageDecoder* CreateWebKitImageDecoder() const OVERRIDE { + return new WebKit::WebImageDecoder(WebKit::WebImageDecoder::TypeICO); + } +}; + +TEST_F(ICOImageDecoderTest, Decoding) { + TestDecoding(); +} + +TEST_F(ICOImageDecoderTest, ImageNonZeroFrameIndex) { + if (data_dir_.empty()) + return; + // Test that the decoder decodes multiple sizes of icons which have them. + // Load an icon that has both favicon-size and larger entries. + base::FilePath multisize_icon_path(data_dir_.AppendASCII("yahoo.ico")); + const base::FilePath md5_sum_path( + GetMD5SumPath(multisize_icon_path).value() + FILE_PATH_LITERAL("2")); + static const int kDesiredFrameIndex = 3; + TestWebKitImageDecoder(multisize_icon_path, md5_sum_path, kDesiredFrameIndex); +} diff --git a/content/test/image_decoder_test.cc b/content/test/image_decoder_test.cc new file mode 100644 index 0000000..b52c5c8 --- /dev/null +++ b/content/test/image_decoder_test.cc @@ -0,0 +1,225 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/test/image_decoder_test.h" + +#include "base/file_util.h" +#include "base/files/file_path.h" +#include "base/md5.h" +#include "base/memory/scoped_ptr.h" +#include "base/path_service.h" +#include "base/string_util.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebData.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebImage.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebImageDecoder.h" + +using base::Time; + +namespace { + +const int kFirstFrameIndex = 0; + +// Determine if we should test with file specified by |path| based +// on |file_selection| and the |threshold| for the file size. +bool ShouldSkipFile(const base::FilePath& path, + ImageDecoderTestFileSelection file_selection, + const int64 threshold) { + if (file_selection == TEST_ALL) + return false; + + int64 image_size = 0; + file_util::GetFileSize(path, &image_size); + return (file_selection == TEST_SMALLER) == (image_size > threshold); +} + +} // namespace + +void ReadFileToVector(const base::FilePath& path, std::vector<char>* contents) { + std::string raw_image_data; + file_util::ReadFileToString(path, &raw_image_data); + contents->resize(raw_image_data.size()); + memcpy(&contents->at(0), raw_image_data.data(), raw_image_data.size()); +} + +base::FilePath GetMD5SumPath(const base::FilePath& path) { + static const base::FilePath::StringType kDecodedDataExtension( + FILE_PATH_LITERAL(".md5sum")); + return base::FilePath(path.value() + kDecodedDataExtension); +} + +#if defined(CALCULATE_MD5_SUMS) +void SaveMD5Sum(const base::FilePath& path, const WebKit::WebImage& web_image) { + // Calculate MD5 sum. + base::MD5Digest digest; + web_image.getSkBitmap().lockPixels(); + base::MD5Sum(web_image.getSkBitmap().getPixels(), + web_image.getSkBitmap().width() * web_image.getSkBitmap().height() * + sizeof(uint32_t), + &digest); + + // Write sum to disk. + int bytes_written = file_util::WriteFile(path, + reinterpret_cast<const char*>(&digest), sizeof digest); + ASSERT_EQ(sizeof digest, bytes_written); + web_image.getSkBitmap().unlockPixels(); +} +#endif + +#if !defined(CALCULATE_MD5_SUMS) +void VerifyImage(const WebKit::WebImageDecoder& decoder, + const base::FilePath& path, + const base::FilePath& md5_sum_path, + size_t frame_index) { + // Make sure decoding can complete successfully. + EXPECT_TRUE(decoder.isSizeAvailable()) << path.value(); + EXPECT_GE(decoder.frameCount(), frame_index) << path.value(); + EXPECT_TRUE(decoder.isFrameCompleteAtIndex(frame_index)) << path.value(); + EXPECT_FALSE(decoder.isFailed()); + + // Calculate MD5 sum. + base::MD5Digest actual_digest; + WebKit::WebImage web_image = decoder.getFrameAtIndex(frame_index); + web_image.getSkBitmap().lockPixels(); + base::MD5Sum(web_image.getSkBitmap().getPixels(), + web_image.getSkBitmap().width() * web_image.getSkBitmap().height() * + sizeof(uint32_t), + &actual_digest); + + // Read the MD5 sum off disk. + std::string file_bytes; + file_util::ReadFileToString(md5_sum_path, &file_bytes); + base::MD5Digest expected_digest; + ASSERT_EQ(sizeof expected_digest, file_bytes.size()) << path.value(); + memcpy(&expected_digest, file_bytes.data(), sizeof expected_digest); + + // Verify that the sums are the same. + EXPECT_EQ(0, + memcmp(&expected_digest, &actual_digest, sizeof(base::MD5Digest))) + << path.value(); + web_image.getSkBitmap().unlockPixels(); +} +#endif + +void ImageDecoderTest::SetUp() { + base::FilePath data_dir; + ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_dir)); + data_dir_ = data_dir.AppendASCII("webkit"). + AppendASCII("data"). + AppendASCII(format_ + "_decoder"); + if (!file_util::PathExists(data_dir_)) { + const testing::TestInfo* const test_info = + testing::UnitTest::GetInstance()->current_test_info(); + LOG(INFO) << test_info->name() << + " not running because test data wasn't found."; + data_dir_.clear(); + return; + } +} + +std::vector<base::FilePath> ImageDecoderTest::GetImageFiles() const { + std::string pattern = "*." + format_; + + file_util::FileEnumerator enumerator(data_dir_, + false, + file_util::FileEnumerator::FILES); + + std::vector<base::FilePath> image_files; + base::FilePath next_file_name; + while (!(next_file_name = enumerator.Next()).empty()) { + base::FilePath base_name = next_file_name.BaseName(); +#if defined(OS_WIN) + std::string base_name_ascii = WideToASCII(base_name.value()); +#else + std::string base_name_ascii = base_name.value(); +#endif + if (!MatchPattern(base_name_ascii, pattern)) + continue; + image_files.push_back(next_file_name); + } + + return image_files; +} + +bool ImageDecoderTest::ShouldImageFail(const base::FilePath& path) const { + const base::FilePath::StringType kBadSuffix(FILE_PATH_LITERAL(".bad.")); + return (path.value().length() > (kBadSuffix.length() + format_.length()) && + !path.value().compare(path.value().length() - format_.length() - + kBadSuffix.length(), + kBadSuffix.length(), kBadSuffix)); +} + +void ImageDecoderTest::TestDecoding( + ImageDecoderTestFileSelection file_selection, + const int64 threshold) { + if (data_dir_.empty()) + return; + const std::vector<base::FilePath> image_files(GetImageFiles()); + for (std::vector<base::FilePath>::const_iterator i = image_files.begin(); + i != image_files.end(); ++i) { + if (ShouldSkipFile(*i, file_selection, threshold)) + continue; + const base::FilePath md5_sum_path(GetMD5SumPath(*i)); + TestWebKitImageDecoder(*i, md5_sum_path, kFirstFrameIndex); + } +} + +void ImageDecoderTest::TestWebKitImageDecoder(const base::FilePath& image_path, + const base::FilePath& md5_sum_path, int desired_frame_index) const { + bool should_test_chunking = true; + bool should_test_failed_images = true; +#ifdef CALCULATE_MD5_SUMS + // Do not test anything just get the md5 sums. + should_test_chunking = false; + should_test_failed_images = false; +#endif + + std::vector<char> image_contents; + ReadFileToVector(image_path, &image_contents); + EXPECT_TRUE(image_contents.size()); + scoped_ptr<WebKit::WebImageDecoder> decoder(CreateWebKitImageDecoder()); + EXPECT_FALSE(decoder->isFailed()); + + if (should_test_chunking) { + // Test chunking file into half. + const int partial_size = image_contents.size()/2; + + WebKit::WebData partial_data( + reinterpret_cast<const char*>(&(image_contents.at(0))), partial_size); + + // Make Sure the image decoder doesn't fail when we ask for the frame + // buffer for this partial image. + // NOTE: We can't check that frame 0 is non-NULL, because if this is an + // ICO and we haven't yet supplied enough data to read the directory, + // there is no framecount and thus no first frame. + decoder->setData(const_cast<WebKit::WebData&>(partial_data), false); + EXPECT_FALSE(decoder->isFailed()) << image_path.value(); + } + + // Make sure passing the complete image results in successful decoding. + WebKit::WebData data(reinterpret_cast<const char*>(&(image_contents.at(0))), + image_contents.size()); + decoder->setData(const_cast<WebKit::WebData&>(data), true); + + if (should_test_failed_images) { + if (ShouldImageFail(image_path)) { + EXPECT_FALSE(decoder->isFrameCompleteAtIndex(kFirstFrameIndex)); + EXPECT_TRUE(decoder->isFailed()); + return; + } + } + + EXPECT_FALSE(decoder->isFailed()) << image_path.value(); + +#ifdef CALCULATE_MD5_SUMS + // Since WebImage does not expose get data by frame, get the size + // through decoder and pass it to fromData so that the closest + // image dats to the size is returned. + WebKit::WebSize size(decoder->getImage(desired_frame_index).size()); + const WebKit::WebImage& image = WebKit::WebImage::fromData(data, size); + SaveMD5Sum(md5_sum_path, image); +#else + VerifyImage(*decoder, image_path, md5_sum_path, desired_frame_index); +#endif +} diff --git a/content/test/image_decoder_test.h b/content/test/image_decoder_test.h new file mode 100644 index 0000000..a7130ea --- /dev/null +++ b/content/test/image_decoder_test.h @@ -0,0 +1,86 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_TEST_IMAGE_DECODER_TEST_H_ +#define CONTENT_TEST_IMAGE_DECODER_TEST_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/files/file_path.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace WebKit { class WebImageDecoder; } + +// If CALCULATE_MD5_SUMS is not defined, then this test decodes a handful of +// image files and compares their MD5 sums to the stored sums on disk. +// +// To recalculate the MD5 sums, uncommment CALCULATE_MD5_SUMS. +// +// The image files and corresponding MD5 sums live in the directory +// chrome/test/data/*_decoder (where "*" is the format being tested). +// +// Note: The MD5 sums calculated in this test by little- and big-endian systems +// will differ, since no endianness correction is done. If we start compiling +// for big endian machines this should be fixed. + +// #define CALCULATE_MD5_SUMS + +enum ImageDecoderTestFileSelection { + TEST_ALL, + TEST_SMALLER, + TEST_BIGGER, +}; + +// Returns the path the decoded data is saved at. +base::FilePath GetMD5SumPath(const base::FilePath& path); + +class ImageDecoderTest : public testing::Test { + public: + explicit ImageDecoderTest(const std::string& format) : format_(format) { } + + protected: + virtual void SetUp() OVERRIDE; + + // Returns the vector of image files for testing. + std::vector<base::FilePath> GetImageFiles() const; + + // Returns true if the image is bogus and should not be successfully decoded. + bool ShouldImageFail(const base::FilePath& path) const; + + // Tests if decoder decodes image at image_path with underlying frame at + // index desired_frame_index. The md5_sum_path is needed if the test is not + // asked to generate one i.e. if # #define CALCULATE_MD5_SUMS is set. + void TestWebKitImageDecoder(const base::FilePath& image_path, + const base::FilePath& md5_sum_path, int desired_frame_index) const; + + // Verifies each of the test image files is decoded correctly and matches the + // expected state. |file_selection| and |threshold| can be used to select + // files to test based on file size. + // If just the MD5 sum is wanted, this skips chunking. + void TestDecoding(ImageDecoderTestFileSelection file_selection, + const int64 threshold); + + void TestDecoding() { + TestDecoding(TEST_ALL, 0); + } + + // Creates WebKit API's decoder. + virtual WebKit::WebImageDecoder* CreateWebKitImageDecoder() const = 0; + + // The format to be decoded, like "bmp" or "ico". + std::string format_; + + protected: + // Path to the test files. + base::FilePath data_dir_; + + private: + DISALLOW_COPY_AND_ASSIGN(ImageDecoderTest); +}; + +#endif // CONTENT_TEST_IMAGE_DECODER_TEST_H_ |