1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <fcntl.h>
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <gmock/gmock.h>
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <ppapi/c/ppb_file_io.h>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <ppapi/c/pp_errors.h>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <ppapi/c/pp_instance.h>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <sys/stat.h>
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <sys/types.h>
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "mock_util.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/kernel_intercept.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_http.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_node_dir.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/osdirent.h"
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/osunistd.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "pepper_interface_mock.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochusing namespace nacl_io;
22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::_;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::DoAll;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::Mock;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::Return;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::SetArgPointee;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::StrEq;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MountHttpMock : public MountHttp {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MountHttpMock(StringMap_t map, PepperInterfaceMock* ppapi) {
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(0, Init(1, map, ppapi));
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~MountHttpMock() {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Destroy();
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NodeMap_t& GetMap() { return node_cache_; }
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  using MountHttp::ParseManifest;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  using MountHttp::FindOrCreateDir;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MountHttpTest : public ::testing::Test {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MountHttpTest();
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~MountHttpTest();
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PepperInterfaceMock ppapi_;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MountHttpMock* mnt_;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const PP_Instance instance_ = 123;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MountHttpTest::MountHttpTest()
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : ppapi_(instance_),
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mnt_(NULL) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MountHttpTest::~MountHttpTest() {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete mnt_;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(MountHttpTest, MountEmpty) {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StringMap_t args;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mnt_ = new MountHttpMock(args, &ppapi_);
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(MountHttpTest, Mkdir) {
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  StringMap_t args;
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  mnt_ = new MountHttpMock(args, &ppapi_);
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  char manifest[] = "-r-- 123 /mydir/foo\n-rw- 234 /thatdir/bar\n";
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, mnt_->ParseManifest(manifest));
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // mkdir of existing directories should give "File exists".
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(EEXIST, mnt_->Mkdir(Path("/"), 0));
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(EEXIST, mnt_->Mkdir(Path("/mydir"), 0));
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // mkdir of non-existent directories should give "Permission denied".
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(EACCES, mnt_->Mkdir(Path("/non_existent"), 0));
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(MountHttpTest, Rmdir) {
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  StringMap_t args;
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  mnt_ = new MountHttpMock(args, &ppapi_);
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  char manifest[] = "-r-- 123 /mydir/foo\n-rw- 234 /thatdir/bar\n";
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, mnt_->ParseManifest(manifest));
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Rmdir on existing dirs should give "Permission Denied"
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(EACCES, mnt_->Rmdir(Path("/")));
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(EACCES, mnt_->Rmdir(Path("/mydir")));
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Rmdir on existing files should give "Not a direcotory"
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(ENOTDIR, mnt_->Rmdir(Path("/mydir/foo")));
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Rmdir on non-existent files should give "No such file or directory"
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(ENOENT, mnt_->Rmdir(Path("/non_existent")));
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(MountHttpTest, Unlink) {
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  StringMap_t args;
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  mnt_ = new MountHttpMock(args, &ppapi_);
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  char manifest[] = "-r-- 123 /mydir/foo\n-rw- 234 /thatdir/bar\n";
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, mnt_->ParseManifest(manifest));
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Unlink of existing files should give "Permission Denied"
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(EACCES, mnt_->Unlink(Path("/mydir/foo")));
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Unlink of existing directory should give "Is a directory"
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(EISDIR, mnt_->Unlink(Path("/mydir")));
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Unlink of non-existent files should give "No such file or directory"
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(ENOENT, mnt_->Unlink(Path("/non_existent")));
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(MountHttpTest, Remove) {
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  StringMap_t args;
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  mnt_ = new MountHttpMock(args, &ppapi_);
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  char manifest[] = "-r-- 123 /mydir/foo\n-rw- 234 /thatdir/bar\n";
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(0, mnt_->ParseManifest(manifest));
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Remove of existing files should give "Permission Denied"
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(EACCES, mnt_->Remove(Path("/mydir/foo")));
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Remove of existing directory should give "Permission Denied"
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(EACCES, mnt_->Remove(Path("/mydir")));
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Unlink of non-existent files should give "No such file or directory"
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(ENOENT, mnt_->Remove(Path("/non_existent")));
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(MountHttpTest, ParseManifest) {
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StringMap_t args;
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  size_t result_size = 0;
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mnt_ = new MountHttpMock(args, &ppapi_);
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char manifest[] = "-r-- 123 /mydir/foo\n-rw- 234 /thatdir/bar\n";
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, mnt_->ParseManifest(manifest));
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ScopedMountNode root;
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, mnt_->FindOrCreateDir(Path("/"), &root));
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_NE((MountNode*)NULL, root.get());
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, root->ChildCount());
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ScopedMountNode dir;
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, mnt_->FindOrCreateDir(Path("/mydir"), &dir));
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_NE((MountNode*)NULL, dir.get());
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, dir->ChildCount());
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MountNode* node = mnt_->GetMap()["/mydir/foo"].get();
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_NE((MountNode*)NULL, node);
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node->GetSize(&result_size));
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(123, result_size);
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since these files are cached thanks to the manifest, we can open them
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // without accessing the PPAPI URL API.
152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ScopedMountNode foo;
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, mnt_->Open(Path("/mydir/foo"), O_RDONLY, &foo));
154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ScopedMountNode bar;
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, mnt_->Open(Path("/thatdir/bar"), O_RDWR, &bar));
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct stat sfoo;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct stat sbar;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(foo->GetStat(&sfoo));
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(bar->GetStat(&sbar));
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(123, sfoo.st_size);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(S_IFREG | S_IREAD, sfoo.st_mode);
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(234, sbar.st_size);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(S_IFREG | S_IREAD | S_IWRITE, sbar.st_mode);
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MountHttpNodeTest : public MountHttpTest {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MountHttpNodeTest();
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown();
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetMountArgs(const StringMap_t& args);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ExpectOpen(const char* method);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ExpectHeaders(const char* headers);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OpenNode();
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetResponse(int status_code, const char* headers);
182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Set a response code, but expect the request to fail. Certain function calls
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // expected by SetResponse are not expected here.
184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void SetResponseExpectFail(int status_code, const char* headers);
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetResponseBody(const char* body);
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResetMocks();
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MountHttpMock* mnt_;
190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ScopedMountNode node_;
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VarInterfaceMock* var_;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLLoaderInterfaceMock* loader_;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRequestInfoInterfaceMock* request_;
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLResponseInfoInterfaceMock* response_;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t response_body_offset_;
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const char path_[];
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const char rel_path_[];
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const PP_Resource loader_resource_ = 235;
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const PP_Resource request_resource_ = 236;
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const PP_Resource response_resource_ = 237;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char MountHttpNodeTest::path_[] = "/foo";
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char MountHttpNodeTest::rel_path_[] = "foo";
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MountHttpNodeTest::MountHttpNodeTest()
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : mnt_(NULL),
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      node_(NULL) {
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static PP_Var MakeString(PP_Resource resource) {
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_Var result = { PP_VARTYPE_STRING, 0, {PP_FALSE} };
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  result.value.as_id = resource;
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MountHttpNodeTest::SetMountArgs(const StringMap_t& args) {
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mnt_ = new MountHttpMock(args, &ppapi_);
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MountHttpNodeTest::ExpectOpen(const char* method) {
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  loader_ = ppapi_.GetURLLoaderInterface();
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request_ = ppapi_.GetURLRequestInfoInterface();
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_ = ppapi_.GetURLResponseInfoInterface();
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var_ = ppapi_.GetVarInterface();
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ON_CALL(*request_, SetProperty(request_resource_, _, _))
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillByDefault(Return(PP_TRUE));
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ON_CALL(*var_, VarFromUtf8(_, _)).WillByDefault(Return(PP_MakeUndefined()));
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*loader_, Create(instance_)).WillOnce(Return(loader_resource_));
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*request_, Create(instance_)).WillOnce(Return(request_resource_));
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_Var var_head = MakeString(345);
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_Var var_url = MakeString(346);
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*var_, VarFromUtf8(StrEq(method), _)).WillOnce(Return(var_head));
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*var_, VarFromUtf8(StrEq(rel_path_), _))
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(Return(var_url));
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define EXPECT_SET_PROPERTY(NAME, VAR) \
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*request_, SetProperty(request_resource_, NAME, VAR))
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_SET_PROPERTY(PP_URLREQUESTPROPERTY_URL, IsEqualToVar(var_url));
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_SET_PROPERTY(PP_URLREQUESTPROPERTY_METHOD, IsEqualToVar(var_head));
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_SET_PROPERTY(PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS, _);
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_SET_PROPERTY(PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS, _);
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#undef EXPECT_SET_PROPERTY
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*loader_, Open(loader_resource_, request_resource_, _))
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(CallCallback<2>(int32_t(PP_OK)));
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*loader_, GetResponseInfo(loader_resource_))
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(Return(response_resource_));
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(ppapi_, ReleaseResource(loader_resource_));
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(ppapi_, ReleaseResource(request_resource_));
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(ppapi_, ReleaseResource(response_resource_));
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MountHttpNodeTest::ExpectHeaders(const char* headers) {
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_Var var_headers = MakeString(347);
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var_ = ppapi_.GetVarInterface();
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*var_, VarFromUtf8(StrEq(headers), _))
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(Return(var_headers));
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*request_, SetProperty(request_resource_,
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     PP_URLREQUESTPROPERTY_HEADERS,
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     IsEqualToVar(var_headers))).Times(1);
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MountHttpNodeTest::SetResponse(int status_code, const char* headers) {
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ON_CALL(*response_, GetProperty(response_resource_, _))
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillByDefault(Return(PP_MakeUndefined()));
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_Var var_headers = MakeString(348);
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*response_,
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetProperty(response_resource_,
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          PP_URLRESPONSEPROPERTY_STATUSCODE))
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(Return(PP_MakeInt32(status_code)));
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*response_,
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetProperty(response_resource_, PP_URLRESPONSEPROPERTY_HEADERS))
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(Return(var_headers));
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*var_, VarToUtf8(IsEqualToVar(var_headers), _))
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(DoAll(SetArgPointee<1>(strlen(headers)),
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      Return(headers)));
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MountHttpNodeTest::SetResponseExpectFail(int status_code,
293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                              const char* headers) {
294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ON_CALL(*response_, GetProperty(response_resource_, _))
295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillByDefault(Return(PP_MakeUndefined()));
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_CALL(*response_,
298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              GetProperty(response_resource_,
299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                          PP_URLRESPONSEPROPERTY_STATUSCODE))
300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      .WillOnce(Return(PP_MakeInt32(status_code)));
301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ACTION_P3(ReadResponseBodyAction, offset, body, body_length) {
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char* buf = static_cast<char*>(arg1);
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t read_length = arg2;
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_CompletionCallback callback = arg3;
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (*offset >= body_length)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  read_length = std::min(read_length, body_length - *offset);
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memcpy(buf, body + *offset, read_length);
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *offset += read_length;
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Also call the callback.
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (callback.func)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*callback.func)(callback.user_data, PP_OK);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return read_length;
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MountHttpNodeTest::SetResponseBody(const char* body) {
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_body_offset_ = 0;
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*loader_, ReadResponseBody(loader_resource_, _, _, _))
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillRepeatedly(ReadResponseBodyAction(
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            &response_body_offset_, body, strlen(body)));
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MountHttpNodeTest::OpenNode() {
329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(0, mnt_->Open(Path(path_), O_RDONLY, &node_));
330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_NE((MountNode*)NULL, node_.get());
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MountHttpNodeTest::ResetMocks() {
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&ppapi_);
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(loader_);
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(request_);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(response_);
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(var_);
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MountHttpNodeTest::TearDown() {
342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  node_.reset();
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete mnt_;
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3467dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_F(MountHttpNodeTest, DISABLED_OpenAndCloseNoCache) {
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  StringMap_t smap;
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  smap["cache_content"] = "false";
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetMountArgs(StringMap_t());
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectOpen("HEAD");
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectHeaders("");
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponse(200, "");
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpenNode();
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(MountHttpNodeTest, OpenAndCloseNotFound) {
357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StringMap_t smap;
358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  smap["cache_content"] = "false";
359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetMountArgs(StringMap_t());
360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExpectOpen("HEAD");
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExpectHeaders("");
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetResponseExpectFail(404, "");
363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(ENOENT, mnt_->Open(Path(path_), O_RDONLY, &node_));
364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(MountHttpNodeTest, OpenAndCloseServerError) {
367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StringMap_t smap;
368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  smap["cache_content"] = "false";
369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetMountArgs(StringMap_t());
370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExpectOpen("HEAD");
371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExpectHeaders("");
372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetResponseExpectFail(500, "");
373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(EIO, mnt_->Open(Path(path_), O_RDONLY, &node_));
374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(MountHttpNodeTest, GetStat) {
377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StringMap_t smap;
378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  smap["cache_content"] = "false";
379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetMountArgs(StringMap_t());
380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExpectOpen("HEAD");
381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExpectHeaders("");
382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetResponse(200, "Content-Length: 42\n");
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  OpenNode();
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  struct stat stat;
386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(0, node_->GetStat(&stat));
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(42, stat.st_size);
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3907dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_F(MountHttpNodeTest, DISABLED_Access) {
391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StringMap_t smap;
392eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  smap["cache_content"] = "false";
393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetMountArgs(StringMap_t());
394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExpectOpen("HEAD");
395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExpectHeaders("");
396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetResponse(200, "");
397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(0, mnt_->Access(Path(path_), R_OK));
398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_F(MountHttpNodeTest, DISABLED_AccessWrite) {
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StringMap_t smap;
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  smap["cache_content"] = "false";
403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetMountArgs(StringMap_t());
404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExpectOpen("HEAD");
405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExpectHeaders("");
406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetResponse(200, "");
407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(EACCES, mnt_->Access(Path(path_), W_OK));
408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(MountHttpNodeTest, AccessNotFound) {
411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StringMap_t smap;
412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  smap["cache_content"] = "false";
413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetMountArgs(StringMap_t());
414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExpectOpen("HEAD");
415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExpectHeaders("");
416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetResponseExpectFail(404, "");
417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ASSERT_EQ(ENOENT, mnt_->Access(Path(path_), R_OK));
418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(MountHttpNodeTest, ReadCached) {
421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  size_t result_size = 0;
422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int result_bytes = 0;
423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetMountArgs(StringMap_t());
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectOpen("HEAD");
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectHeaders("");
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponse(200, "Content-Length: 42\n");
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpenNode();
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResetMocks();
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->GetSize(&result_size));
432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(42, result_size);
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char buf[10];
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memset(&buf[0], 0, sizeof(buf));
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectOpen("GET");
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectHeaders("");
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponse(200, "Content-Length: 42\n");
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponseBody("Here is some response text. And some more.");
441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->Read(0, buf, sizeof(buf) - 1, &result_bytes));
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_STREQ("Here is s", &buf[0]);
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResetMocks();
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Further reads should be cached.
446868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->Read(0, buf, sizeof(buf) - 1, &result_bytes));
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_STREQ("Here is s", &buf[0]);
448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->Read(10, buf, sizeof(buf) - 1, &result_bytes));
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_STREQ("me respon", &buf[0]);
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->GetSize(&result_size));
452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(42, result_size);
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4557dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_F(MountHttpNodeTest, DISABLED_ReadCachedNoContentLength) {
456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  size_t result_size = 0;
457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int result_bytes = 0;
458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetMountArgs(StringMap_t());
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectOpen("HEAD");
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectHeaders("");
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponse(200, "");
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpenNode();
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResetMocks();
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectOpen("GET");
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectHeaders("");
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponse(200, "");  // No Content-Length response here.
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponseBody("Here is some response text. And some more.");
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // GetSize will Read() because it didn't get the content length from the HEAD
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // request.
473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->GetSize(&result_size));
474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(42, result_size);
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  char buf[10];
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  memset(&buf[0], 0, sizeof(buf));
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->Read(0, buf, sizeof(buf) - 1, &result_bytes));
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_STREQ("Here is s", &buf[0]);
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResetMocks();
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Further reads should be cached.
484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->Read(0, buf, sizeof(buf) - 1, &result_bytes));
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_STREQ("Here is s", &buf[0]);
486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->Read(10, buf, sizeof(buf) - 1, &result_bytes));
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_STREQ("me respon", &buf[0]);
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->GetSize(&result_size));
490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(42, result_size);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(MountHttpNodeTest, ReadCachedUnderrun) {
494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  size_t result_size = 0;
495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int result_bytes = 0;
496868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetMountArgs(StringMap_t());
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectOpen("HEAD");
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectHeaders("");
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponse(200, "Content-Length: 100\n");
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpenNode();
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResetMocks();
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->GetSize(&result_size));
505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(100, result_size);
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char buf[10];
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memset(&buf[0], 0, sizeof(buf));
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectOpen("GET");
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectHeaders("");
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponse(200, "Content-Length: 100\n");
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponseBody("abcdefghijklmnopqrstuvwxyz");
514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->Read(0, buf, sizeof(buf) - 1, &result_bytes));
515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(sizeof(buf) - 1, result_bytes);
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_STREQ("abcdefghi", &buf[0]);
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResetMocks();
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->GetSize(&result_size));
520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(26, result_size);
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(MountHttpNodeTest, ReadCachedOverrun) {
524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  size_t result_size = 0;
525868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int result_bytes = 0;
526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetMountArgs(StringMap_t());
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectOpen("HEAD");
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectHeaders("");
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponse(200, "Content-Length: 15\n");
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpenNode();
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResetMocks();
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->GetSize(&result_size));
535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(15, result_size);
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char buf[10];
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memset(&buf[0], 0, sizeof(buf));
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectOpen("GET");
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectHeaders("");
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponse(200, "Content-Length: 15\n");
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponseBody("01234567890123456789");
544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->Read(10, buf, sizeof(buf) - 1, &result_bytes));
545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(5, result_bytes);
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_STREQ("01234", &buf[0]);
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResetMocks();
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
549868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->GetSize(&result_size));
550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(15, result_size);
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(MountHttpNodeTest, ReadPartial) {
554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int result_bytes = 0;
555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StringMap_t args;
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  args["cache_content"] = "false";
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetMountArgs(args);
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectOpen("HEAD");
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectHeaders("");
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponse(200, "");
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpenNode();
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResetMocks();
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char buf[10];
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memset(&buf[0], 0, sizeof(buf));
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectOpen("GET");
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectHeaders("Range: bytes=0-8\n");
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponse(206, "Content-Length: 9\nContent-Range: bytes=0-8\n");
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponseBody("012345678");
572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->Read(0, buf, sizeof(buf) - 1, &result_bytes));
573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(sizeof(buf) - 1, result_bytes);
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_STREQ("012345678", &buf[0]);
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResetMocks();
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Another read is another request.
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectOpen("GET");
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectHeaders("Range: bytes=10-18\n");
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponse(206, "Content-Length: 9\nContent-Range: bytes=10-18\n");
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponseBody("abcdefghi");
582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->Read(10, buf, sizeof(buf) - 1, &result_bytes));
583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(sizeof(buf) - 1, result_bytes);
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_STREQ("abcdefghi", &buf[0]);
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(MountHttpNodeTest, ReadPartialNoServerSupport) {
588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int result_bytes = 0;
589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StringMap_t args;
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  args["cache_content"] = "false";
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetMountArgs(args);
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectOpen("HEAD");
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectHeaders("");
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponse(200, "");
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpenNode();
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResetMocks();
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char buf[10];
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memset(&buf[0], 0, sizeof(buf));
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectOpen("GET");
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectHeaders("Range: bytes=10-18\n");
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponse(200, "Content-Length: 20\n");
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetResponseBody("0123456789abcdefghij");
606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, node_->Read(10, buf, sizeof(buf) - 1, &result_bytes));
607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(sizeof(buf) - 1, result_bytes);
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_STREQ("abcdefghi", &buf[0]);
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
611