blob: d9119da8aee6d5723f5201d6b9f10e5e6855da20 [file] [log] [blame]
[email protected]57bd67982013-07-21 06:07:301// Copyright 2013 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
[email protected]7c766e92013-11-22 20:44:025#include "components/nacl/browser/pnacl_host.h"
[email protected]57bd67982013-07-21 06:07:306
[email protected]d40657e2013-08-08 18:19:237#include <stdio.h>
[email protected]57bd67982013-07-21 06:07:308#include "base/bind.h"
9#include "base/files/scoped_temp_dir.h"
10#include "base/run_loop.h"
11#include "base/threading/sequenced_worker_pool.h"
[email protected]30a90712013-11-18 16:26:1112#include "components/nacl/browser/pnacl_translation_cache.h"
[email protected]57bd67982013-07-21 06:07:3013#include "content/public/browser/browser_thread.h"
14#include "content/public/test/test_browser_thread_bundle.h"
[email protected]abc31ee2013-08-09 07:25:3515#include "net/base/test_completion_callback.h"
[email protected]57bd67982013-07-21 06:07:3016#include "testing/gtest/include/gtest/gtest.h"
17
[email protected]d40657e2013-08-08 18:19:2318#if defined(OS_WIN)
19#define snprintf _snprintf
20#endif
21
[email protected]57bd67982013-07-21 06:07:3022namespace pnacl {
23
24class PnaclHostTest : public testing::Test {
25 protected:
26 PnaclHostTest()
[email protected]d40657e2013-08-08 18:19:2327 : host_(NULL),
28 temp_callback_count_(0),
29 write_callback_count_(0),
[email protected]57bd67982013-07-21 06:07:3030 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
31 virtual void SetUp() {
32 host_ = new PnaclHost();
33 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
34 host_->InitForTest(temp_dir_.path());
[email protected]779dc1782013-10-25 22:07:3035 base::RunLoop().RunUntilIdle();
36 EXPECT_EQ(PnaclHost::CacheReady, host_->cache_state_);
[email protected]57bd67982013-07-21 06:07:3037 }
38 virtual void TearDown() {
[email protected]d40657e2013-08-08 18:19:2339 EXPECT_EQ(0U, host_->pending_translations());
[email protected]779dc1782013-10-25 22:07:3040 // Give the host a chance to de-init the backend, and then delete it.
41 host_->RendererClosing(0);
42 FlushQueues();
43 EXPECT_EQ(PnaclHost::CacheUninitialized, host_->cache_state_);
[email protected]57bd67982013-07-21 06:07:3044 delete host_;
45 }
[email protected]d40657e2013-08-08 18:19:2346 // Flush the blocking pool first, then any tasks it posted to the IO thread.
47 // Do 2 rounds of flushing, because some operations require 2 trips back and
48 // forth between the threads.
49 void FlushQueues() {
50 content::BrowserThread::GetBlockingPool()->FlushForTesting();
51 base::RunLoop().RunUntilIdle();
52 content::BrowserThread::GetBlockingPool()->FlushForTesting();
53 base::RunLoop().RunUntilIdle();
[email protected]57bd67982013-07-21 06:07:3054 }
[email protected]8311d572013-09-05 21:46:1655 int GetCacheSize() { return host_->disk_cache_->Size(); }
[email protected]779dc1782013-10-25 22:07:3056 int CacheIsInitialized() {
57 return host_->cache_state_ == PnaclHost::CacheReady;
58 }
59 void ReInitBackend() {
60 host_->InitForTest(temp_dir_.path());
61 base::RunLoop().RunUntilIdle();
62 EXPECT_EQ(PnaclHost::CacheReady, host_->cache_state_);
63 }
[email protected]57bd67982013-07-21 06:07:3064
65 public: // Required for derived classes to bind this method
[email protected]8311d572013-09-05 21:46:1666 // Callbacks used by tests which call GetNexeFd.
[email protected]d40657e2013-08-08 18:19:2367 // CallbackExpectMiss checks that the fd is valid and a miss is reported,
68 // and also writes some data into the file, which is read back by
69 // CallbackExpectHit
70 void CallbackExpectMiss(base::PlatformFile fd, bool is_hit) {
[email protected]57bd67982013-07-21 06:07:3071 EXPECT_FALSE(is_hit);
[email protected]d40657e2013-08-08 18:19:2372 ASSERT_FALSE(fd == base::kInvalidPlatformFileValue);
73 base::PlatformFileInfo info;
74 EXPECT_TRUE(base::GetPlatformFileInfo(fd, &info));
75 EXPECT_FALSE(info.is_directory);
76 EXPECT_EQ(0LL, info.size);
77 char str[16];
78 memset(str, 0x0, 16);
79 snprintf(str, 16, "testdata%d", ++write_callback_count_);
80 EXPECT_EQ(16, base::WritePlatformFile(fd, 0, str, 16));
81 temp_callback_count_++;
82 }
83 void CallbackExpectHit(base::PlatformFile fd, bool is_hit) {
84 EXPECT_TRUE(is_hit);
85 ASSERT_FALSE(fd == base::kInvalidPlatformFileValue);
86 base::PlatformFileInfo info;
87 EXPECT_TRUE(base::GetPlatformFileInfo(fd, &info));
88 EXPECT_FALSE(info.is_directory);
89 EXPECT_EQ(16LL, info.size);
90 char data[16];
91 memset(data, 0x0, 16);
92 char str[16];
93 memset(str, 0x0, 16);
94 snprintf(str, 16, "testdata%d", write_callback_count_);
95 EXPECT_EQ(16, base::ReadPlatformFile(fd, 0, data, 16));
96 EXPECT_STREQ(str, data);
97 temp_callback_count_++;
[email protected]57bd67982013-07-21 06:07:3098 }
99
100 protected:
101 PnaclHost* host_;
102 int temp_callback_count_;
[email protected]d40657e2013-08-08 18:19:23103 int write_callback_count_;
[email protected]57bd67982013-07-21 06:07:30104 content::TestBrowserThreadBundle thread_bundle_;
105 base::ScopedTempDir temp_dir_;
106};
107
[email protected]d40657e2013-08-08 18:19:23108static nacl::PnaclCacheInfo GetTestCacheInfo() {
109 nacl::PnaclCacheInfo info;
110 info.pexe_url = GURL("http://www.google.com");
111 info.abi_version = 0;
112 info.opt_level = 0;
[email protected]8311d572013-09-05 21:46:16113 info.has_no_store_header = false;
[email protected]d40657e2013-08-08 18:19:23114 return info;
115}
116
[email protected]8311d572013-09-05 21:46:16117#define GET_NEXE_FD(renderer, instance, incognito, info, expect_hit) \
118 do { \
119 SCOPED_TRACE(""); \
120 host_->GetNexeFd( \
121 renderer, \
122 0, /* ignore render_view_id for now */ \
123 instance, \
124 incognito, \
125 info, \
126 base::Bind(expect_hit ? &PnaclHostTest::CallbackExpectHit \
127 : &PnaclHostTest::CallbackExpectMiss, \
128 base::Unretained(this))); \
[email protected]57bd67982013-07-21 06:07:30129 } while (0)
130
[email protected]57bd67982013-07-21 06:07:30131TEST_F(PnaclHostTest, BasicMiss) {
[email protected]d40657e2013-08-08 18:19:23132 nacl::PnaclCacheInfo info = GetTestCacheInfo();
133 // Test cold miss.
[email protected]4241eb02013-08-08 22:15:41134 GET_NEXE_FD(0, 0, false, info, false);
[email protected]d40657e2013-08-08 18:19:23135 EXPECT_EQ(1U, host_->pending_translations());
136 FlushQueues();
137 EXPECT_EQ(1U, host_->pending_translations());
138 EXPECT_EQ(1, temp_callback_count_);
[email protected]26f14b5a2013-08-07 19:23:13139 host_->TranslationFinished(0, 0, true);
[email protected]d40657e2013-08-08 18:19:23140 FlushQueues();
141 EXPECT_EQ(0U, host_->pending_translations());
142 // Test that a different cache info field also misses.
143 info.etag = std::string("something else");
[email protected]4241eb02013-08-08 22:15:41144 GET_NEXE_FD(0, 0, false, info, false);
[email protected]d40657e2013-08-08 18:19:23145 FlushQueues();
146 EXPECT_EQ(2, temp_callback_count_);
147 EXPECT_EQ(1U, host_->pending_translations());
[email protected]57bd67982013-07-21 06:07:30148 host_->RendererClosing(0);
[email protected]779dc1782013-10-25 22:07:30149 FlushQueues();
150 // Check that the cache has de-initialized after the last renderer goes away.
151 EXPECT_FALSE(CacheIsInitialized());
[email protected]57bd67982013-07-21 06:07:30152}
153
154TEST_F(PnaclHostTest, BadArguments) {
[email protected]d40657e2013-08-08 18:19:23155 nacl::PnaclCacheInfo info = GetTestCacheInfo();
[email protected]4241eb02013-08-08 22:15:41156 GET_NEXE_FD(0, 0, false, info, false);
[email protected]d40657e2013-08-08 18:19:23157 EXPECT_EQ(1U, host_->pending_translations());
[email protected]26f14b5a2013-08-07 19:23:13158 host_->TranslationFinished(0, 1, true); // nonexistent translation
[email protected]d40657e2013-08-08 18:19:23159 EXPECT_EQ(1U, host_->pending_translations());
[email protected]57bd67982013-07-21 06:07:30160 host_->RendererClosing(1); // nonexistent renderer
[email protected]d40657e2013-08-08 18:19:23161 EXPECT_EQ(1U, host_->pending_translations());
162 FlushQueues();
163 EXPECT_EQ(1, temp_callback_count_);
[email protected]57bd67982013-07-21 06:07:30164 host_->RendererClosing(0); // close without finishing
[email protected]d40657e2013-08-08 18:19:23165}
166
167TEST_F(PnaclHostTest, BasicHit) {
168 nacl::PnaclCacheInfo info = GetTestCacheInfo();
[email protected]4241eb02013-08-08 22:15:41169 GET_NEXE_FD(0, 0, false, info, false);
[email protected]d40657e2013-08-08 18:19:23170 FlushQueues();
171 EXPECT_EQ(1, temp_callback_count_);
172 host_->TranslationFinished(0, 0, true);
173 FlushQueues();
[email protected]4241eb02013-08-08 22:15:41174 GET_NEXE_FD(0, 1, false, info, true);
[email protected]d40657e2013-08-08 18:19:23175 FlushQueues();
176 EXPECT_EQ(2, temp_callback_count_);
177 EXPECT_EQ(0U, host_->pending_translations());
178}
179
180TEST_F(PnaclHostTest, TranslationErrors) {
181 nacl::PnaclCacheInfo info = GetTestCacheInfo();
[email protected]4241eb02013-08-08 22:15:41182 GET_NEXE_FD(0, 0, false, info, false);
[email protected]d40657e2013-08-08 18:19:23183 // Early abort, before temp file request returns
184 host_->TranslationFinished(0, 0, false);
185 FlushQueues();
186 EXPECT_EQ(0U, host_->pending_translations());
187 EXPECT_EQ(0, temp_callback_count_);
[email protected]779dc1782013-10-25 22:07:30188 // The backend will have been freed when the query comes back and there
189 // are no pending translations.
190 EXPECT_FALSE(CacheIsInitialized());
191 ReInitBackend();
[email protected]d40657e2013-08-08 18:19:23192 // Check that another request for the same info misses successfully.
[email protected]4241eb02013-08-08 22:15:41193 GET_NEXE_FD(0, 0, false, info, false);
[email protected]d40657e2013-08-08 18:19:23194 FlushQueues();
195 host_->TranslationFinished(0, 0, true);
196 FlushQueues();
197 EXPECT_EQ(1, temp_callback_count_);
198 EXPECT_EQ(0U, host_->pending_translations());
199
200 // Now try sending the error after the temp file request returns
201 info.abi_version = 222;
[email protected]4241eb02013-08-08 22:15:41202 GET_NEXE_FD(0, 0, false, info, false);
[email protected]d40657e2013-08-08 18:19:23203 FlushQueues();
204 EXPECT_EQ(2, temp_callback_count_);
205 host_->TranslationFinished(0, 0, false);
206 FlushQueues();
207 EXPECT_EQ(0U, host_->pending_translations());
208 // Check another successful miss
[email protected]4241eb02013-08-08 22:15:41209 GET_NEXE_FD(0, 0, false, info, false);
[email protected]d40657e2013-08-08 18:19:23210 FlushQueues();
211 EXPECT_EQ(3, temp_callback_count_);
212 host_->TranslationFinished(0, 0, false);
213 EXPECT_EQ(0U, host_->pending_translations());
214}
215
[email protected]ac65e6f2013-08-30 00:47:32216TEST_F(PnaclHostTest, OverlappedMissesAfterTempReturn) {
[email protected]d40657e2013-08-08 18:19:23217 nacl::PnaclCacheInfo info = GetTestCacheInfo();
[email protected]4241eb02013-08-08 22:15:41218 GET_NEXE_FD(0, 0, false, info, false);
[email protected]d40657e2013-08-08 18:19:23219 FlushQueues();
220 EXPECT_EQ(1, temp_callback_count_);
221 EXPECT_EQ(1U, host_->pending_translations());
222 // Test that a second request for the same nexe while the first one is still
223 // outstanding eventually hits.
[email protected]4241eb02013-08-08 22:15:41224 GET_NEXE_FD(0, 1, false, info, true);
[email protected]d40657e2013-08-08 18:19:23225 FlushQueues();
226 EXPECT_EQ(2U, host_->pending_translations());
227 // The temp file should not be returned to the second request until after the
228 // first is finished translating.
229 EXPECT_EQ(1, temp_callback_count_);
230 host_->TranslationFinished(0, 0, true);
231 FlushQueues();
232 EXPECT_EQ(2, temp_callback_count_);
233 EXPECT_EQ(0U, host_->pending_translations());
234}
235
[email protected]ac65e6f2013-08-30 00:47:32236TEST_F(PnaclHostTest, OverlappedMissesBeforeTempReturn) {
[email protected]d40657e2013-08-08 18:19:23237 nacl::PnaclCacheInfo info = GetTestCacheInfo();
[email protected]4241eb02013-08-08 22:15:41238 GET_NEXE_FD(0, 0, false, info, false);
[email protected]d40657e2013-08-08 18:19:23239 // Send the 2nd fd request before the first one returns a temp file.
[email protected]4241eb02013-08-08 22:15:41240 GET_NEXE_FD(0, 1, false, info, true);
[email protected]d40657e2013-08-08 18:19:23241 FlushQueues();
242 EXPECT_EQ(1, temp_callback_count_);
243 EXPECT_EQ(2U, host_->pending_translations());
244 FlushQueues();
245 EXPECT_EQ(2U, host_->pending_translations());
246 EXPECT_EQ(1, temp_callback_count_);
247 host_->TranslationFinished(0, 0, true);
248 FlushQueues();
249 EXPECT_EQ(2, temp_callback_count_);
250 EXPECT_EQ(0U, host_->pending_translations());
251}
252
253TEST_F(PnaclHostTest, OverlappedHitsBeforeTempReturn) {
254 nacl::PnaclCacheInfo info = GetTestCacheInfo();
255 // Store one in the cache and complete it.
[email protected]4241eb02013-08-08 22:15:41256 GET_NEXE_FD(0, 0, false, info, false);
[email protected]d40657e2013-08-08 18:19:23257 FlushQueues();
258 EXPECT_EQ(1, temp_callback_count_);
259 host_->TranslationFinished(0, 0, true);
260 FlushQueues();
261 EXPECT_EQ(0U, host_->pending_translations());
[email protected]4241eb02013-08-08 22:15:41262 GET_NEXE_FD(0, 0, false, info, true);
[email protected]d40657e2013-08-08 18:19:23263 // Request the second before the first temp file returns.
[email protected]4241eb02013-08-08 22:15:41264 GET_NEXE_FD(0, 1, false, info, true);
[email protected]d40657e2013-08-08 18:19:23265 FlushQueues();
266 EXPECT_EQ(3, temp_callback_count_);
267 EXPECT_EQ(0U, host_->pending_translations());
268}
269
270TEST_F(PnaclHostTest, OverlappedHitsAfterTempReturn) {
271 nacl::PnaclCacheInfo info = GetTestCacheInfo();
272 // Store one in the cache and complete it.
[email protected]4241eb02013-08-08 22:15:41273 GET_NEXE_FD(0, 0, false, info, false);
[email protected]d40657e2013-08-08 18:19:23274 FlushQueues();
275 EXPECT_EQ(1, temp_callback_count_);
276 host_->TranslationFinished(0, 0, true);
277 FlushQueues();
278 EXPECT_EQ(0U, host_->pending_translations());
[email protected]4241eb02013-08-08 22:15:41279 GET_NEXE_FD(0, 0, false, info, true);
[email protected]d40657e2013-08-08 18:19:23280 FlushQueues();
[email protected]4241eb02013-08-08 22:15:41281 GET_NEXE_FD(0, 1, false, info, true);
[email protected]d40657e2013-08-08 18:19:23282 FlushQueues();
283 EXPECT_EQ(3, temp_callback_count_);
284 EXPECT_EQ(0U, host_->pending_translations());
285}
286
[email protected]ac65e6f2013-08-30 00:47:32287TEST_F(PnaclHostTest, OverlappedMissesRendererClosing) {
[email protected]d40657e2013-08-08 18:19:23288 nacl::PnaclCacheInfo info = GetTestCacheInfo();
[email protected]4241eb02013-08-08 22:15:41289 GET_NEXE_FD(0, 0, false, info, false);
[email protected]d40657e2013-08-08 18:19:23290 // Send the 2nd fd request from a different renderer.
291 // Test that it eventually gets an fd after the first renderer closes.
[email protected]4241eb02013-08-08 22:15:41292 GET_NEXE_FD(1, 1, false, info, false);
[email protected]d40657e2013-08-08 18:19:23293 FlushQueues();
294 EXPECT_EQ(1, temp_callback_count_);
295 EXPECT_EQ(2U, host_->pending_translations());
296 FlushQueues();
297 EXPECT_EQ(2U, host_->pending_translations());
298 EXPECT_EQ(1, temp_callback_count_);
299 host_->RendererClosing(0);
300 FlushQueues();
301 EXPECT_EQ(2, temp_callback_count_);
302 EXPECT_EQ(1U, host_->pending_translations());
303 host_->RendererClosing(1);
[email protected]57bd67982013-07-21 06:07:30304}
305
[email protected]4241eb02013-08-08 22:15:41306TEST_F(PnaclHostTest, Incognito) {
307 nacl::PnaclCacheInfo info = GetTestCacheInfo();
308 GET_NEXE_FD(0, 0, true, info, false);
309 FlushQueues();
310 EXPECT_EQ(1, temp_callback_count_);
311 host_->TranslationFinished(0, 0, true);
312 FlushQueues();
313 // Check that an incognito translation is not stored in the cache
314 GET_NEXE_FD(0, 0, false, info, false);
315 FlushQueues();
316 EXPECT_EQ(2, temp_callback_count_);
317 host_->TranslationFinished(0, 0, true);
318 FlushQueues();
319 // Check that an incognito translation can hit from a normal one.
320 GET_NEXE_FD(0, 0, true, info, true);
321 FlushQueues();
322 EXPECT_EQ(3, temp_callback_count_);
323}
324
[email protected]ac65e6f2013-08-30 00:47:32325TEST_F(PnaclHostTest, IncognitoOverlappedMiss) {
[email protected]4241eb02013-08-08 22:15:41326 nacl::PnaclCacheInfo info = GetTestCacheInfo();
327 GET_NEXE_FD(0, 0, true, info, false);
328 GET_NEXE_FD(0, 1, false, info, false);
329 FlushQueues();
330 // Check that both translations have returned misses, (i.e. that the
331 // second one has not blocked on the incognito one)
332 EXPECT_EQ(2, temp_callback_count_);
333 host_->TranslationFinished(0, 0, true);
334 host_->TranslationFinished(0, 1, true);
335 FlushQueues();
336 EXPECT_EQ(0U, host_->pending_translations());
337
338 // Same test, but issue the 2nd request after the first has returned a miss.
339 info.abi_version = 222;
340 GET_NEXE_FD(0, 0, true, info, false);
341 FlushQueues();
342 EXPECT_EQ(3, temp_callback_count_);
343 GET_NEXE_FD(0, 1, false, info, false);
344 FlushQueues();
345 EXPECT_EQ(4, temp_callback_count_);
346 host_->RendererClosing(0);
347}
348
[email protected]ac65e6f2013-08-30 00:47:32349TEST_F(PnaclHostTest, IncognitoSecondOverlappedMiss) {
[email protected]4241eb02013-08-08 22:15:41350 // If the non-incognito request comes first, it should
351 // behave exactly like OverlappedMissBeforeTempReturn
352 nacl::PnaclCacheInfo info = GetTestCacheInfo();
353 GET_NEXE_FD(0, 0, false, info, false);
354 // Send the 2nd fd request before the first one returns a temp file.
355 GET_NEXE_FD(0, 1, true, info, true);
356 FlushQueues();
357 EXPECT_EQ(1, temp_callback_count_);
358 EXPECT_EQ(2U, host_->pending_translations());
359 FlushQueues();
360 EXPECT_EQ(2U, host_->pending_translations());
361 EXPECT_EQ(1, temp_callback_count_);
362 host_->TranslationFinished(0, 0, true);
363 FlushQueues();
364 EXPECT_EQ(2, temp_callback_count_);
365 EXPECT_EQ(0U, host_->pending_translations());
366}
367
[email protected]8311d572013-09-05 21:46:16368// Test that pexes with the no-store header do not get cached.
369TEST_F(PnaclHostTest, CacheControlNoStore) {
370 nacl::PnaclCacheInfo info = GetTestCacheInfo();
371 info.has_no_store_header = true;
372 GET_NEXE_FD(0, 0, false, info, false);
373 FlushQueues();
374 EXPECT_EQ(1, temp_callback_count_);
375 host_->TranslationFinished(0, 0, true);
376 FlushQueues();
377 EXPECT_EQ(0U, host_->pending_translations());
378 EXPECT_EQ(0, GetCacheSize());
379}
380
381// Test that no-store pexes do not wait, but do duplicate translations
382TEST_F(PnaclHostTest, NoStoreOverlappedMiss) {
383 nacl::PnaclCacheInfo info = GetTestCacheInfo();
384 info.has_no_store_header = true;
385 GET_NEXE_FD(0, 0, false, info, false);
386 GET_NEXE_FD(0, 1, false, info, false);
387 FlushQueues();
388 // Check that both translations have returned misses, (i.e. that the
389 // second one has not blocked on the first one)
390 EXPECT_EQ(2, temp_callback_count_);
391 host_->TranslationFinished(0, 0, true);
392 host_->TranslationFinished(0, 1, true);
393 FlushQueues();
394 EXPECT_EQ(0U, host_->pending_translations());
395
396 // Same test, but issue the 2nd request after the first has returned a miss.
397 info.abi_version = 222;
398 GET_NEXE_FD(0, 0, false, info, false);
399 FlushQueues();
400 EXPECT_EQ(3, temp_callback_count_);
401 GET_NEXE_FD(0, 1, false, info, false);
402 FlushQueues();
403 EXPECT_EQ(4, temp_callback_count_);
404 host_->RendererClosing(0);
405}
406
[email protected]abc31ee2013-08-09 07:25:35407TEST_F(PnaclHostTest, ClearTranslationCache) {
408 nacl::PnaclCacheInfo info = GetTestCacheInfo();
409 // Add 2 entries in the cache
410 GET_NEXE_FD(0, 0, false, info, false);
411 info.abi_version = 222;
412 GET_NEXE_FD(0, 1, false, info, false);
413 FlushQueues();
414 EXPECT_EQ(2, temp_callback_count_);
415 host_->TranslationFinished(0, 0, true);
416 host_->TranslationFinished(0, 1, true);
417 FlushQueues();
418 EXPECT_EQ(0U, host_->pending_translations());
419 EXPECT_EQ(2, GetCacheSize());
420 net::TestCompletionCallback cb;
421 // Since we are using a memory backend, the clear should happen immediately.
[email protected]8311d572013-09-05 21:46:16422 host_->ClearTranslationCacheEntriesBetween(
423 base::Time(), base::Time(), base::Bind(cb.callback(), 0));
[email protected]779dc1782013-10-25 22:07:30424 // Check that the translation cache has been cleared before flushing the
425 // queues, because the backend will be freed once it is.
[email protected]abc31ee2013-08-09 07:25:35426 EXPECT_EQ(0, GetCacheSize());
[email protected]779dc1782013-10-25 22:07:30427 EXPECT_EQ(0, cb.GetResult(net::ERR_IO_PENDING));
428 // Now check that the backend has been freed.
429 EXPECT_FALSE(CacheIsInitialized());
[email protected]abc31ee2013-08-09 07:25:35430}
431
[email protected]57bd67982013-07-21 06:07:30432} // namespace pnacl