1 // Copyright (c) 2010 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 <string> 6 7 #include "base/string16.h" 8 #include "base/string_util.h" 9 #include "base/stringprintf.h" 10 #include "base/utf_string_conversions.h" 11 #include "net/base/net_errors.h" 12 #include "net/http/http_auth_cache.h" 13 #include "net/http/http_auth_handler.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 16 namespace net { 17 18 namespace { 19 20 class MockAuthHandler : public HttpAuthHandler { 21 public: 22 MockAuthHandler(HttpAuth::Scheme scheme, 23 const std::string& realm, 24 HttpAuth::Target target) { 25 // Can't use initializer list since these are members of the base class. 26 auth_scheme_ = scheme; 27 realm_ = realm; 28 score_ = 1; 29 target_ = target; 30 properties_ = 0; 31 } 32 33 virtual HttpAuth::AuthorizationResult HandleAnotherChallenge( 34 HttpAuth::ChallengeTokenizer* challenge) { 35 return HttpAuth::AUTHORIZATION_RESULT_REJECT; 36 } 37 38 protected: 39 virtual bool Init(HttpAuth::ChallengeTokenizer* challenge) { 40 return false; // Unused. 41 } 42 43 virtual int GenerateAuthTokenImpl(const string16*, 44 const string16*, 45 const HttpRequestInfo*, 46 CompletionCallback* callback, 47 std::string* auth_token) { 48 *auth_token = "mock-credentials"; 49 return OK; 50 } 51 52 53 private: 54 ~MockAuthHandler() {} 55 }; 56 57 const char* kRealm1 = "Realm1"; 58 const char* kRealm2 = "Realm2"; 59 const char* kRealm3 = "Realm3"; 60 const char* kRealm4 = "Realm4"; 61 const char* kRealm5 = "Realm5"; 62 const string16 k123(ASCIIToUTF16("123")); 63 const string16 k1234(ASCIIToUTF16("1234")); 64 const string16 kAdmin(ASCIIToUTF16("admin")); 65 const string16 kAlice(ASCIIToUTF16("alice")); 66 const string16 kAlice2(ASCIIToUTF16("alice2")); 67 const string16 kPassword(ASCIIToUTF16("password")); 68 const string16 kRoot(ASCIIToUTF16("root")); 69 const string16 kUsername(ASCIIToUTF16("username")); 70 const string16 kWileCoyote(ASCIIToUTF16("wilecoyote")); 71 72 } // namespace 73 74 // Test adding and looking-up cache entries (both by realm and by path). 75 TEST(HttpAuthCacheTest, Basic) { 76 GURL origin("http://www.google.com"); 77 HttpAuthCache cache; 78 HttpAuthCache::Entry* entry; 79 80 // Add cache entries for 4 realms: "Realm1", "Realm2", "Realm3" and 81 // "Realm4" 82 83 scoped_ptr<HttpAuthHandler> realm1_handler( 84 new MockAuthHandler(HttpAuth::AUTH_SCHEME_BASIC, 85 kRealm1, 86 HttpAuth::AUTH_SERVER)); 87 cache.Add(origin, realm1_handler->realm(), realm1_handler->auth_scheme(), 88 "Basic realm=Realm1", ASCIIToUTF16("realm1-user"), 89 ASCIIToUTF16("realm1-password"), "/foo/bar/index.html"); 90 91 scoped_ptr<HttpAuthHandler> realm2_handler( 92 new MockAuthHandler(HttpAuth::AUTH_SCHEME_BASIC, 93 kRealm2, 94 HttpAuth::AUTH_SERVER)); 95 cache.Add(origin, realm2_handler->realm(), realm2_handler->auth_scheme(), 96 "Basic realm=Realm2", ASCIIToUTF16("realm2-user"), 97 ASCIIToUTF16("realm2-password"), "/foo2/index.html"); 98 99 scoped_ptr<HttpAuthHandler> realm3_basic_handler( 100 new MockAuthHandler(HttpAuth::AUTH_SCHEME_BASIC, 101 kRealm3, 102 HttpAuth::AUTH_PROXY)); 103 cache.Add(origin, realm3_basic_handler->realm(), 104 realm3_basic_handler->auth_scheme(), "Basic realm=Realm3", 105 ASCIIToUTF16("realm3-basic-user"), 106 ASCIIToUTF16("realm3-basic-password"), ""); 107 108 scoped_ptr<HttpAuthHandler> realm3_digest_handler( 109 new MockAuthHandler(HttpAuth::AUTH_SCHEME_DIGEST, 110 kRealm3, 111 HttpAuth::AUTH_PROXY)); 112 cache.Add(origin, realm3_digest_handler->realm(), 113 realm3_digest_handler->auth_scheme(), "Digest realm=Realm3", 114 ASCIIToUTF16("realm3-digest-user"), 115 ASCIIToUTF16("realm3-digest-password"), "/baz/index.html"); 116 117 scoped_ptr<HttpAuthHandler> realm4_basic_handler( 118 new MockAuthHandler(HttpAuth::AUTH_SCHEME_BASIC, 119 kRealm4, 120 HttpAuth::AUTH_SERVER)); 121 cache.Add(origin, realm4_basic_handler->realm(), 122 realm4_basic_handler->auth_scheme(), "Basic realm=Realm4", 123 ASCIIToUTF16("realm4-basic-user"), 124 ASCIIToUTF16("realm4-basic-password"), "/"); 125 126 // There is no Realm5 127 entry = cache.Lookup(origin, kRealm5, HttpAuth::AUTH_SCHEME_BASIC); 128 EXPECT_TRUE(NULL == entry); 129 130 // While Realm3 does exist, the origin scheme is wrong. 131 entry = cache.Lookup(GURL("https://www.google.com"), kRealm3, 132 HttpAuth::AUTH_SCHEME_BASIC); 133 EXPECT_TRUE(NULL == entry); 134 135 // Realm, origin scheme ok, authentication scheme wrong 136 entry = cache.Lookup 137 (GURL("http://www.google.com"), kRealm1, HttpAuth::AUTH_SCHEME_DIGEST); 138 EXPECT_TRUE(NULL == entry); 139 140 // Valid lookup by origin, realm, scheme. 141 entry = cache.Lookup( 142 GURL("http://www.google.com:80"), kRealm3, HttpAuth::AUTH_SCHEME_BASIC); 143 ASSERT_FALSE(NULL == entry); 144 EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme()); 145 EXPECT_EQ(kRealm3, entry->realm()); 146 EXPECT_EQ("Basic realm=Realm3", entry->auth_challenge()); 147 EXPECT_EQ(ASCIIToUTF16("realm3-basic-user"), entry->username()); 148 EXPECT_EQ(ASCIIToUTF16("realm3-basic-password"), entry->password()); 149 150 // Valid lookup by origin, realm, scheme when there's a duplicate 151 // origin, realm in the cache 152 entry = cache.Lookup( 153 GURL("http://www.google.com:80"), kRealm3, HttpAuth::AUTH_SCHEME_DIGEST); 154 ASSERT_FALSE(NULL == entry); 155 EXPECT_EQ(HttpAuth::AUTH_SCHEME_DIGEST, entry->scheme()); 156 EXPECT_EQ(kRealm3, entry->realm()); 157 EXPECT_EQ("Digest realm=Realm3", entry->auth_challenge()); 158 EXPECT_EQ(ASCIIToUTF16("realm3-digest-user"), entry->username()); 159 EXPECT_EQ(ASCIIToUTF16("realm3-digest-password"), entry->password()); 160 161 // Valid lookup by realm. 162 entry = cache.Lookup(origin, kRealm2, HttpAuth::AUTH_SCHEME_BASIC); 163 ASSERT_FALSE(NULL == entry); 164 EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme()); 165 EXPECT_EQ(kRealm2, entry->realm()); 166 EXPECT_EQ("Basic realm=Realm2", entry->auth_challenge()); 167 EXPECT_EQ(ASCIIToUTF16("realm2-user"), entry->username()); 168 EXPECT_EQ(ASCIIToUTF16("realm2-password"), entry->password()); 169 170 // Check that subpaths are recognized. 171 HttpAuthCache::Entry* realm2_entry = cache.Lookup( 172 origin, kRealm2, HttpAuth::AUTH_SCHEME_BASIC); 173 HttpAuthCache::Entry* realm4_entry = cache.Lookup( 174 origin, kRealm4, HttpAuth::AUTH_SCHEME_BASIC); 175 EXPECT_FALSE(NULL == realm2_entry); 176 EXPECT_FALSE(NULL == realm4_entry); 177 // Realm4 applies to '/' and Realm2 applies to '/foo2/'. 178 // LookupByPath() should return the closest enclosing path. 179 // Positive tests: 180 entry = cache.LookupByPath(origin, "/foo2/index.html"); 181 EXPECT_TRUE(realm2_entry == entry); 182 entry = cache.LookupByPath(origin, "/foo2/foobar.html"); 183 EXPECT_TRUE(realm2_entry == entry); 184 entry = cache.LookupByPath(origin, "/foo2/bar/index.html"); 185 EXPECT_TRUE(realm2_entry == entry); 186 entry = cache.LookupByPath(origin, "/foo2/"); 187 EXPECT_TRUE(realm2_entry == entry); 188 entry = cache.LookupByPath(origin, "/foo2"); 189 EXPECT_TRUE(realm4_entry == entry); 190 entry = cache.LookupByPath(origin, "/"); 191 EXPECT_TRUE(realm4_entry == entry); 192 193 // Negative tests: 194 entry = cache.LookupByPath(origin, "/foo3/index.html"); 195 EXPECT_FALSE(realm2_entry == entry); 196 entry = cache.LookupByPath(origin, ""); 197 EXPECT_FALSE(realm2_entry == entry); 198 199 // Confirm we find the same realm, different auth scheme by path lookup 200 HttpAuthCache::Entry* realm3_digest_entry = 201 cache.Lookup(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST); 202 EXPECT_FALSE(NULL == realm3_digest_entry); 203 entry = cache.LookupByPath(origin, "/baz/index.html"); 204 EXPECT_TRUE(realm3_digest_entry == entry); 205 entry = cache.LookupByPath(origin, "/baz/"); 206 EXPECT_TRUE(realm3_digest_entry == entry); 207 entry = cache.LookupByPath(origin, "/baz"); 208 EXPECT_FALSE(realm3_digest_entry == entry); 209 210 // Confirm we find the same realm, different auth scheme by path lookup 211 HttpAuthCache::Entry* realm3DigestEntry = 212 cache.Lookup(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST); 213 EXPECT_FALSE(NULL == realm3DigestEntry); 214 entry = cache.LookupByPath(origin, "/baz/index.html"); 215 EXPECT_TRUE(realm3DigestEntry == entry); 216 entry = cache.LookupByPath(origin, "/baz/"); 217 EXPECT_TRUE(realm3DigestEntry == entry); 218 entry = cache.LookupByPath(origin, "/baz"); 219 EXPECT_FALSE(realm3DigestEntry == entry); 220 221 // Lookup using empty path (may be used for proxy). 222 entry = cache.LookupByPath(origin, ""); 223 EXPECT_FALSE(NULL == entry); 224 EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme()); 225 EXPECT_EQ(kRealm3, entry->realm()); 226 } 227 228 TEST(HttpAuthCacheTest, AddPath) { 229 HttpAuthCache::Entry entry; 230 231 // All of these paths have a common root /1/2/2/4/5/ 232 entry.AddPath("/1/2/3/4/5/x.txt"); 233 entry.AddPath("/1/2/3/4/5/y.txt"); 234 entry.AddPath("/1/2/3/4/5/z.txt"); 235 236 EXPECT_EQ(1U, entry.paths_.size()); 237 EXPECT_EQ("/1/2/3/4/5/", entry.paths_.front()); 238 239 // Add a new entry (not a subpath). 240 entry.AddPath("/1/XXX/q"); 241 EXPECT_EQ(2U, entry.paths_.size()); 242 EXPECT_EQ("/1/XXX/", entry.paths_.front()); 243 EXPECT_EQ("/1/2/3/4/5/", entry.paths_.back()); 244 245 // Add containing paths of /1/2/3/4/5/ -- should swallow up the deeper paths. 246 entry.AddPath("/1/2/3/4/x.txt"); 247 EXPECT_EQ(2U, entry.paths_.size()); 248 EXPECT_EQ("/1/2/3/4/", entry.paths_.front()); 249 EXPECT_EQ("/1/XXX/", entry.paths_.back()); 250 entry.AddPath("/1/2/3/x"); 251 EXPECT_EQ(2U, entry.paths_.size()); 252 EXPECT_EQ("/1/2/3/", entry.paths_.front()); 253 EXPECT_EQ("/1/XXX/", entry.paths_.back()); 254 255 entry.AddPath("/index.html"); 256 EXPECT_EQ(1U, entry.paths_.size()); 257 EXPECT_EQ("/", entry.paths_.front()); 258 } 259 260 // Calling Add when the realm entry already exists, should append that 261 // path. 262 TEST(HttpAuthCacheTest, AddToExistingEntry) { 263 HttpAuthCache cache; 264 GURL origin("http://www.foobar.com:70"); 265 const std::string auth_challenge = "Basic realm=MyRealm"; 266 267 scoped_ptr<HttpAuthHandler> handler( 268 new MockAuthHandler( 269 HttpAuth::AUTH_SCHEME_BASIC, "MyRealm", HttpAuth::AUTH_SERVER)); 270 HttpAuthCache::Entry* orig_entry = cache.Add( 271 origin, handler->realm(), handler->auth_scheme(), auth_challenge, 272 ASCIIToUTF16("user1"), ASCIIToUTF16("password1"), "/x/y/z/"); 273 cache.Add(origin, handler->realm(), handler->auth_scheme(), auth_challenge, 274 ASCIIToUTF16("user2"), ASCIIToUTF16("password2"), "/z/y/x/"); 275 cache.Add(origin, handler->realm(), handler->auth_scheme(), auth_challenge, 276 ASCIIToUTF16("user3"), ASCIIToUTF16("password3"), "/z/y"); 277 278 HttpAuthCache::Entry* entry = cache.Lookup( 279 origin, "MyRealm", HttpAuth::AUTH_SCHEME_BASIC); 280 281 EXPECT_TRUE(entry == orig_entry); 282 EXPECT_EQ(ASCIIToUTF16("user3"), entry->username()); 283 EXPECT_EQ(ASCIIToUTF16("password3"), entry->password()); 284 285 EXPECT_EQ(2U, entry->paths_.size()); 286 EXPECT_EQ("/z/", entry->paths_.front()); 287 EXPECT_EQ("/x/y/z/", entry->paths_.back()); 288 } 289 290 TEST(HttpAuthCacheTest, Remove) { 291 GURL origin("http://foobar2.com"); 292 293 scoped_ptr<HttpAuthHandler> realm1_handler( 294 new MockAuthHandler( 295 HttpAuth::AUTH_SCHEME_BASIC, kRealm1, HttpAuth::AUTH_SERVER)); 296 297 scoped_ptr<HttpAuthHandler> realm2_handler( 298 new MockAuthHandler( 299 HttpAuth::AUTH_SCHEME_BASIC, kRealm2, HttpAuth::AUTH_SERVER)); 300 301 scoped_ptr<HttpAuthHandler> realm3_basic_handler( 302 new MockAuthHandler( 303 HttpAuth::AUTH_SCHEME_BASIC, kRealm3, HttpAuth::AUTH_SERVER)); 304 305 scoped_ptr<HttpAuthHandler> realm3_digest_handler( 306 new MockAuthHandler( 307 HttpAuth::AUTH_SCHEME_DIGEST, kRealm3, HttpAuth::AUTH_SERVER)); 308 309 HttpAuthCache cache; 310 cache.Add(origin, realm1_handler->realm(), realm1_handler->auth_scheme(), 311 "basic realm=Realm1", kAlice, k123, "/"); 312 cache.Add(origin, realm2_handler->realm(), realm2_handler->auth_scheme(), 313 "basic realm=Realm2", ASCIIToUTF16("bob"), ASCIIToUTF16("princess"), 314 "/"); 315 cache.Add(origin, realm3_basic_handler->realm(), 316 realm3_basic_handler->auth_scheme(), "basic realm=Realm3", 317 kAdmin, kPassword, "/"); 318 cache.Add(origin, realm3_digest_handler->realm(), 319 realm3_digest_handler->auth_scheme(), "digest realm=Realm3", 320 kRoot, kWileCoyote, "/"); 321 322 // Fails, because there is no realm "Realm5". 323 EXPECT_FALSE(cache.Remove( 324 origin, kRealm5, HttpAuth::AUTH_SCHEME_BASIC, kAlice, k123)); 325 326 // Fails because the origin is wrong. 327 EXPECT_FALSE(cache.Remove(GURL("http://foobar2.com:100"), 328 kRealm1, 329 HttpAuth::AUTH_SCHEME_BASIC, 330 kAlice, 331 k123)); 332 333 // Fails because the username is wrong. 334 EXPECT_FALSE(cache.Remove( 335 origin, kRealm1, HttpAuth::AUTH_SCHEME_BASIC, kAlice2, k123)); 336 337 // Fails because the password is wrong. 338 EXPECT_FALSE(cache.Remove( 339 origin, kRealm1, HttpAuth::AUTH_SCHEME_BASIC, kAlice, k1234)); 340 341 // Fails because the authentication type is wrong. 342 EXPECT_FALSE(cache.Remove( 343 origin, kRealm1, HttpAuth::AUTH_SCHEME_DIGEST, kAlice, k123)); 344 345 // Succeeds. 346 EXPECT_TRUE(cache.Remove( 347 origin, kRealm1, HttpAuth::AUTH_SCHEME_BASIC, kAlice, k123)); 348 349 // Fails because we just deleted the entry! 350 EXPECT_FALSE(cache.Remove( 351 origin, kRealm1, HttpAuth::AUTH_SCHEME_BASIC, kAlice, k123)); 352 353 // Succeed when there are two authentication types for the same origin,realm. 354 EXPECT_TRUE(cache.Remove( 355 origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST, kRoot, kWileCoyote)); 356 357 // Succeed as above, but when entries were added in opposite order 358 cache.Add(origin, realm3_digest_handler->realm(), 359 realm3_digest_handler->auth_scheme(), "digest realm=Realm3", 360 kRoot, kWileCoyote, "/"); 361 EXPECT_TRUE(cache.Remove( 362 origin, kRealm3, HttpAuth::AUTH_SCHEME_BASIC, kAdmin, kPassword)); 363 364 // Make sure that removing one entry still leaves the other available for 365 // lookup. 366 HttpAuthCache::Entry* entry = cache.Lookup( 367 origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST); 368 EXPECT_FALSE(NULL == entry); 369 } 370 371 TEST(HttpAuthCacheTest, UpdateStaleChallenge) { 372 HttpAuthCache cache; 373 GURL origin("http://foobar2.com"); 374 scoped_ptr<HttpAuthHandler> digest_handler( 375 new MockAuthHandler( 376 HttpAuth::AUTH_SCHEME_DIGEST, kRealm1, HttpAuth::AUTH_PROXY)); 377 HttpAuthCache::Entry* entry_pre = cache.Add( 378 origin, 379 digest_handler->realm(), 380 digest_handler->auth_scheme(), 381 "Digest realm=Realm1," 382 "nonce=\"s3MzvFhaBAA=4c520af5acd9d8d7ae26947529d18c8eae1e98f4\"", 383 ASCIIToUTF16("realm-digest-user"), 384 ASCIIToUTF16("realm-digest-password"), 385 "/baz/index.html"); 386 ASSERT_TRUE(entry_pre != NULL); 387 388 EXPECT_EQ(2, entry_pre->IncrementNonceCount()); 389 EXPECT_EQ(3, entry_pre->IncrementNonceCount()); 390 EXPECT_EQ(4, entry_pre->IncrementNonceCount()); 391 392 bool update_success = cache.UpdateStaleChallenge( 393 origin, 394 digest_handler->realm(), 395 digest_handler->auth_scheme(), 396 "Digest realm=Realm1," 397 "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\"," 398 "stale=\"true\""); 399 EXPECT_TRUE(update_success); 400 401 // After the stale update, the entry should still exist in the cache and 402 // the nonce count should be reset to 0. 403 HttpAuthCache::Entry* entry_post = cache.Lookup( 404 origin, 405 digest_handler->realm(), 406 digest_handler->auth_scheme()); 407 ASSERT_TRUE(entry_post != NULL); 408 EXPECT_EQ(2, entry_post->IncrementNonceCount()); 409 410 // UpdateStaleChallenge will fail if an entry doesn't exist in the cache. 411 bool update_failure = cache.UpdateStaleChallenge( 412 origin, 413 kRealm2, 414 digest_handler->auth_scheme(), 415 "Digest realm=Realm2," 416 "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\"," 417 "stale=\"true\""); 418 EXPECT_FALSE(update_failure); 419 } 420 421 // Test fixture class for eviction tests (contains helpers for bulk 422 // insertion and existence testing). 423 class HttpAuthCacheEvictionTest : public testing::Test { 424 protected: 425 HttpAuthCacheEvictionTest() : origin_("http://www.google.com") { } 426 427 std::string GenerateRealm(int realm_i) { 428 return base::StringPrintf("Realm %d", realm_i); 429 } 430 431 std::string GeneratePath(int realm_i, int path_i) { 432 return base::StringPrintf("/%d/%d/x/y", realm_i, path_i); 433 } 434 435 void AddRealm(int realm_i) { 436 AddPathToRealm(realm_i, 0); 437 } 438 439 void AddPathToRealm(int realm_i, int path_i) { 440 cache_.Add(origin_, GenerateRealm(realm_i), HttpAuth::AUTH_SCHEME_BASIC, "", 441 kUsername, kPassword, GeneratePath(realm_i, path_i)); 442 } 443 444 void CheckRealmExistence(int realm_i, bool exists) { 445 const HttpAuthCache::Entry* entry = 446 cache_.Lookup( 447 origin_, GenerateRealm(realm_i), HttpAuth::AUTH_SCHEME_BASIC); 448 if (exists) { 449 EXPECT_FALSE(entry == NULL); 450 EXPECT_EQ(GenerateRealm(realm_i), entry->realm()); 451 } else { 452 EXPECT_TRUE(entry == NULL); 453 } 454 } 455 456 void CheckPathExistence(int realm_i, int path_i, bool exists) { 457 const HttpAuthCache::Entry* entry = 458 cache_.LookupByPath(origin_, GeneratePath(realm_i, path_i)); 459 if (exists) { 460 EXPECT_FALSE(entry == NULL); 461 EXPECT_EQ(GenerateRealm(realm_i), entry->realm()); 462 } else { 463 EXPECT_TRUE(entry == NULL); 464 } 465 } 466 467 GURL origin_; 468 HttpAuthCache cache_; 469 470 static const int kMaxPaths = HttpAuthCache::kMaxNumPathsPerRealmEntry; 471 static const int kMaxRealms = HttpAuthCache::kMaxNumRealmEntries; 472 }; 473 474 // Add the maxinim number of realm entries to the cache. Each of these entries 475 // must still be retrievable. Next add three more entries -- since the cache is 476 // full this causes FIFO eviction of the first three entries. 477 TEST_F(HttpAuthCacheEvictionTest, RealmEntryEviction) { 478 for (int i = 0; i < kMaxRealms; ++i) 479 AddRealm(i); 480 481 for (int i = 0; i < kMaxRealms; ++i) 482 CheckRealmExistence(i, true); 483 484 for (int i = 0; i < 3; ++i) 485 AddRealm(i + kMaxRealms); 486 487 for (int i = 0; i < 3; ++i) 488 CheckRealmExistence(i, false); 489 490 for (int i = 0; i < kMaxRealms; ++i) 491 CheckRealmExistence(i + 3, true); 492 } 493 494 // Add the maximum number of paths to a single realm entry. Each of these 495 // paths should be retrievable. Next add 3 more paths -- since the cache is 496 // full this causes FIFO eviction of the first three paths. 497 TEST_F(HttpAuthCacheEvictionTest, RealmPathEviction) { 498 for (int i = 0; i < kMaxPaths; ++i) 499 AddPathToRealm(0, i); 500 501 for (int i = 1; i < kMaxRealms; ++i) 502 AddRealm(i); 503 504 for (int i = 0; i < 3; ++i) 505 AddPathToRealm(0, i + kMaxPaths); 506 507 for (int i = 0; i < 3; ++i) 508 CheckPathExistence(0, i, false); 509 510 for (int i = 0; i < kMaxPaths; ++i) 511 CheckPathExistence(0, i + 3, true); 512 513 for (int i = 0; i < kMaxRealms; ++i) 514 CheckRealmExistence(i, true); 515 } 516 517 } // namespace net 518