15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/test_file_ref.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <sstream>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_file_io.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/c/private/ppb_testing_private.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/cpp/directory_entry.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/file_io.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/file_ref.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/file_system.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/instance.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/url_loader.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/url_request_info.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/url_response_info.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/test_utils.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/testing_instance.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)REGISTER_TEST_CASE(FileRef);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kPersFileName = "persistent";
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kTempFileName = "temporary";
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kParentPath = "/foo/bar";
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kPersFilePath = "/foo/bar/persistent";
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kTempFilePath = "/foo/bar/temporary";
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* kTerribleName = "!@#$%^&*()-_=+{}[] ;:'\"|`~\t\n\r\b?";
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)typedef std::vector<pp::DirectoryEntry> DirEntries;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ReportMismatch(const std::string& method_name,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const std::string& returned_result,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const std::string& expected_result) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return method_name + " returned '" + returned_result + "'; '" +
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_result + "' expected.";
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestFileRef::Init() {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CheckTestingInterface() && EnsureRunningOverHTTP();
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string TestFileRef::MakeExternalFileRef(pp::FileRef* file_ref_ext) {
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pp::URLRequestInfo request(instance_);
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request.SetURL("test_url_loader_data/hello.txt");
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request.SetStreamToFile(true);
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pp::URLLoader loader(instance_);
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(loader.Open(request, callback.GetCallback()));
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pp::URLResponseInfo response_info(loader.GetResponseInfo());
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(response_info.is_null());
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(200, response_info.GetStatusCode());
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *file_ref_ext = pp::FileRef(response_info.GetBodyAsFileRef());
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_FILESYSTEMTYPE_EXTERNAL, file_ref_ext->GetFileSystemType());
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PASS();
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int32_t TestFileRef::DeleteDirectoryRecursively(pp::FileRef* dir) {
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!dir)
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return PP_ERROR_BADARGUMENT;
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallbackWithOutput<DirEntries> output_callback(
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      instance_->pp_instance(), callback_type());
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  output_callback.WaitForResult(
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      dir->ReadDirectoryEntries(output_callback.GetCallback()));
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int32_t rv = output_callback.result();
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND)
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return rv;
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DirEntries entries = output_callback.output();
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (DirEntries::const_iterator it = entries.begin();
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       it != entries.end();
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       ++it) {
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    pp::FileRef file_ref = it->file_ref();
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (it->file_type() == PP_FILETYPE_DIRECTORY) {
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      rv = DeleteDirectoryRecursively(&file_ref);
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return rv;
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      callback.WaitForResult(file_ref.Delete(callback.GetCallback()));
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      rv = callback.result();
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND)
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return rv;
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(dir->Delete(callback.GetCallback()));
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return callback.result();
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestFileRef::RunTests(const std::string& filter) {
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RUN_CALLBACK_TEST(TestFileRef, Create, filter);
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RUN_CALLBACK_TEST(TestFileRef, GetFileSystemType, filter);
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RUN_CALLBACK_TEST(TestFileRef, GetName, filter);
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RUN_CALLBACK_TEST(TestFileRef, GetPath, filter);
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RUN_CALLBACK_TEST(TestFileRef, GetParent, filter);
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RUN_CALLBACK_TEST(TestFileRef, MakeDirectory, filter);
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RUN_CALLBACK_TEST(TestFileRef, QueryAndTouchFile, filter);
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RUN_CALLBACK_TEST(TestFileRef, DeleteFileAndDirectory, filter);
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RUN_CALLBACK_TEST(TestFileRef, RenameFileAndDirectory, filter);
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RUN_CALLBACK_TEST(TestFileRef, Query, filter);
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RUN_CALLBACK_TEST(TestFileRef, FileNameEscaping, filter);
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RUN_CALLBACK_TEST(TestFileRef, ReadDirectoryEntries, filter);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFileRef::TestCreate() {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> invalid_paths;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  invalid_paths.push_back("invalid_path");  // no '/' at the first character
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  invalid_paths.push_back(std::string());   // empty path
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following are directory traversal checks
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  invalid_paths.push_back("..");
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  invalid_paths.push_back("/../invalid_path");
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  invalid_paths.push_back("/../../invalid_path");
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  invalid_paths.push_back("/invalid/../../path");
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t num_invalid_paths = invalid_paths.size();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileSystem file_system_pers(
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileSystem file_system_temp(
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t j = 0; j < num_invalid_paths; ++j) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pp::FileRef file_ref_pers(file_system_pers, invalid_paths[j].c_str());
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (file_ref_pers.pp_resource() != 0) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "file_ref_pers expected to be invalid for path: " +
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          invalid_paths[j];
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pp::FileRef file_ref_temp(file_system_temp, invalid_paths[j].c_str());
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (file_ref_temp.pp_resource() != 0) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "file_ref_temp expected to be invalid for path: " +
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          invalid_paths[j];
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFileRef::TestGetFileSystemType() {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileSystem file_system_pers(
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileSystem file_system_temp(
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (file_ref_pers.GetFileSystemType() != PP_FILESYSTEMTYPE_LOCALPERSISTENT)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return "file_ref_pers expected to be persistent.";
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (file_ref_temp.GetFileSystemType() != PP_FILESYSTEMTYPE_LOCALTEMPORARY)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return "file_ref_temp expected to be temporary.";
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pp::FileRef file_ref_ext;
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string result = MakeExternalFileRef(&file_ref_ext);
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!result.empty())
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return result;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFileRef::TestGetName() {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileSystem file_system_pers(
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileSystem file_system_temp(
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string name = file_ref_pers.GetName().AsString();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (name != kPersFileName)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ReportMismatch("FileRef::GetName", name, kPersFileName);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  name = file_ref_temp.GetName().AsString();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (name != kTempFileName)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ReportMismatch("FileRef::GetName", name, kTempFileName);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the "/" case.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref_slash(file_system_temp, "/");
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  name = file_ref_slash.GetName().AsString();
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (name != "/")
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ReportMismatch("FileRef::GetName", name, "/");
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::URLRequestInfo request(instance_);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.SetURL("test_url_loader_data/hello.txt");
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.SetStreamToFile(true);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::URLLoader loader(instance_);
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(loader.Open(request, callback.GetCallback()));
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::URLResponseInfo response_info(loader.GetResponseInfo());
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(response_info.is_null());
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(200, response_info.GetStatusCode());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref_ext(response_info.GetBodyAsFileRef());
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  name = file_ref_ext.GetName().AsString();
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(name.empty());
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFileRef::TestGetPath() {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileSystem file_system_pers(
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileSystem file_system_temp(
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(kPersFilePath, file_ref_pers.GetPath().AsString());
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(kTempFilePath, file_ref_temp.GetPath().AsString());
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::URLRequestInfo request(instance_);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.SetURL("test_url_loader_data/hello.txt");
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.SetStreamToFile(true);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::URLLoader loader(instance_);
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(loader.Open(request, callback.GetCallback()));
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::URLResponseInfo response_info(loader.GetResponseInfo());
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(response_info.is_null());
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(200, response_info.GetStatusCode());
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref_ext(response_info.GetBodyAsFileRef());
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(file_ref_ext.GetPath().is_undefined());
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFileRef::TestGetParent() {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileSystem file_system_pers(
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileSystem file_system_temp(
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(kParentPath, file_ref_pers.GetParent().GetPath().AsString());
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(kParentPath, file_ref_temp.GetParent().GetPath().AsString());
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the "/" case.
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref_slash(file_system_temp, "/");
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ("/", file_ref_slash.GetParent().GetPath().AsString());
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the "/foo" case (the parent is "/").
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref_with_root_parent(file_system_temp, "/foo");
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ("/", file_ref_with_root_parent.GetParent().GetPath().AsString());
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::URLRequestInfo request(instance_);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.SetURL("test_url_loader_data/hello.txt");
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.SetStreamToFile(true);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::URLLoader loader(instance_);
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(loader.Open(request, callback.GetCallback()));
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::URLResponseInfo response_info(loader.GetResponseInfo());
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(response_info.is_null());
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(200, response_info.GetStatusCode());
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref_ext(response_info.GetBodyAsFileRef());
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(file_ref_ext.GetParent().is_null());
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFileRef::TestMakeDirectory() {
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open.
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MakeDirectory.
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef dir_ref(file_system, "/test_dir_make_directory");
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(dir_ref.MakeDirectory(callback.GetCallback()));
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MakeDirectory aborted.
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int32_t rv = PP_ERROR_FAILED;
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    rv = pp::FileRef(file_system, "/test_dir_make_abort")
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        .MakeDirectory(callback.GetCallback());
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForAbortResult(rv);
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MakeDirectoryIncludingAncestors.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dir_ref = pp::FileRef(file_system, "/dir_make_dir_1/dir_make_dir_2");
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      dir_ref.MakeDirectoryIncludingAncestors(callback.GetCallback()));
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MakeDirectoryIncludingAncestors aborted.
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    rv = pp::FileRef(file_system, "/dir_make_abort_1/dir_make_abort_2")
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        .MakeDirectoryIncludingAncestors(callback.GetCallback());
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForAbortResult(rv);
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // MakeDirectory with nested path should fail.
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dir_ref = pp::FileRef(file_system, "/dir_make_dir_3/dir_make_dir_4");
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(dir_ref.MakeDirectory(callback.GetCallback()));
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_NE(PP_OK, callback.result());
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFileRef::TestQueryAndTouchFile() {
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref(file_system, "/file_touch");
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileIO file_io(instance_);
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      file_io.Open(file_ref,
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   PP_FILEOPENFLAG_CREATE |
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   PP_FILEOPENFLAG_TRUNCATE |
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   PP_FILEOPENFLAG_WRITE,
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   callback.GetCallback()));
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Write some data to have a non-zero file size.
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(file_io.Write(0, "test", 4, callback.GetCallback()));
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(4, callback.result());
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Touch.
364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const PP_Time last_access_time = 123 * 24 * 3600.0;
365ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // last_modified_time's granularity is 2 seconds
366ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // See note in test_file_io.cc for why we use this time.
367ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const PP_Time last_modified_time = 100 * 24 * 3600.0;
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(file_ref.Touch(last_access_time, last_modified_time,
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        callback.GetCallback()));
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Touch aborted.
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int32_t rv = PP_ERROR_FAILED;
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    rv = pp::FileRef(file_system, "/file_touch_abort")
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        .Touch(last_access_time, last_modified_time, callback.GetCallback());
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(rv);
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == PP_OK_COMPLETIONPENDING) {
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Touch tried to run asynchronously and should have been aborted.
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(PP_ERROR_ABORTED, callback.result());
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Touch ran synchronously and should have failed because the file does not
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // exist.
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(PP_ERROR_FILENOTFOUND, callback.result());
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Query.
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_FileInfo info;
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(file_io.Query(&info, callback.GetCallback()));
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(4, info.size);
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_FILETYPE_REGULAR, info.type);
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_FILESYSTEMTYPE_LOCALTEMPORARY, info.system_type);
3980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Disabled due to DST-related failure: crbug.com/314579
4000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // ASSERT_EQ(last_access_time, info.last_access_time);
4010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // ASSERT_EQ(last_modified_time, info.last_modified_time);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancellation test.
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(viettrungluu): this test causes a bunch of LOG(WARNING)s; investigate.
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(viettrungluu): check |info| for late writes.
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    rv = pp::FileRef(file_system, "/file_touch").Touch(
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        last_access_time, last_modified_time, callback.GetCallback());
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForAbortResult(rv);
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFileRef::TestDeleteFileAndDirectory() {
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref(file_system, "/file_delete");
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileIO file_io(instance_);
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(file_ref.Delete(callback.GetCallback()));
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef dir_ref(file_system, "/dir_delete");
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(dir_ref.MakeDirectory(callback.GetCallback()));
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(dir_ref.Delete(callback.GetCallback()));
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef nested_dir_ref(file_system, "/dir_delete_1/dir_delete_2");
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      nested_dir_ref.MakeDirectoryIncludingAncestors(callback.GetCallback()));
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Attempt to delete the parent directory (should fail; it's non-empty).
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef parent_dir_ref = nested_dir_ref.GetParent();
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(parent_dir_ref.Delete(callback.GetCallback()));
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_FAILED, callback.result());
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef nonexistent_file_ref(file_system, "/nonexistent_file_delete");
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(nonexistent_file_ref.Delete(callback.GetCallback()));
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_FILENOTFOUND, callback.result());
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete aborted.
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int32_t rv = PP_ERROR_FAILED;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pp::FileRef file_ref_abort(file_system, "/file_delete_abort");
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pp::FileIO file_io_abort(instance_);
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback.WaitForResult(
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        file_io_abort.Open(file_ref_abort, PP_FILEOPENFLAG_CREATE,
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           callback.GetCallback()));
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK_CALLBACK_BEHAVIOR(callback);
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(PP_OK, callback.result());
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    rv = file_ref_abort.Delete(callback.GetCallback());
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForAbortResult(rv);
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFileRef::TestRenameFileAndDirectory() {
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef file_ref(file_system, "/file_rename");
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileIO file_io(instance_);
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef target_file_ref(file_system, "/target_file_rename");
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      file_ref.Rename(target_file_ref, callback.GetCallback()));
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef dir_ref(file_system, "/dir_rename");
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(dir_ref.MakeDirectory(callback.GetCallback()));
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef target_dir_ref(file_system, "/target_dir_rename");
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      dir_ref.Rename(target_dir_ref, callback.GetCallback()));
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef nested_dir_ref(file_system, "/dir_rename_1/dir_rename_2");
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      nested_dir_ref.MakeDirectoryIncludingAncestors(callback.GetCallback()));
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Try to rename nested directory to the parent name. Should fail.
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef target_nested_dir_ref(file_system, "/dir_rename_1");
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      nested_dir_ref.Rename(target_nested_dir_ref, callback.GetCallback()));
519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_FAILED, callback.result());
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Rename aborted.
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(viettrungluu): Figure out what we want to do if the target file
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // resource is destroyed before completion.
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int32_t rv = PP_ERROR_FAILED;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::FileRef target_file_ref_abort(file_system,
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    "/target_file_rename_abort");
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pp::FileRef file_ref_abort(file_system, "/file_rename_abort");
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pp::FileIO file_io_abort(instance_);
531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback.WaitForResult(
532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        file_io_abort.Open(file_ref_abort, PP_FILEOPENFLAG_CREATE,
533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           callback.GetCallback()));
534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK_CALLBACK_BEHAVIOR(callback);
535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(PP_OK, callback.result());
536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    rv = file_ref_abort.Rename(target_file_ref_abort, callback.GetCallback());
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForAbortResult(rv);
540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PASS();
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string TestFileRef::TestQuery() {
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pp::FileRef file_ref(file_system, "/file");
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pp::FileIO file_io(instance_);
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE,
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      callback.GetCallback()));
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We touch the file so we can easily check access and modified time.
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(file_io.Touch(0, 0, callback.GetCallback()));
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallbackWithOutput<PP_FileInfo> out_callback(
566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      instance_->pp_instance(), callback_type());
567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  out_callback.WaitForResult(file_ref.Query(out_callback.GetCallback()));
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(out_callback);
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, out_callback.result());
570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PP_FileInfo info = out_callback.output();
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(0, info.size);
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_FILETYPE_REGULAR, info.type);
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_FILESYSTEMTYPE_LOCALTEMPORARY, info.system_type);
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_DOUBLE_EQ(0.0, info.last_access_time);
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_DOUBLE_EQ(0.0, info.last_modified_time);
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Query a file ref on an external filesystem.
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pp::FileRef file_ref_ext;
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string result = MakeExternalFileRef(&file_ref_ext);
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!result.empty())
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return result;
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  out_callback.WaitForResult(file_ref_ext.Query(out_callback.GetCallback()));
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(out_callback);
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (out_callback.result() != PP_OK)
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ReportError("Query() result", out_callback.result());
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, out_callback.result());
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  info = out_callback.output();
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_FILETYPE_REGULAR, info.type);
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_FILESYSTEMTYPE_EXTERNAL, info.system_type);
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We can't touch the file, so just sanity check the times.
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(info.creation_time >= 0.0);
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(info.last_modified_time >= 0.0);
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(info.last_access_time >= 0.0);
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Query a file ref for a file that doesn't exist.
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pp::FileRef missing_file_ref(file_system, "/missing_file");
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  out_callback.WaitForResult(missing_file_ref.Query(
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      out_callback.GetCallback()));
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(out_callback);
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_ERROR_FILENOTFOUND, out_callback.result());
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string TestFileRef::TestFileNameEscaping() {
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string test_dir_path = "/dir_for_escaping_test";
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a directory in which to test.
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pp::FileRef test_dir_ref(file_system, test_dir_path.c_str());
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(test_dir_ref.MakeDirectory(callback.GetCallback()));
619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create the file with the terrible name.
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string full_file_path = test_dir_path + "/" + kTerribleName;
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pp::FileRef file_ref(file_system, full_file_path.c_str());
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pp::FileIO file_io(instance_);
626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(
627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // FileRef::ReadDirectoryEntries only works out-of-process.
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (testing_interface_->IsOutOfProcess()) {
633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TestCompletionCallbackWithOutput<DirEntries>
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        output_callback(instance_->pp_instance(), callback_type());
635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    output_callback.WaitForResult(
637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        test_dir_ref.ReadDirectoryEntries(output_callback.GetCallback()));
638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK_CALLBACK_BEHAVIOR(output_callback);
639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(PP_OK, output_callback.result());
640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DirEntries entries = output_callback.output();
642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(1, entries.size());
643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(kTerribleName, entries.front().file_ref().GetName().AsString());
644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PASS();
647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string TestFileRef::TestReadDirectoryEntries() {
650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pp::FileSystem file_system(
652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Setup testing directories and files.
658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const char* test_dir_name = "/test_get_next_file";
659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const char* file_prefix = "file_";
660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const char* dir_prefix = "dir_";
661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pp::FileRef test_dir(file_system, test_dir_name);
663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int32_t rv = DeleteDirectoryRecursively(&test_dir);
664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(rv == PP_OK || rv == PP_ERROR_FILENOTFOUND);
665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.WaitForResult(test_dir.MakeDirectory(callback.GetCallback()));
667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const int kNumFiles = 3;
671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> expected_file_names;
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 1; i <= kNumFiles; ++i) {
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::ostringstream buffer;
674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    buffer << test_dir_name << '/' << file_prefix << i;
675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    pp::FileRef file_ref(file_system, buffer.str().c_str());
676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    pp::FileIO file_io(instance_);
678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback.WaitForResult(
679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK_CALLBACK_BEHAVIOR(callback);
681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(PP_OK, callback.result());
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    expected_file_names.insert(buffer.str());
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const int kNumDirectories = 3;
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> expected_dir_names;
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (int i = 1; i <= kNumDirectories; ++i) {
689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::ostringstream buffer;
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    buffer << test_dir_name << '/' << dir_prefix << i;
691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    pp::FileRef file_ref(file_system, buffer.str().c_str());
692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback.WaitForResult(file_ref.MakeDirectory(callback.GetCallback()));
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK_CALLBACK_BEHAVIOR(callback);
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(PP_OK, callback.result());
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    expected_dir_names.insert(buffer.str());
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test that |ReadDirectoryEntries()| is able to fetch all
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // directories and files that we created.
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TestCompletionCallbackWithOutput<DirEntries> output_callback(
704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        instance_->pp_instance(), callback_type());
705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    output_callback.WaitForResult(
707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        test_dir.ReadDirectoryEntries(output_callback.GetCallback()));
708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK_CALLBACK_BEHAVIOR(output_callback);
709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(PP_OK, output_callback.result());
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DirEntries entries = output_callback.output();
712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    size_t sum = expected_file_names.size() + expected_dir_names.size();
713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(sum, entries.size());
714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (DirEntries::const_iterator it = entries.begin();
716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         it != entries.end(); ++it) {
717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pp::FileRef file_ref = it->file_ref();
718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string file_path = file_ref.GetPath().AsString();
719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::set<std::string>::iterator found =
720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          expected_file_names.find(file_path);
721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (found != expected_file_names.end()) {
722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (it->file_type() != PP_FILETYPE_REGULAR)
723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          return file_path + " should have been a regular file.";
724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        expected_file_names.erase(found);
725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        found = expected_dir_names.find(file_path);
727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (found == expected_dir_names.end())
728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          return "Unexpected file path: " + file_path;
729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (it->file_type() != PP_FILETYPE_DIRECTORY)
730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          return file_path + " should have been a directory.";
731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        expected_dir_names.erase(found);
732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(expected_file_names.empty());
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(expected_dir_names.empty());
736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test cancellation of asynchronous |ReadDirectoryEntries()|.
739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallbackWithOutput<DirEntries> output_callback(
740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      instance_->pp_instance(), callback_type());
741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    rv = pp::FileRef(file_system, test_dir_name)
743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        .ReadDirectoryEntries(output_callback.GetCallback());
744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  output_callback.WaitForAbortResult(rv);
746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(output_callback);
747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PASS();
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
751