TEST(LockManager, CompatibleFirstImmediateGrant) { LockManager lockMgr; const ResourceId resId(RESOURCE_GLOBAL, 0); MMAPV1LockerImpl locker1; LockRequestCombo request1(&locker1); MMAPV1LockerImpl locker2; LockRequestCombo request2(&locker2); request2.compatibleFirst = true; MMAPV1LockerImpl locker3; LockRequestCombo request3(&locker3); // Lock all in IS mode ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_IS)); ASSERT(LOCK_OK == lockMgr.lock(resId, &request2, MODE_IS)); ASSERT(LOCK_OK == lockMgr.lock(resId, &request3, MODE_IS)); // Now an exclusive mode comes, which would block MMAPV1LockerImpl lockerX; LockRequestCombo requestX(&lockerX); ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestX, MODE_X)); // If an S comes, it should be granted, because of request2 { MMAPV1LockerImpl lockerS; LockRequestCombo requestS(&lockerS); ASSERT(LOCK_OK == lockMgr.lock(resId, &requestS, MODE_S)); ASSERT(lockMgr.unlock(&requestS)); } // If request1 goes away, the policy should still be compatible-first, because of request2 ASSERT(lockMgr.unlock(&request1)); // If S comes again, it should be granted, because of request2 still there { MMAPV1LockerImpl lockerS; LockRequestCombo requestS(&lockerS); ASSERT(LOCK_OK == lockMgr.lock(resId, &requestS, MODE_S)); ASSERT(lockMgr.unlock(&requestS)); } // With request2 gone the policy should go back to FIFO, even though request3 is active ASSERT(lockMgr.unlock(&request2)); { MMAPV1LockerImpl lockerS; LockRequestCombo requestS(&lockerS); ASSERT(LOCK_WAITING == lockMgr.lock(resId, &requestS, MODE_S)); ASSERT(lockMgr.unlock(&requestS)); } // Unlock request3 to keep the lock mgr not assert for leaked locks ASSERT(lockMgr.unlock(&request3)); ASSERT(lockMgr.unlock(&requestX)); }
TEST_F(ResourceFetcherTest, RevalidateDeferedResourceFromTwoInitiators) { KURL url(ParsedURLString, "http://127.0.0.1:8000/font.woff"); ResourceResponse response; response.setURL(url); response.setHTTPStatusCode(200); response.setHTTPHeaderField(HTTPNames::ETag, "1234567890"); Platform::current()->getURLLoaderMockFactory()->registerURL( url, WrappedResourceResponse(response), ""); ResourceFetcherTestMockFetchContext* context = ResourceFetcherTestMockFetchContext::create(); ResourceFetcher* fetcher = ResourceFetcher::create(context); // Fetch to cache a resource. ResourceRequest request1(url); FetchRequest fetchRequest1 = FetchRequest(request1, FetchInitiatorInfo()); Resource* resource1 = FontResource::fetch(fetchRequest1, fetcher); ASSERT_TRUE(resource1); fetcher->startLoad(resource1); Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests(); EXPECT_TRUE(resource1->isLoaded()); EXPECT_FALSE(resource1->errorOccurred()); // Set the context as it is on reloads. context->setLoadComplete(true); context->setCachePolicy(CachePolicyRevalidate); // Revalidate the resource. ResourceRequest request2(url); FetchRequest fetchRequest2 = FetchRequest(request2, FetchInitiatorInfo()); Resource* resource2 = FontResource::fetch(fetchRequest2, fetcher); ASSERT_TRUE(resource2); EXPECT_EQ(resource1, resource2); EXPECT_TRUE(resource2->isCacheValidator()); EXPECT_TRUE(resource2->stillNeedsLoad()); // Fetch the same resource again before actual load operation starts. ResourceRequest request3(url); FetchRequest fetchRequest3 = FetchRequest(request3, FetchInitiatorInfo()); Resource* resource3 = FontResource::fetch(fetchRequest3, fetcher); ASSERT_TRUE(resource3); EXPECT_EQ(resource2, resource3); EXPECT_TRUE(resource3->isCacheValidator()); EXPECT_TRUE(resource3->stillNeedsLoad()); // startLoad() can be called from any initiator. Here, call it from the // latter. fetcher->startLoad(resource3); Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests(); EXPECT_TRUE(resource3->isLoaded()); EXPECT_FALSE(resource3->errorOccurred()); EXPECT_TRUE(resource2->isLoaded()); EXPECT_FALSE(resource2->errorOccurred()); memoryCache()->remove(resource1); }
TEST(RequestTests, Constructors) { gallocy::http::Request request1(GET_REQUEST, gallocy::common::Peer()); ASSERT_EQ(request1.method, "GET"); #if 0 gallocy::http::Request request2 = request1; ASSERT_EQ(request2.method, "GET"); gallocy::http::Request request3(request1); ASSERT_EQ(request3.method, "GET"); #endif }
TEST(LockManager, CompatibleFirstGrantAlreadyQueued) { LockManager lockMgr; const ResourceId resId(RESOURCE_GLOBAL, 0); // This tests the following behavior: // Lock held in X, queue: S IX IS, where S is compatibleFirst. // Once X unlocks both the S and IS requests should proceed. MMAPV1LockerImpl locker1; LockRequestCombo request1(&locker1); MMAPV1LockerImpl locker2; LockRequestCombo request2(&locker2); request2.compatibleFirst = true; MMAPV1LockerImpl locker3; LockRequestCombo request3(&locker3); MMAPV1LockerImpl locker4; LockRequestCombo request4(&locker4); // Hold the lock in X and establish the S IX IS queue. ASSERT(LOCK_OK == lockMgr.lock(resId, &request1, MODE_X)); ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request2, MODE_S)); ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request3, MODE_IX)); ASSERT(LOCK_WAITING == lockMgr.lock(resId, &request4, MODE_IS)); // Now unlock, so all readers should be able to proceed, while the IX remains queued. ASSERT(lockMgr.unlock(&request1)); ASSERT(request2.lastResult == LOCK_OK); ASSERT(request3.lastResult == LOCK_INVALID); ASSERT(request4.lastResult == LOCK_OK); // Now unlock the S lock, and the IX succeeds as well. ASSERT(lockMgr.unlock(&request2)); ASSERT(request3.lastResult == LOCK_OK); // Unlock remaining ASSERT(lockMgr.unlock(&request4)); ASSERT(lockMgr.unlock(&request3)); }