Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(494)

Side by Side Diff: google_apis/gaia/oauth2_token_service_unittest.cc

Issue 22581003: Handling of multiple concurrent requests from different clients in OAuth2TokenService (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <string> 5 #include <string>
6 6
7 #include "base/message_loop/message_loop.h" 7 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h" 8 #include "base/run_loop.h"
9 #include "google_apis/gaia/gaia_constants.h" 9 #include "google_apis/gaia/gaia_constants.h"
10 #include "google_apis/gaia/google_service_auth_error.h" 10 #include "google_apis/gaia/google_service_auth_error.h"
11 #include "google_apis/gaia/oauth2_access_token_consumer.h" 11 #include "google_apis/gaia/oauth2_access_token_consumer.h"
12 #include "google_apis/gaia/oauth2_access_token_fetcher.h"
12 #include "google_apis/gaia/oauth2_token_service.h" 13 #include "google_apis/gaia/oauth2_token_service.h"
13 #include "google_apis/gaia/oauth2_token_service_test_util.h" 14 #include "google_apis/gaia/oauth2_token_service_test_util.h"
14 #include "net/http/http_status_code.h" 15 #include "net/http/http_status_code.h"
15 #include "net/url_request/test_url_fetcher_factory.h" 16 #include "net/url_request/test_url_fetcher_factory.h"
16 #include "net/url_request/url_fetcher_delegate.h" 17 #include "net/url_request/url_fetcher_delegate.h"
17 #include "net/url_request/url_request_test_util.h" 18 #include "net/url_request/url_request_test_util.h"
18 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
19 20
20 // A testing consumer that retries on error. 21 // A testing consumer that retries on error.
21 class RetryingTestingOAuth2TokenServiceConsumer 22 class RetryingTestingOAuth2TokenServiceConsumer
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 public: 72 public:
72 virtual void SetUp() OVERRIDE { 73 virtual void SetUp() OVERRIDE {
73 oauth2_service_.reset( 74 oauth2_service_.reset(
74 new TestOAuth2TokenService(new net::TestURLRequestContextGetter( 75 new TestOAuth2TokenService(new net::TestURLRequestContextGetter(
75 message_loop_.message_loop_proxy()))); 76 message_loop_.message_loop_proxy())));
76 } 77 }
77 78
78 virtual void TearDown() OVERRIDE { 79 virtual void TearDown() OVERRIDE {
79 // Makes sure that all the clean up tasks are run. 80 // Makes sure that all the clean up tasks are run.
80 base::RunLoop().RunUntilIdle(); 81 base::RunLoop().RunUntilIdle();
82 OAuth2AccessTokenFetcher::ResetLastFetcherIdForTest();
81 } 83 }
82 84
83 protected: 85 protected:
84 base::MessageLoopForIO message_loop_; // net:: stuff needs IO message loop. 86 base::MessageLoopForIO message_loop_; // net:: stuff needs IO message loop.
85 net::TestURLFetcherFactory factory_; 87 net::TestURLFetcherFactory factory_;
86 scoped_ptr<TestOAuth2TokenService> oauth2_service_; 88 scoped_ptr<TestOAuth2TokenService> oauth2_service_;
87 TestingOAuth2TokenServiceConsumer consumer_; 89 TestingOAuth2TokenServiceConsumer consumer_;
88 }; 90 };
89 91
90 TEST_F(OAuth2TokenServiceTest, NoOAuth2RefreshToken) { 92 TEST_F(OAuth2TokenServiceTest, NoOAuth2RefreshToken) {
91 scoped_ptr<OAuth2TokenService::Request> request( 93 scoped_ptr<OAuth2TokenService::Request> request(
92 oauth2_service_->StartRequest(std::set<std::string>(), &consumer_)); 94 oauth2_service_->StartRequest(std::set<std::string>(), &consumer_));
93 base::RunLoop().RunUntilIdle(); 95 base::RunLoop().RunUntilIdle();
94 96
95 EXPECT_EQ(0, consumer_.number_of_successful_tokens_); 97 EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
96 EXPECT_EQ(1, consumer_.number_of_errors_); 98 EXPECT_EQ(1, consumer_.number_of_errors_);
97 } 99 }
98 100
99 TEST_F(OAuth2TokenServiceTest, FailureShouldNotRetry) { 101 TEST_F(OAuth2TokenServiceTest, FailureShouldNotRetry) {
100 oauth2_service_->set_refresh_token("refreshToken"); 102 oauth2_service_->set_refresh_token("refreshToken");
101 scoped_ptr<OAuth2TokenService::Request> request( 103 scoped_ptr<OAuth2TokenService::Request> request(
102 oauth2_service_->StartRequest(std::set<std::string>(), &consumer_)); 104 oauth2_service_->StartRequest(std::set<std::string>(), &consumer_));
103 base::RunLoop().RunUntilIdle(); 105 base::RunLoop().RunUntilIdle();
104 106
105 EXPECT_EQ(0, consumer_.number_of_successful_tokens_); 107 EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
106 EXPECT_EQ(0, consumer_.number_of_errors_); 108 EXPECT_EQ(0, consumer_.number_of_errors_);
107 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); 109 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
108 EXPECT_TRUE(fetcher); 110 ASSERT_TRUE(fetcher);
109 fetcher->set_response_code(net::HTTP_UNAUTHORIZED); 111 fetcher->set_response_code(net::HTTP_UNAUTHORIZED);
110 fetcher->SetResponseString(std::string()); 112 fetcher->SetResponseString(std::string());
111 fetcher->delegate()->OnURLFetchComplete(fetcher); 113 fetcher->delegate()->OnURLFetchComplete(fetcher);
112 EXPECT_EQ(0, consumer_.number_of_successful_tokens_); 114 EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
113 EXPECT_EQ(1, consumer_.number_of_errors_); 115 EXPECT_EQ(1, consumer_.number_of_errors_);
114 EXPECT_EQ(fetcher, factory_.GetFetcherByID(0)); 116 EXPECT_EQ(fetcher, factory_.GetFetcherByID(0));
115 } 117 }
116 118
117 TEST_F(OAuth2TokenServiceTest, SuccessWithoutCaching) { 119 TEST_F(OAuth2TokenServiceTest, SuccessWithoutCaching) {
118 oauth2_service_->set_refresh_token("refreshToken"); 120 oauth2_service_->set_refresh_token("refreshToken");
119 scoped_ptr<OAuth2TokenService::Request> request( 121 scoped_ptr<OAuth2TokenService::Request> request(
120 oauth2_service_->StartRequest(std::set<std::string>(), &consumer_)); 122 oauth2_service_->StartRequest(std::set<std::string>(), &consumer_));
121 base::RunLoop().RunUntilIdle(); 123 base::RunLoop().RunUntilIdle();
122 124
123 EXPECT_EQ(0, consumer_.number_of_successful_tokens_); 125 EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
124 EXPECT_EQ(0, consumer_.number_of_errors_); 126 EXPECT_EQ(0, consumer_.number_of_errors_);
125 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); 127 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
126 EXPECT_TRUE(fetcher); 128 ASSERT_TRUE(fetcher);
127 fetcher->set_response_code(net::HTTP_OK); 129 fetcher->set_response_code(net::HTTP_OK);
128 fetcher->SetResponseString(GetValidTokenResponse("token", 3600)); 130 fetcher->SetResponseString(GetValidTokenResponse("token", 3600));
129 fetcher->delegate()->OnURLFetchComplete(fetcher); 131 fetcher->delegate()->OnURLFetchComplete(fetcher);
130 EXPECT_EQ(1, consumer_.number_of_successful_tokens_); 132 EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
131 EXPECT_EQ(0, consumer_.number_of_errors_); 133 EXPECT_EQ(0, consumer_.number_of_errors_);
132 EXPECT_EQ("token", consumer_.last_token_); 134 EXPECT_EQ("token", consumer_.last_token_);
133 } 135 }
134 136
135 TEST_F(OAuth2TokenServiceTest, SuccessWithCaching) { 137 TEST_F(OAuth2TokenServiceTest, SuccessWithCaching) {
136 std::set<std::string> scopes1; 138 std::set<std::string> scopes1;
137 scopes1.insert("s1"); 139 scopes1.insert("s1");
138 scopes1.insert("s2"); 140 scopes1.insert("s2");
139 std::set<std::string> scopes1_same; 141 std::set<std::string> scopes1_same;
140 scopes1_same.insert("s2"); 142 scopes1_same.insert("s2");
141 scopes1_same.insert("s1"); 143 scopes1_same.insert("s1");
142 std::set<std::string> scopes2; 144 std::set<std::string> scopes2;
143 scopes2.insert("s3"); 145 scopes2.insert("s3");
144 146
145 oauth2_service_->set_refresh_token("refreshToken"); 147 oauth2_service_->set_refresh_token("refreshToken");
146 148
147 // First request. 149 // First request.
148 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest( 150 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest(
149 scopes1, &consumer_)); 151 scopes1, &consumer_));
150 base::RunLoop().RunUntilIdle(); 152 base::RunLoop().RunUntilIdle();
151 153
152 EXPECT_EQ(0, consumer_.number_of_successful_tokens_); 154 EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
153 EXPECT_EQ(0, consumer_.number_of_errors_); 155 EXPECT_EQ(0, consumer_.number_of_errors_);
154 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); 156 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
155 EXPECT_TRUE(fetcher); 157 ASSERT_TRUE(fetcher);
156 fetcher->set_response_code(net::HTTP_OK); 158 fetcher->set_response_code(net::HTTP_OK);
157 fetcher->SetResponseString(GetValidTokenResponse("token", 3600)); 159 fetcher->SetResponseString(GetValidTokenResponse("token", 3600));
158 fetcher->delegate()->OnURLFetchComplete(fetcher); 160 fetcher->delegate()->OnURLFetchComplete(fetcher);
159 EXPECT_EQ(1, consumer_.number_of_successful_tokens_); 161 EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
160 EXPECT_EQ(0, consumer_.number_of_errors_); 162 EXPECT_EQ(0, consumer_.number_of_errors_);
161 EXPECT_EQ("token", consumer_.last_token_); 163 EXPECT_EQ("token", consumer_.last_token_);
162 164
163 // Second request to the same set of scopes, should return the same token 165 // Second request to the same set of scopes, should return the same token
164 // without needing a network request. 166 // without needing a network request.
165 scoped_ptr<OAuth2TokenService::Request> request2( 167 scoped_ptr<OAuth2TokenService::Request> request2(
166 oauth2_service_->StartRequest(scopes1_same, &consumer_)); 168 oauth2_service_->StartRequest(scopes1_same, &consumer_));
167 base::RunLoop().RunUntilIdle(); 169 base::RunLoop().RunUntilIdle();
168 170
169 // No new network fetcher. 171 // No new network fetcher.
170 EXPECT_EQ(fetcher, factory_.GetFetcherByID(0)); 172 EXPECT_EQ(1U, factory_.GetFetcherCount());
171 EXPECT_EQ(2, consumer_.number_of_successful_tokens_); 173 EXPECT_EQ(2, consumer_.number_of_successful_tokens_);
172 EXPECT_EQ(0, consumer_.number_of_errors_); 174 EXPECT_EQ(0, consumer_.number_of_errors_);
173 EXPECT_EQ("token", consumer_.last_token_); 175 EXPECT_EQ("token", consumer_.last_token_);
174 176
175 // Third request to a new set of scopes, should return another token. 177 // Third request to a new set of scopes, should return another token.
176 scoped_ptr<OAuth2TokenService::Request> request3( 178 scoped_ptr<OAuth2TokenService::Request> request3(
177 oauth2_service_->StartRequest(scopes2, &consumer_)); 179 oauth2_service_->StartRequest(scopes2, &consumer_));
178 base::RunLoop().RunUntilIdle(); 180 base::RunLoop().RunUntilIdle();
179 EXPECT_EQ(2, consumer_.number_of_successful_tokens_); 181 EXPECT_EQ(2, consumer_.number_of_successful_tokens_);
180 EXPECT_EQ(0, consumer_.number_of_errors_); 182 EXPECT_EQ(0, consumer_.number_of_errors_);
181 fetcher = factory_.GetFetcherByID(0); 183 ASSERT_EQ(2U, factory_.GetFetcherCount());
182 EXPECT_TRUE(fetcher); 184 fetcher = factory_.GetFetcherByID(1);
185 ASSERT_TRUE(fetcher);
183 fetcher->set_response_code(net::HTTP_OK); 186 fetcher->set_response_code(net::HTTP_OK);
184 fetcher->SetResponseString(GetValidTokenResponse("token2", 3600)); 187 fetcher->SetResponseString(GetValidTokenResponse("token2", 3600));
185 fetcher->delegate()->OnURLFetchComplete(fetcher); 188 fetcher->delegate()->OnURLFetchComplete(fetcher);
186 EXPECT_EQ(3, consumer_.number_of_successful_tokens_); 189 EXPECT_EQ(3, consumer_.number_of_successful_tokens_);
187 EXPECT_EQ(0, consumer_.number_of_errors_); 190 EXPECT_EQ(0, consumer_.number_of_errors_);
188 EXPECT_EQ("token2", consumer_.last_token_); 191 EXPECT_EQ("token2", consumer_.last_token_);
189 } 192 }
190 193
191 TEST_F(OAuth2TokenServiceTest, SuccessAndExpirationAndFailure) { 194 TEST_F(OAuth2TokenServiceTest, SuccessAndExpirationAndFailure) {
192 oauth2_service_->set_refresh_token("refreshToken"); 195 oauth2_service_->set_refresh_token("refreshToken");
193 196
194 // First request. 197 // First request.
195 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest( 198 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest(
196 std::set<std::string>(), &consumer_)); 199 std::set<std::string>(), &consumer_));
197 base::RunLoop().RunUntilIdle(); 200 base::RunLoop().RunUntilIdle();
198 EXPECT_EQ(0, consumer_.number_of_successful_tokens_); 201 EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
199 EXPECT_EQ(0, consumer_.number_of_errors_); 202 EXPECT_EQ(0, consumer_.number_of_errors_);
200 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); 203 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
201 EXPECT_TRUE(fetcher); 204 ASSERT_TRUE(fetcher);
202 fetcher->set_response_code(net::HTTP_OK); 205 fetcher->set_response_code(net::HTTP_OK);
203 fetcher->SetResponseString(GetValidTokenResponse("token", 0)); 206 fetcher->SetResponseString(GetValidTokenResponse("token", 0));
204 fetcher->delegate()->OnURLFetchComplete(fetcher); 207 fetcher->delegate()->OnURLFetchComplete(fetcher);
205 EXPECT_EQ(1, consumer_.number_of_successful_tokens_); 208 EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
206 EXPECT_EQ(0, consumer_.number_of_errors_); 209 EXPECT_EQ(0, consumer_.number_of_errors_);
207 EXPECT_EQ("token", consumer_.last_token_); 210 EXPECT_EQ("token", consumer_.last_token_);
208 211
209 // Second request must try to access the network as the token has expired. 212 // Second request must try to access the network as the token has expired.
210 scoped_ptr<OAuth2TokenService::Request> request2( 213 scoped_ptr<OAuth2TokenService::Request> request2(
211 oauth2_service_->StartRequest(std::set<std::string>(), &consumer_)); 214 oauth2_service_->StartRequest(std::set<std::string>(), &consumer_));
212 base::RunLoop().RunUntilIdle(); 215 base::RunLoop().RunUntilIdle();
213 EXPECT_EQ(1, consumer_.number_of_successful_tokens_); 216 EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
214 EXPECT_EQ(0, consumer_.number_of_errors_); 217 EXPECT_EQ(0, consumer_.number_of_errors_);
215 218
216 // Network failure. 219 // Network failure.
217 fetcher = factory_.GetFetcherByID(0); 220 ASSERT_EQ(2U, factory_.GetFetcherCount());
218 EXPECT_TRUE(fetcher); 221 fetcher = factory_.GetFetcherByID(1);
222 ASSERT_TRUE(fetcher);
219 fetcher->set_response_code(net::HTTP_UNAUTHORIZED); 223 fetcher->set_response_code(net::HTTP_UNAUTHORIZED);
220 fetcher->SetResponseString(std::string()); 224 fetcher->SetResponseString(std::string());
221 fetcher->delegate()->OnURLFetchComplete(fetcher); 225 fetcher->delegate()->OnURLFetchComplete(fetcher);
222 EXPECT_EQ(1, consumer_.number_of_successful_tokens_); 226 EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
223 EXPECT_EQ(1, consumer_.number_of_errors_); 227 EXPECT_EQ(1, consumer_.number_of_errors_);
224 } 228 }
225 229
226 TEST_F(OAuth2TokenServiceTest, SuccessAndExpirationAndSuccess) { 230 TEST_F(OAuth2TokenServiceTest, SuccessAndExpirationAndSuccess) {
227 oauth2_service_->set_refresh_token("refreshToken"); 231 oauth2_service_->set_refresh_token("refreshToken");
228 232
229 // First request. 233 // First request.
230 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest( 234 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest(
231 std::set<std::string>(), &consumer_)); 235 std::set<std::string>(), &consumer_));
232 base::RunLoop().RunUntilIdle(); 236 base::RunLoop().RunUntilIdle();
233 EXPECT_EQ(0, consumer_.number_of_successful_tokens_); 237 EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
234 EXPECT_EQ(0, consumer_.number_of_errors_); 238 EXPECT_EQ(0, consumer_.number_of_errors_);
235 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); 239 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
236 EXPECT_TRUE(fetcher); 240 ASSERT_TRUE(fetcher);
237 fetcher->set_response_code(net::HTTP_OK); 241 fetcher->set_response_code(net::HTTP_OK);
238 fetcher->SetResponseString(GetValidTokenResponse("token", 0)); 242 fetcher->SetResponseString(GetValidTokenResponse("token", 0));
239 fetcher->delegate()->OnURLFetchComplete(fetcher); 243 fetcher->delegate()->OnURLFetchComplete(fetcher);
240 EXPECT_EQ(1, consumer_.number_of_successful_tokens_); 244 EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
241 EXPECT_EQ(0, consumer_.number_of_errors_); 245 EXPECT_EQ(0, consumer_.number_of_errors_);
242 EXPECT_EQ("token", consumer_.last_token_); 246 EXPECT_EQ("token", consumer_.last_token_);
243 247
244 // Second request must try to access the network as the token has expired. 248 // Second request must try to access the network as the token has expired.
245 scoped_ptr<OAuth2TokenService::Request> request2( 249 scoped_ptr<OAuth2TokenService::Request> request2(
246 oauth2_service_->StartRequest(std::set<std::string>(), &consumer_)); 250 oauth2_service_->StartRequest(std::set<std::string>(), &consumer_));
247 base::RunLoop().RunUntilIdle(); 251 base::RunLoop().RunUntilIdle();
248 EXPECT_EQ(1, consumer_.number_of_successful_tokens_); 252 EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
249 EXPECT_EQ(0, consumer_.number_of_errors_); 253 EXPECT_EQ(0, consumer_.number_of_errors_);
250 254
251 fetcher = factory_.GetFetcherByID(0); 255 ASSERT_EQ(2U, factory_.GetFetcherCount());
252 EXPECT_TRUE(fetcher); 256 fetcher = factory_.GetFetcherByID(1);
257 ASSERT_TRUE(fetcher);
253 fetcher->set_response_code(net::HTTP_OK); 258 fetcher->set_response_code(net::HTTP_OK);
254 fetcher->SetResponseString(GetValidTokenResponse("another token", 0)); 259 fetcher->SetResponseString(GetValidTokenResponse("another token", 0));
255 fetcher->delegate()->OnURLFetchComplete(fetcher); 260 fetcher->delegate()->OnURLFetchComplete(fetcher);
256 EXPECT_EQ(2, consumer_.number_of_successful_tokens_); 261 EXPECT_EQ(2, consumer_.number_of_successful_tokens_);
257 EXPECT_EQ(0, consumer_.number_of_errors_); 262 EXPECT_EQ(0, consumer_.number_of_errors_);
258 EXPECT_EQ("another token", consumer_.last_token_); 263 EXPECT_EQ("another token", consumer_.last_token_);
259 } 264 }
260 265
261 TEST_F(OAuth2TokenServiceTest, RequestDeletedBeforeCompletion) { 266 TEST_F(OAuth2TokenServiceTest, RequestDeletedBeforeCompletion) {
262 oauth2_service_->set_refresh_token("refreshToken"); 267 oauth2_service_->set_refresh_token("refreshToken");
263 268
264 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest( 269 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest(
265 std::set<std::string>(), &consumer_)); 270 std::set<std::string>(), &consumer_));
266 base::RunLoop().RunUntilIdle(); 271 base::RunLoop().RunUntilIdle();
267 EXPECT_EQ(0, consumer_.number_of_successful_tokens_); 272 EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
268 EXPECT_EQ(0, consumer_.number_of_errors_); 273 EXPECT_EQ(0, consumer_.number_of_errors_);
269 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); 274 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
270 EXPECT_TRUE(fetcher); 275 ASSERT_TRUE(fetcher);
271 276
272 request.reset(); 277 request.reset();
273 278
274 fetcher->set_response_code(net::HTTP_OK); 279 fetcher->set_response_code(net::HTTP_OK);
275 fetcher->SetResponseString(GetValidTokenResponse("token", 3600)); 280 fetcher->SetResponseString(GetValidTokenResponse("token", 3600));
276 fetcher->delegate()->OnURLFetchComplete(fetcher); 281 fetcher->delegate()->OnURLFetchComplete(fetcher);
277 EXPECT_EQ(0, consumer_.number_of_successful_tokens_); 282 EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
278 EXPECT_EQ(0, consumer_.number_of_errors_); 283 EXPECT_EQ(0, consumer_.number_of_errors_);
279 } 284 }
280 285
281 TEST_F(OAuth2TokenServiceTest, RequestDeletedAfterCompletion) { 286 TEST_F(OAuth2TokenServiceTest, RequestDeletedAfterCompletion) {
282 oauth2_service_->set_refresh_token("refreshToken"); 287 oauth2_service_->set_refresh_token("refreshToken");
283 288
284 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest( 289 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest(
285 std::set<std::string>(), &consumer_)); 290 std::set<std::string>(), &consumer_));
286 base::RunLoop().RunUntilIdle(); 291 base::RunLoop().RunUntilIdle();
287 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); 292 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
293 ASSERT_TRUE(fetcher);
288 fetcher->set_response_code(net::HTTP_OK); 294 fetcher->set_response_code(net::HTTP_OK);
289 fetcher->SetResponseString(GetValidTokenResponse("token", 3600)); 295 fetcher->SetResponseString(GetValidTokenResponse("token", 3600));
290 fetcher->delegate()->OnURLFetchComplete(fetcher); 296 fetcher->delegate()->OnURLFetchComplete(fetcher);
291 EXPECT_EQ(1, consumer_.number_of_successful_tokens_); 297 EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
292 EXPECT_EQ(0, consumer_.number_of_errors_); 298 EXPECT_EQ(0, consumer_.number_of_errors_);
293 EXPECT_EQ("token", consumer_.last_token_); 299 EXPECT_EQ("token", consumer_.last_token_);
294 300
295 request.reset(); 301 request.reset();
296 302
297 EXPECT_EQ(1, consumer_.number_of_successful_tokens_); 303 EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
298 EXPECT_EQ(0, consumer_.number_of_errors_); 304 EXPECT_EQ(0, consumer_.number_of_errors_);
299 EXPECT_EQ("token", consumer_.last_token_); 305 EXPECT_EQ("token", consumer_.last_token_);
300 } 306 }
301 307
302 TEST_F(OAuth2TokenServiceTest, MultipleRequestsForTheSameScopesWithOneDeleted) { 308 TEST_F(OAuth2TokenServiceTest, MultipleRequestsForTheSameScopesWithOneDeleted) {
303 oauth2_service_->set_refresh_token("refreshToken"); 309 oauth2_service_->set_refresh_token("refreshToken");
304 310
305 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest( 311 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest(
306 std::set<std::string>(), &consumer_)); 312 std::set<std::string>(), &consumer_));
307 base::RunLoop().RunUntilIdle(); 313 base::RunLoop().RunUntilIdle();
308 scoped_ptr<OAuth2TokenService::Request> request2( 314 scoped_ptr<OAuth2TokenService::Request> request2(
309 oauth2_service_->StartRequest(std::set<std::string>(), &consumer_)); 315 oauth2_service_->StartRequest(std::set<std::string>(), &consumer_));
310 base::RunLoop().RunUntilIdle(); 316 base::RunLoop().RunUntilIdle();
311 317
312 request.reset(); 318 request.reset();
313 319
314 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); 320 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
321 ASSERT_TRUE(fetcher);
315 fetcher->set_response_code(net::HTTP_OK); 322 fetcher->set_response_code(net::HTTP_OK);
316 fetcher->SetResponseString(GetValidTokenResponse("token", 3600)); 323 fetcher->SetResponseString(GetValidTokenResponse("token", 3600));
317 fetcher->delegate()->OnURLFetchComplete(fetcher); 324 fetcher->delegate()->OnURLFetchComplete(fetcher);
318 EXPECT_EQ(1, consumer_.number_of_successful_tokens_); 325 EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
319 EXPECT_EQ(0, consumer_.number_of_errors_); 326 EXPECT_EQ(0, consumer_.number_of_errors_);
320 } 327 }
321 328
322 TEST_F(OAuth2TokenServiceTest, ClearedRefreshTokenFailsSubsequentRequests) { 329 TEST_F(OAuth2TokenServiceTest, ClearedRefreshTokenFailsSubsequentRequests) {
323 // We have a valid refresh token; the first request is successful. 330 // We have a valid refresh token; the first request is successful.
324 oauth2_service_->set_refresh_token("refreshToken"); 331 oauth2_service_->set_refresh_token("refreshToken");
325 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest( 332 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest(
326 std::set<std::string>(), &consumer_)); 333 std::set<std::string>(), &consumer_));
327 base::RunLoop().RunUntilIdle(); 334 base::RunLoop().RunUntilIdle();
328 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); 335 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
336 ASSERT_TRUE(fetcher);
329 fetcher->set_response_code(net::HTTP_OK); 337 fetcher->set_response_code(net::HTTP_OK);
330 fetcher->SetResponseString(GetValidTokenResponse("token", 3600)); 338 fetcher->SetResponseString(GetValidTokenResponse("token", 3600));
331 fetcher->delegate()->OnURLFetchComplete(fetcher); 339 fetcher->delegate()->OnURLFetchComplete(fetcher);
332 EXPECT_EQ(1, consumer_.number_of_successful_tokens_); 340 EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
333 EXPECT_EQ(0, consumer_.number_of_errors_); 341 EXPECT_EQ(0, consumer_.number_of_errors_);
334 EXPECT_EQ("token", consumer_.last_token_); 342 EXPECT_EQ("token", consumer_.last_token_);
335 343
336 // The refresh token is no longer available; subsequent requests fail. 344 // The refresh token is no longer available; subsequent requests fail.
337 oauth2_service_->set_refresh_token(""); 345 oauth2_service_->set_refresh_token("");
338 request = oauth2_service_->StartRequest(std::set<std::string>(), &consumer_); 346 request = oauth2_service_->StartRequest(std::set<std::string>(), &consumer_);
339 base::RunLoop().RunUntilIdle(); 347 base::RunLoop().RunUntilIdle();
340 EXPECT_EQ(fetcher, factory_.GetFetcherByID(0)); 348 EXPECT_EQ(1U, factory_.GetFetcherCount());
341 EXPECT_EQ(1, consumer_.number_of_successful_tokens_); 349 EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
342 EXPECT_EQ(1, consumer_.number_of_errors_); 350 EXPECT_EQ(1, consumer_.number_of_errors_);
343 } 351 }
344 352
345 TEST_F(OAuth2TokenServiceTest, 353 TEST_F(OAuth2TokenServiceTest,
346 ChangedRefreshTokenDoesNotAffectInFlightRequests) { 354 ChangedRefreshTokenDoesNotAffectInFlightRequests) {
347 oauth2_service_->set_refresh_token("first refreshToken"); 355 oauth2_service_->set_refresh_token("first refreshToken");
348 std::set<std::string> scopes; 356 std::set<std::string> scopes;
349 scopes.insert("s1"); 357 scopes.insert("s1");
350 scopes.insert("s2"); 358 scopes.insert("s2");
351 359
352 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest( 360 scoped_ptr<OAuth2TokenService::Request> request(oauth2_service_->StartRequest(
353 scopes, &consumer_)); 361 scopes, &consumer_));
354 base::RunLoop().RunUntilIdle(); 362 base::RunLoop().RunUntilIdle();
363 ASSERT_EQ(1U, factory_.GetFetcherCount());
355 net::TestURLFetcher* fetcher1 = factory_.GetFetcherByID(0); 364 net::TestURLFetcher* fetcher1 = factory_.GetFetcherByID(0);
365 ASSERT_TRUE(fetcher1);
356 366
357 // Note |request| is still pending when the refresh token changes. 367 // Note |request| is still pending when the refresh token changes.
358 oauth2_service_->set_refresh_token("second refreshToken"); 368 oauth2_service_->set_refresh_token("second refreshToken");
359 369
360 // A 2nd request (using the new refresh token) that occurs and completes 370 // A 2nd request (using the new refresh token) that occurs and completes
361 // while the 1st request is in flight is successful. 371 // while the 1st request is in flight is successful.
362 TestingOAuth2TokenServiceConsumer consumer2; 372 TestingOAuth2TokenServiceConsumer consumer2;
363 scoped_ptr<OAuth2TokenService::Request> request2( 373 scoped_ptr<OAuth2TokenService::Request> request2(
364 oauth2_service_->StartRequest(scopes, &consumer2)); 374 oauth2_service_->StartRequest(scopes, &consumer2));
365 base::RunLoop().RunUntilIdle(); 375 base::RunLoop().RunUntilIdle();
366 376
367 net::TestURLFetcher* fetcher2 = factory_.GetFetcherByID(0); 377 ASSERT_EQ(2U, factory_.GetFetcherCount());
378 net::TestURLFetcher* fetcher2 = factory_.GetFetcherByID(1);
368 fetcher2->set_response_code(net::HTTP_OK); 379 fetcher2->set_response_code(net::HTTP_OK);
369 fetcher2->SetResponseString(GetValidTokenResponse("second token", 3600)); 380 fetcher2->SetResponseString(GetValidTokenResponse("second token", 3600));
370 fetcher2->delegate()->OnURLFetchComplete(fetcher2); 381 fetcher2->delegate()->OnURLFetchComplete(fetcher2);
371 EXPECT_EQ(1, consumer2.number_of_successful_tokens_); 382 EXPECT_EQ(1, consumer2.number_of_successful_tokens_);
372 EXPECT_EQ(0, consumer2.number_of_errors_); 383 EXPECT_EQ(0, consumer2.number_of_errors_);
373 EXPECT_EQ("second token", consumer2.last_token_); 384 EXPECT_EQ("second token", consumer2.last_token_);
374 385
375 fetcher1->set_response_code(net::HTTP_OK); 386 fetcher1->set_response_code(net::HTTP_OK);
376 fetcher1->SetResponseString(GetValidTokenResponse("first token", 3600)); 387 fetcher1->SetResponseString(GetValidTokenResponse("first token", 3600));
377 fetcher1->delegate()->OnURLFetchComplete(fetcher1); 388 fetcher1->delegate()->OnURLFetchComplete(fetcher1);
(...skipping 27 matching lines...) Expand all
405 EXPECT_EQ(0, consumer.number_of_errors_); 416 EXPECT_EQ(0, consumer.number_of_errors_);
406 417
407 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); 418 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
408 ASSERT_TRUE(fetcher); 419 ASSERT_TRUE(fetcher);
409 fetcher->set_response_code(net::HTTP_UNAUTHORIZED); 420 fetcher->set_response_code(net::HTTP_UNAUTHORIZED);
410 fetcher->SetResponseString(std::string()); 421 fetcher->SetResponseString(std::string());
411 fetcher->delegate()->OnURLFetchComplete(fetcher); 422 fetcher->delegate()->OnURLFetchComplete(fetcher);
412 EXPECT_EQ(0, consumer.number_of_successful_tokens_); 423 EXPECT_EQ(0, consumer.number_of_successful_tokens_);
413 EXPECT_EQ(1, consumer.number_of_errors_); 424 EXPECT_EQ(1, consumer.number_of_errors_);
414 425
415 fetcher = factory_.GetFetcherByID(0); 426 ASSERT_EQ(2U, factory_.GetFetcherCount());
427 fetcher = factory_.GetFetcherByID(1);
416 ASSERT_TRUE(fetcher); 428 ASSERT_TRUE(fetcher);
417 fetcher->set_response_code(net::HTTP_UNAUTHORIZED); 429 fetcher->set_response_code(net::HTTP_UNAUTHORIZED);
418 fetcher->SetResponseString(std::string()); 430 fetcher->SetResponseString(std::string());
419 fetcher->delegate()->OnURLFetchComplete(fetcher); 431 fetcher->delegate()->OnURLFetchComplete(fetcher);
420 EXPECT_EQ(0, consumer.number_of_successful_tokens_); 432 EXPECT_EQ(0, consumer.number_of_successful_tokens_);
421 EXPECT_EQ(2, consumer.number_of_errors_); 433 EXPECT_EQ(2, consumer.number_of_errors_);
422 } 434 }
423 435
424 TEST_F(OAuth2TokenServiceTest, InvalidateToken) { 436 TEST_F(OAuth2TokenServiceTest, InvalidateToken) {
425 std::set<std::string> scopes; 437 std::set<std::string> scopes;
426 oauth2_service_->set_refresh_token("refreshToken"); 438 oauth2_service_->set_refresh_token("refreshToken");
427 439
428 // First request. 440 // First request.
429 scoped_ptr<OAuth2TokenService::Request> request( 441 scoped_ptr<OAuth2TokenService::Request> request(
430 oauth2_service_->StartRequest(scopes, &consumer_)); 442 oauth2_service_->StartRequest(scopes, &consumer_));
431 base::RunLoop().RunUntilIdle(); 443 base::RunLoop().RunUntilIdle();
432 444
433 EXPECT_EQ(0, consumer_.number_of_successful_tokens_); 445 EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
434 EXPECT_EQ(0, consumer_.number_of_errors_); 446 EXPECT_EQ(0, consumer_.number_of_errors_);
435 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); 447 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
436 EXPECT_TRUE(fetcher); 448 ASSERT_TRUE(fetcher);
437 fetcher->set_response_code(net::HTTP_OK); 449 fetcher->set_response_code(net::HTTP_OK);
438 fetcher->SetResponseString(GetValidTokenResponse("token", 3600)); 450 fetcher->SetResponseString(GetValidTokenResponse("token", 3600));
439 fetcher->delegate()->OnURLFetchComplete(fetcher); 451 fetcher->delegate()->OnURLFetchComplete(fetcher);
440 EXPECT_EQ(1, consumer_.number_of_successful_tokens_); 452 EXPECT_EQ(1, consumer_.number_of_successful_tokens_);
441 EXPECT_EQ(0, consumer_.number_of_errors_); 453 EXPECT_EQ(0, consumer_.number_of_errors_);
442 EXPECT_EQ("token", consumer_.last_token_); 454 EXPECT_EQ("token", consumer_.last_token_);
443 455
444 // Second request, should return the same token without needing a network 456 // Second request, should return the same token without needing a network
445 // request. 457 // request.
446 scoped_ptr<OAuth2TokenService::Request> request2( 458 scoped_ptr<OAuth2TokenService::Request> request2(
447 oauth2_service_->StartRequest(scopes, &consumer_)); 459 oauth2_service_->StartRequest(scopes, &consumer_));
448 base::RunLoop().RunUntilIdle(); 460 base::RunLoop().RunUntilIdle();
449 461
450 // No new network fetcher. 462 // No new network fetcher.
451 EXPECT_EQ(fetcher, factory_.GetFetcherByID(0)); 463 ASSERT_EQ(1U, factory_.GetFetcherCount());
452 EXPECT_EQ(2, consumer_.number_of_successful_tokens_); 464 EXPECT_EQ(2, consumer_.number_of_successful_tokens_);
453 EXPECT_EQ(0, consumer_.number_of_errors_); 465 EXPECT_EQ(0, consumer_.number_of_errors_);
454 EXPECT_EQ("token", consumer_.last_token_); 466 EXPECT_EQ("token", consumer_.last_token_);
455 467
456 // Invalidating the token should return a new token on the next request. 468 // Invalidating the token should return a new token on the next request.
457 oauth2_service_->InvalidateToken(scopes, consumer_.last_token_); 469 oauth2_service_->InvalidateToken(scopes, consumer_.last_token_);
458 scoped_ptr<OAuth2TokenService::Request> request3( 470 scoped_ptr<OAuth2TokenService::Request> request3(
459 oauth2_service_->StartRequest(scopes, &consumer_)); 471 oauth2_service_->StartRequest(scopes, &consumer_));
460 base::RunLoop().RunUntilIdle(); 472 base::RunLoop().RunUntilIdle();
461 EXPECT_EQ(2, consumer_.number_of_successful_tokens_); 473 EXPECT_EQ(2, consumer_.number_of_successful_tokens_);
462 EXPECT_EQ(0, consumer_.number_of_errors_); 474 EXPECT_EQ(0, consumer_.number_of_errors_);
463 fetcher = factory_.GetFetcherByID(0); 475 ASSERT_EQ(2U, factory_.GetFetcherCount());
464 EXPECT_TRUE(fetcher); 476 fetcher = factory_.GetFetcherByID(1);
477 ASSERT_TRUE(fetcher);
465 fetcher->set_response_code(net::HTTP_OK); 478 fetcher->set_response_code(net::HTTP_OK);
466 fetcher->SetResponseString(GetValidTokenResponse("token2", 3600)); 479 fetcher->SetResponseString(GetValidTokenResponse("token2", 3600));
467 fetcher->delegate()->OnURLFetchComplete(fetcher); 480 fetcher->delegate()->OnURLFetchComplete(fetcher);
468 EXPECT_EQ(3, consumer_.number_of_successful_tokens_); 481 EXPECT_EQ(3, consumer_.number_of_successful_tokens_);
469 EXPECT_EQ(0, consumer_.number_of_errors_); 482 EXPECT_EQ(0, consumer_.number_of_errors_);
470 EXPECT_EQ("token2", consumer_.last_token_); 483 EXPECT_EQ("token2", consumer_.last_token_);
471 } 484 }
472 485
473 TEST_F(OAuth2TokenServiceTest, CancelAllRequests) { 486 TEST_F(OAuth2TokenServiceTest, CancelAllRequests) {
474 oauth2_service_->set_refresh_token("refreshToken"); 487 oauth2_service_->set_refresh_token("refreshToken");
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 oauth2_service_->CancelRequestsForTokenForTest("refreshToken"); 526 oauth2_service_->CancelRequestsForTokenForTest("refreshToken");
514 527
515 EXPECT_EQ(0, consumer_.number_of_successful_tokens_); 528 EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
516 EXPECT_EQ(2, consumer_.number_of_errors_); 529 EXPECT_EQ(2, consumer_.number_of_errors_);
517 530
518 oauth2_service_->CancelRequestsForTokenForTest("refreshToken2"); 531 oauth2_service_->CancelRequestsForTokenForTest("refreshToken2");
519 532
520 EXPECT_EQ(0, consumer_.number_of_successful_tokens_); 533 EXPECT_EQ(0, consumer_.number_of_successful_tokens_);
521 EXPECT_EQ(3, consumer_.number_of_errors_); 534 EXPECT_EQ(3, consumer_.number_of_errors_);
522 } 535 }
536
537 TEST_F(OAuth2TokenServiceTest, SameScopesRequestedForDifferentClients) {
538 std::string client_id_1("client1");
539 std::string client_secret_1("secret1");
540 std::string client_id_2("client2");
541 std::string client_secret_2("secret2");
542 std::set<std::string> scope_set;
543 scope_set.insert("scope1");
544 scope_set.insert("scope2");
545
546 std::string refresh_token("refreshToken");
547 oauth2_service_->set_refresh_token(refresh_token);
548
549 scoped_ptr<OAuth2TokenService::Request> request1(
550 oauth2_service_->StartRequestForClient(client_id_1,
551 client_secret_1,
552 scope_set,
553 &consumer_));
554 scoped_ptr<OAuth2TokenService::Request> request2(
555 oauth2_service_->StartRequestForClient(client_id_2,
556 client_secret_2,
557 scope_set,
558 &consumer_));
559 // Start a request that should be duplicate of |request1|.
560 scoped_ptr<OAuth2TokenService::Request> request3(
561 oauth2_service_->StartRequestForClient(client_id_1,
562 client_secret_1,
563 scope_set,
564 &consumer_));
565 base::RunLoop().RunUntilIdle();
566
567 ASSERT_EQ(2U,
568 oauth2_service_->GetNumPendingRequestsForTesting(
569 client_id_1,
570 refresh_token,
571 scope_set));
572 ASSERT_EQ(1U,
573 oauth2_service_->GetNumPendingRequestsForTesting(
574 client_id_2,
575 refresh_token,
576 scope_set));
577 }
578
579 TEST_F(OAuth2TokenServiceTest, ClientScopeSetOrderTest) {
580 OAuth2TokenService::ScopeSet set_0;
581 OAuth2TokenService::ScopeSet set_1;
582 set_1.insert("1");
583
584 OAuth2TokenService::ClientScopeSet sets[] = {
585 OAuth2TokenService::ClientScopeSet("0", set_0),
586 OAuth2TokenService::ClientScopeSet("0", set_1),
587 OAuth2TokenService::ClientScopeSet("1", set_0),
588 OAuth2TokenService::ClientScopeSet("1", set_1),
589 };
590
591 for (size_t i = 0; i < arraysize(sets); i++) {
592 for (size_t j = 0; j < arraysize(sets); j++) {
593 if (i == j) {
594 EXPECT_FALSE(sets[i] < sets[j]) << " i=" << i << ", j=" << j;
595 EXPECT_FALSE(sets[j] < sets[i]) << " i=" << i << ", j=" << j;
596 } else if (i < j) {
597 EXPECT_TRUE(sets[i] < sets[j]) << " i=" << i << ", j=" << j;
598 EXPECT_FALSE(sets[j] < sets[i]) << " i=" << i << ", j=" << j;
599 } else {
600 EXPECT_TRUE(sets[j] < sets[i]) << " i=" << i << ", j=" << j;
601 EXPECT_FALSE(sets[i] < sets[j]) << " i=" << i << ", j=" << j;
602 }
603 }
604 }
605 }
606
607 TEST_F(OAuth2TokenServiceTest, FetchParametersOrderTest) {
608 OAuth2TokenService::ScopeSet set_0;
609 OAuth2TokenService::ScopeSet set_1;
610 set_1.insert("1");
611
612 OAuth2TokenService::FetchParameters params[] = {
613 OAuth2TokenService::FetchParameters("0", "0", set_0),
614 OAuth2TokenService::FetchParameters("0", "0", set_1),
615 OAuth2TokenService::FetchParameters("0", "1", set_0),
616 OAuth2TokenService::FetchParameters("0", "1", set_1),
617 OAuth2TokenService::FetchParameters("1", "0", set_0),
618 OAuth2TokenService::FetchParameters("1", "0", set_1),
619 OAuth2TokenService::FetchParameters("1", "1", set_0),
620 OAuth2TokenService::FetchParameters("1", "1", set_1),
621 };
622
623 for (size_t i = 0; i < arraysize(params); i++) {
624 for (size_t j = 0; j < arraysize(params); j++) {
625 if (i == j) {
626 EXPECT_FALSE(params[i] < params[j]) << " i=" << i << ", j=" << j;
627 EXPECT_FALSE(params[j] < params[i]) << " i=" << i << ", j=" << j;
628 } else if (i < j) {
629 EXPECT_TRUE(params[i] < params[j]) << " i=" << i << ", j=" << j;
630 EXPECT_FALSE(params[j] < params[i]) << " i=" << i << ", j=" << j;
631 } else {
632 EXPECT_TRUE(params[j] < params[i]) << " i=" << i << ", j=" << j;
633 EXPECT_FALSE(params[i] < params[j]) << " i=" << i << ", j=" << j;
634 }
635 }
636 }
637 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698