Newer
Older
<?php
// $Id$
/**
* @file
* Feeds tests.
*/
/**
* Test cron scheduling.
*/
class FeedsSchedulerTestCase extends FeedsWebTestCase {
/**
* Describe this test.
*/
public function getInfo() {
return array(
'name' => t('Scheduler'),
'description' => t('Tests for feeds scheduler.'),
'group' => t('Feeds'),
);
}
/**
public function testScheduling() {
// Create importer configuration.
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
$this->createImporterConfiguration();
$this->addMappings('syndication',
array(
array(
'source' => 'title',
'target' => 'title',
'unique' => FALSE,
),
array(
'source' => 'description',
'target' => 'body',
'unique' => FALSE,
),
array(
'source' => 'timestamp',
'target' => 'created',
'unique' => FALSE,
),
array(
'source' => 'url',
'target' => 'url',
'unique' => TRUE,
),
array(
'source' => 'guid',
'target' => 'guid',
'unique' => TRUE,
),
)
);
// Create 10 feed nodes. Turn off import on create before doing that.
$edit = array(
'import_on_create' => FALSE,
);
$this->drupalPost('admin/structure/feeds/edit/syndication/settings', $edit, 'Save');
$this->assertText('Do not import on submission');
$nids = $this->createFeedNodes();
// This implicitly tests the import_on_create node setting being 0.
$this->assertTrue($nids[0] == 1 && $nids[1] == 2, 'Node ids sequential.');
Alex Barth
committed
// Check whether feed got properly added to scheduler.
foreach ($nids as $nid) {
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND id = :nid AND name = 'feeds_source_import' AND last <> 0 AND scheduled = 0 AND period = 1800 AND periodic = 1", array(':nid' => $nid))->fetchField());
Alex Barth
committed
}
// Take time for comparisons.
$time = time();
sleep(1);
// Log out and run cron, no changes.
$this->drupalLogout();
$count = db_query("SELECT COUNT(*) FROM {job_schedule} WHERE last > :time", array(':time' => $time))->fetchField();
Alex Barth
committed
$this->assertEqual($count, 0, '0 feeds refreshed on cron.');
// Set next time to 0 to simulate updates.
// There should be 2 x job_schedule_num (= 10) feeds updated now.
db_query("UPDATE {job_schedule} SET next = 0");
$this->cronRun();
$this->cronRun();
// There should be feeds_schedule_num X 2 (= 20) feeds updated now.
$schedule = array();
$rows = db_query("SELECT id, last, scheduled FROM {job_schedule} WHERE last > :time", array(':time' => $time));
foreach ($rows as $row) {
Alex Barth
committed
$schedule[$row->id] = $row;
$this->assertEqual(count($schedule), 20, '20 feeds refreshed on cron.'. $count);
// There should be 200 article nodes in the database.
$count = db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article' AND status = 1")->fetchField();
$this->assertEqual($count, 200, 'There are 200 article nodes aggregated.'. $count);
// There shouldn't be any items with scheduled = 1 now, if so, this would
// mean they are stuck.
$count = db_query("SELECT COUNT(*) FROM {job_schedule} WHERE scheduled = 1")->fetchField();
$this->assertEqual($count, 0, 'All items are unscheduled (schedule flag = 0).'. $count);
// Hit cron again twice.
$this->cronRun();
$this->cronRun();
// The import_period setting of the feed configuration is 1800, there
// shouldn't be any change to the database now.
$equal = TRUE;
$rows = db_query("SELECT id, last, scheduled FROM {job_schedule} WHERE last > :time", array(':time' => $time));
foreach ($rows as $row) {
Alex Barth
committed
$equal = $equal && ($row->last == $schedule[$row->id]->last);
}
$this->assertTrue($equal, 'Schedule did not change.');
// Log back in and set refreshing to as often as possible.
$this->drupalLogin($this->admin_user);
$edit = array(
'import_period' => 0,
);
$this->drupalPost('admin/structure/feeds/edit/syndication/settings', $edit, 'Save');
$this->assertText('Refresh: as often as possible');
Alex Barth
committed
$this->drupalLogout();
Alex Barth
committed
// Hit cron once, this should cause Feeds to reschedule all entries.
Alex Barth
committed
$equal = FALSE;
$rows = db_query("SELECT id, last, scheduled FROM {job_schedule} WHERE last > :time", array(':time' => $time));
foreach ($rows as $row) {
Alex Barth
committed
$equal = $equal && ($row->last == $schedule[$row->id]->last);
$schedule[$row->id] = $row;
Alex Barth
committed
$this->assertFalse($equal, 'Every feed schedule time changed.');
Alex Barth
committed
// Hit cron again, 4 times now, every item should change again.
for ($i = 0; $i < 4; $i++) {
Alex Barth
committed
}
$equal = FALSE;
$rows = db_query("SELECT id, last, scheduled FROM {job_schedule} WHERE last > :time", array(':time' => $time));
foreach ($rows as $row) {
Alex Barth
committed
$equal = $equal && ($row->last == $schedule[$row->id]->last);
}
$this->assertFalse($equal, 'Every feed schedule time changed.');
// There should be 200 article nodes in the database.
$count = db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article' AND status = 1")->fetchField();
$this->assertEqual($count, 200, 'The total of 200 article nodes has not changed.');
Alex Barth
committed
// Set expire settings, check rescheduling.
$max_last = db_query("SELECT MAX(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 0")->fetchField();
$min_last = db_query("SELECT MIN(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 0")->fetchField();
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND last <> 0 AND scheduled = 0")->fetchField());
$this->drupalLogin($this->admin_user);
Alex Barth
committed
$this->setSettings('syndication', 'FeedsNodeProcessor', array('expire' => 86400));
$this->drupalLogout();
sleep(1);
$this->cronRun();
// There should be a feeds_importer_expire job now, and all last fields should be reset.
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND last <> 0 AND scheduled = 0 AND period = 3600")->fetchField());
$new_max_last = db_query("SELECT MAX(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 0")->fetchField();
$new_min_last = db_query("SELECT MIN(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 0")->fetchField();
Alex Barth
committed
$this->assertNotEqual($new_max_last, $max_last);
$this->assertNotEqual($new_min_last, $min_last);
$this->assertEqual($new_max_last, $new_min_last);
$max_last = $new_max_last;
$min_last = $new_min_last;
// Set import settings, check rescheduling.
$this->drupalLogin($this->admin_user);
Alex Barth
committed
$this->setSettings('syndication', '', array('import_period' => 3600));
$this->drupalLogout();
sleep(1);
$this->cronRun();
$new_max_last = db_query("SELECT MAX(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 3600")->fetchField();
$new_min_last = db_query("SELECT MIN(last) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period = 3600")->fetchField();
Alex Barth
committed
$this->assertNotEqual($new_max_last, $max_last);
$this->assertNotEqual($new_min_last, $min_last);
$this->assertEqual($new_max_last, $new_min_last);
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND period <> 3600")->fetchField());
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND period = 3600 AND last = :last", array(':last' => $new_min_last))->fetchField());
Alex Barth
committed
// Delete source, delete importer, check schedule.
$this->drupalLogin($this->admin_user);
Alex Barth
committed
$nid = array_shift($nids);
$this->drupalPost("node/$nid/delete", array(), t('Delete'));
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import' AND id = :nid", array(':nid' => $nid))->fetchField());
$this->assertEqual(count($nids), db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import'")->fetchField());
$this->assertEqual(1, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND id = 0")->fetchField());
Alex Barth
committed
$this->drupalPost('admin/structure/feeds/delete/syndication', array(), t('Delete'));
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_importer_expire' AND id = 0")->fetchField());
$this->assertEqual(count($nids), db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND name = 'feeds_source_import'")->fetchField());
}
/**
* Test batching on cron.
*/
function testBatching() {
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
// Set up an importer.
$this->createImporterConfiguration('Node import', 'node');
// Set and configure plugins and mappings.
$edit = array(
'content_type' => '',
);
$this->drupalPost('admin/structure/feeds/edit/node/settings', $edit, 'Save');
$this->setPlugin('node', 'FeedsFileFetcher');
$this->setPlugin('node', 'FeedsCSVParser');
$mappings = array(
'0' => array(
'source' => 'title',
'target' => 'title',
),
);
$this->addMappings('node', $mappings);
// Verify that there are 86 nodes total.
$this->importFile('node', $this->absolutePath() .'/tests/feeds/many_nodes.csv');
$this->assertText('Created 86 Article nodes.');
// Run batch twice with two different process limits.
// 50 = FEEDS_PROCESS_LIMIT.
foreach (array(10, 50) as $limit) {
variable_set('feeds_process_limit', $limit);
db_query("UPDATE {job_schedule} SET next = 0");
$this->drupalPost('import/node/delete-items', array(), 'Delete');
$this->assertEqual(0, db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article'")->fetchField());
// Hit cron (item count / limit) times, assert correct number of articles.
for ($i = 0; $i < ceil(86 / $limit); $i++) {
$this->cronRun();
sleep(1);
if ($limit * ($i + 1) < 86) {
$count = $limit * ($i + 1);
$period = 0; // Import should be rescheduled for ASAP.
}
else {
$count = 86; // We've reached our total of 86.
$period = 1800; // Hence we should find the Source's default period.
}
$this->assertEqual($count, db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article'")->fetchField());
$this->assertEqual($period, db_query("SELECT period FROM {job_schedule} WHERE type = 'node' AND id = 0")->fetchField());
}
}
// Delete a couple of nodes, then hit cron again. They should not be replaced
// as the minimum update time is 30 minutes.
$nodes = db_query_range("SELECT nid FROM {node} WHERE type = 'article'", 0, 2);
foreach ($nodes as $node) {
$this->drupalPost("node/{$node->nid}/delete", array(), 'Delete');
}
$this->assertEqual(84, db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article'")->fetchField());
$this->cronRun();
$this->assertEqual(84, db_query("SELECT COUNT(*) FROM {node} WHERE type = 'article'")->fetchField());
Alex Barth
committed
/**
* Helper, log in as an admin user.
*/
protected function loginAdmin() {
$this->drupalLogin($this->admin_user);
Alex Barth
committed
}
/**
Alex Barth
committed
*/
protected function showSchedule() {
$jobs = db_query("SELECT * FROM {job_schedule}");
foreach ($jobs as $job) {
$this->error('<pre>' . print_r($job, true) . '</pre>');
}
Alex Barth
committed
}