Projet

Général

Profil

Paste
Télécharger (16,2 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / feeds / tests / FeedsHTTPCacheTest.test @ ed9a13f1

1
<?php
2

    
3
/**
4
 * @coversDefaultClass FeedsHTTPCache
5
 * @group feeds
6
 */
7
class FeedsHTTPCacheTest extends FeedsWebTestCase {
8
  /**
9
   * Default Feeds cache dir.
10
   *
11
   * @var string
12
   */
13
  const FEEDS_CACHE_DIR = 'private://feeds/cache';
14

    
15
  /**
16
   * The cache object.
17
   *
18
   * @var FeedsHTTPCache
19
   */
20
  protected $cache;
21

    
22
  /**
23
   * {@inheritdoc}
24
   */
25
  public static function getInfo() {
26
    return array(
27
      'name' => 'FeedsHTTPCache class test',
28
      'description' => 'Covers class FeedsHTTPCache.',
29
      'group' => 'Feeds',
30
    );
31
  }
32

    
33
  /**
34
   * {@inheritdoc}
35
   */
36
  public function setUp() {
37
    parent::setUp();
38

    
39
    // Create an instance of FeedsHTTPCache to test with.
40
    $this->cache = new FeedsHTTPCache('cache_feeds_http');
41
  }
42

    
43
  /**
44
   * Creates a dummy HTTP response.
45
   *
46
   * @param bool $with_data
47
   *   (optional) If data should be included.
48
   *   Defaults to TRUE.
49
   *
50
   * @return object
51
   *   The created response.
52
   */
53
  protected function createHttpResponse($with_data = TRUE) {
54
    $response = new stdClass();
55
    $response->code = 200;
56
    $response->headers = array(
57
      'content-type' => 'text/plain; charset=utf-8',
58
      'x-host' => 'http://www.example.com',
59
    );
60
    if ($with_data) {
61
      $response->data = static::randomString(255);
62
    }
63

    
64
    return $response;
65
  }
66

    
67
  /**
68
   * Creates a cache record, bypassing the API.
69
   *
70
   * @param string $cid
71
   *   (optional) The cache item ID.
72
   * @param object $response
73
   *   (optional) The response to save.
74
   *
75
   * @return string
76
   *   The cache item ID.
77
   */
78
  protected function createCacheRecord($cid = NULL, $response = NULL) {
79
    if (empty($cid)) {
80
      $cid = static::randomName();
81
    }
82
    if (empty($response)) {
83
      $response = $this->createHttpResponse(FALSE);
84
      $response->file_path = static::FEEDS_CACHE_DIR . '/' . $cid;
85
    }
86

    
87
    $record = new stdClass();
88
    $record->cid = $cid;
89
    $record->data = serialize($response);
90
    $record->expire = CACHE_PERMANENT;
91
    $record->created = REQUEST_TIME;
92
    $record->serialized = TRUE;
93

    
94
    drupal_write_record('cache_feeds_http', $record);
95

    
96
    return $cid;
97
  }
98

    
99
  /**
100
   * Creates a cache record using the API.
101
   *
102
   * @param string $cid
103
   *   (optional) The cache item ID.
104
   * @param object $response
105
   *   (optional) The response to save.
106
   *
107
   * @return string
108
   *   The cache item ID.
109
   */
110
  protected function createCacheRecordUsingApi($cid = NULL, $response = NULL) {
111
    if (empty($cid)) {
112
      $cid = static::randomName();
113
    }
114
    if (empty($response)) {
115
      $response = $this->createHttpResponse();
116
    }
117
    $this->cache->set($cid, $response);
118

    
119
    return $cid;
120
  }
121

    
122
  /**
123
   * Asserts that an item with a certain ID exists in the feeds cache table.
124
   *
125
   * @param string $cid
126
   *   The cache item ID.
127
   */
128
  protected function assertCacheItemExists($cid) {
129
    $message = format_string('Cache item @cid exists.', array(
130
      '@cid' => $cid,
131
    ));
132

    
133
    $count = db_select('cache_feeds_http')
134
      ->fields('cache_feeds_http', array('cid'))
135
      ->condition('cid', $cid)
136
      ->countQuery()
137
      ->execute()
138
      ->fetchField();
139
    $this->assertEqual(1, $count, $message);
140
  }
141

    
142
  /**
143
   * Asserts that an item with a certain ID does not exist in the feeds cache
144
   * table.
145
   *
146
   * @param string $cid
147
   *   The cache item ID.
148
   */
149
  protected function assertNoCacheItemExists($cid) {
150
    $message = format_string('Cache item @cid does not exist.', array(
151
      '@cid' => $cid,
152
    ));
153

    
154
    $count = db_select('cache_feeds_http')
155
      ->fields('cache_feeds_http', array('cid'))
156
      ->condition('cid', $cid)
157
      ->countQuery()
158
      ->execute()
159
      ->fetchField();
160
    $this->assertEqual(0, $count, $message);
161
  }
162

    
163
  /**
164
   * Asserts that a cache file with a certain ID exists on the file system.
165
   *
166
   * @param string $cid
167
   *   The cache item ID.
168
   */
169
  protected function assertCacheFileExists($cid) {
170
    $message = format_string('Cache file @cid exists.', array(
171
      '@cid' => $cid,
172
    ));
173

    
174
    $this->assertTrue(file_exists(static::FEEDS_CACHE_DIR . '/' . $cid), $message);
175
  }
176

    
177
  /**
178
   * Asserts that a cache file with a certain ID does not exist on the file
179
   * system.
180
   *
181
   * @param string $cid
182
   *   The cache item ID.
183
   */
184
  protected function assertNoCacheFileExists($cid) {
185
    $message = format_string('Cache file @cid does not exist.', array(
186
      '@cid' => $cid,
187
    ));
188

    
189
    $this->assertFalse(file_exists(static::FEEDS_CACHE_DIR . '/' . $cid), $message);
190
  }
191

    
192
  /**
193
   * @covers FeedsHTTPCache::get().
194
   */
195
  public function testGet() {
196
    $cid = static::randomName();
197
    $file_data = static::randomName();
198

    
199
    // Save a file to the cache dir.
200
    $dir = static::FEEDS_CACHE_DIR;
201
    file_prepare_directory($dir, FILE_CREATE_DIRECTORY);
202
    file_put_contents(static::FEEDS_CACHE_DIR . '/' . $cid, $file_data);
203

    
204
    // Manually create a record in cache_feeds_http table.
205
    $this->createCacheRecord($cid);
206

    
207
    // Assert that the item can be get from cache.
208
    $item = $this->cache->get($cid);
209
    $this->assertEqual($file_data, $item->data->getFileContents());
210
  }
211

    
212
  /**
213
   * @covers FeedsHTTPCache::getMultiple().
214
   */
215
  public function testGetMultiple() {
216
    $cid1 = static::randomName();
217
    $cid2 = static::randomName();
218
    $cid3 = static::randomName();
219

    
220
    $file1 = static::randomName();
221
    $file2 = static::randomName();
222
    $file3 = static::randomName();
223

    
224
    // Save a few files to the cache dir.
225
    $dir = static::FEEDS_CACHE_DIR;
226
    file_prepare_directory($dir, FILE_CREATE_DIRECTORY);
227
    file_put_contents(static::FEEDS_CACHE_DIR . '/' . $cid1, $file1);
228
    file_put_contents(static::FEEDS_CACHE_DIR . '/' . $cid2, $file2);
229
    file_put_contents(static::FEEDS_CACHE_DIR . '/' . $cid3, $file3);
230

    
231
    // Create a few records in cache_feeds_http table.
232
    $this->createCacheRecord($cid1);
233
    $this->createCacheRecord($cid2);
234
    $this->createCacheRecord($cid3);
235

    
236
    $cids = array(
237
      $cid2,
238
      $cid3,
239
    );
240

    
241
    // Assert that the expected items are get from the cache.
242
    $items = $this->cache->getMultiple($cids);
243
    $this->assertFalse(isset($items[$cid1]));
244
    $this->assertTrue(isset($items[$cid2]));
245
    $this->assertTrue(isset($items[$cid3]));
246
    $this->assertEqual($file2, $items[$cid2]->data->getFileContents());
247
    $this->assertEqual($file3, $items[$cid3]->data->getFileContents());
248
  }
249

    
250
  /**
251
   * @covers FeedsHTTPCache::set().
252
   */
253
  public function testSet() {
254
    $response = $this->createHttpResponse();
255
    $cid = $this->createCacheRecordUsingApi(NULL, $response);
256

    
257
    // Assert that a record was created with the expected data.
258
    $record = db_select('cache_feeds_http')
259
      ->fields('cache_feeds_http', array())
260
      ->condition('cid', $cid)
261
      ->execute()
262
      ->fetch();
263

    
264
    // Check cache record.
265
    $this->assertEqual($cid, $record->cid);
266
    $this->assertEqual(CACHE_PERMANENT, $record->expire);
267

    
268
    // Check that the raw data wasn't saved in the cache record.
269
    $this->assertFalse(strpos($record->data, $response->data), 'The raw data was not saved in the database.');
270

    
271
    // Check properties.
272
    $saved_response = unserialize($record->data);
273
    $this->assertTrue($saved_response instanceof FeedsHTTPCacheItem, 'Cached data is instance of class FeedsHTTPCacheItem.');
274
    $this->assertEqual($response->headers, $saved_response->headers);
275
    $this->assertEqual(static::FEEDS_CACHE_DIR . '/' . $cid, $saved_response->file_path);
276

    
277
    // Assert that a file was created on the file system.
278
    $this->assertTrue(file_exists(static::FEEDS_CACHE_DIR . '/' . $cid));
279
  }
280

    
281
  /**
282
   * @covers FeedsHTTPCache::clear().
283
   *
284
   * Tests if a single cached file can get cleaned up.
285
   */
286
  public function testClear() {
287
    // Create a few cache entries.
288
    $cid1 = $this->createCacheRecordUsingApi();
289
    $cid2 = $this->createCacheRecordUsingApi();
290

    
291
    // Assert that items were created in the database.
292
    $this->assertCacheItemExists($cid1);
293
    $this->assertCacheItemExists($cid2);
294

    
295
    // Assert that files exist.
296
    $this->assertCacheFileExists($cid1);
297
    $this->assertCacheFileExists($cid2);
298

    
299
    // Now clear first item.
300
    $this->cache->clear($cid1);
301

    
302
    // Assert that item 1 is removed from the database, but item 2 still exists.
303
    $this->assertNoCacheItemExists($cid1);
304
    $this->assertCacheItemExists($cid2);
305

    
306
    // Assert that file 1 is gone as well, but file 2 still exists.
307
    $this->assertNoCacheFileExists($cid1);
308
    $this->assertCacheFileExists($cid2);
309
  }
310

    
311
  /**
312
   * @covers FeedsHTTPCache::clear().
313
   *
314
   * Tests if multiple cached files can get cleaned up.
315
   */
316
  public function testClearMultiple() {
317
    // Create a few cache entries.
318
    $cid1 = $this->createCacheRecordUsingApi();
319
    $cid2 = $this->createCacheRecordUsingApi();
320
    $cid3 = $this->createCacheRecordUsingApi();
321
    $cid4 = $this->createCacheRecordUsingApi();
322

    
323
    // Remove item 2 and 4.
324
    $this->cache->clear(array(
325
      $cid2,
326
      $cid4,
327
    ));
328

    
329
    // Assert that some records are removed.
330
    $this->assertCacheItemExists($cid1);
331
    $this->assertNoCacheItemExists($cid2);
332
    $this->assertCacheItemExists($cid3);
333
    $this->assertNoCacheItemExists($cid4);
334

    
335
    // Assert that only these files were removed.
336
    $this->assertCacheFileExists($cid1);
337
    $this->assertNoCacheFileExists($cid2);
338
    $this->assertCacheFileExists($cid3);
339
    $this->assertNoCacheFileExists($cid4);
340
  }
341

    
342
  /**
343
   * @covers FeedsHTTPCache::clear().
344
   *
345
   * Tests if expired cached files can get cleaned up.
346
   */
347
  public function testClearExpired() {
348
    // Create a cache entry that should not expire.
349
    $cid_permanent = $this->createCacheRecordUsingApi();
350

    
351
    // Create a cache entry with an expire time in the past.
352
    $cid_expire_past = static::randomName();
353
    $this->cache->set($cid_expire_past, $this->createHttpResponse(), REQUEST_TIME - 60);
354

    
355
    // Create a cache entry that expires exactly now.
356
    $cid_expire_now = static::randomName();
357
    $this->cache->set($cid_expire_now, $this->createHttpResponse(), REQUEST_TIME);
358

    
359
    // Create a cache entry that expires in the future.
360
    $cid_expire_future = static::randomName();
361
    $this->cache->set($cid_expire_future, $this->createHttpResponse(), REQUEST_TIME + 60);
362

    
363
    // Clear all expired cache entries.
364
    $this->cache->clear();
365

    
366
    // Assert existence of cache entries.
367
    $this->assertCacheItemExists($cid_permanent);
368
    $this->assertNoCacheItemExists($cid_expire_past);
369
    $this->assertCacheItemExists($cid_expire_now);
370
    $this->assertCacheItemExists($cid_expire_future);
371

    
372
    // Assert existence of cache files.
373
    $this->assertCacheFileExists($cid_permanent);
374
    $this->assertNoCacheFileExists($cid_expire_past);
375
    $this->assertCacheFileExists($cid_expire_now);
376
    $this->assertCacheFileExists($cid_expire_future);
377
  }
378

    
379
  /**
380
   * @covers FeedsHTTPCache::clear().
381
   *
382
   * Tests if expired cached files can get cleaned up using the cache_lifetime
383
   * variable.
384
   */
385
  public function testClearExpiredUsingCacheLifeTime() {
386
    variable_set('cache_lifetime', 120);
387

    
388
    // Create a cache entry that should not expire.
389
    $cid_permanent = $this->createCacheRecordUsingApi();
390

    
391
    // Create a cache entry with an expire time in the past.
392
    $cid_expire_past = static::randomName();
393
    $this->cache->set($cid_expire_past, $this->createHttpResponse(), REQUEST_TIME - 60);
394

    
395
    // Create a cache entry that expires exactly now.
396
    $cid_expire_now = static::randomName();
397
    $this->cache->set($cid_expire_now, $this->createHttpResponse(), REQUEST_TIME);
398

    
399
    // Create a cache entry that expires in the future.
400
    $cid_expire_future = static::randomName();
401
    $this->cache->set($cid_expire_future, $this->createHttpResponse(), REQUEST_TIME + 60);
402

    
403
    // Call clear. Nothing should be cleared because the last cache flush was
404
    // too recently.
405
    variable_set('cache_flush_cache_feeds_http', REQUEST_TIME - 90);
406
    $this->cache->clear();
407

    
408
    // Ensure all cached files still exist as cache lifetime has not exceeded.
409
    $this->assertCacheItemExists($cid_permanent);
410
    $this->assertCacheItemExists($cid_expire_past);
411
    $this->assertCacheItemExists($cid_expire_now);
412
    $this->assertCacheItemExists($cid_expire_future);
413
    $this->assertCacheFileExists($cid_permanent);
414
    $this->assertCacheFileExists($cid_expire_past);
415
    $this->assertCacheFileExists($cid_expire_now);
416
    $this->assertCacheFileExists($cid_expire_future);
417

    
418
    // Now do as if cache lifetime has passed.
419
    variable_set('cache_flush_cache_feeds_http', REQUEST_TIME - 121);
420
    $this->cache->clear();
421

    
422
    // Assert existence of cache entries.
423
    $this->assertCacheItemExists($cid_permanent);
424
    $this->assertNoCacheItemExists($cid_expire_past);
425
    $this->assertCacheItemExists($cid_expire_now);
426
    $this->assertCacheItemExists($cid_expire_future);
427

    
428
    // Assert existence of cache files.
429
    $this->assertCacheFileExists($cid_permanent);
430
    $this->assertNoCacheFileExists($cid_expire_past);
431
    $this->assertCacheFileExists($cid_expire_now);
432
    $this->assertCacheFileExists($cid_expire_future);
433
  }
434

    
435
  /**
436
   * @covers FeedsHTTPCache::clear().
437
   *
438
   * Tests if all cached files can get cleaned up.
439
   */
440
  public function testClearAll() {
441
    // Create a few cache entries.
442
    $cid1 = $this->createCacheRecordUsingApi();
443
    $cid2 = $this->createCacheRecordUsingApi();
444
    $cid3 = $this->createCacheRecordUsingApi();
445

    
446
    // Now clear complete cache.
447
    $this->cache->clear('*', TRUE);
448

    
449
    // Assert that cache_feeds_http is empty.
450
    $count = db_select('cache_feeds_http')
451
      ->fields('cache_feeds_http', array('cid'))
452
      ->countQuery()
453
      ->execute()
454
      ->fetchField();
455
    $this->assertEqual(0, $count, 'The cache_feeds_http item is empty.');
456

    
457
    // Assert that the feeds cache dir is empty.
458
    $empty = (count(glob(static::FEEDS_CACHE_DIR . '/*')) === 0);
459
    $this->assertTrue($empty, 'The feeds cache directory is empty.');
460
  }
461

    
462
  /**
463
   * @covers FeedsHTTPCache::clear().
464
   *
465
   * Tests if cached files starting with a certain string can get cleaned up.
466
   */
467
  public function testClearUsingWildcard() {
468
    // Create a few cids, where the first few chars of cid1 and cid3 are the
469
    // same and cid2 has a completely different string.
470
    $cid1 = 'abc123';
471
    $cid2 = 'def456';
472
    $cid3 = 'abc789';
473
    $this->createCacheRecordUsingApi($cid1);
474
    $this->createCacheRecordUsingApi($cid2);
475
    $this->createCacheRecordUsingApi($cid3);
476

    
477
    // Clear all cache entries that start with 'abc'.
478
    $this->cache->clear('abc', TRUE);
479

    
480
    // Assert that all records starting with 'abc' are gone.
481
    $this->assertNoCacheItemExists($cid1);
482
    $this->assertCacheItemExists($cid2);
483
    $this->assertNoCacheItemExists($cid3);
484

    
485
    // Assert that all files in the cache dir starting with 'abc' are gone.
486
    $this->assertNoCacheFileExists($cid1);
487
    $this->assertCacheFileExists($cid2);
488
    $this->assertNoCacheFileExists($cid3);
489
  }
490

    
491
  /**
492
   * @covers FeedsHTTPCache::isEmpty().
493
   */
494
  public function testIsEmpty() {
495
    // Add a record to the cache_feeds_http table.
496
    $this->createCacheRecord();
497

    
498
    // Assert that the cache is not empty.
499
    $this->assertFalse($this->cache->isEmpty(), 'The cache is empty.');
500

    
501
    // Truncate the table and assert that the cache class tells us that it is
502
    // empty.
503
    db_truncate('cache_feeds_http')->execute();
504
    $this->assertTrue($this->cache->isEmpty());
505

    
506
    // Add a file to the cache dir, without a entry in the database.
507
    $dir = static::FEEDS_CACHE_DIR;
508
    file_prepare_directory($dir, FILE_CREATE_DIRECTORY);
509
    file_put_contents(static::FEEDS_CACHE_DIR . '/abc123', static::randomName());
510
    // And assert that the cache class reports that the cache is not empty.
511
    $this->assertFalse($this->cache->isEmpty());
512
  }
513

    
514
  /**
515
   * @covers FeedsHTTPCache::saveFile().
516
   */
517
  public function testSaveFile() {
518
    $cid = static::randomName();
519
    $response = $this->createHttpResponse();
520
    $this->cache->saveFile($cid, $response);
521
    $this->assertCacheFileExists($cid);
522
  }
523

    
524
  /**
525
   * @covers FeedsHTTPCache::saveFile().
526
   *
527
   * Tests failing to create cache directory.
528
   */
529
  public function testSaveFileException() {
530
    variable_set('feeds_http_file_cache_dir', 'file://non-writeable-dir/feeds');
531

    
532
    $cid = static::randomName();
533
    $response = $this->createHttpResponse();
534
    try {
535
      $this->cache->saveFile($cid, $response);
536
    }
537
    catch (Exception $e) {
538
    }
539
    $this->assertTrue(isset($e), 'An exception is thrown.');
540

    
541
    $this->assertNoCacheFileExists($cid);
542
  }
543

    
544
}