- add sources.
[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/file_util.h"
8 #include "base/files/file_path.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 "testing/gtest/include/gtest/gtest.h"
20 #include "webkit/browser/fileapi/copy_or_move_file_validator.h"
21 #include "webkit/browser/fileapi/file_system_backend.h"
22 #include "webkit/browser/fileapi/file_system_context.h"
23 #include "webkit/browser/fileapi/file_system_operation_runner.h"
24 #include "webkit/browser/fileapi/file_system_url.h"
25 #include "webkit/browser/fileapi/isolated_context.h"
26 #include "webkit/common/fileapi/file_system_types.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::PlatformFileError result,
43                            const base::PlatformFileInfo& file_info) {
44   if (result == base::PLATFORM_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(file_util::CreateDirectory(src_path));
109
110     ScopedVector<fileapi::FileSystemBackend> additional_providers;
111     additional_providers.push_back(new fileapi::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         fileapi::CreateFileSystemContextWithAdditionalProvidersForTesting(
117             NULL, additional_providers.Pass(), base);
118
119     move_src_ = file_system_context_->CreateCrackedFileSystemURL(
120         GURL(kOrigin), fileapi::kFileSystemTypeTest,
121         base::FilePath::FromUTF8Unsafe(filename));
122
123     test_file_size_ = content.size();
124     base::FilePath test_file = src_path.AppendASCII(filename);
125     ASSERT_EQ(test_file_size_,
126               file_util::WriteFile(test_file, content.data(), test_file_size_));
127
128     base::FilePath dest_path = base.AppendASCII("dest_fs");
129     ASSERT_TRUE(file_util::CreateDirectory(dest_path));
130     std::string dest_fsid =
131         fileapi::IsolatedContext::GetInstance()->RegisterFileSystemForPath(
132             fileapi::kFileSystemTypeNativeMedia, dest_path, NULL);
133
134     size_t extension_index = filename.find_last_of(".");
135     ASSERT_NE(std::string::npos, extension_index);
136     std::string extension = filename.substr(extension_index);
137     std::string dest_root_fs_url = fileapi::GetIsolatedFileSystemRootURIString(
138         GURL(kOrigin), dest_fsid, "dest_fs/");
139     move_dest_ = file_system_context_->CrackURL(GURL(
140           dest_root_fs_url + "move_dest" + extension));
141
142     content::BrowserThread::PostTask(
143         content::BrowserThread::IO,
144         FROM_HERE,
145         base::Bind(&MediaFileValidatorTest::CheckFiles,
146                    base::Unretained(this), true,
147                    base::Bind(&MediaFileValidatorTest::OnTestFilesReady,
148                               base::Unretained(this), expected_result)));
149   }
150
151   void SetupFromFileOnFileThread(const std::string& filename,
152                                  const base::FilePath& source,
153                                  bool expected_result) {
154     std::string content;
155     ASSERT_TRUE(base::ReadFileToString(source, &content));
156     SetupOnFileThread(filename, content, expected_result);
157   }
158
159   // Check that exactly one of |move_src_| and |move_dest_| exists.
160   // |src_expected| indicates which one should exist.  When complete,
161   // |callback| is called with success/failure.
162   void CheckFiles(bool src_expected,
163                   const base::Callback<void(bool success)>& callback) {
164     CheckFile(move_src_, src_expected ? test_file_size_ : kNoFileSize,
165               base::Bind(&MediaFileValidatorTest::OnCheckFilesFirstResult,
166                          base::Unretained(this), !src_expected, callback));
167   }
168
169   // Helper that checks a file has the |expected_size|, which may be
170   // |kNoFileSize| if the file should not exist.  |callback| is called
171   // with success/failure.
172   void CheckFile(fileapi::FileSystemURL url,
173                  int64 expected_size,
174                  const base::Callback<void(bool success)>& callback) {
175     operation_runner()->GetMetadata(url,
176                                     base::Bind(&HandleCheckFileResult,
177                                                expected_size, callback));
178   }
179
180   // Helper that checks the result of |move_src_| lookup and then checks
181   // |move_dest_| if all is as expected.
182   void OnCheckFilesFirstResult(bool dest_expected,
183                                const base::Callback<void(bool)>& callback,
184                                bool src_result) {
185     EXPECT_TRUE(src_result);
186     if (!src_result) {
187       callback.Run(false);
188       return;
189     }
190     CheckFile(move_dest_, dest_expected ? test_file_size_ : kNoFileSize,
191               callback);
192   }
193
194   // Assert |test_files_ready| and then do the actual test of moving
195   // |move_src_| to |move_dest_|.
196   void OnTestFilesReady(bool expected_result, bool test_files_ready) {
197     ASSERT_TRUE(test_files_ready);
198     operation_runner()->Move(
199         move_src_, move_dest_, fileapi::FileSystemOperation::OPTION_NONE,
200         base::Bind(&MediaFileValidatorTest::OnMoveResult,
201                    base::Unretained(this), expected_result));
202   }
203
204   // Check that the move succeeded/failed based on expectation and then
205   // check that the right file exists.
206   void OnMoveResult(bool expected_result, base::PlatformFileError result) {
207     if (expected_result)
208       EXPECT_EQ(base::PLATFORM_FILE_OK, result);
209     else
210       EXPECT_EQ(base::PLATFORM_FILE_ERROR_SECURITY, result);
211     CheckFiles(!expected_result,
212                base::Bind(&MediaFileValidatorTest::OnTestFilesCheckResult,
213                           base::Unretained(this)));
214   }
215
216   // Check that the correct test file exists and then post the result back
217   // to the UI thread.
218   void OnTestFilesCheckResult(bool result) {
219     EXPECT_TRUE(result);
220     content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
221                                      loop_runner_->QuitClosure());
222   }
223
224   fileapi::FileSystemOperationRunner* operation_runner() {
225     return file_system_context_->operation_runner();
226   }
227
228   base::ScopedTempDir base_dir_;
229
230   scoped_refptr<fileapi::FileSystemContext> file_system_context_;
231
232   int test_file_size_;
233
234   fileapi::FileSystemURL move_src_;
235   fileapi::FileSystemURL move_dest_;
236
237   scoped_refptr<content::MessageLoopRunner> loop_runner_;
238
239   DISALLOW_COPY_AND_ASSIGN(MediaFileValidatorTest);
240 };
241
242 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, UnsupportedExtension) {
243   MoveTest("a.txt", std::string(kValidImage, arraysize(kValidImage)), false);
244 }
245
246 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, ValidImage) {
247   MoveTest("a.webp", std::string(kValidImage, arraysize(kValidImage)), true);
248 }
249
250 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, InvalidImage) {
251   MoveTest("a.webp", std::string(kInvalidMediaFile,
252            arraysize(kInvalidMediaFile)), false);
253 }
254
255 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, InvalidAudio) {
256   MoveTest("a.ogg", std::string(kInvalidMediaFile,
257            arraysize(kInvalidMediaFile)), false);
258 }
259
260 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, ValidAudio) {
261   base::FilePath test_file = GetMediaTestDir();
262   ASSERT_FALSE(test_file.empty());
263   test_file = test_file.AppendASCII("sfx.ogg");
264   MoveTestFromFile("sfx.ogg", test_file, true);
265 }
266
267 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, InvalidVideo) {
268   base::FilePath test_file = GetMediaTestDir();
269   ASSERT_FALSE(test_file.empty());
270   test_file = test_file.AppendASCII("no_streams.webm");
271   MoveTestFromFile("no_streams.webm", test_file, false);
272 }
273
274 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, ValidVideo) {
275   base::FilePath test_file = GetMediaTestDir();
276   ASSERT_FALSE(test_file.empty());
277   test_file = test_file.AppendASCII("bear-320x240-multitrack.webm");
278   MoveTestFromFile("multitrack.webm", test_file, true);
279 }