158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/basictypes.h"
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/files/file_path.h"
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/run_loop.h"
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/test/test_file_system_context.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h"
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemContext;
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemOperationRunner;
1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemType;
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURL;
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace content {
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void GetStatus(bool* done,
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               base::File::Error *status_out,
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               base::File::Error status) {
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_FALSE(*done);
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  *done = true;
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  *status_out = status;
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void GetCancelStatus(bool* operation_done,
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     bool* cancel_done,
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     base::File::Error *status_out,
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     base::File::Error status) {
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Cancel callback must be always called after the operation's callback.
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(*operation_done);
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_FALSE(*cancel_done);
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  *cancel_done = true;
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  *status_out = status;
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class FileSystemOperationRunnerTest : public testing::Test {
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) protected:
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FileSystemOperationRunnerTest() {}
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~FileSystemOperationRunnerTest() {}
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ASSERT_TRUE(base_.CreateUniqueTempDir());
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::FilePath base_dir = base_.path();
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    file_system_context_ =
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        CreateFileSystemContextForTesting(NULL, base_dir);
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    file_system_context_ = NULL;
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FileSystemURL URL(const std::string& path) {
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return file_system_context_->CreateCrackedFileSystemURL(
5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://example.com"),
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        storage::kFileSystemTypeTemporary,
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        base::FilePath::FromUTF8Unsafe(path));
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FileSystemOperationRunner* operation_runner() {
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return file_system_context_->operation_runner();
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::ScopedTempDir base_;
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::MessageLoop message_loop_;
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_refptr<FileSystemContext> file_system_context_;
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FileSystemOperationRunnerTest);
7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, NotFoundError) {
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool done = false;
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error status = base::File::FILE_ERROR_FAILED;
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Regular NOT_FOUND error, which is called asynchronously.
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  operation_runner()->Truncate(URL("foo"), 0,
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                               base::Bind(&GetStatus, &done, &status));
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_FALSE(done);
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(done);
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, status);
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, InvalidURLError) {
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool done = false;
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error status = base::File::FILE_ERROR_FAILED;
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Invalid URL error, which calls DidFinish synchronously.
9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  operation_runner()->Truncate(FileSystemURL(), 0,
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                               base::Bind(&GetStatus, &done, &status));
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // The error call back shouldn't be fired synchronously.
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_FALSE(done);
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(done);
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_ERROR_INVALID_URL, status);
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, NotFoundErrorAndCancel) {
10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool done = false;
10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool cancel_done = false;
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error status = base::File::FILE_ERROR_FAILED;
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error cancel_status = base::File::FILE_ERROR_FAILED;
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Call Truncate with non-existent URL, and try to cancel it immediately
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // after that (before its callback is fired).
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FileSystemOperationRunner::OperationID id =
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      operation_runner()->Truncate(URL("foo"), 0,
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   base::Bind(&GetStatus, &done, &status));
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  operation_runner()->Cancel(id, base::Bind(&GetCancelStatus,
11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                            &done, &cancel_done,
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                            &cancel_status));
11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_FALSE(done);
12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_FALSE(cancel_done);
121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(done);
12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(cancel_done);
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, status);
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, cancel_status);
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, InvalidURLErrorAndCancel) {
13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool done = false;
13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool cancel_done = false;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error status = base::File::FILE_ERROR_FAILED;
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error cancel_status = base::File::FILE_ERROR_FAILED;
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Call Truncate with invalid URL, and try to cancel it immediately
13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // after that (before its callback is fired).
13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FileSystemOperationRunner::OperationID id =
13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      operation_runner()->Truncate(FileSystemURL(), 0,
13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  base::Bind(&GetStatus, &done, &status));
14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  operation_runner()->Cancel(id, base::Bind(&GetCancelStatus,
14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                            &done, &cancel_done,
14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                            &cancel_status));
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_FALSE(done);
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_FALSE(cancel_done);
146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(done);
14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(cancel_done);
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_ERROR_INVALID_URL, status);
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, cancel_status);
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, CancelWithInvalidId) {
155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const FileSystemOperationRunner::OperationID kInvalidId = -1;
156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool done = true;  // The operation is not running.
157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool cancel_done = false;
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error cancel_status = base::File::FILE_ERROR_FAILED;
159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  operation_runner()->Cancel(kInvalidId, base::Bind(&GetCancelStatus,
160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                                    &done, &cancel_done,
161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                                    &cancel_status));
162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ASSERT_TRUE(cancel_done);
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, cancel_status);
165d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace content
168