1 | <?php |
---|
2 | module_load_include('test', 'feeds', 'tests/feeds'); |
---|
3 | |
---|
4 | /** |
---|
5 | * @file |
---|
6 | * Feeds tests. |
---|
7 | */ |
---|
8 | |
---|
9 | /** |
---|
10 | * Test cron scheduling. |
---|
11 | */ |
---|
12 | class FeedsSchedulerTestCase extends FeedsWebTestCase { |
---|
13 | |
---|
14 | public static function getInfo() { |
---|
15 | return array( |
---|
16 | 'name' => 'Scheduler', |
---|
17 | 'description' => 'Tests for feeds scheduler.', |
---|
18 | 'group' => 'Feeds', |
---|
19 | ); |
---|
20 | } |
---|
21 | |
---|
22 | /** |
---|
23 | * Test scheduling on cron. |
---|
24 | */ |
---|
25 | public function testScheduling() { |
---|
26 | // Create importer configuration. |
---|
27 | $this->createImporterConfiguration(); |
---|
28 | $this->addMappings('syndication', |
---|
29 | array( |
---|
30 | array( |
---|
31 | 'source' => 'title', |
---|
32 | 'target' => 'title', |
---|
33 | 'unique' => FALSE, |
---|
34 | ), |
---|
35 | array( |
---|
36 | 'source' => 'description', |
---|
37 | 'target' => 'body', |
---|
38 | 'unique' => FALSE, |
---|
39 | ), |
---|
40 | array( |
---|
41 | 'source' => 'timestamp', |
---|
42 | 'target' => 'created', |
---|
43 | 'unique' => FALSE, |
---|
44 | ), |
---|
45 | array( |
---|
46 | 'source' => 'url', |
---|
47 | 'target' => 'url', |
---|
48 | 'unique' => TRUE, |
---|
49 | ), |
---|
50 | array( |
---|
51 | 'source' => 'guid', |
---|
52 | 'target' => 'guid', |
---|
53 | 'unique' => TRUE, |
---|
54 | ), |
---|
55 | ) |
---|
56 | ); |
---|
57 | |
---|
58 | // Create 10 feed nodes. Turn off import on create before doing that. |
---|
59 | $edit = array( |
---|
60 | 'import_on_create' => FALSE, |
---|
61 | ); |
---|
62 | $this->drupalPost('admin/build/feeds/edit/syndication/settings', $edit, 'Save'); |
---|
63 | $this->assertText('Do not import on create'); |
---|
64 | |
---|
65 | $nids = $this->createFeedNodes(); |
---|
66 | // This implicitly tests the import_on_create node setting being 0. |
---|
67 | $this->assertTrue($nids[0] == 1 && $nids[1] == 2, 'Node ids sequential.'); |
---|
68 | |
---|
69 | // Check whether feed got properly added to scheduler. |
---|
70 | foreach ($nids as $nid) { |
---|
71 | $this->assertEqual(1, db_result(db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND id = %d AND callback = 'feeds_source_import' AND last <> 0 AND scheduled = 0 AND period = 1800 AND periodic = 1", $nid))); |
---|
72 | } |
---|
73 | |
---|
74 | // Take time for comparisons. |
---|
75 | $time = time(); |
---|
76 | sleep(1); |
---|
77 | |
---|
78 | // Log out and run cron, no changes. |
---|
79 | $this->drupalLogout(); |
---|
80 | $this->cronRun(); |
---|
81 | $count = db_result(db_query("SELECT COUNT(*) FROM {job_schedule} WHERE last > %d", $time)); |
---|
82 | $this->assertEqual($count, 0, '0 feeds refreshed on cron.'); |
---|
83 | |
---|
84 | // Set next time to 0 to simulate updates. |
---|
85 | // There should be 2 x job_schedule_num (= 10) feeds updated now. |
---|
86 | db_query("UPDATE {job_schedule} SET next = 0"); |
---|
87 | $this->cronRun(); |
---|
88 | $this->cronRun(); |
---|
89 | |
---|
90 | $schedule = array(); |
---|
91 | $count = db_result(db_query("SELECT COUNT(*) FROM {job_schedule} WHERE last > %d", $time)); |
---|
92 | $this->assertEqual($count, 10, '10 feeds refreshed on cron.'); |
---|
93 | $result = db_query("SELECT * FROM {job_schedule}", $time); |
---|
94 | |
---|
95 | // There should be 100 story nodes in the database. |
---|
96 | $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story'")); |
---|
97 | $this->assertEqual($count, 100, 'There are 100 story nodes aggregated.'); |
---|
98 | |
---|
99 | // Hit twice cron again. |
---|
100 | $this->cronRun(); |
---|
101 | $this->cronRun(); |
---|
102 | |
---|
103 | // There should be feeds_schedule_num X 2 (= 20) feeds updated now. |
---|
104 | $schedule = array(); |
---|
105 | $result = db_query("SELECT id, last, scheduled FROM {job_schedule} WHERE last > %d", $time); |
---|
106 | while ($row = db_fetch_object($result)) { |
---|
107 | $schedule[$row->id] = $row; |
---|
108 | } |
---|
109 | $this->assertEqual(count($schedule), 20, '20 feeds refreshed on cron.'); |
---|
110 | |
---|
111 | // There should be 200 story nodes in the database. |
---|
112 | $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story' AND status = 1")); |
---|
113 | $this->assertEqual($count, 200, 'There are 200 story nodes aggregated.'); |
---|
114 | |
---|
115 | // There shouldn't be any items with scheduled = 1 now, if so, this would |
---|
116 | // mean they are stuck. |
---|
117 | $count = db_result(db_query("SELECT COUNT(*) FROM {job_schedule} WHERE scheduled = 1")); |
---|
118 | $this->assertEqual($count, 0, 'All items are unscheduled (schedule flag = 0).'); |
---|
119 | |
---|
120 | // Hit cron again twice. |
---|
121 | $this->cronRun(); |
---|
122 | $this->cronRun(); |
---|
123 | |
---|
124 | // The import_period setting of the feed configuration is 1800, there |
---|
125 | // shouldn't be any change to the database now. |
---|
126 | $equal = TRUE; |
---|
127 | $result = db_query("SELECT id, last, scheduled FROM {job_schedule} WHERE last > %d", $time); |
---|
128 | while ($row = db_fetch_object($result)) { |
---|
129 | $equal = $equal && ($row->last == $schedule[$row->id]->last); |
---|
130 | } |
---|
131 | $this->assertTrue($equal, 'Schedule did not change.'); |
---|
132 | |
---|
133 | // Log back in and set refreshing to as often as possible. |
---|
134 | $this->drupalLogin($this->admin_user); |
---|
135 | $edit = array( |
---|
136 | 'import_period' => 0, |
---|
137 | ); |
---|
138 | $this->drupalPost('admin/build/feeds/edit/syndication/settings', $edit, 'Save'); |
---|
139 | $this->assertText('Refresh: as often as possible'); |
---|
140 | $this->drupalLogout(); |
---|
141 | |
---|
142 | // Hit cron once, this should cause Feeds to reschedule all entries. |
---|
143 | $this->cronRun(); |
---|
144 | $equal = FALSE; |
---|
145 | $result = db_query("SELECT id, last, scheduled FROM {job_schedule} WHERE last > %d", $time); |
---|
146 | while ($row = db_fetch_object($result)) { |
---|
147 | $equal = $equal && ($row->last == $schedule[$row->id]->last); |
---|
148 | $schedule[$row->id] = $row; |
---|
149 | } |
---|
150 | $this->assertFalse($equal, 'Every feed schedule time changed.'); |
---|
151 | |
---|
152 | // Hit cron again, 4 times now, every item should change again. |
---|
153 | for ($i = 0; $i < 4; $i++) { |
---|
154 | $this->cronRun(); |
---|
155 | } |
---|
156 | $equal = FALSE; |
---|
157 | $result = db_query("SELECT id, last, scheduled FROM {job_schedule} WHERE last > %d", $time); |
---|
158 | while ($row = db_fetch_object($result)) { |
---|
159 | $equal = $equal && ($row->last == $schedule[$row->id]->last); |
---|
160 | } |
---|
161 | $this->assertFalse($equal, 'Every feed schedule time changed.'); |
---|
162 | |
---|
163 | // There should be 200 story nodes in the database. |
---|
164 | $count = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story' AND status = 1")); |
---|
165 | $this->assertEqual($count, 200, 'The total of 200 story nodes has not changed.'); |
---|
166 | |
---|
167 | // Set expire settings, check rescheduling. |
---|
168 | $max_last = db_result(db_query("SELECT MAX(last) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_source_import' AND period = 0")); |
---|
169 | $min_last = db_result(db_query("SELECT MIN(last) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_source_import' AND period = 0")); |
---|
170 | $this->assertEqual(0, db_result(db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_importer_expire' AND last <> 0 AND scheduled = 0"))); |
---|
171 | $this->drupalLogin($this->admin_user); |
---|
172 | $this->setSettings('syndication', 'FeedsNodeProcessor', array('expire' => 86400)); |
---|
173 | $this->drupalLogout(); |
---|
174 | sleep(1); |
---|
175 | $this->cronRun(); |
---|
176 | // There should be a feeds_importer_expire callback now, and all last fields should be reset. |
---|
177 | $this->assertEqual(1, db_result(db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_importer_expire' AND last <> 0 AND scheduled = 0 AND period = 3600"))); |
---|
178 | $new_max_last = db_result(db_query("SELECT MAX(last) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_source_import' AND period = 0")); |
---|
179 | $new_min_last = db_result(db_query("SELECT MIN(last) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_source_import' AND period = 0")); |
---|
180 | $this->assertNotEqual($new_max_last, $max_last); |
---|
181 | $this->assertNotEqual($new_min_last, $min_last); |
---|
182 | $this->assertEqual($new_max_last, $new_min_last); |
---|
183 | $max_last = $new_max_last; |
---|
184 | $min_last = $new_min_last; |
---|
185 | |
---|
186 | // Set import settings, check rescheduling. |
---|
187 | $this->drupalLogin($this->admin_user); |
---|
188 | $this->setSettings('syndication', '', array('import_period' => 3600)); |
---|
189 | $this->drupalLogout(); |
---|
190 | sleep(1); |
---|
191 | $this->cronRun(); |
---|
192 | $new_max_last = db_result(db_query("SELECT MAX(last) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_source_import' AND period = 3600")); |
---|
193 | $new_min_last = db_result(db_query("SELECT MIN(last) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_source_import' AND period = 3600")); |
---|
194 | $this->assertNotEqual($new_max_last, $max_last); |
---|
195 | $this->assertNotEqual($new_min_last, $min_last); |
---|
196 | $this->assertEqual($new_max_last, $new_min_last); |
---|
197 | $this->assertEqual(0, db_result(db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_source_import' AND period <> 3600"))); |
---|
198 | $this->assertEqual(1, db_result(db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_importer_expire' AND period = 3600 AND last = %d", $new_min_last))); |
---|
199 | |
---|
200 | // Delete source, delete importer, check schedule. |
---|
201 | $this->drupalLogin($this->admin_user); |
---|
202 | $nid = array_shift($nids); |
---|
203 | $this->drupalPost("node/$nid/delete", array(), t('Delete')); |
---|
204 | $this->assertEqual(0, db_result(db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_source_import' AND id = %d", $nid))); |
---|
205 | $this->assertEqual(count($nids), db_result(db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_source_import'"))); |
---|
206 | $this->assertEqual(1, db_result(db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_importer_expire' AND id =0"))); |
---|
207 | |
---|
208 | $this->drupalPost('admin/build/feeds/delete/syndication', array(), t('Delete')); |
---|
209 | $this->assertEqual(0, db_result(db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_importer_expire' AND id =0"))); |
---|
210 | $this->assertEqual(count($nids), db_result(db_query("SELECT COUNT(*) FROM {job_schedule} WHERE type = 'syndication' AND callback = 'feeds_source_import'"))); |
---|
211 | } |
---|
212 | |
---|
213 | /** |
---|
214 | * Test batching on cron. |
---|
215 | */ |
---|
216 | function testBatching() { |
---|
217 | // Set up an importer. |
---|
218 | $this->createImporterConfiguration(); |
---|
219 | // Verify that there are 150 nodes total. |
---|
220 | $nid = $this->createFeedNode('syndication', $GLOBALS['base_url'] .'/'. drupal_get_path('module', 'feeds') .'/tests/feeds/many_items.rss2'); |
---|
221 | $this->assertText('Created 150 Story nodes.'); |
---|
222 | $this->drupalPost('node/'. $nid .'/delete-items', array(), 'Delete'); |
---|
223 | $this->assertText('Deleted 150 nodes.'); |
---|
224 | |
---|
225 | // Set next time to 0 to simulate updates. |
---|
226 | db_query("UPDATE {job_schedule} SET next = 0"); |
---|
227 | // Hit cron 3 times, assert correct number of story nodes. |
---|
228 | for ($i = 1; $i <= 3; $i++) { |
---|
229 | $this->cronRun(); |
---|
230 | sleep(1); |
---|
231 | // 50 == FEEDS_NODE_BATCH_SIZE |
---|
232 | $this->assertEqual(50 * $i, db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story'"))); |
---|
233 | $this->assertEqual(0, db_result(db_query("SELECT period FROM {job_schedule} WHERE type = 'syndication' AND id = %d", $nid))); |
---|
234 | } |
---|
235 | // Run one more time to cause the batch to reset, check period back to 1800. |
---|
236 | $this->cronRun(); |
---|
237 | $this->assertEqual(1800, db_result(db_query("SELECT period FROM {job_schedule} WHERE type = 'syndication' AND id = %d", $nid))); |
---|
238 | |
---|
239 | // Delete a couple of nodes, then hit cron again. They should not be replaced |
---|
240 | // as the minimum update time is 30 minutes. |
---|
241 | $result = db_query_range("SELECT nid FROM {node} WHERE type = 'story'", 0, 2); |
---|
242 | while ($node = db_fetch_object($result)) { |
---|
243 | $this->drupalPost("node/{$node->nid}/delete", array(), 'Delete'); |
---|
244 | } |
---|
245 | $this->assertEqual(148, db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story'"))); |
---|
246 | $this->cronRun(); |
---|
247 | $this->assertEqual(148, db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = 'story'"))); |
---|
248 | } |
---|
249 | } |
---|