1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "base/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/platform_file.h"
11 #include "chrome/common/media_galleries/pmp_constants.h"
12 #include "chrome/common/media_galleries/pmp_test_util.h"
13 #include "chrome/utility/media_galleries/pmp_column_reader.h"
14 #include "testing/gtest/include/gtest/gtest.h"
20 bool InitColumnReaderFromBytes(
21 PmpColumnReader
* const reader
,
22 const std::vector
<char>& data
,
23 const PmpFieldType expected_type
) {
24 base::ScopedTempDir temp_dir
;
25 if (!temp_dir
.CreateUniqueTempDir())
28 base::FilePath temp_path
;
29 if (!base::CreateTemporaryFileInDir(temp_dir
.path(), &temp_path
))
32 // Explicit conversion from signed to unsigned.
33 size_t bytes_written
= base::WriteFile(temp_path
, &data
[0], data
.size());
34 if (bytes_written
!= data
.size())
37 int flags
= base::PLATFORM_FILE_OPEN
| base::PLATFORM_FILE_READ
;
38 base::PlatformFile platform_file
=
39 base::CreatePlatformFile(temp_path
, flags
, NULL
, NULL
);
40 if (platform_file
== base::kInvalidPlatformFileValue
)
43 bool read_success
= reader
->ReadFile(platform_file
, expected_type
);
45 base::ClosePlatformFile(platform_file
);
50 // Overridden version of Read method to make test code templatable.
51 bool DoRead(const PmpColumnReader
* reader
, uint32 row
, std::string
* target
) {
52 return reader
->ReadString(row
, target
);
55 bool DoRead(const PmpColumnReader
* reader
, uint32 row
, uint32
* target
) {
56 return reader
->ReadUInt32(row
, target
);
59 bool DoRead(const PmpColumnReader
* reader
, uint32 row
, double* target
) {
60 return reader
->ReadDouble64(row
, target
);
63 bool DoRead(const PmpColumnReader
* reader
, uint32 row
, uint8
* target
) {
64 return reader
->ReadUInt8(row
, target
);
67 bool DoRead(const PmpColumnReader
* reader
, uint32 row
, uint64
* target
) {
68 return reader
->ReadUInt64(row
, target
);
73 void TestValid(const PmpFieldType field_type
,
74 const std::vector
<T
>& elems
) {
75 PmpColumnReader reader
;
76 std::vector
<char> data
=
77 PmpTestUtil::MakeHeaderAndBody(field_type
, elems
.size(), elems
);
78 ASSERT_TRUE(InitColumnReaderFromBytes(&reader
, data
, field_type
));
79 EXPECT_EQ(elems
.size(), reader
.rows_read());
81 for (uint32 i
= 0; i
< elems
.size() && i
< reader
.rows_read(); i
++) {
83 EXPECT_TRUE(DoRead(&reader
, i
, &target
));
84 EXPECT_EQ(elems
[i
], target
);
89 void TestMalformed(const PmpFieldType field_type
,
90 const std::vector
<T
>& elems
) {
91 PmpColumnReader reader_too_few_declared_rows
;
92 std::vector
<char> data_too_few_declared_rows
=
93 PmpTestUtil::MakeHeaderAndBody(field_type
, elems
.size()-1, elems
);
94 EXPECT_FALSE(InitColumnReaderFromBytes(&reader_too_few_declared_rows
,
95 data_too_few_declared_rows
,
98 PmpColumnReader reader_too_many_declared_rows
;
99 std::vector
<char> data_too_many_declared_rows
=
100 PmpTestUtil::MakeHeaderAndBody(field_type
, elems
.size()+1, elems
);
101 EXPECT_FALSE(InitColumnReaderFromBytes(&reader_too_many_declared_rows
,
102 data_too_many_declared_rows
,
105 PmpColumnReader reader_truncated
;
106 std::vector
<char> data_truncated
=
107 PmpTestUtil::MakeHeaderAndBody(field_type
, elems
.size(), elems
);
108 data_truncated
.resize(data_truncated
.size()-10);
109 EXPECT_FALSE(InitColumnReaderFromBytes(&reader_truncated
,
113 PmpColumnReader reader_padded
;
114 std::vector
<char> data_padded
=
115 PmpTestUtil::MakeHeaderAndBody(field_type
, elems
.size(), elems
);
116 data_padded
.resize(data_padded
.size()+10);
117 EXPECT_FALSE(InitColumnReaderFromBytes(&reader_padded
,
123 void TestPrimitive(const PmpFieldType field_type
) {
124 // Make an ascending vector of the primitive.
126 std::vector
<T
> data(n
, 0);
127 for (uint32 i
= 0; i
< n
; i
++) {
131 TestValid
<T
>(field_type
, data
);
132 TestMalformed
<T
>(field_type
, data
);
136 TEST(PmpColumnReaderTest
, HeaderParsingAndValidation
) {
137 PmpColumnReader reader_good_header
;
138 std::vector
<char> good_header
=
139 PmpTestUtil::MakeHeader(PMP_TYPE_STRING
, 0);
140 EXPECT_TRUE(InitColumnReaderFromBytes(&reader_good_header
,
143 EXPECT_EQ(0U, reader_good_header
.rows_read()) <<
144 "Read non-zero rows from header-only data.";
146 PmpColumnReader reader_bad_magic_bytes
;
147 std::vector
<char> bad_magic_bytes
=
148 PmpTestUtil::MakeHeader(PMP_TYPE_STRING
, 0);
149 bad_magic_bytes
[0] = (char)0xff;
150 EXPECT_FALSE(InitColumnReaderFromBytes(&reader_bad_magic_bytes
,
154 PmpColumnReader reader_inconsistent_types
;
155 std::vector
<char> inconsistent_type
=
156 PmpTestUtil::MakeHeader(PMP_TYPE_STRING
, 0);
157 inconsistent_type
[kPmpFieldType1Offset
] = (char)0xff;
158 EXPECT_FALSE(InitColumnReaderFromBytes(&reader_inconsistent_types
,
162 PmpColumnReader reader_invalid_type
;
163 std::vector
<char> invalid_type
=
164 PmpTestUtil::MakeHeader(PMP_TYPE_STRING
, 0);
165 invalid_type
[kPmpFieldType1Offset
] = (char)0xff;
166 invalid_type
[kPmpFieldType2Offset
] = (char)0xff;
167 EXPECT_FALSE(InitColumnReaderFromBytes(&reader_invalid_type
,
171 PmpColumnReader reader_incomplete_header
;
172 std::vector
<char> incomplete_header
=
173 PmpTestUtil::MakeHeader(PMP_TYPE_STRING
, 0);
174 incomplete_header
.resize(10);
175 EXPECT_FALSE(InitColumnReaderFromBytes(&reader_incomplete_header
,
180 TEST(PmpColumnReaderTest
, StringParsing
) {
181 std::vector
<std::string
> empty_strings(100, "");
183 // Test empty strings read okay.
184 TestValid(PMP_TYPE_STRING
, empty_strings
);
186 std::vector
<std::string
> mixed_strings
;
187 mixed_strings
.push_back("");
188 mixed_strings
.push_back("Hello");
189 mixed_strings
.push_back("World");
190 mixed_strings
.push_back("");
191 mixed_strings
.push_back("123123");
192 mixed_strings
.push_back("Q");
193 mixed_strings
.push_back("");
195 // Test that a mixed set of strings read correctly.
196 TestValid(PMP_TYPE_STRING
, mixed_strings
);
198 // Test with the data messed up in a variety of ways.
199 TestMalformed(PMP_TYPE_STRING
, mixed_strings
);
202 TEST(PmpColumnReaderTest
, PrimitiveParsing
) {
203 TestPrimitive
<uint32
>(PMP_TYPE_UINT32
);
204 TestPrimitive
<double>(PMP_TYPE_DOUBLE64
);
205 TestPrimitive
<uint8
>(PMP_TYPE_UINT8
);
206 TestPrimitive
<uint64
>(PMP_TYPE_UINT64
);
211 } // namespace picasa