// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ppapi/tests/test_file_io.h"

#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <algorithm>
#include <vector>

#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_file_io.h"
#include "ppapi/c/private/pp_file_handle.h"
#include "ppapi/c/private/ppb_testing_private.h"
#include "ppapi/cpp/file_io.h"
#include "ppapi/cpp/file_ref.h"
#include "ppapi/cpp/file_system.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/private/file_io_private.h"
#include "ppapi/cpp/private/pass_file_handle.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"

#if defined(PPAPI_OS_WIN)
# include <io.h>
# include <windows.h>
// TODO(hamaji): Use standard windows APIs instead of compatibility layer?
# define lseek _lseek
# define read _read
# define write _write
# define ssize_t int
#else
# include <sys/mman.h>
# include <unistd.h>
#endif

REGISTER_TEST_CASE(FileIO);

namespace {

std::string ReportMismatch(const std::string& method_name,
                           const std::string& returned_result,
                           const std::string& expected_result) {
  return method_name + " returned '" + returned_result + "'; '" +
      expected_result + "' expected.";
}

std::string ReportOpenError(int32_t open_flags) {
  static const char* kFlagNames[] = {
    "PP_FILEOPENFLAG_READ",
    "PP_FILEOPENFLAG_WRITE",
    "PP_FILEOPENFLAG_CREATE",
    "PP_FILEOPENFLAG_TRUNCATE",
    "PP_FILEOPENFLAG_EXCLUSIVE"
  };

  std::string result = "FileIO:Open had unexpected behavior with flags: ";
  bool first_flag = true;
  for (int32_t mask = 1, index = 0; mask <= PP_FILEOPENFLAG_EXCLUSIVE;
       mask <<= 1, ++index) {
    if (mask & open_flags) {
      if (first_flag) {
        first_flag = false;
      } else {
        result += " | ";
      }
      result += kFlagNames[index];
    }
  }
  if (first_flag)
    result += "[None]";

  return result;
}

int32_t ReadEntireFile(PP_Instance instance,
                       pp::FileIO* file_io,
                       int32_t offset,
                       std::string* data,
                       CallbackType callback_type) {
  TestCompletionCallback callback(instance, callback_type);
  char buf[256];
  int32_t read_offset = offset;

  for (;;) {
    callback.WaitForResult(
        file_io->Read(read_offset, buf, sizeof(buf), callback.GetCallback()));
    if (callback.result() < 0)
      return callback.result();
    if (callback.result() == 0)
      break;
    read_offset += callback.result();
    data->append(buf, callback.result());
  }

  return PP_OK;
}

int32_t ReadToArrayEntireFile(PP_Instance instance,
                              pp::FileIO* file_io,
                              int32_t offset,
                              std::string* data,
                              CallbackType callback_type) {
  TestCompletionCallbackWithOutput< std::vector<char> > callback(
      instance, callback_type);

  for (;;) {
    callback.WaitForResult(file_io->Read(offset, 256, callback.GetCallback()));
    int32_t rv = callback.result();
    if (rv < 0)
      return rv;
    if (rv == 0)
      break;
    const std::vector<char>& output = callback.output();
    assert(rv == static_cast<int32_t>(output.size()));
    offset += rv;
    data->append(output.begin(), output.end());
  }

  return PP_OK;
}

#if !defined(PPAPI_OS_WIN)
bool ReadEntireFileFromFileHandle(int fd, std::string* data) {
  if (lseek(fd, 0, SEEK_SET) < 0)
    return false;
  data->clear();

  int ret;
  do {
    char buf[8192];
    ret = read(fd, buf, sizeof(buf));
    if (ret > 0)
      data->append(buf, ret);
  } while (ret > 0);
  return ret == 0;
}
#endif  // !defined(PPAPI_OS_WIN)

int32_t WriteEntireBuffer(PP_Instance instance,
                          pp::FileIO* file_io,
                          int32_t offset,
                          const std::string& data,
                          CallbackType callback_type) {
  TestCompletionCallback callback(instance, callback_type);
  int32_t write_offset = offset;
  const char* buf = data.c_str();
  int32_t size = static_cast<int32_t>(data.size());

  while (write_offset < offset + size) {
    callback.WaitForResult(file_io->Write(write_offset,
                                          &buf[write_offset - offset],
                                          size - write_offset + offset,
                                          callback.GetCallback()));
    if (callback.result() < 0)
      return callback.result();
    if (callback.result() == 0)
      return PP_ERROR_FAILED;
    write_offset += callback.result();
  }

  return PP_OK;
}

}  // namespace

bool TestFileIO::Init() {
  return CheckTestingInterface() && EnsureRunningOverHTTP();
}

void TestFileIO::RunTests(const std::string& filter) {
  RUN_CALLBACK_TEST(TestFileIO, Open, filter);
  RUN_CALLBACK_TEST(TestFileIO, OpenDirectory, filter);
  RUN_CALLBACK_TEST(TestFileIO, ReadWriteSetLength, filter);
  RUN_CALLBACK_TEST(TestFileIO, ReadToArrayWriteSetLength, filter);
  RUN_CALLBACK_TEST(TestFileIO, TouchQuery, filter);
  RUN_CALLBACK_TEST(TestFileIO, AbortCalls, filter);
  RUN_CALLBACK_TEST(TestFileIO, ParallelReads, filter);
  RUN_CALLBACK_TEST(TestFileIO, ParallelWrites, filter);
  RUN_CALLBACK_TEST(TestFileIO, NotAllowMixedReadWrite, filter);
  RUN_CALLBACK_TEST(TestFileIO, RequestOSFileHandle, filter);
  RUN_CALLBACK_TEST(TestFileIO, RequestOSFileHandleWithOpenExclusive, filter);
  RUN_CALLBACK_TEST(TestFileIO, Mmap, filter);

  // TODO(viettrungluu): add tests:
  //  - that PP_ERROR_PENDING is correctly returned
  //  - that operations respect the file open modes (flags)
}

