Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / media_galleries / fileapi / media_file_validator_browsertest.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 "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/files/file_path.h"
8 #include "base/files/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "base/path_service.h"
13 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
14 #include "chrome/test/base/in_process_browser_test.h"
15 #include "content/public/test/browser_test.h"
16 #include "content/public/test/test_file_system_backend.h"
17 #include "content/public/test/test_file_system_context.h"
18 #include "content/public/test/test_utils.h"
19 #include "storage/browser/fileapi/copy_or_move_file_validator.h"
20 #include "storage/browser/fileapi/file_system_backend.h"
21 #include "storage/browser/fileapi/file_system_context.h"
22 #include "storage/browser/fileapi/file_system_operation_runner.h"
23 #include "storage/browser/fileapi/file_system_url.h"
24 #include "storage/browser/fileapi/isolated_context.h"
25 #include "storage/common/fileapi/file_system_types.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 namespace {
29
30 const char kOrigin[] = "http://foo";
31
32 const char kValidImage[] = "RIFF0\0\0\0WEBPVP8 $\0\0\0\xB2\x02\0\x9D\x01\x2A"
33                            "\x01\0\x01\0\x2F\x9D\xCE\xE7s\xA8((((\x01\x9CK(\0"
34                            "\x05\xCE\xB3l\0\0\xFE\xD8\x80\0\0";
35
36 const char kInvalidMediaFile[] = "Not a media file";
37
38 const int64 kNoFileSize = -1;
39
40 void HandleCheckFileResult(int64 expected_size,
41                            const base::Callback<void(bool success)>& callback,
42                            base::File::Error result,
43                            const base::File::Info& file_info) {
44   if (result == base::File::FILE_OK) {
45     if (!file_info.is_directory && expected_size != kNoFileSize &&
46         file_info.size == expected_size) {
47       callback.Run(true);
48       return;
49     }
50   } else {
51     if (expected_size == kNoFileSize) {
52       callback.Run(true);
53       return;
54     }
55   }
56   callback.Run(false);
57 }
58
59 base::FilePath GetMediaTestDir() {
60   base::FilePath test_file;
61   if (!PathService::Get(base::DIR_SOURCE_ROOT, &test_file))
62     return base::FilePath();
63   return test_file.AppendASCII("media").AppendASCII("test").AppendASCII("data");
64 }
65
66 }  // namespace
67
68 class MediaFileValidatorTest : public InProcessBrowserTest {
69  public:
70   MediaFileValidatorTest() : test_file_size_(0) {}
71
72   virtual ~MediaFileValidatorTest() {}
73
74   // Write |content| into |filename| in a test file system and try to move
75   // it into a media file system.  The result is compared to |expected_result|.
76   void MoveTest(const std::string& filename, const std::string& content,
77                 bool expected_result) {
78     content::BrowserThread::PostTask(
79         content::BrowserThread::FILE,
80         FROM_HERE,
81         base::Bind(&MediaFileValidatorTest::SetupOnFileThread,
82                    base::Unretained(this), filename, content, expected_result));
83     loop_runner_ = new content::MessageLoopRunner;
84     loop_runner_->Run();
85   }
86
87   // Write |source| into |filename| in a test file system and try to move it
88   // into a media file system.  The result is compared to |expected_result|.
89   void MoveTestFromFile(const std::string& filename,
90                         const base::FilePath& source, bool expected_result) {
91     content::BrowserThread::PostTask(
92         content::BrowserThread::FILE,
93         FROM_HERE,
94         base::Bind(&MediaFileValidatorTest::SetupFromFileOnFileThread,
95                    base::Unretained(this), filename, source, expected_result));
96     loop_runner_ = new content::MessageLoopRunner;
97     loop_runner_->Run();
98   }
99
100  private:
101   // Create the test files, filesystem objects, etc.
102   void SetupOnFileThread(const std::string& filename,
103                          const std::string& content,
104                          bool expected_result) {
105     ASSERT_TRUE(base_dir_.CreateUniqueTempDir());
106     base::FilePath base = base_dir_.path();
107     base::FilePath src_path = base.AppendASCII("src_fs");
108     ASSERT_TRUE(base::CreateDirectory(src_path));
109
110     ScopedVector<storage::FileSystemBackend> additional_providers;
111     additional_providers.push_back(new content::TestFileSystemBackend(
112         base::MessageLoopProxy::current().get(), src_path));
113     additional_providers.push_back(new MediaFileSystemBackend(
114         base, base::MessageLoopProxy::current().get()));
115     file_system_context_ =
116         content::CreateFileSystemContextWithAdditionalProvidersForTesting(
117             NULL, additional_providers.Pass(), base);
118
119     move_src_ = file_system_context_->CreateCrackedFileSystemURL(
120         GURL(kOrigin),
121         storage::kFileSystemTypeTest,
122         base::FilePath::FromUTF8Unsafe(filename));
123
124     test_file_size_ = content.size();
125     base::FilePath test_file = src_path.AppendASCII(filename);
126     ASSERT_EQ(test_file_size_,
127               base::WriteFile(test_file, content.data(), test_file_size_));
128
129     base::FilePath dest_path = base.AppendASCII("dest_fs");
130     ASSERT_TRUE(base::CreateDirectory(dest_path));
131     std::string dest_fsid =
132         storage::IsolatedContext::GetInstance()->RegisterFileSystemForPath(
133             storage::kFileSystemTypeNativeMedia,
134             std::string(),
135             dest_path,
136             NULL);
137
138     size_t extension_index = filename.find_last_of(".");
139     ASSERT_NE(std::string::npos, extension_index);
140     std::string extension = filename.substr(extension_index);
141     std::string dest_root_fs_url = storage::GetIsolatedFileSystemRootURIString(
142         GURL(kOrigin), dest_fsid, "dest_fs/");
143     move_dest_ = file_system_context_->CrackURL(GURL(
144           dest_root_fs_url + "move_dest" + extension));
145
146     content::BrowserThread::PostTask(
147         content::BrowserThread::IO,
148         FROM_HERE,
149         base::Bind(&MediaFileValidatorTest::CheckFiles,
150                    base::Unretained(this), true,
151                    base::Bind(&MediaFileValidatorTest::OnTestFilesReady,
152                               base::Unretained(this), expected_result)));
153   }
154
155   void SetupFromFileOnFileThread(const std::string& filename,
156                                  const base::FilePath& source,
157                                  bool expected_result) {
158     std::string content;
159     ASSERT_TRUE(base::ReadFileToString(source, &content));
160     SetupOnFileThread(filename, content, expected_result);
161   }
162
163   // Check that exactly one of |move_src_| and |move_dest_| exists.
164   // |src_expected| indicates which one should exist.  When complete,
165   // |callback| is called with success/failure.
166   void CheckFiles(bool src_expected,
167                   const base::Callback<void(bool success)>& callback) {
168     CheckFile(move_src_, src_expected ? test_file_size_ : kNoFileSize,
169               base::Bind(&MediaFileValidatorTest::OnCheckFilesFirstResult,
170                          base::Unretained(this), !src_expected, callback));
171   }
172
173   // Helper that checks a file has the |expected_size|, which may be
174   // |kNoFileSize| if the file should not exist.  |callback| is called
175   // with success/failure.
176   void CheckFile(storage::FileSystemURL url,
177                  int64 expected_size,
178                  const base::Callback<void(bool success)>& callback) {
179     operation_runner()->GetMetadata(url,
180                                     base::Bind(&HandleCheckFileResult,
181                                                expected_size, callback));
182   }
183
184   // Helper that checks the result of |move_src_| lookup and then checks
185   // |move_dest_| if all is as expected.
186   void OnCheckFilesFirstResult(bool dest_expected,
187                                const base::Callback<void(bool)>& callback,
188                                bool src_result) {
189     EXPECT_TRUE(src_result);
190     if (!src_result) {
191       callback.Run(false);
192       return;
193     }
194     CheckFile(move_dest_, dest_expected ? test_file_size_ : kNoFileSize,
195               callback);
196   }
197
198   // Assert |test_files_ready| and then do the actual test of moving
199   // |move_src_| to |move_dest_|.
200   void OnTestFilesReady(bool expected_result, bool test_files_ready) {
201     ASSERT_TRUE(test_files_ready);
202     operation_runner()->Move(move_src_,
203                              move_dest_,
204                              storage::FileSystemOperation::OPTION_NONE,
205                              base::Bind(&MediaFileValidatorTest::OnMoveResult,
206                                         base::Unretained(this),
207                                         expected_result));
208   }
209
210   // Check that the move succeeded/failed based on expectation and then
211   // check that the right file exists.
212   void OnMoveResult(bool expected_result, base::File::Error result) {
213     if (expected_result)
214       EXPECT_EQ(base::File::FILE_OK, result);
215     else
216       EXPECT_EQ(base::File::FILE_ERROR_SECURITY, result);
217     CheckFiles(!expected_result,
218                base::Bind(&MediaFileValidatorTest::OnTestFilesCheckResult,
219                           base::Unretained(this)));
220   }
221
222   // Check that the correct test file exists and then post the result back
223   // to the UI thread.
224   void OnTestFilesCheckResult(bool result) {
225     EXPECT_TRUE(result);
226     content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
227                                      loop_runner_->QuitClosure());
228   }
229
230   storage::FileSystemOperationRunner* operation_runner() {
231     return file_system_context_->operation_runner();
232   }
233
234   base::ScopedTempDir base_dir_;
235
236   scoped_refptr<storage::FileSystemContext> file_system_context_;
237
238   int test_file_size_;
239
240   storage::FileSystemURL move_src_;
241   storage::FileSystemURL move_dest_;
242
243   scoped_refptr<content::MessageLoopRunner> loop_runner_;
244
245   DISALLOW_COPY_AND_ASSIGN(MediaFileValidatorTest);
246 };
247
248 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, UnsupportedExtension) {
249   MoveTest("a.txt", std::string(kValidImage, arraysize(kValidImage)), false);
250 }
251
252 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, ValidImage) {
253   MoveTest("a.webp", std::string(kValidImage, arraysize(kValidImage)), true);
254 }
255
256 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, InvalidImage) {
257   MoveTest("a.webp", std::string(kInvalidMediaFile,
258            arraysize(kInvalidMediaFile)), false);
259 }
260
261 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, InvalidAudio) {
262   MoveTest("a.ogg", std::string(kInvalidMediaFile,
263            arraysize(kInvalidMediaFile)), false);
264 }
265
266 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, ValidAudio) {
267   base::FilePath test_file = GetMediaTestDir();
268   ASSERT_FALSE(test_file.empty());
269   test_file = test_file.AppendASCII("sfx.ogg");
270   MoveTestFromFile("sfx.ogg", test_file, true);
271 }
272
273 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, InvalidVideo) {
274   base::FilePath test_file = GetMediaTestDir();
275   ASSERT_FALSE(test_file.empty());
276   test_file = test_file.AppendASCII("no_streams.webm");
277   MoveTestFromFile("no_streams.webm", test_file, false);
278 }
279
280 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, ValidVideo) {
281   base::FilePath test_file = GetMediaTestDir();
282   ASSERT_FALSE(test_file.empty());
283   test_file = test_file.AppendASCII("bear-320x240-multitrack.webm");
284   MoveTestFromFile("multitrack.webm", test_file, true);
285 }