blob: 013c546098ead731838d862cc62742901e04e7cb [file] [log] [blame]
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <fcntl.h>
6#include <gmock/gmock.h>
7#include <ppapi/c/ppb_file_io.h>
8#include <ppapi/c/pp_errors.h>
9#include <ppapi/c/pp_instance.h>
10#include <sys/stat.h>
11#include <sys/types.h>
12
13#include "mock_util.h"
14#include "nacl_io/kernel_intercept.h"
15#include "nacl_io/mount_http.h"
16#include "nacl_io/mount_node_dir.h"
17#include "nacl_io/osdirent.h"
18#include "nacl_io/osunistd.h"
19#include "pepper_interface_mock.h"
20
21using namespace nacl_io;
22
23using ::testing::_;
24using ::testing::DoAll;
25using ::testing::Mock;
26using ::testing::Return;
27using ::testing::SetArgPointee;
28using ::testing::StrEq;
29
30
31class MountHttpMock : public MountHttp {
32 public:
33 MountHttpMock(StringMap_t map, PepperInterfaceMock* ppapi) {
34 EXPECT_EQ(0, Init(1, map, ppapi));
35 }
36
37 ~MountHttpMock() {
38 Destroy();
39 }
40
41 NodeMap_t& GetMap() { return node_cache_; }
42
43 using MountHttp::ParseManifest;
44 using MountHttp::FindOrCreateDir;
45};
46
47class MountHttpTest : public ::testing::Test {
48 public:
49 MountHttpTest();
50 ~MountHttpTest();
51
52 protected:
53 PepperInterfaceMock ppapi_;
54 MountHttpMock* mnt_;
55
56 static const PP_Instance instance_ = 123;
57};
58
59MountHttpTest::MountHttpTest()
60 : ppapi_(instance_),
61 mnt_(NULL) {
62}
63
64MountHttpTest::~MountHttpTest() {
65 delete mnt_;
66}
67
68
69TEST_F(MountHttpTest, MountEmpty) {
70 StringMap_t args;
71 mnt_ = new MountHttpMock(args, &ppapi_);
72}
73
74TEST_F(MountHttpTest, Mkdir) {
75 StringMap_t args;
76 mnt_ = new MountHttpMock(args, &ppapi_);
77 char manifest[] = "-r-- 123 /mydir/foo\n-rw- 234 /thatdir/bar\n";
78 EXPECT_EQ(0, mnt_->ParseManifest(manifest));
79 // mkdir of existing directories should give "File exists".
80 EXPECT_EQ(EEXIST, mnt_->Mkdir(Path("/"), 0));
81 EXPECT_EQ(EEXIST, mnt_->Mkdir(Path("/mydir"), 0));
82 // mkdir of non-existent directories should give "Permission denied".
83 EXPECT_EQ(EACCES, mnt_->Mkdir(Path("/non_existent"), 0));
84}
85
86TEST_F(MountHttpTest, Rmdir) {
87 StringMap_t args;
88 mnt_ = new MountHttpMock(args, &ppapi_);
89 char manifest[] = "-r-- 123 /mydir/foo\n-rw- 234 /thatdir/bar\n";
90 EXPECT_EQ(0, mnt_->ParseManifest(manifest));
91 // Rmdir on existing dirs should give "Permission Denied"
92 EXPECT_EQ(EACCES, mnt_->Rmdir(Path("/")));
93 EXPECT_EQ(EACCES, mnt_->Rmdir(Path("/mydir")));
94 // Rmdir on existing files should give "Not a direcotory"
95 EXPECT_EQ(ENOTDIR, mnt_->Rmdir(Path("/mydir/foo")));
96 // Rmdir on non-existent files should give "No such file or directory"
97 EXPECT_EQ(ENOENT, mnt_->Rmdir(Path("/non_existent")));
98}
99
100TEST_F(MountHttpTest, Unlink) {
101 StringMap_t args;
102 mnt_ = new MountHttpMock(args, &ppapi_);
103 char manifest[] = "-r-- 123 /mydir/foo\n-rw- 234 /thatdir/bar\n";
104 EXPECT_EQ(0, mnt_->ParseManifest(manifest));
105 // Unlink of existing files should give "Permission Denied"
106 EXPECT_EQ(EACCES, mnt_->Unlink(Path("/mydir/foo")));
107 // Unlink of existing directory should give "Is a directory"
108 EXPECT_EQ(EISDIR, mnt_->Unlink(Path("/mydir")));
109 // Unlink of non-existent files should give "No such file or directory"
110 EXPECT_EQ(ENOENT, mnt_->Unlink(Path("/non_existent")));
111}
112
113TEST_F(MountHttpTest, Remove) {
114 StringMap_t args;
115 mnt_ = new MountHttpMock(args, &ppapi_);
116 char manifest[] = "-r-- 123 /mydir/foo\n-rw- 234 /thatdir/bar\n";
117 EXPECT_EQ(0, mnt_->ParseManifest(manifest));
118 // Remove of existing files should give "Permission Denied"
119 EXPECT_EQ(EACCES, mnt_->Remove(Path("/mydir/foo")));
120 // Remove of existing directory should give "Permission Denied"
121 EXPECT_EQ(EACCES, mnt_->Remove(Path("/mydir")));
122 // Unlink of non-existent files should give "No such file or directory"
123 EXPECT_EQ(ENOENT, mnt_->Remove(Path("/non_existent")));
124}
125
126TEST_F(MountHttpTest, ParseManifest) {
127 StringMap_t args;
128 size_t result_size = 0;
129
130 mnt_ = new MountHttpMock(args, &ppapi_);
131
Torne (Richard Coles)58537e22013-09-12 12:10:22 +0100132 // Multiple consecutive newlines or spaces should be ignored.
133 char manifest[] = "-r-- 123 /mydir/foo\n\n-rw- 234 /thatdir/bar\n";
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +0100134 EXPECT_EQ(0, mnt_->ParseManifest(manifest));
135
136 ScopedMountNode root;
137 EXPECT_EQ(0, mnt_->FindOrCreateDir(Path("/"), &root));
138 ASSERT_NE((MountNode*)NULL, root.get());
139 EXPECT_EQ(2, root->ChildCount());
140
141 ScopedMountNode dir;
142 EXPECT_EQ(0, mnt_->FindOrCreateDir(Path("/mydir"), &dir));
143 ASSERT_NE((MountNode*)NULL, dir.get());
144 EXPECT_EQ(1, dir->ChildCount());
145
146 MountNode* node = mnt_->GetMap()["/mydir/foo"].get();
147 EXPECT_NE((MountNode*)NULL, node);
148 EXPECT_EQ(0, node->GetSize(&result_size));
149 EXPECT_EQ(123, result_size);
150
151 // Since these files are cached thanks to the manifest, we can open them
152 // without accessing the PPAPI URL API.
153 ScopedMountNode foo;
154 EXPECT_EQ(0, mnt_->Open(Path("/mydir/foo"), O_RDONLY, &foo));
155
156 ScopedMountNode bar;
157 EXPECT_EQ(0, mnt_->Open(Path("/thatdir/bar"), O_RDWR, &bar));
158
159 struct stat sfoo;
160 struct stat sbar;
161
162 EXPECT_FALSE(foo->GetStat(&sfoo));
163 EXPECT_FALSE(bar->GetStat(&sbar));
164
165 EXPECT_EQ(123, sfoo.st_size);
166 EXPECT_EQ(S_IFREG | S_IREAD, sfoo.st_mode);
167
168 EXPECT_EQ(234, sbar.st_size);
169 EXPECT_EQ(S_IFREG | S_IREAD | S_IWRITE, sbar.st_mode);
170}
171
172
173class MountHttpNodeTest : public MountHttpTest {
174 public:
175 MountHttpNodeTest();
176 virtual void TearDown();
177
178 void SetMountArgs(const StringMap_t& args);
179 void ExpectOpen(const char* method);
180 void ExpectHeaders(const char* headers);
181 void OpenNode();
182 void SetResponse(int status_code, const char* headers);
183 // Set a response code, but expect the request to fail. Certain function calls
184 // expected by SetResponse are not expected here.
185 void SetResponseExpectFail(int status_code, const char* headers);
186 void SetResponseBody(const char* body);
187 void ResetMocks();
188
189 protected:
190 MountHttpMock* mnt_;
191 ScopedMountNode node_;
192
193 CoreInterfaceMock* core_;
194 VarInterfaceMock* var_;
195 URLLoaderInterfaceMock* loader_;
196 URLRequestInfoInterfaceMock* request_;
197 URLResponseInfoInterfaceMock* response_;
198 size_t response_body_offset_;
199
200 static const char path_[];
201 static const char rel_path_[];
202 static const PP_Resource loader_resource_ = 235;
203 static const PP_Resource request_resource_ = 236;
204 static const PP_Resource response_resource_ = 237;
205};
206
207// static
208const char MountHttpNodeTest::path_[] = "/foo";
209// static
210const char MountHttpNodeTest::rel_path_[] = "foo";
211
212MountHttpNodeTest::MountHttpNodeTest()
213 : mnt_(NULL),
214 node_(NULL) {
215}
216
217static PP_Var MakeString(PP_Resource resource) {
218 PP_Var result = { PP_VARTYPE_STRING, 0, {PP_FALSE} };
219 result.value.as_id = resource;
220 return result;
221}
222
223void MountHttpNodeTest::SetMountArgs(const StringMap_t& args) {
224 mnt_ = new MountHttpMock(args, &ppapi_);
225}
226
227void MountHttpNodeTest::ExpectOpen(const char* method) {
228 core_ = ppapi_.GetCoreInterface();
229 loader_ = ppapi_.GetURLLoaderInterface();
230 request_ = ppapi_.GetURLRequestInfoInterface();
231 response_ = ppapi_.GetURLResponseInfoInterface();
232 var_ = ppapi_.GetVarInterface();
233
234 ON_CALL(*request_, SetProperty(request_resource_, _, _))
235 .WillByDefault(Return(PP_TRUE));
236 ON_CALL(*var_, VarFromUtf8(_, _)).WillByDefault(Return(PP_MakeUndefined()));
237
238 EXPECT_CALL(*loader_, Create(instance_)).WillOnce(Return(loader_resource_));
239 EXPECT_CALL(*request_, Create(instance_)).WillOnce(Return(request_resource_));
240
241 PP_Var var_head = MakeString(345);
242 PP_Var var_url = MakeString(346);
243 EXPECT_CALL(*var_, VarFromUtf8(StrEq(method), _)).WillOnce(Return(var_head));
244 EXPECT_CALL(*var_, VarFromUtf8(StrEq(rel_path_), _))
245 .WillOnce(Return(var_url));
246
247#define EXPECT_SET_PROPERTY(NAME, VAR) \
248 EXPECT_CALL(*request_, SetProperty(request_resource_, NAME, VAR))
249
250 EXPECT_SET_PROPERTY(PP_URLREQUESTPROPERTY_URL, IsEqualToVar(var_url));
251 EXPECT_SET_PROPERTY(PP_URLREQUESTPROPERTY_METHOD, IsEqualToVar(var_head));
252 EXPECT_SET_PROPERTY(PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS, _);
253 EXPECT_SET_PROPERTY(PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS, _);
254
255#undef EXPECT_SET_PROPERTY
256
257 EXPECT_CALL(*loader_, Open(loader_resource_, request_resource_, _))
258 .WillOnce(DoAll(CallCallback<2>(int32_t(PP_OK)),
259 Return(int32_t(PP_OK_COMPLETIONPENDING))));
260 EXPECT_CALL(*loader_, GetResponseInfo(loader_resource_))
261 .WillOnce(Return(response_resource_));
262
263 EXPECT_CALL(*core_, ReleaseResource(loader_resource_));
264 EXPECT_CALL(*core_, ReleaseResource(request_resource_));
265 EXPECT_CALL(*core_, ReleaseResource(response_resource_));
266}
267
268void MountHttpNodeTest::ExpectHeaders(const char* headers) {
269 PP_Var var_headers = MakeString(347);
270 var_ = ppapi_.GetVarInterface();
271 EXPECT_CALL(*var_, VarFromUtf8(StrEq(headers), _))
272 .WillOnce(Return(var_headers));
273
274 EXPECT_CALL(*request_, SetProperty(request_resource_,
275 PP_URLREQUESTPROPERTY_HEADERS,
276 IsEqualToVar(var_headers))).Times(1);
277}
278
279void MountHttpNodeTest::SetResponse(int status_code, const char* headers) {
280 ON_CALL(*response_, GetProperty(response_resource_, _))
281 .WillByDefault(Return(PP_MakeUndefined()));
282
283 PP_Var var_headers = MakeString(348);
284 EXPECT_CALL(*response_,
285 GetProperty(response_resource_,
286 PP_URLRESPONSEPROPERTY_STATUSCODE))
287 .WillOnce(Return(PP_MakeInt32(status_code)));
288 EXPECT_CALL(*response_,
289 GetProperty(response_resource_, PP_URLRESPONSEPROPERTY_HEADERS))
290 .WillOnce(Return(var_headers));
291 EXPECT_CALL(*var_, VarToUtf8(IsEqualToVar(var_headers), _))
292 .WillOnce(DoAll(SetArgPointee<1>(strlen(headers)),
293 Return(headers)));
294}
295
296void MountHttpNodeTest::SetResponseExpectFail(int status_code,
297 const char* headers) {
298 ON_CALL(*response_, GetProperty(response_resource_, _))
299 .WillByDefault(Return(PP_MakeUndefined()));
300
301 EXPECT_CALL(*response_,
302 GetProperty(response_resource_,
303 PP_URLRESPONSEPROPERTY_STATUSCODE))
304 .WillOnce(Return(PP_MakeInt32(status_code)));
305}
306
307ACTION_P3(ReadResponseBodyAction, offset, body, body_length) {
308 char* buf = static_cast<char*>(arg1);
309 size_t read_length = arg2;
310 PP_CompletionCallback callback = arg3;
311 if (*offset >= body_length)
312 return 0;
313
314 read_length = std::min(read_length, body_length - *offset);
315 memcpy(buf, body + *offset, read_length);
316 *offset += read_length;
317
318 // Also call the callback.
319 if (callback.func)
320 (*callback.func)(callback.user_data, PP_OK);
321
322 return read_length;
323}
324
325void MountHttpNodeTest::SetResponseBody(const char* body) {
326 response_body_offset_ = 0;
327 EXPECT_CALL(*loader_, ReadResponseBody(loader_resource_, _, _, _))
328 .WillRepeatedly(ReadResponseBodyAction(
329 &response_body_offset_, body, strlen(body)));
330}
331
332void MountHttpNodeTest::OpenNode() {
333 ASSERT_EQ(0, mnt_->Open(Path(path_), O_RDONLY, &node_));
334 ASSERT_NE((MountNode*)NULL, node_.get());
335}
336
337void MountHttpNodeTest::ResetMocks() {
338 Mock::VerifyAndClearExpectations(&ppapi_);
339 Mock::VerifyAndClearExpectations(loader_);
340 Mock::VerifyAndClearExpectations(request_);
341 Mock::VerifyAndClearExpectations(response_);
342 Mock::VerifyAndClearExpectations(var_);
343}
344
345void MountHttpNodeTest::TearDown() {
346 node_.reset();
347 delete mnt_;
348}
349
350// TODO(binji): These tests are all broken now. In another CL, I'll reimplement
351// these tests using an HTTP fake.
352TEST_F(MountHttpNodeTest, DISABLED_OpenAndCloseNoCache) {
353 StringMap_t smap;
354 smap["cache_content"] = "false";
355 SetMountArgs(StringMap_t());
356 ExpectOpen("HEAD");
357 ExpectHeaders("");
358 SetResponse(200, "");
359 OpenNode();
360}
361
362TEST_F(MountHttpNodeTest, DISABLED_OpenAndCloseNotFound) {
363 StringMap_t smap;
364 smap["cache_content"] = "false";
365 SetMountArgs(StringMap_t());
366 ExpectOpen("HEAD");
367 ExpectHeaders("");
368 SetResponseExpectFail(404, "");
369 ASSERT_EQ(ENOENT, mnt_->Open(Path(path_), O_RDONLY, &node_));
370}
371
372TEST_F(MountHttpNodeTest, DISABLED_OpenAndCloseServerError) {
373 StringMap_t smap;
374 smap["cache_content"] = "false";
375 SetMountArgs(StringMap_t());
376 ExpectOpen("HEAD");
377 ExpectHeaders("");
378 SetResponseExpectFail(500, "");
379 ASSERT_EQ(EIO, mnt_->Open(Path(path_), O_RDONLY, &node_));
380}
381
382TEST_F(MountHttpNodeTest, DISABLED_GetStat) {
383 StringMap_t smap;
384 smap["cache_content"] = "false";
385 SetMountArgs(StringMap_t());
386 ExpectOpen("HEAD");
387 ExpectHeaders("");
388 SetResponse(200, "Content-Length: 42\n");
389 OpenNode();
390
391 struct stat stat;
392 EXPECT_EQ(0, node_->GetStat(&stat));
393 EXPECT_EQ(42, stat.st_size);
394}
395
396TEST_F(MountHttpNodeTest, DISABLED_Access) {
397 StringMap_t smap;
398 smap["cache_content"] = "false";
399 SetMountArgs(StringMap_t());
400 ExpectOpen("HEAD");
401 ExpectHeaders("");
402 SetResponse(200, "");
403 ASSERT_EQ(0, mnt_->Access(Path(path_), R_OK));
404}
405
406TEST_F(MountHttpNodeTest, DISABLED_AccessWrite) {
407 StringMap_t smap;
408 smap["cache_content"] = "false";
409 SetMountArgs(StringMap_t());
410 ExpectOpen("HEAD");
411 ExpectHeaders("");
412 SetResponse(200, "");
413 ASSERT_EQ(EACCES, mnt_->Access(Path(path_), W_OK));
414}
415
416TEST_F(MountHttpNodeTest, DISABLED_AccessNotFound) {
417 StringMap_t smap;
418 smap["cache_content"] = "false";
419 SetMountArgs(StringMap_t());
420 ExpectOpen("HEAD");
421 ExpectHeaders("");
422 SetResponseExpectFail(404, "");
423 ASSERT_EQ(ENOENT, mnt_->Access(Path(path_), R_OK));
424}
425
426TEST_F(MountHttpNodeTest, DISABLED_ReadCached) {
427 size_t result_size = 0;
428 int result_bytes = 0;
429
430 SetMountArgs(StringMap_t());
431 ExpectOpen("HEAD");
432 ExpectHeaders("");
433 SetResponse(200, "Content-Length: 42\n");
434 OpenNode();
435 ResetMocks();
436
437 EXPECT_EQ(0, node_->GetSize(&result_size));
438 EXPECT_EQ(42, result_size);
439
440 char buf[10];
441 memset(&buf[0], 0, sizeof(buf));
442
443 ExpectOpen("GET");
444 ExpectHeaders("");
445 SetResponse(200, "Content-Length: 42\n");
446 SetResponseBody("Here is some response text. And some more.");
447 EXPECT_EQ(0, node_->Read(0, buf, sizeof(buf) - 1, &result_bytes));
448 EXPECT_STREQ("Here is s", &buf[0]);
449 ResetMocks();
450
451 // Further reads should be cached.
452 EXPECT_EQ(0, node_->Read(0, buf, sizeof(buf) - 1, &result_bytes));
453 EXPECT_STREQ("Here is s", &buf[0]);
454 EXPECT_EQ(0, node_->Read(10, buf, sizeof(buf) - 1, &result_bytes));
455 EXPECT_STREQ("me respon", &buf[0]);
456
457 EXPECT_EQ(0, node_->GetSize(&result_size));
458 EXPECT_EQ(42, result_size);
459}
460
461TEST_F(MountHttpNodeTest, DISABLED_ReadCachedNoContentLength) {
462 size_t result_size = 0;
463 int result_bytes = 0;
464
465 SetMountArgs(StringMap_t());
466 ExpectOpen("HEAD");
467 ExpectHeaders("");
468 SetResponse(200, "");
469 OpenNode();
470 ResetMocks();
471
472 ExpectOpen("GET");
473 ExpectHeaders("");
474 SetResponse(200, ""); // No Content-Length response here.
475 SetResponseBody("Here is some response text. And some more.");
476
477 // GetSize will Read() because it didn't get the content length from the HEAD
478 // request.
479 EXPECT_EQ(0, node_->GetSize(&result_size));
480 EXPECT_EQ(42, result_size);
481
482 char buf[10];
483 memset(&buf[0], 0, sizeof(buf));
484
485 EXPECT_EQ(0, node_->Read(0, buf, sizeof(buf) - 1, &result_bytes));
486 EXPECT_STREQ("Here is s", &buf[0]);
487 ResetMocks();
488
489 // Further reads should be cached.
490 EXPECT_EQ(0, node_->Read(0, buf, sizeof(buf) - 1, &result_bytes));
491 EXPECT_STREQ("Here is s", &buf[0]);
492 EXPECT_EQ(0, node_->Read(10, buf, sizeof(buf) - 1, &result_bytes));
493 EXPECT_STREQ("me respon", &buf[0]);
494
495 EXPECT_EQ(0, node_->GetSize(&result_size));
496 EXPECT_EQ(42, result_size);
497}
498
499TEST_F(MountHttpNodeTest, DISABLED_ReadCachedUnderrun) {
500 size_t result_size = 0;
501 int result_bytes = 0;
502
503 SetMountArgs(StringMap_t());
504 ExpectOpen("HEAD");
505 ExpectHeaders("");
506 SetResponse(200, "Content-Length: 100\n");
507 OpenNode();
508 ResetMocks();
509
510 EXPECT_EQ(0, node_->GetSize(&result_size));
511 EXPECT_EQ(100, result_size);
512
513 char buf[10];
514 memset(&buf[0], 0, sizeof(buf));
515
516 ExpectOpen("GET");
517 ExpectHeaders("");
518 SetResponse(200, "Content-Length: 100\n");
519 SetResponseBody("abcdefghijklmnopqrstuvwxyz");
520 EXPECT_EQ(0, node_->Read(0, buf, sizeof(buf) - 1, &result_bytes));
521 EXPECT_EQ(sizeof(buf) - 1, result_bytes);
522 EXPECT_STREQ("abcdefghi", &buf[0]);
523 ResetMocks();
524
525 EXPECT_EQ(0, node_->GetSize(&result_size));
526 EXPECT_EQ(26, result_size);
527}
528
529TEST_F(MountHttpNodeTest, DISABLED_ReadCachedOverrun) {
530 size_t result_size = 0;
531 int result_bytes = 0;
532
533 SetMountArgs(StringMap_t());
534 ExpectOpen("HEAD");
535 ExpectHeaders("");
536 SetResponse(200, "Content-Length: 15\n");
537 OpenNode();
538 ResetMocks();
539
540 EXPECT_EQ(0, node_->GetSize(&result_size));
541 EXPECT_EQ(15, result_size);
542
543 char buf[10];
544 memset(&buf[0], 0, sizeof(buf));
545
546 ExpectOpen("GET");
547 ExpectHeaders("");
548 SetResponse(200, "Content-Length: 15\n");
549 SetResponseBody("01234567890123456789");
550 EXPECT_EQ(0, node_->Read(10, buf, sizeof(buf) - 1, &result_bytes));
551 EXPECT_EQ(5, result_bytes);
552 EXPECT_STREQ("01234", &buf[0]);
553 ResetMocks();
554
555 EXPECT_EQ(0, node_->GetSize(&result_size));
556 EXPECT_EQ(15, result_size);
557}
558
559TEST_F(MountHttpNodeTest, DISABLED_ReadPartial) {
560 int result_bytes = 0;
561
562 StringMap_t args;
563 args["cache_content"] = "false";
564 SetMountArgs(args);
565 ExpectOpen("HEAD");
566 ExpectHeaders("");
567 SetResponse(200, "");
568 OpenNode();
569 ResetMocks();
570
571 char buf[10];
572 memset(&buf[0], 0, sizeof(buf));
573
574 ExpectOpen("GET");
575 ExpectHeaders("Range: bytes=0-8\n");
576 SetResponse(206, "Content-Length: 9\nContent-Range: bytes=0-8\n");
577 SetResponseBody("012345678");
578 EXPECT_EQ(0, node_->Read(0, buf, sizeof(buf) - 1, &result_bytes));
579 EXPECT_EQ(sizeof(buf) - 1, result_bytes);
580 EXPECT_STREQ("012345678", &buf[0]);
581 ResetMocks();
582
583 // Another read is another request.
584 ExpectOpen("GET");
585 ExpectHeaders("Range: bytes=10-18\n");
586 SetResponse(206, "Content-Length: 9\nContent-Range: bytes=10-18\n");
587 SetResponseBody("abcdefghi");
588 EXPECT_EQ(0, node_->Read(10, buf, sizeof(buf) - 1, &result_bytes));
589 EXPECT_EQ(sizeof(buf) - 1, result_bytes);
590 EXPECT_STREQ("abcdefghi", &buf[0]);
591}
592
593TEST_F(MountHttpNodeTest, DISABLED_ReadPartialNoServerSupport) {
594 int result_bytes = 0;
595
596 StringMap_t args;
597 args["cache_content"] = "false";
598 SetMountArgs(args);
599 ExpectOpen("HEAD");
600 ExpectHeaders("");
601 SetResponse(200, "");
602 OpenNode();
603 ResetMocks();
604
605 char buf[10];
606 memset(&buf[0], 0, sizeof(buf));
607
608 ExpectOpen("GET");
609 ExpectHeaders("Range: bytes=10-18\n");
610 SetResponse(200, "Content-Length: 20\n");
611 SetResponseBody("0123456789abcdefghij");
612 EXPECT_EQ(0, node_->Read(10, buf, sizeof(buf) - 1, &result_bytes));
613 EXPECT_EQ(sizeof(buf) - 1, result_bytes);
614 EXPECT_STREQ("abcdefghi", &buf[0]);
615}
616