cron.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. <?php
  2. /**
  3. * Test the cron scheduling functions
  4. *
  5. * @group cron
  6. */
  7. class Tests_Cron extends WP_UnitTestCase {
  8. function setUp() {
  9. parent::setUp();
  10. // make sure the schedule is clear
  11. _set_cron_array(array());
  12. }
  13. function tearDown() {
  14. parent::tearDown();
  15. // make sure the schedule is clear
  16. _set_cron_array(array());
  17. }
  18. function test_wp_get_schedule_empty() {
  19. // nothing scheduled
  20. $hook = rand_str();
  21. $this->assertFalse(wp_get_schedule($hook));
  22. }
  23. function test_schedule_event_single() {
  24. // schedule an event and make sure it's returned by wp_next_scheduled
  25. $hook = rand_str();
  26. $timestamp = strtotime('+1 hour');
  27. wp_schedule_single_event( $timestamp, $hook );
  28. $this->assertEquals( $timestamp, wp_next_scheduled($hook) );
  29. // it's a non recurring event
  30. $this->assertEquals( '', wp_get_schedule($hook) );
  31. }
  32. function test_schedule_event_single_args() {
  33. // schedule an event with arguments and make sure it's returned by wp_next_scheduled
  34. $hook = rand_str();
  35. $timestamp = strtotime('+1 hour');
  36. $args = array(rand_str());
  37. wp_schedule_single_event( $timestamp, $hook, $args );
  38. // this returns the timestamp only if we provide matching args
  39. $this->assertEquals( $timestamp, wp_next_scheduled($hook, $args) );
  40. // these don't match so return nothing
  41. $this->assertEquals( false, wp_next_scheduled($hook) );
  42. $this->assertEquals( false, wp_next_scheduled($hook, array(rand_str())) );
  43. // it's a non recurring event
  44. $this->assertEquals( '', wp_get_schedule($hook, $args) );
  45. }
  46. function test_schedule_event() {
  47. // schedule an event and make sure it's returned by wp_next_scheduled
  48. $hook = rand_str();
  49. $recur = 'hourly';
  50. $timestamp = strtotime('+1 hour');
  51. wp_schedule_event( $timestamp, $recur, $hook );
  52. // it's scheduled for the right time
  53. $this->assertEquals( $timestamp, wp_next_scheduled($hook) );
  54. // it's a recurring event
  55. $this->assertEquals( $recur, wp_get_schedule($hook) );
  56. }
  57. function test_schedule_event_args() {
  58. // schedule an event and make sure it's returned by wp_next_scheduled
  59. $hook = rand_str();
  60. $timestamp = strtotime('+1 hour');
  61. $recur = 'hourly';
  62. $args = array(rand_str());
  63. wp_schedule_event( $timestamp, 'hourly', $hook, $args );
  64. // this returns the timestamp only if we provide matching args
  65. $this->assertEquals( $timestamp, wp_next_scheduled($hook, $args) );
  66. // these don't match so return nothing
  67. $this->assertEquals( false, wp_next_scheduled($hook) );
  68. $this->assertEquals( false, wp_next_scheduled($hook, array(rand_str())) );
  69. $this->assertEquals( $recur, wp_get_schedule($hook, $args) );
  70. }
  71. function test_unschedule_event() {
  72. // schedule an event and make sure it's returned by wp_next_scheduled
  73. $hook = rand_str();
  74. $timestamp = strtotime('+1 hour');
  75. wp_schedule_single_event( $timestamp, $hook );
  76. $this->assertEquals( $timestamp, wp_next_scheduled($hook) );
  77. // now unschedule it and make sure it's gone
  78. wp_unschedule_event( $timestamp, $hook );
  79. $this->assertEquals( false, wp_next_scheduled($hook) );
  80. }
  81. function test_clear_schedule() {
  82. $hook = rand_str();
  83. $args = array(rand_str());
  84. // schedule several events with and without arguments
  85. wp_schedule_single_event( strtotime('+1 hour'), $hook );
  86. wp_schedule_single_event( strtotime('+2 hour'), $hook );
  87. wp_schedule_single_event( strtotime('+3 hour'), $hook, $args );
  88. wp_schedule_single_event( strtotime('+4 hour'), $hook, $args );
  89. // make sure they're returned by wp_next_scheduled()
  90. $this->assertTrue( wp_next_scheduled($hook) > 0 );
  91. $this->assertTrue( wp_next_scheduled($hook, $args) > 0 );
  92. // clear the schedule for the no args events and make sure it's gone
  93. wp_clear_scheduled_hook($hook);
  94. $this->assertFalse( wp_next_scheduled($hook) );
  95. // the args events should still be there
  96. $this->assertTrue( wp_next_scheduled($hook, $args) > 0 );
  97. // clear the schedule for the args events and make sure they're gone too
  98. // note: wp_clear_scheduled_hook() expects args passed directly, rather than as an array
  99. wp_clear_scheduled_hook($hook, $args);
  100. $this->assertFalse( wp_next_scheduled($hook, $args) );
  101. }
  102. function test_clear_schedule_multiple_args() {
  103. $hook = rand_str();
  104. $args = array(rand_str(), rand_str());
  105. // schedule several events with and without arguments
  106. wp_schedule_single_event( strtotime('+1 hour'), $hook );
  107. wp_schedule_single_event( strtotime('+2 hour'), $hook );
  108. wp_schedule_single_event( strtotime('+3 hour'), $hook, $args );
  109. wp_schedule_single_event( strtotime('+4 hour'), $hook, $args );
  110. // make sure they're returned by wp_next_scheduled()
  111. $this->assertTrue( wp_next_scheduled($hook) > 0 );
  112. $this->assertTrue( wp_next_scheduled($hook, $args) > 0 );
  113. // clear the schedule for the no args events and make sure it's gone
  114. wp_clear_scheduled_hook($hook);
  115. $this->assertFalse( wp_next_scheduled($hook) );
  116. // the args events should still be there
  117. $this->assertTrue( wp_next_scheduled($hook, $args) > 0 );
  118. // clear the schedule for the args events and make sure they're gone too
  119. // note: wp_clear_scheduled_hook() used to expect args passed directly, rather than as an array pre WP 3.0
  120. wp_clear_scheduled_hook($hook, $args);
  121. $this->assertFalse( wp_next_scheduled($hook, $args) );
  122. }
  123. /**
  124. * @ticket 10468
  125. */
  126. function test_clear_schedule_new_args() {
  127. $hook = rand_str();
  128. $args = array(rand_str());
  129. $multi_hook = rand_str();
  130. $multi_args = array(rand_str(), rand_str());
  131. // schedule several events with and without arguments
  132. wp_schedule_single_event( strtotime('+1 hour'), $hook );
  133. wp_schedule_single_event( strtotime('+2 hour'), $hook );
  134. wp_schedule_single_event( strtotime('+3 hour'), $hook, $args );
  135. wp_schedule_single_event( strtotime('+4 hour'), $hook, $args );
  136. wp_schedule_single_event( strtotime('+5 hour'), $multi_hook, $multi_args );
  137. wp_schedule_single_event( strtotime('+6 hour'), $multi_hook, $multi_args );
  138. // make sure they're returned by wp_next_scheduled()
  139. $this->assertTrue( wp_next_scheduled($hook) > 0 );
  140. $this->assertTrue( wp_next_scheduled($hook, $args) > 0 );
  141. // clear the schedule for the no args events and make sure it's gone
  142. wp_clear_scheduled_hook($hook);
  143. $this->assertFalse( wp_next_scheduled($hook) );
  144. // the args events should still be there
  145. $this->assertTrue( wp_next_scheduled($hook, $args) > 0 );
  146. // clear the schedule for the args events and make sure they're gone too
  147. // wp_clear_scheduled_hook() should take args as an array like the other functions.
  148. wp_clear_scheduled_hook($hook, $args);
  149. $this->assertFalse( wp_next_scheduled($hook, $args) );
  150. // clear the schedule for the args events and make sure they're gone too
  151. // wp_clear_scheduled_hook() should take args as an array like the other functions and does from WP 3.0
  152. wp_clear_scheduled_hook($multi_hook, $multi_args);
  153. $this->assertFalse( wp_next_scheduled($multi_hook, $multi_args) );
  154. }
  155. /**
  156. * @ticket 6966
  157. */
  158. function test_duplicate_event() {
  159. // duplicate events close together should be skipped
  160. $hook = rand_str();
  161. $args = array(rand_str());
  162. $ts1 = strtotime('+5 minutes');
  163. $ts2 = strtotime('+3 minutes');
  164. // first one works
  165. wp_schedule_single_event( $ts1, $hook, $args );
  166. // second one is ignored
  167. wp_schedule_single_event( $ts2, $hook, $args );
  168. // the next event should be at +5 minutes, not +3
  169. $this->assertEquals( $ts1, wp_next_scheduled($hook, $args) );
  170. }
  171. /**
  172. * @ticket 6966
  173. */
  174. function test_not_duplicate_event() {
  175. // duplicate events far apart should work normally
  176. $hook = rand_str();
  177. $args = array(rand_str());
  178. $ts1 = strtotime('+30 minutes');
  179. $ts2 = strtotime('+3 minutes');
  180. // first one works
  181. wp_schedule_single_event( $ts1, $hook, $args );
  182. // second works too
  183. wp_schedule_single_event( $ts2, $hook, $args );
  184. // the next event should be at +5 minutes, not +3
  185. $this->assertEquals( $ts2, wp_next_scheduled($hook, $args) );
  186. wp_unschedule_event( $ts2, $hook, $args );
  187. // following event should be there too
  188. $this->assertEquals( $ts1, wp_next_scheduled($hook, $args) );
  189. }
  190. }
  191. /*
  192. * Disable the WP Cron running test for the moment as it kills the whole test suite.
  193. * TODO - Fix it to work with the new cron implementation in trunk
  194. *
  195. class WPTestCronRunning extends _WPEmptyBlog {
  196. function setUp() {
  197. parent::setUp();
  198. // make sure the schedule is clear
  199. _set_cron_array(array());
  200. }
  201. function tearDown() {
  202. parent::tearDown();
  203. // make sure the schedule is clear
  204. _set_cron_array(array());
  205. }
  206. function _do_cron() {
  207. // FIXME: wp-cron.php is difficult to test, could be wrapped in a function
  208. $_GET['check'] = wp_hash('187425');
  209. require(ABSPATH.'/wp-cron.php');
  210. }
  211. function test_run_schedule_single() {
  212. // schedule an event, run it, and make sure the hook is called
  213. $hook = rand_str();
  214. $args = array(rand_str());
  215. $timestamp = strtotime('-1 second');
  216. // register a test action
  217. $a = new MockAction();
  218. add_action($hook, array(&$a, 'action'));
  219. // schedule an event for 1 second ago
  220. wp_schedule_single_event( $timestamp, $hook, $args );
  221. $this->assertEquals( $timestamp, wp_next_scheduled($hook, $args) );
  222. // run cron jobs
  223. $this->_do_cron();
  224. // our action should have been called once with the correct args
  225. $this->assertEquals( 1, $a->get_call_count() );
  226. $this->assertEquals( array($args), $a->get_args() );
  227. // it shouldn't appear in the schedule anymore
  228. $this->assertFalse( wp_next_scheduled($hook, $args) );
  229. }
  230. function test_run_schedule_recurring() {
  231. // schedule a recurring event, run it, and make sure the hook is called
  232. $hook = rand_str();
  233. $args = array(rand_str());
  234. $timestamp = strtotime('-1 second');
  235. $recur = 'hourly';
  236. // register a test action
  237. $a = new MockAction();
  238. add_action($hook, array(&$a, 'action'));
  239. // schedule an event for 1 second ago
  240. wp_schedule_event( $timestamp, $recur, $hook, $args );
  241. $this->assertEquals( $timestamp, wp_next_scheduled($hook, $args) );
  242. $this->assertEquals( $recur, wp_get_schedule($hook, $args) );
  243. // run cron jobs
  244. $this->_do_cron();
  245. // our action should have been called once with the correct args
  246. $this->assertEquals( 1, $a->get_call_count() );
  247. $this->assertEquals( array($args), $a->get_args() );
  248. // it should appear in the schedule to run again in an hour's time
  249. $this->assertEquals( $timestamp + 3600, wp_next_scheduled($hook, $args) );
  250. }
  251. }
  252. */