- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / utility / media_galleries / pmp_column_reader_unittest.cc
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.
4
5 #include <algorithm>
6 #include <vector>
7
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"
15
16 namespace picasa {
17
18 namespace {
19
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())
26     return false;
27
28   base::FilePath temp_path;
29   if (!file_util::CreateTemporaryFileInDir(temp_dir.path(), &temp_path))
30     return false;
31
32   // Explicit conversion from signed to unsigned.
33   size_t bytes_written = file_util::WriteFile(temp_path, &data[0], data.size());
34   if (bytes_written != data.size())
35     return false;
36
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)
41     return false;
42
43   bool read_success = reader->ReadFile(platform_file, expected_type);
44
45   base::ClosePlatformFile(platform_file);
46
47   return read_success;
48 }
49
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);
53 }
54
55 bool DoRead(const PmpColumnReader* reader, uint32 row, uint32* target) {
56   return reader->ReadUInt32(row, target);
57 }
58
59 bool DoRead(const PmpColumnReader* reader, uint32 row, double* target) {
60   return reader->ReadDouble64(row, target);
61 }
62
63 bool DoRead(const PmpColumnReader* reader, uint32 row, uint8* target) {
64   return reader->ReadUInt8(row, target);
65 }
66
67 bool DoRead(const PmpColumnReader* reader, uint32 row, uint64* target) {
68   return reader->ReadUInt64(row, target);
69 }
70
71 // TestValid
72 template<class T>
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());
80
81   for (uint32 i = 0; i < elems.size() && i < reader.rows_read(); i++) {
82     T target;
83     EXPECT_TRUE(DoRead(&reader, i, &target));
84     EXPECT_EQ(elems[i], target);
85   }
86 }
87
88 template<class T>
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,
96                                          field_type));
97
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,
103                                          field_type));
104
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,
110                                          data_truncated,
111                                          field_type));
112
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,
118                                          data_padded,
119                                          field_type));
120 }
121
122 template<class T>
123 void TestPrimitive(const PmpFieldType field_type) {
124   // Make an ascending vector of the primitive.
125   uint32 n = 100;
126   std::vector<T> data(n, 0);
127   for (uint32 i = 0; i < n; i++) {
128     data[i] = i*3;
129   }
130
131   TestValid<T>(field_type, data);
132   TestMalformed<T>(field_type, data);
133 }
134
135
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,
141                                         good_header,
142                                         PMP_TYPE_STRING));
143   EXPECT_EQ(0U, reader_good_header.rows_read()) <<
144       "Read non-zero rows from header-only data.";
145
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,
151                                          bad_magic_bytes,
152                                          PMP_TYPE_STRING));
153
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,
159                                          inconsistent_type,
160                                          PMP_TYPE_STRING));
161
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,
168                                          invalid_type,
169                                          PMP_TYPE_STRING));
170
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,
176                                          incomplete_header,
177                                          PMP_TYPE_STRING));
178 }
179
180 TEST(PmpColumnReaderTest, StringParsing) {
181   std::vector<std::string> empty_strings(100, "");
182
183   // Test empty strings read okay.
184   TestValid(PMP_TYPE_STRING, empty_strings);
185
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("");
194
195   // Test that a mixed set of strings read correctly.
196   TestValid(PMP_TYPE_STRING, mixed_strings);
197
198   // Test with the data messed up in a variety of ways.
199   TestMalformed(PMP_TYPE_STRING, mixed_strings);
200 }
201
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);
207 }
208
209 }  // namespace
210
211 }  // namespace picasa