/Source/externals/GData/Source/HTTPFetcher/Tests/GTMHTTPFetcherCachingTest.m

http://google-email-uploader-mac.googlecode.com/ · Objective C · 275 lines · 172 code · 44 blank · 59 comment · 13 complexity · ac585bfd49496ab262a02bf0d7f62d69 MD5 · raw file

  1. /* Copyright (c) 2010 Google Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. //
  16. // GTMHTTPFetcherCachingTest.m
  17. //
  18. #import <XCTest/XCTest.h>
  19. #import "GTMHTTPFetcher.h"
  20. // copies of interfaces to private fetch history classes
  21. @interface GTMCachedURLResponse : NSObject
  22. - (id)initWithResponse:(NSURLResponse *)response data:(NSData *)data;
  23. - (NSURLResponse *)response;
  24. - (NSData *)data;
  25. - (NSDate *)useDate;
  26. - (void)setUseDate:(NSDate *)date;
  27. - (NSDate *)reservationDate;
  28. - (void)setReservationDate:(NSDate *)date;
  29. @end
  30. @interface GTMURLCache : NSObject
  31. - (id)initWithMemoryCapacity:(NSUInteger)totalBytes;
  32. - (GTMCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request;
  33. - (void)storeCachedResponse:(GTMCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request;
  34. - (void)removeCachedResponseForRequest:(NSURLRequest *)request;
  35. - (void)removeAllCachedResponses;
  36. - (NSUInteger)memoryCapacity;
  37. - (void)setMemoryCapacity:(NSUInteger)totalBytes;
  38. - (NSDictionary *)responses;
  39. - (NSUInteger)totalDataSize;
  40. - (void)setReservationInterval:(NSTimeInterval)secs;
  41. @end
  42. @interface GTMCookieStorage : NSObject
  43. - (void)setCookies:(NSArray *)newCookies;
  44. - (NSArray *)cookiesForURL:(NSURL *)theURL;
  45. - (NSHTTPCookie *)cookieMatchingCookie:(NSHTTPCookie *)cookie;
  46. - (void)removeExpiredCookies;
  47. - (void)removeAllCookies;
  48. @end
  49. @interface GTMHTTPFetcherCachingTest : XCTestCase
  50. @end
  51. @implementation GTMHTTPFetcherCachingTest
  52. - (void)testURLCache {
  53. // allocate a cache that prunes at 30 bytes of response data
  54. NSUInteger cacheCapacity = 30;
  55. GTMURLCache *cache = [[[GTMURLCache alloc] initWithMemoryCapacity:cacheCapacity] autorelease];
  56. // set the reservation interval for our cache to something quick
  57. const NSTimeInterval resInterval = 0.1;
  58. [cache setReservationInterval:resInterval];
  59. // allocate 6 responses with 10 bytes of data each; put a reservation on just
  60. // the second of the 6
  61. NSMutableArray *requests = [NSMutableArray array];
  62. NSMutableArray *cachedResponses = [NSMutableArray array];
  63. for (int idx = 0; idx < 6; idx++) {
  64. NSString *urlStr = [NSString stringWithFormat:@"http://example.com/%d", idx];
  65. NSURL *url = [NSURL URLWithString:urlStr];
  66. NSURLRequest *request = [NSURLRequest requestWithURL:url];
  67. [requests addObject:request];
  68. NSURLResponse *response;
  69. response = [[[NSURLResponse alloc] initWithURL:url
  70. MIMEType:@"text/xml"
  71. expectedContentLength:-1
  72. textEncodingName:nil] autorelease];
  73. GTMCachedURLResponse *cachedResponse;
  74. NSData *data = [@"1234567890" dataUsingEncoding:NSUTF8StringEncoding];
  75. XCTAssertEqual([data length], (NSUInteger) 10, @"data should be 10 bytes");
  76. cachedResponse = [[[GTMCachedURLResponse alloc] initWithResponse:response
  77. data:data] autorelease];
  78. [cachedResponses addObject:cachedResponse];
  79. if (idx == 1) {
  80. [cachedResponse setReservationDate:[NSDate date]];
  81. }
  82. [cache storeCachedResponse:cachedResponse
  83. forRequest:request];
  84. }
  85. // step through retrieving all previous requests
  86. //
  87. // the cache should contain the second response (since it's reserved) and the
  88. // last two responses
  89. for (int idx = 0; idx < 6; idx++) {
  90. NSURLRequest *request = [requests objectAtIndex:idx];
  91. GTMCachedURLResponse *cachedResponse, *expectedResponse;
  92. cachedResponse = [cache cachedResponseForRequest:request];
  93. if (idx == 1 || idx >= 4) {
  94. expectedResponse = [cachedResponses objectAtIndex:idx];
  95. XCTAssertEqualObjects(cachedResponse, expectedResponse, @"wrong response");
  96. } else {
  97. // these should be pruned out
  98. XCTAssertNil(cachedResponse, @"unexpected response present");
  99. }
  100. }
  101. // wait for the reservation to expire
  102. [NSThread sleepForTimeInterval:(2 * resInterval)];
  103. // re-store the first response, with its date set to now; the
  104. // previously-reserved response should be oldest and thus pruned out
  105. NSURLRequest *firstRequest = [requests objectAtIndex:0];
  106. GTMCachedURLResponse *firstResponse = [cachedResponses objectAtIndex:0];
  107. [firstResponse setUseDate:[NSDate date]];
  108. [cache storeCachedResponse:firstResponse
  109. forRequest:firstRequest];
  110. // again, step through retrieving all previous requests
  111. //
  112. // now the cache should contain the first response and the last two responses
  113. for (int idx = 0; idx < 6; idx++) {
  114. NSURLRequest *request = [requests objectAtIndex:idx];
  115. GTMCachedURLResponse *cachedResponse, *expectedResponse;
  116. cachedResponse = [cache cachedResponseForRequest:request];
  117. if (idx == 0 || idx >= 4) {
  118. expectedResponse = [cachedResponses objectAtIndex:idx];
  119. XCTAssertEqualObjects(cachedResponse, expectedResponse, @"wrong response");
  120. } else {
  121. // these should be aged out
  122. XCTAssertNil(cachedResponse, @"unexpected response present");
  123. }
  124. }
  125. // create a response too big to fit in the cache, and verify that it wasn't
  126. NSString *hugeUrlStr = [NSString stringWithFormat:@"http://example.com/huge"];
  127. NSURL *hugeURL = [NSURL URLWithString:hugeUrlStr];
  128. NSURLRequest *hugeRequest = [NSURLRequest requestWithURL:hugeURL];
  129. NSURLResponse *response;
  130. response = [[[NSURLResponse alloc] initWithURL:hugeURL
  131. MIMEType:@"text/xml"
  132. expectedContentLength:-1
  133. textEncodingName:nil] autorelease];
  134. NSMutableData *hugeData = [NSMutableData data];
  135. [hugeData setLength:cacheCapacity];
  136. GTMCachedURLResponse *hugeResponse;
  137. hugeResponse = [[[GTMCachedURLResponse alloc] initWithResponse:response
  138. data:hugeData] autorelease];
  139. [cache storeCachedResponse:hugeResponse
  140. forRequest:hugeRequest];
  141. // verify that the response wasn't really stored in the cache
  142. XCTAssertEqual([[cache responses] count], (NSUInteger)3,
  143. @"huge not ignored");
  144. GTMCachedURLResponse *foundResponse;
  145. foundResponse = [cache cachedResponseForRequest:hugeRequest];
  146. XCTAssertNil(foundResponse, @"huge was cached");
  147. // make the huge response size just right for pushing everything else out of
  148. // the cache
  149. [hugeData setLength:(cacheCapacity - 1)];
  150. hugeResponse = [[[GTMCachedURLResponse alloc] initWithResponse:response
  151. data:hugeData] autorelease];
  152. [cache storeCachedResponse:hugeResponse
  153. forRequest:hugeRequest];
  154. // verify that it crowded out the other responses
  155. XCTAssertEqual([[cache responses] count], (NSUInteger)1,
  156. @"huge didn't fill the cache");
  157. foundResponse = [cache cachedResponseForRequest:hugeRequest];
  158. XCTAssertNotNil(foundResponse, @"huge was not cached");
  159. }
  160. - (void)testCookieStorage {
  161. GTMCookieStorage *cookieStorage = [[[GTMCookieStorage alloc] init] autorelease];
  162. NSArray *foundCookies;
  163. NSURL *fullURL = [NSURL URLWithString:@"http://photos.example.com"];
  164. NSURL *subdomainURL = [NSURL URLWithString:@"http://frogbreath.example.com"];
  165. foundCookies = [cookieStorage cookiesForURL:fullURL];
  166. XCTAssertEqual([foundCookies count], (NSUInteger) 0, @"no cookies expected");
  167. // make two unique cookies
  168. NSDictionary *cookie1Props = [NSDictionary dictionaryWithObjectsAndKeys:
  169. @"TRUE", NSHTTPCookieDiscard,
  170. @"photos.example.com", NSHTTPCookieDomain,
  171. @"Snark", NSHTTPCookieName,
  172. @"/", NSHTTPCookiePath,
  173. @"cook1=foo", NSHTTPCookieValue, nil];
  174. NSHTTPCookie *testCookie1 = [NSHTTPCookie cookieWithProperties:cookie1Props];
  175. NSDictionary *cookie2Props = [NSDictionary dictionaryWithObjectsAndKeys:
  176. @"FALSE", NSHTTPCookieDiscard,
  177. @".example.com", NSHTTPCookieDomain,
  178. @"Trump", NSHTTPCookieName,
  179. @"/", NSHTTPCookiePath,
  180. @"cook2=gnu", NSHTTPCookieValue, nil];
  181. NSHTTPCookie *testCookie2 = [NSHTTPCookie cookieWithProperties:cookie2Props];
  182. // make a cookie that would replace cookie 2, and make this one expire
  183. //
  184. // expirations have to be in the future or the cookie won't get stored
  185. NSTimeInterval kExpirationInterval = 0.1;
  186. NSDate *expiredDate = [NSDate dateWithTimeIntervalSinceNow:kExpirationInterval];
  187. NSDictionary *cookie2aProps = [NSDictionary dictionaryWithObjectsAndKeys:
  188. @"FALSE", NSHTTPCookieDiscard,
  189. @".example.com", NSHTTPCookieDomain,
  190. @"Trump", NSHTTPCookieName,
  191. @"/", NSHTTPCookiePath,
  192. expiredDate, NSHTTPCookieExpires,
  193. @"cook2=snu", NSHTTPCookieValue, nil];
  194. NSHTTPCookie *testCookie2a = [NSHTTPCookie cookieWithProperties:cookie2aProps];
  195. // store the first two cookies
  196. NSArray *array = [NSArray arrayWithObjects:
  197. testCookie1, testCookie2, nil];
  198. [cookieStorage setCookies:array];
  199. foundCookies = [cookieStorage cookiesForURL:fullURL];
  200. XCTAssertEqual([foundCookies count], (NSUInteger) 2,
  201. @"full domain cookie retrieval");
  202. foundCookies = [cookieStorage cookiesForURL:subdomainURL];
  203. XCTAssertEqual((int)[foundCookies count], 1, @"subdomain cookie retrieval");
  204. // store cookie 2a, replacing cookie 2
  205. array = [NSArray arrayWithObject:testCookie2a];
  206. [cookieStorage setCookies:array];
  207. foundCookies = [cookieStorage cookiesForURL:subdomainURL];
  208. XCTAssertEqual((int)[foundCookies count], 1, @"subdomain 2a retrieval");
  209. NSHTTPCookie *foundCookie = [foundCookies lastObject];
  210. XCTAssertEqualObjects([foundCookie value], [testCookie2a value],
  211. @"cookie replacement");
  212. // wait for cookie 2a to expire, then remove expired cookies
  213. //
  214. // 30-May-2012: Apparently, on Mac OS X 10.7.4, the expiration is no
  215. // longer stored, even for version 0 cookies.
  216. //
  217. // [NSThread sleepForTimeInterval:(2 * kExpirationInterval)];
  218. // [cookieStorage removeExpiredCookies];
  219. //
  220. // foundCookies = [cookieStorage cookiesForURL:subdomainURL];
  221. // STAssertEquals((int)[foundCookies count], 0, @"pruned removal");
  222. //
  223. // foundCookies = [cookieStorage cookiesForURL:fullURL];
  224. // STAssertEquals((int)[foundCookies count], 1, @"pruned removal remaining");
  225. XCTAssertNil([testCookie2a expiresDate]);
  226. // remove all cookies
  227. [cookieStorage removeAllCookies];
  228. foundCookies = [cookieStorage cookiesForURL:fullURL];
  229. XCTAssertEqual((int)[foundCookies count], 0, @"remove all");
  230. }
  231. @end