std::string TestFileIO::TestOpen() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  pp::FileRef file_ref(file_system, "/file_open");

  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  std::string result;
  result = MatchOpenExpectations(
      &file_system,
      PP_FILEOPENFLAG_READ,
      DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS);
  if (!result.empty())
    return result;

  // Test the behavior of the power set of
  //   { PP_FILEOPENFLAG_CREATE,
  //     PP_FILEOPENFLAG_TRUNCATE,
  //     PP_FILEOPENFLAG_EXCLUSIVE }.

  // First of all, none of them are specified.
  result = MatchOpenExpectations(
      &file_system,
      PP_FILEOPENFLAG_WRITE,
      DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS);
  if (!result.empty())
    return result;

  result = MatchOpenExpectations(
      &file_system,
      PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE,
      CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS);
  if (!result.empty())
    return result;

  result = MatchOpenExpectations(
      &file_system,
      PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_EXCLUSIVE,
      DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS);
  if (!result.empty())
    return result;

  result = MatchOpenExpectations(
      &file_system,
      PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_TRUNCATE,
      DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | TRUNCATE_IF_EXISTS);
  if (!result.empty())
    return result;

  result = MatchOpenExpectations(
      &file_system,
      PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE |
      PP_FILEOPENFLAG_EXCLUSIVE,
      CREATE_IF_DOESNT_EXIST | DONT_OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS);
  if (!result.empty())
    return result;

  result = MatchOpenExpectations(
      &file_system,
      PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE | PP_FILEOPENFLAG_TRUNCATE,
      CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | TRUNCATE_IF_EXISTS);
  if (!result.empty())
    return result;

  result = MatchOpenExpectations(
      &file_system,
      PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_EXCLUSIVE |
      PP_FILEOPENFLAG_TRUNCATE,
      DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | TRUNCATE_IF_EXISTS);
  if (!result.empty())
    return result;

  result = MatchOpenExpectations(
      &file_system,
      PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE |
      PP_FILEOPENFLAG_EXCLUSIVE | PP_FILEOPENFLAG_TRUNCATE,
      CREATE_IF_DOESNT_EXIST | DONT_OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS);
  if (!result.empty())
    return result;

  // Invalid combination: PP_FILEOPENFLAG_TRUNCATE without
  // PP_FILEOPENFLAG_WRITE.
  result = MatchOpenExpectations(
      &file_system,
      PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_TRUNCATE,
      INVALID_FLAG_COMBINATION);
  if (!result.empty())
    return result;

  PASS();
}

std::string TestFileIO::TestOpenDirectory() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Make a directory.
  pp::FileRef dir_ref(file_system, "/test_dir_open_directory");
  callback.WaitForResult(dir_ref.MakeDirectory(
      PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Open the directory. This is expected to fail since directories cannot be
  // opened.
  pp::FileIO file_io(instance_);
  callback.WaitForResult(file_io.Open(dir_ref, PP_FILEOPENFLAG_READ,
                                      callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_ERROR_NOTAFILE, callback.result());

  PASS();
}

std::string TestFileIO::TestReadWriteSetLength() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  pp::FileRef file_ref(file_system, "/file_read_write_setlength");
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileIO file_io(instance_);
  callback.WaitForResult(file_io.Open(file_ref,
                                      PP_FILEOPENFLAG_CREATE |
                                      PP_FILEOPENFLAG_TRUNCATE |
                                      PP_FILEOPENFLAG_READ |
                                      PP_FILEOPENFLAG_WRITE,
                                      callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Write something to the file.
  int32_t rv = WriteEntireBuffer(instance_->pp_instance(), &file_io, 0,
                                 "test_test", callback_type());
  ASSERT_EQ(PP_OK, rv);

  // Attempt to read a negative number of bytes; it should fail.
  char buf[256];
  callback.WaitForResult(file_io.Read(0,
                                      buf,
                                      -1,
                                      callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_ERROR_FAILED, callback.result());

  // Read the entire file.
  std::string read_buffer;
  rv = ReadEntireFile(instance_->pp_instance(), &file_io, 0, &read_buffer,
                      callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_EQ(std::string("test_test"), read_buffer);

  // Truncate the file.
  callback.WaitForResult(file_io.SetLength(4, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Check the file contents.
  read_buffer.clear();
  rv = ReadEntireFile(instance_->pp_instance(), &file_io, 0, &read_buffer,
                      callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_EQ(std::string("test"), read_buffer);

  // Try to read past the end of the file.
  read_buffer.clear();
  rv = ReadEntireFile(instance_->pp_instance(), &file_io, 100, &read_buffer,
                      callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_TRUE(read_buffer.empty());

  // Write past the end of the file. The file should be zero-padded.
  rv = WriteEntireBuffer(instance_->pp_instance(), &file_io, 8, "test",
                         callback_type());
  ASSERT_EQ(PP_OK, rv);

  // Check the contents of the file.
  read_buffer.clear();
  rv = ReadEntireFile(instance_->pp_instance(), &file_io, 0, &read_buffer,
                      callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_EQ(std::string("test\0\0\0\0test", 12), read_buffer);

  // Extend the file.
  callback.WaitForResult(file_io.SetLength(16, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Check the contents of the file.
  read_buffer.clear();
  rv = ReadEntireFile(instance_->pp_instance(), &file_io, 0, &read_buffer,
                      callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_EQ(std::string("test\0\0\0\0test\0\0\0\0", 16), read_buffer);

  // Write in the middle of the file.
  rv = WriteEntireBuffer(instance_->pp_instance(), &file_io, 4, "test",
                         callback_type());
  ASSERT_EQ(PP_OK, rv);

  // Check the contents of the file.
  read_buffer.clear();
  rv = ReadEntireFile(instance_->pp_instance(), &file_io, 0, &read_buffer,
                      callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_EQ(std::string("testtesttest\0\0\0\0", 16), read_buffer);

  // Read from the middle of the file.
  read_buffer.clear();
  rv = ReadEntireFile(instance_->pp_instance(), &file_io, 4, &read_buffer,
                      callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_EQ(std::string("testtest\0\0\0\0", 12), read_buffer);

  // Append to the end of the file.
  pp::FileIO file_io2(instance_);
  callback.WaitForResult(file_io2.Open(file_ref,
                                       PP_FILEOPENFLAG_CREATE |
                                       PP_FILEOPENFLAG_READ |
                                       PP_FILEOPENFLAG_APPEND,
                                       callback.GetCallback()));
  rv = WriteEntireBuffer(instance_->pp_instance(), &file_io2, 0, "appended",
                         callback_type());
  ASSERT_EQ(PP_OK, rv);
  read_buffer.clear();
  rv = ReadEntireFile(instance_->pp_instance(), &file_io2, 0, &read_buffer,
                      callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_EQ(std::string("testtesttest\0\0\0\0appended", 24), read_buffer);

  PASS();
}

// This is basically a copy of TestReadWriteSetLength, but with the new Read
// API.  With this test case, we can make sure the two Read's have the same
// behavior.
std::string TestFileIO::TestReadToArrayWriteSetLength() {
  if (callback_type() == PP_BLOCKING) {
    // This test does not make sense for blocking callbacks.
    PASS();
  }
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  pp::FileRef file_ref(file_system, "/file_read_write_setlength");
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileIO file_io(instance_);
  callback.WaitForResult(file_io.Open(file_ref,
                                      PP_FILEOPENFLAG_CREATE |
                                      PP_FILEOPENFLAG_TRUNCATE |
                                      PP_FILEOPENFLAG_READ |
                                      PP_FILEOPENFLAG_WRITE,
                                      callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Write something to the file.
  int32_t rv = WriteEntireBuffer(instance_->pp_instance(), &file_io, 0,
                                 "test_test", callback_type());
  ASSERT_EQ(PP_OK, rv);

  TestCompletionCallbackWithOutput< std::vector<char> > callback2(
      instance_->pp_instance(), callback_type());
  // Attempt to read a negative number of bytes; it should fail.
  callback2.WaitForResult(file_io.Read(0, -1, callback2.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback2);
  ASSERT_EQ(PP_ERROR_FAILED, callback2.result());

  // Read the entire file.
  std::string read_buffer;
  read_buffer.reserve(10);
  rv = ReadToArrayEntireFile(instance_->pp_instance(), &file_io, 0,
                             &read_buffer, callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_EQ(std::string("test_test"), read_buffer);

  // Truncate the file.
  callback.WaitForResult(file_io.SetLength(4, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, rv);

  // Check the file contents.
  read_buffer.clear();
  rv = ReadToArrayEntireFile(instance_->pp_instance(), &file_io, 0,
                             &read_buffer, callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_EQ(std::string("test"), read_buffer);

  // Try to read past the end of the file.
  read_buffer.clear();
  rv = ReadToArrayEntireFile(instance_->pp_instance(), &file_io, 100,
                             &read_buffer, callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_TRUE(read_buffer.empty());

  // Write past the end of the file. The file should be zero-padded.
  rv = WriteEntireBuffer(instance_->pp_instance(), &file_io, 8, "test",
                         callback_type());
  ASSERT_EQ(PP_OK, rv);

  // Check the contents of the file.
  read_buffer.clear();
  rv = ReadToArrayEntireFile(instance_->pp_instance(), &file_io, 0,
                             &read_buffer, callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_EQ(std::string("test\0\0\0\0test", 12), read_buffer);

  // Extend the file.
  callback.WaitForResult(file_io.SetLength(16, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Check the contents of the file.
  read_buffer.clear();
  rv = ReadToArrayEntireFile(instance_->pp_instance(), &file_io, 0,
                             &read_buffer, callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_EQ(std::string("test\0\0\0\0test\0\0\0\0", 16), read_buffer);

  // Write in the middle of the file.
  rv = WriteEntireBuffer(instance_->pp_instance(), &file_io, 4, "test",
                         callback_type());
  ASSERT_EQ(PP_OK, rv);

  // Check the contents of the file.
  read_buffer.clear();
  rv = ReadToArrayEntireFile(instance_->pp_instance(), &file_io, 0,
                             &read_buffer, callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_EQ(std::string("testtesttest\0\0\0\0", 16), read_buffer);

  // Read from the middle of the file.
  read_buffer.clear();
  rv = ReadToArrayEntireFile(instance_->pp_instance(), &file_io, 4,
                             &read_buffer, callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_EQ(std::string("testtest\0\0\0\0", 12), read_buffer);

  PASS();
}

std::string TestFileIO::TestTouchQuery() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileRef file_ref(file_system, "/file_touch");
  pp::FileIO file_io(instance_);
  callback.WaitForResult(file_io.Open(file_ref,
                                      PP_FILEOPENFLAG_CREATE |
                                      PP_FILEOPENFLAG_TRUNCATE |
                                      PP_FILEOPENFLAG_WRITE,
                                      callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Write some data to have a non-zero file size.
  callback.WaitForResult(file_io.Write(0, "test", 4, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(4, callback.result());

  const PP_Time last_access_time = 123 * 24 * 3600.0;
  // last_modified_time's granularity is 2 seconds
  // NOTE: In NaCl on Windows, NaClDescIO uses _fstat64 to retrieve file info.
  // This function returns strange values for very small time values (near the
  // Unix Epoch). For a value like 246.0, it returns -1. For larger values, it
  // returns values that are exactly an hour less. The value below is handled
  // correctly, and is only 100 days after the start of Unix time.
  const PP_Time last_modified_time = 100 * 24 * 3600.0;
  callback.WaitForResult(file_io.Touch(last_access_time, last_modified_time,
                                       callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  PP_FileInfo info;
  callback.WaitForResult(file_io.Query(&info, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  if ((info.size != 4) ||
      (info.type != PP_FILETYPE_REGULAR) ||
      (info.system_type != PP_FILESYSTEMTYPE_LOCALTEMPORARY))
      // Disabled due to DST-related failure: crbug.com/314579
      //(info.last_access_time != last_access_time) ||
      //(info.last_modified_time != last_modified_time))
    return "FileIO::Query() has returned bad data.";

  // Call |Query()| again, to make sure it works a second time.
  callback.WaitForResult(file_io.Query(&info, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  PASS();
}

std::string TestFileIO::TestAbortCalls() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  pp::FileRef file_ref(file_system, "/file_abort_calls");
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  int32_t rv = PP_ERROR_FAILED;
  // First, create a file on which to do ops.
  {
    pp::FileIO file_io(instance_);
    callback.WaitForResult(
        file_io.Open(file_ref,
                     PP_FILEOPENFLAG_CREATE | PP_FILEOPENFLAG_WRITE,
                     callback.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(callback);
    ASSERT_EQ(PP_OK, callback.result());

    // N.B.: Should write at least 3 bytes.
    rv = WriteEntireBuffer(instance_->pp_instance(), &file_io, 0,
                           "foobarbazquux", callback_type());
    ASSERT_EQ(PP_OK, rv);
  }

  // Abort |Open()|.
  {
    rv = pp::FileIO(instance_)
        .Open(file_ref, PP_FILEOPENFLAG_READ, callback.GetCallback());
  }
  callback.WaitForAbortResult(rv);
  CHECK_CALLBACK_BEHAVIOR(callback);

  // Abort |Query()|.
  {
    PP_FileInfo info = { 0 };
    // Save a copy and make sure |info| doesn't get written to if it is aborted.
    PP_FileInfo info_copy;
    memcpy(&info_copy, &info, sizeof(info));
    {
      pp::FileIO file_io(instance_);
      callback.WaitForResult(file_io.Open(file_ref, PP_FILEOPENFLAG_READ,
                                          callback.GetCallback()));
      CHECK_CALLBACK_BEHAVIOR(callback);
      ASSERT_EQ(PP_OK, callback.result());

      rv = file_io.Query(&info, callback.GetCallback());
    }  // Destroy |file_io|.
    callback.WaitForResult(rv);
    CHECK_CALLBACK_BEHAVIOR(callback);
    if (callback_type() == PP_BLOCKING) {
      ASSERT_EQ(PP_OK, callback.result());
      // The operation completed synchronously, so |info| should have changed.
      ASSERT_NE(0, memcmp(&info_copy, &info, sizeof(info)));
    } else {
      ASSERT_EQ(PP_ERROR_ABORTED, callback.result());
      ASSERT_EQ(0, memcmp(&info_copy, &info, sizeof(info)));
    }
  }

  // Abort |Touch()|.
  {
    {
      pp::FileIO file_io(instance_);
      callback.WaitForResult(file_io.Open(file_ref, PP_FILEOPENFLAG_WRITE,
                                          callback.GetCallback()));
      CHECK_CALLBACK_BEHAVIOR(callback);
      ASSERT_EQ(PP_OK, callback.result());

      rv = file_io.Touch(0, 0, callback.GetCallback());
    }  // Destroy |file_io|.
    callback.WaitForAbortResult(rv);
    CHECK_CALLBACK_BEHAVIOR(callback);
  }

  // Abort |Read()|.
  {
    char buf[3] = { 0 };
    {
      pp::FileIO file_io(instance_);
      callback.WaitForResult(file_io.Open(file_ref, PP_FILEOPENFLAG_READ,
                                          callback.GetCallback()));
      CHECK_CALLBACK_BEHAVIOR(callback);
      ASSERT_EQ(PP_OK, callback.result());

      rv = file_io.Read(0, buf, sizeof(buf), callback.GetCallback());
    }  // Destroy |file_io|.
    // Save a copy to make sure buf isn't written to in the async case.
    char buf_copy[3];
    memcpy(&buf_copy, &buf, sizeof(buf));
    callback.WaitForResult(rv);
    CHECK_CALLBACK_BEHAVIOR(callback);
    if (callback_type() == PP_BLOCKING) {
      ASSERT_EQ(callback.result(), sizeof(buf));
    } else {
      ASSERT_EQ(PP_ERROR_ABORTED, callback.result());
      ASSERT_EQ(0, memcmp(&buf_copy, &buf, sizeof(buf)));
    }
  }

  // Abort |Write()|.
  {
    char buf[3] = { 0 };
    {
      pp::FileIO file_io(instance_);
      callback.WaitForResult(file_io.Open(file_ref, PP_FILEOPENFLAG_WRITE,
                                          callback.GetCallback()));
      CHECK_CALLBACK_BEHAVIOR(callback);
      ASSERT_EQ(PP_OK, callback.result());

      rv = file_io.Write(0, buf, sizeof(buf), callback.GetCallback());
    }  // Destroy |file_io|.
    callback.WaitForResult(rv);
    CHECK_CALLBACK_BEHAVIOR(callback);
    if (callback_type() == PP_BLOCKING)
      ASSERT_EQ(callback.result(), sizeof(buf));
    else
      ASSERT_EQ(PP_ERROR_ABORTED, callback.result());
  }

  // Abort |SetLength()|.
  {
    {
      pp::FileIO file_io(instance_);
      callback.WaitForResult(file_io.Open(file_ref, PP_FILEOPENFLAG_WRITE,
                                          callback.GetCallback()));
      CHECK_CALLBACK_BEHAVIOR(callback);
      ASSERT_EQ(PP_OK, callback.result());

      rv = file_io.SetLength(3, callback.GetCallback());
    }  // Destroy |file_io|.
    callback.WaitForAbortResult(rv);
    CHECK_CALLBACK_BEHAVIOR(callback);
  }

  // Abort |Flush|.
  {
    {
      pp::FileIO file_io(instance_);
      callback.WaitForResult(file_io.Open(file_ref, PP_FILEOPENFLAG_WRITE,
                                          callback.GetCallback()));
      CHECK_CALLBACK_BEHAVIOR(callback);
      ASSERT_EQ(PP_OK, callback.result());

      rv = file_io.Flush(callback.GetCallback());
    }  // Destroy |file_io|.
    callback.WaitForAbortResult(rv);
    CHECK_CALLBACK_BEHAVIOR(callback);
  }

  PASS();
}

std::string TestFileIO::TestParallelReads() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  pp::FileRef file_ref(file_system, "/file_parallel_reads");
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileIO file_io(instance_);
  callback.WaitForResult(file_io.Open(file_ref,
                                      PP_FILEOPENFLAG_CREATE |
                                      PP_FILEOPENFLAG_TRUNCATE |
                                      PP_FILEOPENFLAG_READ |
                                      PP_FILEOPENFLAG_WRITE,
                                      callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Set up testing contents.
  int32_t rv = WriteEntireBuffer(instance_->pp_instance(), &file_io, 0,
                                 "abcdefghijkl", callback_type());
  ASSERT_EQ(PP_OK, rv);

  // Parallel read operations.
  const char* border = "__border__";
  const int32_t border_size = static_cast<int32_t>(strlen(border));

  TestCompletionCallback callback_1(instance_->pp_instance(), callback_type());
  int32_t read_offset_1 = 0;
  int32_t size_1 = 3;
  std::vector<char> extended_buf_1(border_size * 2 + size_1);
  char* buf_1 = &extended_buf_1[border_size];
  memcpy(&extended_buf_1[0], border, border_size);
  memcpy(buf_1 + size_1, border, border_size);

  TestCompletionCallback callback_2(instance_->pp_instance(), callback_type());
  int32_t read_offset_2 = size_1;
  int32_t size_2 = 9;
  std::vector<char> extended_buf_2(border_size * 2 + size_2);
  char* buf_2 = &extended_buf_2[border_size];
  memcpy(&extended_buf_2[0], border, border_size);
  memcpy(buf_2 + size_2, border, border_size);

  int32_t rv_1 = PP_OK;
  int32_t rv_2 = PP_OK;
  while (size_1 >= 0 && size_2 >= 0 && size_1 + size_2 > 0) {
    if (size_1 > 0) {
      rv_1 = file_io.Read(read_offset_1, buf_1, size_1,
                          callback_1.GetCallback());
    }
    if (size_2 > 0) {
      rv_2 = file_io.Read(read_offset_2, buf_2, size_2,
                          callback_2.GetCallback());
    }
    if (size_1 > 0) {
      callback_1.WaitForResult(rv_1);
      CHECK_CALLBACK_BEHAVIOR(callback_1);
      ASSERT_TRUE(callback_1.result() > 0);
      read_offset_1 += callback_1.result();
      buf_1 += callback_1.result();
      size_1 -= callback_1.result();
    }

    if (size_2 > 0) {
      callback_2.WaitForResult(rv_2);
      CHECK_CALLBACK_BEHAVIOR(callback_2);
      ASSERT_TRUE(callback_2.result() > 0);
      read_offset_2 += callback_2.result();
      buf_2 += callback_2.result();
      size_2 -= callback_2.result();
    }
  }

  // If |size_1| or |size_2| is not 0, we have invoked wrong callback(s).
  ASSERT_EQ(0, size_1);
  ASSERT_EQ(0, size_2);

  // Make sure every read operation writes into the correct buffer.
  const char expected_result_1[] = "__border__abc__border__";
  const char expected_result_2[] = "__border__defghijkl__border__";
  ASSERT_TRUE(strncmp(&extended_buf_1[0], expected_result_1,
                      strlen(expected_result_1)) == 0);
  ASSERT_TRUE(strncmp(&extended_buf_2[0], expected_result_2,
                      strlen(expected_result_2)) == 0);
  PASS();
}

std::string TestFileIO::TestParallelWrites() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  pp::FileRef file_ref(file_system, "/file_parallel_writes");
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileIO file_io(instance_);
  callback.WaitForResult(file_io.Open(file_ref,
                                      PP_FILEOPENFLAG_CREATE |
                                      PP_FILEOPENFLAG_TRUNCATE |
                                      PP_FILEOPENFLAG_READ |
                                      PP_FILEOPENFLAG_WRITE,
                                      callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Parallel write operations.
  TestCompletionCallback callback_1(instance_->pp_instance(), callback_type());
  int32_t write_offset_1 = 0;
  const char* buf_1 = "abc";
  int32_t size_1 = static_cast<int32_t>(strlen(buf_1));

  TestCompletionCallback callback_2(instance_->pp_instance(), callback_type());
  int32_t write_offset_2 = size_1;
  const char* buf_2 = "defghijkl";
  int32_t size_2 = static_cast<int32_t>(strlen(buf_2));

  int32_t rv_1 = PP_OK;
  int32_t rv_2 = PP_OK;
  while (size_1 >= 0 && size_2 >= 0 && size_1 + size_2 > 0) {
    if (size_1 > 0) {
      // Copy the buffer so we can erase it below.
      std::string str_1(buf_1);
      rv_1 = file_io.Write(
          write_offset_1, &str_1[0], static_cast<int32_t>(str_1.size()),
          callback_1.GetCallback());
      // Erase the buffer to test that async writes copy it.
      std::fill(str_1.begin(), str_1.end(), 0);
    }
    if (size_2 > 0) {
      // Copy the buffer so we can erase it below.
      std::string str_2(buf_2);
      rv_2 = file_io.Write(
          write_offset_2, &str_2[0], static_cast<int32_t>(str_2.size()),
          callback_2.GetCallback());
      // Erase the buffer to test that async writes copy it.
      std::fill(str_2.begin(), str_2.end(), 0);
    }

    if (size_1 > 0) {
      callback_1.WaitForResult(rv_1);
      CHECK_CALLBACK_BEHAVIOR(callback_1);
      ASSERT_TRUE(callback_1.result() > 0);
      write_offset_1 += callback_1.result();
      buf_1 += callback_1.result();
      size_1 -= callback_1.result();
    }

    if (size_2 > 0) {
      callback_2.WaitForResult(rv_2);
      CHECK_CALLBACK_BEHAVIOR(callback_2);
      ASSERT_TRUE(callback_2.result() > 0);
      write_offset_2 += callback_2.result();
      buf_2 += callback_2.result();
      size_2 -= callback_2.result();
    }
  }

  // If |size_1| or |size_2| is not 0, we have invoked wrong callback(s).
  ASSERT_EQ(0, size_1);
  ASSERT_EQ(0, size_2);

  // Check the file contents.
  std::string read_buffer;
  int32_t rv = ReadEntireFile(instance_->pp_instance(), &file_io, 0,
                              &read_buffer, callback_type());
  ASSERT_EQ(PP_OK, rv);
  ASSERT_EQ(std::string("abcdefghijkl"), read_buffer);

  PASS();
}

std::string TestFileIO::TestNotAllowMixedReadWrite() {
  if (callback_type() == PP_BLOCKING) {
    // This test does not make sense for blocking callbacks.
    PASS();
  }
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  pp::FileRef file_ref(file_system, "/file_not_allow_mixed_read_write");
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileIO file_io(instance_);
  callback.WaitForResult(file_io.Open(file_ref,
                                      PP_FILEOPENFLAG_CREATE |
                                      PP_FILEOPENFLAG_TRUNCATE |
                                      PP_FILEOPENFLAG_READ |
                                      PP_FILEOPENFLAG_WRITE,
                                      callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  TestCompletionCallback callback_1(instance_->pp_instance(), PP_REQUIRED);
  int32_t write_offset_1 = 0;
  const char* buf_1 = "mnopqrstuvw";
  int32_t rv_1 = file_io.Write(write_offset_1, buf_1,
                               static_cast<int32_t>(strlen(buf_1)),
                               callback_1.GetCallback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, rv_1);

  TestCompletionCallback callback_2(instance_->pp_instance(), callback_type());
  int32_t read_offset_2 = 4;
  char buf_2[3];
  callback_2.WaitForResult(file_io.Read(read_offset_2, buf_2, sizeof(buf_2),
                                        callback_2.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback_2);
  ASSERT_EQ(PP_ERROR_INPROGRESS, callback_2.result());
  callback_1.WaitForResult(rv_1);
  CHECK_CALLBACK_BEHAVIOR(callback_1);

  // Cannot query while a write is pending.
  rv_1 = file_io.Write(write_offset_1, buf_1,
                       static_cast<int32_t>(strlen(buf_1)),
                       callback_1.GetCallback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, rv_1);
  PP_FileInfo info;
  callback_2.WaitForResult(file_io.Query(&info, callback_2.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback_2);
  ASSERT_EQ(PP_ERROR_INPROGRESS, callback_2.result());
  callback_1.WaitForResult(rv_1);
  CHECK_CALLBACK_BEHAVIOR(callback_1);

  // Cannot touch while a write is pending.
  rv_1 = file_io.Write(write_offset_1, buf_1,
                       static_cast<int32_t>(strlen(buf_1)),
                       callback_1.GetCallback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, rv_1);
  callback_2.WaitForResult(file_io.Touch(1234.0, 5678.0,
                           callback_2.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback_2);
  ASSERT_EQ(PP_ERROR_INPROGRESS, callback_2.result());
  callback_1.WaitForResult(rv_1);
  CHECK_CALLBACK_BEHAVIOR(callback_1);

  // Cannot set length while a write is pending.
  rv_1 = file_io.Write(write_offset_1, buf_1,
                       static_cast<int32_t>(strlen(buf_1)),
                       callback_1.GetCallback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, rv_1);
  callback_2.WaitForResult(file_io.SetLength(123, callback_2.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback_2);
  ASSERT_EQ(PP_ERROR_INPROGRESS, callback_2.result());
  callback_1.WaitForResult(rv_1);
  CHECK_CALLBACK_BEHAVIOR(callback_1);

  PASS();
}

std::string TestFileIO::TestRequestOSFileHandle() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  pp::FileRef file_ref(file_system, "/file_os_fd");

  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileIO_Private file_io(instance_);
  callback.WaitForResult(file_io.Open(file_ref,
                                      PP_FILEOPENFLAG_CREATE |
                                      PP_FILEOPENFLAG_TRUNCATE |
                                      PP_FILEOPENFLAG_READ |
                                      PP_FILEOPENFLAG_WRITE,
                                      callback.GetCallback()));
  ASSERT_EQ(PP_OK, callback.result());

  TestCompletionCallbackWithOutput<pp::PassFileHandle> output_callback(
      instance_->pp_instance(), callback_type());
  output_callback.WaitForResult(
      file_io.RequestOSFileHandle(output_callback.GetCallback()));
  PP_FileHandle handle = output_callback.output().Release();
  ASSERT_EQ(PP_OK, output_callback.result());

  if (handle == PP_kInvalidFileHandle)
    return "FileIO::RequestOSFileHandle() returned a bad file handle.";
#if defined(PPAPI_OS_WIN)
  int fd = _open_osfhandle(reinterpret_cast<intptr_t>(handle),
                           _O_RDWR | _O_BINARY);
#else
  int fd = handle;
#endif
  if (fd < 0)
    return "FileIO::RequestOSFileHandle() returned a bad file descriptor.";

  // Check write(2) for the native FD.
  const std::string msg = "foobar";
  ssize_t cnt = write(fd, msg.data(), static_cast<unsigned>(msg.size()));
  if (cnt < 0)
    return ReportError("write for native FD returned error", errno);
  if (cnt != static_cast<ssize_t>(msg.size()))
    return ReportError("write for native FD count mismatch", cnt);

  // Check lseek(2) for the native FD.
  off_t off = lseek(fd, 0, SEEK_CUR);
  if (off == static_cast<off_t>(-1))
    return ReportError("lseek for native FD returned error", errno);
  if (off != static_cast<off_t>(msg.size()))
    return ReportError("lseek for native FD offset mismatch", off);

  off = lseek(fd, 0, SEEK_SET);
  if (off == static_cast<off_t>(-1))
    return ReportError("lseek for native FD returned error", errno);
  if (off != 0)
    return ReportError("lseek for native FD offset mismatch", off);

  // Check read(2) for the native FD.
  std::string buf(msg.size(), '\0');
  cnt = read(fd, &buf[0], static_cast<unsigned>(msg.size()));
  if (cnt < 0)
    return ReportError("read for native FD returned error", errno);
  if (cnt != static_cast<ssize_t>(msg.size()))
    return ReportError("read for native FD count mismatch", cnt);
  if (msg != buf)
    return ReportMismatch("read for native FD", buf, msg);
  PASS();
}

// Calling RequestOSFileHandle with the FileIO that is opened with
// PP_FILEOPENFLAG_EXCLUSIVE used to cause NaCl module to crash while loading.
// This is a regression test for crbug.com/243241.
std::string TestFileIO::TestRequestOSFileHandleWithOpenExclusive() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  pp::FileRef file_ref(file_system, "/file_os_fd2");

  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  ASSERT_EQ(PP_OK, callback.result());

  // Open with PP_FILEOPENFLAG_CREATE and PP_FILEOPENFLAG_EXCLUSIVE will fail
  // if the file already exists. Delete it here to make sure it does not.
  callback.WaitForResult(file_ref.Delete(callback.GetCallback()));

  pp::FileIO_Private file_io(instance_);
  callback.WaitForResult(file_io.Open(file_ref,
                                      PP_FILEOPENFLAG_CREATE |
                                      PP_FILEOPENFLAG_READ |
                                      PP_FILEOPENFLAG_WRITE |
                                      PP_FILEOPENFLAG_EXCLUSIVE,
                                      callback.GetCallback()));
  ASSERT_EQ(PP_OK, callback.result());

  TestCompletionCallbackWithOutput<pp::PassFileHandle> output_callback(
      instance_->pp_instance(), callback_type());
  output_callback.WaitForResult(
      file_io.RequestOSFileHandle(output_callback.GetCallback()));
  PP_FileHandle handle = output_callback.output().Release();
  if (handle == PP_kInvalidFileHandle)
    return "FileIO::RequestOSFileHandle() returned a bad file handle.";
  ASSERT_EQ(PP_OK, output_callback.result());

  PASS();
}

std::string TestFileIO::TestMmap() {
#if !defined(PPAPI_OS_WIN)
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  pp::FileRef file_ref(file_system, "/file_os_fd");

  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileIO_Private file_io(instance_);
  callback.WaitForResult(file_io.Open(file_ref,
                                      PP_FILEOPENFLAG_CREATE |
                                      PP_FILEOPENFLAG_TRUNCATE |
                                      PP_FILEOPENFLAG_READ |
                                      PP_FILEOPENFLAG_WRITE,
                                      callback.GetCallback()));
  ASSERT_EQ(PP_OK, callback.result());

  TestCompletionCallbackWithOutput<pp::PassFileHandle> output_callback(
      instance_->pp_instance(), callback_type());
  output_callback.WaitForResult(
      file_io.RequestOSFileHandle(output_callback.GetCallback()));
  PP_FileHandle handle = output_callback.output().Release();
  ASSERT_EQ(PP_OK, output_callback.result());

  if (handle == PP_kInvalidFileHandle)
    return "FileIO::RequestOSFileHandle() returned a bad file handle.";
  int fd = handle;
  if (fd < 0)
    return "FileIO::RequestOSFileHandle() returned a bad file descriptor.";

  // Check write(2) for the native FD.
  const std::string msg = "foobar";
  ssize_t cnt = write(fd, msg.data(), msg.size());
  if (cnt < 0)
    return ReportError("write for native FD returned error", errno);
  if (cnt != static_cast<ssize_t>(msg.size()))
    return ReportError("write for native FD count mismatch", cnt);

  // BEGIN mmap(2) test with a file handle opened in READ-WRITE mode.
  // Check mmap(2) for read.
  {
    char* mapped = reinterpret_cast<char*>(
        mmap(NULL, msg.size(), PROT_READ, MAP_PRIVATE, fd, 0));
    if (mapped == MAP_FAILED)
      return ReportError("mmap(r) for native FD returned errno", errno);
    // Make sure the buffer is cleared.
    std::string buf = std::string(msg.size(), '\0');
    memcpy(&buf[0], mapped, msg.size());
    if (msg != buf)
      return ReportMismatch("mmap(r) for native FD", buf, msg);
    int r = munmap(mapped, msg.size());
    if (r < 0)
      return ReportError("munmap for native FD returned error", errno);
  }

  // Check mmap(2) for write with MAP_PRIVATE
  {
    char* mapped = reinterpret_cast<char*>(
        mmap(NULL, msg.size(), PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0));
    if (mapped == MAP_FAILED)
      return ReportError("mmap(r) for native FD returned errno", errno);
    // Make sure the file is not polluted by writing to privage mmap.
    strncpy(mapped, "baz", 3);
    std::string read_buffer;
    ASSERT_TRUE(ReadEntireFileFromFileHandle(fd, &read_buffer));
    if (msg != read_buffer)
      return ReportMismatch("file content != msg", read_buffer, msg);
    int r = munmap(mapped, msg.size());
    if (r < 0)
      return ReportError("munmap for native FD returned error", errno);
  }

  // Check mmap(2) for write with MAP_SHARED.
  {
    char* mapped = reinterpret_cast<char*>(
        mmap(NULL, msg.size(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
    if (mapped == MAP_FAILED)
      return ReportError("mmap(w) for native FD returned errno", errno);
    // s/foo/baz/
    strncpy(mapped, "baz", 3);
    std::string read_buffer;
    ASSERT_TRUE(ReadEntireFileFromFileHandle(fd, &read_buffer));
    if (read_buffer != "bazbar")
      return ReportMismatch("file content != msg", read_buffer, "bazbar");
    int r = munmap(mapped, msg.size());
    if (r < 0)
      return ReportError("munmap for native FD returned error", errno);
  }
  // END mmap(2) test with a file handle opened in READ-WRITE mode.

  if (close(fd) < 0)
    return ReportError("close for native FD returned error", errno);

  // BEGIN mmap(2) test with a file handle opened in READONLY mode.
  file_io = pp::FileIO_Private(instance_);
  callback.WaitForResult(file_io.Open(file_ref,
                                      PP_FILEOPENFLAG_READ,
                                      callback.GetCallback()));
  ASSERT_EQ(PP_OK, callback.result());

  output_callback = TestCompletionCallbackWithOutput<pp::PassFileHandle>(
      instance_->pp_instance(), callback_type());
  output_callback.WaitForResult(
      file_io.RequestOSFileHandle(output_callback.GetCallback()));
  handle = output_callback.output().Release();
  ASSERT_EQ(PP_OK, output_callback.result());

  if (handle == PP_kInvalidFileHandle)
    return "FileIO::RequestOSFileHandle() returned a bad file handle.";
  fd = handle;
  if (fd < 0)
    return "FileIO::RequestOSFileHandle() returned a bad file descriptor.";

  const std::string msg2 = "bazbar";

  // Check mmap(2) for read.
  {
    char* mapped = reinterpret_cast<char*>(
        mmap(NULL, msg2.size(), PROT_READ, MAP_PRIVATE, fd, 0));
    if (mapped == MAP_FAILED)
      return ReportError("mmap(r) for native FD returned errno", errno);
    // Make sure the buffer is cleared.
    std::string buf = std::string(msg2.size(), '\0');
    memcpy(&buf[0], mapped, msg2.size());
    if (msg2 != buf)
      return ReportMismatch("mmap(r) for native FD", buf, msg2);
    int r = munmap(mapped, msg2.size());
    if (r < 0)
      return ReportError("munmap for native FD returned error", errno);
  }

  // Check mmap(2) for write with MAP_PRIVATE
  {
    char* mapped = reinterpret_cast<char*>(
        mmap(NULL, msg2.size(), PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0));
    if (mapped == MAP_FAILED)
      return ReportError("mmap(r) for native FD returned errno", errno);
    // Make sure the file is not polluted by writing to privage mmap.
    strncpy(mapped, "baz", 3);
    std::string read_buffer;
    ASSERT_TRUE(ReadEntireFileFromFileHandle(fd, &read_buffer));
    if (msg2 != read_buffer)
      return ReportMismatch("file content != msg2", read_buffer, msg2);
    int r = munmap(mapped, msg2.size());
    if (r < 0)
      return ReportError("munmap for native FD returned error", errno);
  }

  // Check mmap(2) for write with MAP_SHARED.
  {
    char* mapped = reinterpret_cast<char*>(
        mmap(NULL, msg2.size(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
    if (mapped != MAP_FAILED)
      return ReportError("mmap(w) for native FD must fail when opened readonly",
                         -1);
  }
  // END mmap(2) test with a file handle opened in READONLY mode.

  if (close(fd) < 0)
    return ReportError("close for native FD returned error", errno);
#endif  // !defined(PPAPI_OS_WIN)

  PASS();
}

std::string TestFileIO::MatchOpenExpectations(pp::FileSystem* file_system,
                                              int32_t open_flags,
                                              int32_t expectations) {
  std::string bad_argument =
      "TestFileIO::MatchOpenExpectations has invalid input arguments.";
  bool invalid_combination = !!(expectations & INVALID_FLAG_COMBINATION);
  if (invalid_combination) {
    if (expectations != INVALID_FLAG_COMBINATION)
      return bad_argument;
  } else {
    // Validate that one and only one of <some_expectation> and
    // DONT_<some_expectation> is specified.
    for (size_t remains = expectations, end = END_OF_OPEN_EXPECATION_PAIRS;
         end != 0; remains >>= 2, end >>= 2) {
      if (!!(remains & 1) == !!(remains & 2))
        return bad_argument;
    }
  }
  bool create_if_doesnt_exist = !!(expectations & CREATE_IF_DOESNT_EXIST);
  bool open_if_exists = !!(expectations & OPEN_IF_EXISTS);
  bool truncate_if_exists = !!(expectations & TRUNCATE_IF_EXISTS);

  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  pp::FileRef existent_file_ref(
      *file_system, "/match_open_expectation_existent_non_empty_file");
  pp::FileRef nonexistent_file_ref(
      *file_system, "/match_open_expectation_nonexistent_file");

  // Setup files for test.
  {
    callback.WaitForResult(existent_file_ref.Delete(callback.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(callback);
    ASSERT_TRUE(callback.result() == PP_OK ||
                callback.result() == PP_ERROR_FILENOTFOUND);
    callback.WaitForResult(nonexistent_file_ref.Delete(callback.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(callback);
    ASSERT_TRUE(callback.result() == PP_OK ||
                callback.result() == PP_ERROR_FILENOTFOUND);

    pp::FileIO existent_file_io(instance_);
    callback.WaitForResult(existent_file_io.Open(
        existent_file_ref,
        PP_FILEOPENFLAG_CREATE | PP_FILEOPENFLAG_WRITE,
        callback.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(callback);
    ASSERT_EQ(PP_OK, callback.result());
    int32_t rv = WriteEntireBuffer(instance_->pp_instance(), &existent_file_io,
                                   0, "foobar", callback_type());
    ASSERT_EQ(PP_OK, rv);
  }

  pp::FileIO existent_file_io(instance_);
  callback.WaitForResult(existent_file_io.Open(existent_file_ref, open_flags,
                                               callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  if ((invalid_combination && callback.result() == PP_OK) ||
      (!invalid_combination &&
       ((callback.result() == PP_OK) != open_if_exists))) {
    return ReportOpenError(open_flags);
  }

  if (!invalid_combination && open_if_exists) {
    PP_FileInfo info;
    callback.WaitForResult(existent_file_io.Query(&info,
                                                  callback.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(callback);
    ASSERT_EQ(PP_OK, callback.result());
    if (truncate_if_exists != (info.size == 0))
      return ReportOpenError(open_flags);
  }

  pp::FileIO nonexistent_file_io(instance_);
  callback.WaitForResult(nonexistent_file_io.Open(nonexistent_file_ref,
                                                  open_flags,
                                                  callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  if ((invalid_combination && callback.result() == PP_OK) ||
      (!invalid_combination &&
       ((callback.result() == PP_OK) != create_if_doesnt_exist))) {
    return ReportOpenError(open_flags);
  }

  return std::string();
}

// TODO(viettrungluu): Test Close(). crbug.com/69457
