Merge pull request #23162 from thenbrent/fix/23121

Update Action Scheduler to v2.2.3
This commit is contained in:
Timmy Crawford 2019-03-28 07:42:55 -07:00 committed by GitHub
commit ae1841a82c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 20 additions and 4839 deletions

View File

@ -1,3 +0,0 @@
phpunit.xml
vendor
.idea

View File

@ -1,37 +0,0 @@
# Travis CI Configuration File
# Tell Travis CI we're using PHP
language: php
# We nee to use Precise, not Trusty, to test against PHP 5.3, see https://github.com/travis-ci/travis-ci/issues/8219
dist: precise
# Versions of PHP to test against
php:
- "5.3"
- "5.4"
- "5.5"
- "5.6"
- "7.0"
- "7.1"
# Specify versions of WordPress to test against
# WP_VERSION = WordPress version number (use "master" for SVN trunk)
# WP_MULTISITE = whether to test multisite (use either "0" or "1")
env:
- WP_VERSION=4.8 WP_MULTISITE=0
- WP_VERSION=4.7 WP_MULTISITE=0
- WP_VERSION=4.6 WP_MULTISITE=0
- WP_VERSION=4.8 WP_MULTISITE=1
- WP_VERSION=4.7 WP_MULTISITE=1
- WP_VERSION=4.6 WP_MULTISITE=1
# Grab the setup script and execute
before_script:
- source tests/travis/setup.sh $TRAVIS_PHP_VERSION
script:
- if [[ "$TRAVIS_PHP_VERSION" == "7.1" ]] && [[ "$WP_VERSION" == "4.8" ]] && [[ "$WP_MULTISITE" == "0" ]] && [[ "$TRAVIS_BRANCH" == "master" ]]; then phpunit --configuration tests/phpunit.xml.dist --coverage-clover clover.xml; else phpunit --configuration tests/phpunit.xml.dist; fi
after_script:
- bash <(curl -s https://codecov.io/bash)

View File

@ -1,14 +1,14 @@
<?php <?php
/* /*
* Plugin Name: Action Scheduler * Plugin Name: Action Scheduler
* Plugin URI: https://github.com/prospress/action-scheduler * Plugin URI: https://actionscheduler.org
* Description: A robust scheduling library for use in WordPress plugins. * Description: A robust scheduling library for use in WordPress plugins.
* Author: Prospress * Author: Prospress
* Author URI: http://prospress.com/ * Author URI: http://prospress.com/
* Version: 2.2.1 * Version: 2.2.3
* License: GPLv3 * License: GPLv3
* *
* Copyright 2018 Prospress, Inc. (email : freedoms@prospress.com) * Copyright 2019 Prospress, Inc. (email : freedoms@prospress.com)
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -25,21 +25,21 @@
* *
*/ */
if ( ! function_exists( 'action_scheduler_register_2_dot_2_dot_1' ) ) { if ( ! function_exists( 'action_scheduler_register_2_dot_2_dot_3' ) ) {
if ( ! class_exists( 'ActionScheduler_Versions' ) ) { if ( ! class_exists( 'ActionScheduler_Versions' ) ) {
require_once( 'classes/ActionScheduler_Versions.php' ); require_once( 'classes/ActionScheduler_Versions.php' );
add_action( 'plugins_loaded', array( 'ActionScheduler_Versions', 'initialize_latest_version' ), 1, 0 ); add_action( 'plugins_loaded', array( 'ActionScheduler_Versions', 'initialize_latest_version' ), 1, 0 );
} }
add_action( 'plugins_loaded', 'action_scheduler_register_2_dot_2_dot_1', 0, 0 ); add_action( 'plugins_loaded', 'action_scheduler_register_2_dot_2_dot_3', 0, 0 );
function action_scheduler_register_2_dot_2_dot_1() { function action_scheduler_register_2_dot_2_dot_3() {
$versions = ActionScheduler_Versions::instance(); $versions = ActionScheduler_Versions::instance();
$versions->register( '2.2.1', 'action_scheduler_initialize_2_dot_2_dot_1' ); $versions->register( '2.2.3', 'action_scheduler_initialize_2_dot_2_dot_3' );
} }
function action_scheduler_initialize_2_dot_2_dot_1() { function action_scheduler_initialize_2_dot_2_dot_3() {
require_once( 'classes/ActionScheduler.php' ); require_once( 'classes/ActionScheduler.php' );
ActionScheduler::init( __FILE__ ); ActionScheduler::init( __FILE__ );
} }

View File

@ -112,11 +112,7 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
$this->process_action( $action_id ); $this->process_action( $action_id );
$this->progress_bar->tick(); $this->progress_bar->tick();
$this->maybe_stop_the_insanity();
// Free up memory after every 50 items
if ( 0 === $this->progress_bar->current() % 50 ) {
$this->stop_the_insanity();
}
} }
$completed = $this->progress_bar->current(); $completed = $this->progress_bar->current();
@ -207,4 +203,15 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
call_user_func( array( $wp_object_cache, '__remoteset' ) ); // important call_user_func( array( $wp_object_cache, '__remoteset' ) ); // important
} }
} }
/**
* Maybe trigger the stop_the_insanity() method to free up memory.
*/
protected function maybe_stop_the_insanity() {
// The value returned by progress_bar->current() might be padded. Remove padding, and convert to int.
$current_iteration = intval( trim( $this->progress_bar->current() ) );
if ( 0 === $current_iteration % 50 ) {
$this->stop_the_insanity();
}
}
} }

View File

@ -1,13 +0,0 @@
codecov:
branch: master
coverage:
ignore:
- tests/.*
- lib/.*
status:
project: false
patch: false
changes: false
comment: false

File diff suppressed because it is too large Load Diff

View File

@ -1,44 +0,0 @@
<?php
/**
* Class ActionScheduler_UnitTestCase
*/
class ActionScheduler_UnitTestCase extends WP_UnitTestCase {
protected $existing_timezone;
/**
* Counts the number of test cases executed by run(TestResult result).
*
* @return int
*/
public function count() {
return 'UTC' == date_default_timezone_get() ? 2 : 3;
}
/**
* We want to run every test multiple times using a different timezone to make sure
* that they are unaffected by changes to PHP's timezone.
*/
public function run( PHPUnit\Framework\TestResult $result = NULL ){
if ($result === NULL) {
$result = $this->createResult();
}
if ( 'UTC' != ( $this->existing_timezone = date_default_timezone_get() ) ) {
date_default_timezone_set( 'UTC' );
$result->run( $this );
}
date_default_timezone_set( 'Pacific/Fiji' ); // UTC+12
$result->run( $this );
date_default_timezone_set( 'Pacific/Tahiti' ); // UTC-10: it's a magical place
$result->run( $this );
date_default_timezone_set( $this->existing_timezone );
return $result;
}
}

View File

@ -1,31 +0,0 @@
<?php
$GLOBALS['wp_tests_options'][ 'template' ] = 'twentyseventeen';
$GLOBALS['wp_tests_options'][ 'stylesheet' ] = 'twentyseventeen';
$GLOBALS['wp_tests_options'][ 'active_plugins' ][] = basename( dirname( __DIR__ ) ) .'/action-scheduler.php';
// Check for select constants defined as environment variables
foreach ( array('WP_CONTENT_DIR', 'WP_CONTENT_URL', 'WP_PLUGIN_DIR', 'WP_PLUGIN_URL', 'WPMU_PLUGIN_DIR') as $env_constant ) {
if ( false !== getenv( $env_constant ) && !defined( $env_constant ) ) {
define( $env_constant, getenv( $env_constant ));
}
}
// If the wordpress-tests repo location has been customized (and specified
// with WP_TESTS_DIR), use that location. This will most commonly be the case
// when configured for use with Travis CI.
// Otherwise, we'll just assume that this plugin is installed in the WordPress
// SVN external checkout configured in the wordpress-tests repo.
if( false !== getenv( 'WP_TESTS_DIR' ) ) {
require getenv( 'WP_TESTS_DIR' ) . '/includes/bootstrap.php';
} else {
require dirname( dirname( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) ) ) . '/tests/phpunit/includes/bootstrap.php';
}
if ( class_exists( 'PHPUnit\Framework\TestResult' ) ) { // PHPUnit 6.0 or newer
include_once('ActionScheduler_UnitTestCase.php');
} else {
include_once('phpunit/deprecated/ActionScheduler_UnitTestCase.php');
}

View File

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="bootstrap.php"
>
<testsuites>
<testsuite name="Action Scheduler">
<directory>./phpunit</directory>
</testsuite>
</testsuites>
<groups>
<exclude>
<group>ignore</group>
</exclude>
</groups>
<filter>
<whitelist processsUncoveredFilesFromWhitelist="true">
<directory suffix=".php">..</directory>
<exclude>
<directory>.</directory>
</exclude>
</whitelist>
</filter>
</phpunit>

View File

@ -1,44 +0,0 @@
<?php
/**
* Class ActionScheduler_UnitTestCase
*/
class ActionScheduler_UnitTestCase extends WP_UnitTestCase {
protected $existing_timezone;
/**
* Counts the number of test cases executed by run(TestResult result).
*
* @return int
*/
public function count() {
return 'UTC' == date_default_timezone_get() ? 2 : 3;
}
/**
* We want to run every test multiple times using a different timezone to make sure
* that they are unaffected by changes to PHP's timezone.
*/
public function run( PHPUnit_Framework_TestResult $result = NULL ){
if ($result === NULL) {
$result = $this->createResult();
}
if ( 'UTC' != ( $this->existing_timezone = date_default_timezone_get() ) ) {
date_default_timezone_set( 'UTC' );
$result->run( $this );
}
date_default_timezone_set( 'Pacific/Fiji' ); // UTC+12
$result->run( $this );
date_default_timezone_set( 'Pacific/Tahiti' ); // UTC-10: it's a magical place
$result->run( $this );
date_default_timezone_set( $this->existing_timezone );
return $result;
}
}

View File

@ -1,100 +0,0 @@
<?php
/**
* @group timezone
*/
class ActionScheduler_TimezoneHelper_Test extends ActionScheduler_UnitTestCase {
/**
* Ensure that the timezone string we expect works properly.
*
* @dataProvider local_timezone_provider
*
* @param $timezone_string
*/
public function test_local_timezone_strings( $timezone_string ) {
$timezone_filter = function ( $tz ) use ( $timezone_string ) {
return $timezone_string;
};
add_filter( 'option_timezone_string', $timezone_filter );
$date = new ActionScheduler_DateTime();
$timezone = ActionScheduler_TimezoneHelper::set_local_timezone( $date )->getTimezone();
$this->assertInstanceOf( 'DateTimeZone', $timezone );
$this->assertEquals( $timezone_string, $timezone->getName() );
remove_filter( 'option_timezone_string', $timezone_filter );
}
public function local_timezone_provider() {
return array(
array( 'America/New_York' ),
array( 'Australia/Melbourne' ),
array( 'UTC' ),
);
}
/**
* Ensure that most GMT offsets don't return UTC as the timezone.
*
* @dataProvider local_timezone_offsets_provider
*
* @param $gmt_offset
*/
public function test_local_timezone_offsets( $gmt_offset ) {
$gmt_filter = function ( $gmt ) use ( $gmt_offset ) {
return $gmt_offset;
};
$date = new ActionScheduler_DateTime();
add_filter( 'option_gmt_offset', $gmt_filter );
ActionScheduler_TimezoneHelper::set_local_timezone( $date );
remove_filter( 'option_gmt_offset', $gmt_filter );
$offset_in_seconds = $gmt_offset * HOUR_IN_SECONDS;
$this->assertEquals( $offset_in_seconds, $date->getOffset() );
$this->assertEquals( $offset_in_seconds, $date->getOffsetTimestamp() - $date->getTimestamp() );
}
public function local_timezone_offsets_provider() {
return array(
array( '-11' ),
array( '-10.5' ),
array( '-10' ),
array( '-9' ),
array( '-8' ),
array( '-7' ),
array( '-6' ),
array( '-5' ),
array( '-4.5' ),
array( '-4' ),
array( '-3.5' ),
array( '-3' ),
array( '-2' ),
array( '-1' ),
array( '1' ),
array( '1.5' ),
array( '2' ),
array( '3' ),
array( '4' ),
array( '5' ),
array( '5.5' ),
array( '5.75' ),
array( '6' ),
array( '7' ),
array( '8' ),
array( '8.5' ),
array( '9' ),
array( '9.5' ),
array( '10' ),
array( '10.5' ),
array( '11' ),
array( '11.5' ),
array( '12' ),
array( '13' ),
);
}
}

View File

@ -1,55 +0,0 @@
<?php
/**
* Class ActionScheduler_Action_Test
* @group actions
*/
class ActionScheduler_Action_Test extends ActionScheduler_UnitTestCase {
public function test_set_schedule() {
$time = as_get_datetime_object();
$schedule = new ActionScheduler_SimpleSchedule($time);
$action = new ActionScheduler_Action('my_hook', array(), $schedule);
$this->assertEquals( $schedule, $action->get_schedule() );
}
public function test_null_schedule() {
$action = new ActionScheduler_Action('my_hook');
$this->assertInstanceOf( 'ActionScheduler_NullSchedule', $action->get_schedule() );
}
public function test_set_hook() {
$action = new ActionScheduler_Action('my_hook');
$this->assertEquals( 'my_hook', $action->get_hook() );
}
public function test_args() {
$action = new ActionScheduler_Action('my_hook');
$this->assertEmpty($action->get_args());
$action = new ActionScheduler_Action('my_hook', array(5,10,15));
$this->assertEqualSets(array(5,10,15), $action->get_args());
}
public function test_set_group() {
$action = new ActionScheduler_Action('my_hook', array(), NULL, 'my_group');
$this->assertEquals('my_group', $action->get_group());
}
public function test_execute() {
$mock = new MockAction();
$random = md5(rand());
add_action( $random, array( $mock, 'action' ) );
$action = new ActionScheduler_Action( $random, array($random) );
$action->execute();
remove_action( $random, array( $mock, 'action' ) );
$this->assertEquals( 1, $mock->get_call_count() );
$events = $mock->get_events();
$event = reset($events);
$this->assertEquals( $random, reset($event['args']) );
}
}

View File

@ -1,16 +0,0 @@
<?php
/**
* Class ActionScheduler_NullAction_Test
* @group actions
*/
class ActionScheduler_NullAction_Test extends ActionScheduler_UnitTestCase {
public function test_null_action() {
$action = new ActionScheduler_NullAction();
$this->assertEmpty($action->get_hook());
$this->assertEmpty($action->get_args());
$this->assertNull($action->get_schedule()->next());
}
}

View File

@ -1,375 +0,0 @@
<?php
/**
* Class ActionScheduler_wpPostStore_Test
* @group stores
*/
class ActionScheduler_wpPostStore_Test extends ActionScheduler_UnitTestCase {
public function test_create_action() {
$time = as_get_datetime_object();
$schedule = new ActionScheduler_SimpleSchedule($time);
$action = new ActionScheduler_Action('my_hook', array(), $schedule);
$store = new ActionScheduler_wpPostStore();
$action_id = $store->save_action($action);
$this->assertNotEmpty($action_id);
}
public function test_create_action_with_scheduled_date() {
$time = as_get_datetime_object( strtotime( '-1 week' ) );
$action = new ActionScheduler_Action( 'my_hook', array(), new ActionScheduler_SimpleSchedule( $time ) );
$store = new ActionScheduler_wpPostStore();
$action_id = $store->save_action( $action, $time );
$action_date = $store->get_date( $action_id );
$this->assertEquals( $time->getTimestamp(), $action_date->getTimestamp() );
}
public function test_retrieve_action() {
$time = as_get_datetime_object();
$schedule = new ActionScheduler_SimpleSchedule($time);
$action = new ActionScheduler_Action('my_hook', array(), $schedule, 'my_group');
$store = new ActionScheduler_wpPostStore();
$action_id = $store->save_action($action);
$retrieved = $store->fetch_action($action_id);
$this->assertEquals($action->get_hook(), $retrieved->get_hook());
$this->assertEqualSets($action->get_args(), $retrieved->get_args());
$this->assertEquals($action->get_schedule()->next()->getTimestamp(), $retrieved->get_schedule()->next()->getTimestamp());
$this->assertEquals($action->get_group(), $retrieved->get_group());
}
/**
* @expectedException ActionScheduler_InvalidActionException
* @dataProvider provide_bad_args
*
* @param string $content
*/
public function test_action_bad_args( $content ) {
$store = new ActionScheduler_wpPostStore();
$post_id = wp_insert_post( array(
'post_type' => ActionScheduler_wpPostStore::POST_TYPE,
'post_status' => ActionScheduler_Store::STATUS_PENDING,
'post_content' => $content,
) );
$store->fetch_action( $post_id );
}
public function provide_bad_args() {
return array(
array( '{"bad_json":true}}' ),
);
}
public function test_cancel_action() {
$time = as_get_datetime_object();
$schedule = new ActionScheduler_SimpleSchedule($time);
$action = new ActionScheduler_Action('my_hook', array(), $schedule, 'my_group');
$store = new ActionScheduler_wpPostStore();
$action_id = $store->save_action($action);
$store->cancel_action( $action_id );
$fetched = $store->fetch_action( $action_id );
$this->assertInstanceOf( 'ActionScheduler_CanceledAction', $fetched );
}
public function test_claim_actions() {
$created_actions = array();
$store = new ActionScheduler_wpPostStore();
for ( $i = 3 ; $i > -3 ; $i-- ) {
$time = as_get_datetime_object($i.' hours');
$schedule = new ActionScheduler_SimpleSchedule($time);
$action = new ActionScheduler_Action('my_hook', array($i), $schedule, 'my_group');
$created_actions[] = $store->save_action($action);
}
$claim = $store->stake_claim();
$this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
$this->assertCount( 3, $claim->get_actions() );
$this->assertEqualSets( array_slice( $created_actions, 3, 3 ), $claim->get_actions() );
}
public function test_claim_actions_order() {
$store = new ActionScheduler_wpPostStore();
$schedule = new ActionScheduler_SimpleSchedule( as_get_datetime_object( '-1 hour' ) );
$created_actions = array(
$store->save_action( new ActionScheduler_Action( 'my_hook', array( 1 ), $schedule, 'my_group' ) ),
$store->save_action( new ActionScheduler_Action( 'my_hook', array( 1 ), $schedule, 'my_group' ) ),
);
$claim = $store->stake_claim();
$this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
// Verify uniqueness of action IDs.
$this->assertEquals( 2, count( array_unique( $created_actions ) ) );
// Verify the count and order of the actions.
$claimed_actions = $claim->get_actions();
$this->assertCount( 2, $claimed_actions );
$this->assertEquals( $created_actions, $claimed_actions );
// Verify the reversed order doesn't pass.
$reversed_actions = array_reverse( $created_actions );
$this->assertNotEquals( $reversed_actions, $claimed_actions );
}
public function test_duplicate_claim() {
$created_actions = array();
$store = new ActionScheduler_wpPostStore();
for ( $i = 0 ; $i > -3 ; $i-- ) {
$time = as_get_datetime_object($i.' hours');
$schedule = new ActionScheduler_SimpleSchedule($time);
$action = new ActionScheduler_Action('my_hook', array($i), $schedule, 'my_group');
$created_actions[] = $store->save_action($action);
}
$claim1 = $store->stake_claim();
$claim2 = $store->stake_claim();
$this->assertCount( 3, $claim1->get_actions() );
$this->assertCount( 0, $claim2->get_actions() );
}
public function test_release_claim() {
$created_actions = array();
$store = new ActionScheduler_wpPostStore();
for ( $i = 0 ; $i > -3 ; $i-- ) {
$time = as_get_datetime_object($i.' hours');
$schedule = new ActionScheduler_SimpleSchedule($time);
$action = new ActionScheduler_Action('my_hook', array($i), $schedule, 'my_group');
$created_actions[] = $store->save_action($action);
}
$claim1 = $store->stake_claim();
$store->release_claim( $claim1 );
$claim2 = $store->stake_claim();
$this->assertCount( 3, $claim2->get_actions() );
}
public function test_search() {
$created_actions = array();
$store = new ActionScheduler_wpPostStore();
for ( $i = -3 ; $i <= 3 ; $i++ ) {
$time = as_get_datetime_object($i.' hours');
$schedule = new ActionScheduler_SimpleSchedule($time);
$action = new ActionScheduler_Action('my_hook', array($i), $schedule, 'my_group');
$created_actions[] = $store->save_action($action);
}
$next_no_args = $store->find_action( 'my_hook' );
$this->assertEquals( $created_actions[0], $next_no_args );
$next_with_args = $store->find_action( 'my_hook', array( 'args' => array( 1 ) ) );
$this->assertEquals( $created_actions[4], $next_with_args );
$non_existent = $store->find_action( 'my_hook', array( 'args' => array( 17 ) ) );
$this->assertNull( $non_existent );
}
public function test_search_by_group() {
$store = new ActionScheduler_wpPostStore();
$schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('tomorrow'));
$abc = $store->save_action(new ActionScheduler_Action('my_hook', array(1), $schedule, 'abc'));
$def = $store->save_action(new ActionScheduler_Action('my_hook', array(1), $schedule, 'def'));
$ghi = $store->save_action(new ActionScheduler_Action('my_hook', array(1), $schedule, 'ghi'));
$this->assertEquals( $abc, $store->find_action('my_hook', array('group' => 'abc')));
$this->assertEquals( $def, $store->find_action('my_hook', array('group' => 'def')));
$this->assertEquals( $ghi, $store->find_action('my_hook', array('group' => 'ghi')));
}
public function test_post_author() {
$current_user = get_current_user_id();
$time = as_get_datetime_object();
$schedule = new ActionScheduler_SimpleSchedule($time);
$action = new ActionScheduler_Action('my_hook', array(), $schedule);
$store = new ActionScheduler_wpPostStore();
$action_id = $store->save_action($action);
$post = get_post($action_id);
$this->assertEquals(0, $post->post_author);
$new_user = $this->factory->user->create_object(array(
'user_login' => __FUNCTION__,
'user_pass' => md5(rand()),
));
wp_set_current_user( $new_user );
$schedule = new ActionScheduler_SimpleSchedule($time);
$action = new ActionScheduler_Action('my_hook', array(), $schedule);
$action_id = $store->save_action($action);
$post = get_post($action_id);
$this->assertEquals(0, $post->post_author);
wp_set_current_user($current_user);
}
/**
* @issue 13
*/
public function test_post_status_for_recurring_action() {
$time = as_get_datetime_object('10 minutes');
$schedule = new ActionScheduler_IntervalSchedule($time, HOUR_IN_SECONDS);
$action = new ActionScheduler_Action('my_hook', array(), $schedule);
$store = new ActionScheduler_wpPostStore();
$action_id = $store->save_action($action);
$action = $store->fetch_action($action_id);
$action->execute();
$store->mark_complete( $action_id );
$next = $action->get_schedule()->next( as_get_datetime_object() );
$new_action_id = $store->save_action( $action, $next );
$this->assertEquals('publish', get_post_status($action_id));
$this->assertEquals('pending', get_post_status($new_action_id));
}
public function test_get_run_date() {
$time = as_get_datetime_object('-10 minutes');
$schedule = new ActionScheduler_IntervalSchedule($time, HOUR_IN_SECONDS);
$action = new ActionScheduler_Action('my_hook', array(), $schedule);
$store = new ActionScheduler_wpPostStore();
$action_id = $store->save_action($action);
$this->assertEquals( $store->get_date($action_id)->getTimestamp(), $time->getTimestamp() );
$action = $store->fetch_action($action_id);
$action->execute();
$now = as_get_datetime_object();
$store->mark_complete( $action_id );
$this->assertEquals( $store->get_date($action_id)->getTimestamp(), $now->getTimestamp() );
$next = $action->get_schedule()->next( $now );
$new_action_id = $store->save_action( $action, $next );
$this->assertEquals( (int)($now->getTimestamp()) + HOUR_IN_SECONDS, $store->get_date($new_action_id)->getTimestamp() );
}
public function test_get_status() {
$time = as_get_datetime_object('-10 minutes');
$schedule = new ActionScheduler_IntervalSchedule($time, HOUR_IN_SECONDS);
$action = new ActionScheduler_Action('my_hook', array(), $schedule);
$store = new ActionScheduler_wpPostStore();
$action_id = $store->save_action($action);
$this->assertEquals( ActionScheduler_Store::STATUS_PENDING, $store->get_status( $action_id ) );
$store->mark_complete( $action_id );
$this->assertEquals( ActionScheduler_Store::STATUS_COMPLETE, $store->get_status( $action_id ) );
$store->mark_failure( $action_id );
$this->assertEquals( ActionScheduler_Store::STATUS_FAILED, $store->get_status( $action_id ) );
}
public function test_claim_actions_by_hooks() {
$hook1 = __FUNCTION__ . '_hook_1';
$hook2 = __FUNCTION__ . '_hook_2';
$store = new ActionScheduler_wpPostStore();
$schedule = new ActionScheduler_SimpleSchedule( as_get_datetime_object( '-1 hour' ) );
$action1 = $store->save_action( new ActionScheduler_Action( $hook1, array(), $schedule ) );
$action2 = $store->save_action( new ActionScheduler_Action( $hook2, array(), $schedule ) );
// Claiming no hooks should include all actions.
$claim = $store->stake_claim( 10 );
$this->assertEquals( 2, count( $claim->get_actions() ) );
$this->assertTrue( in_array( $action1, $claim->get_actions() ) );
$this->assertTrue( in_array( $action2, $claim->get_actions() ) );
$store->release_claim( $claim );
// Claiming a hook should claim only actions with that hook
$claim = $store->stake_claim( 10, null, array( $hook1 ) );
$this->assertEquals( 1, count( $claim->get_actions() ) );
$this->assertTrue( in_array( $action1, $claim->get_actions() ) );
$store->release_claim( $claim );
// Claiming two hooks should claim actions with either of those hooks
$claim = $store->stake_claim( 10, null, array( $hook1, $hook2 ) );
$this->assertEquals( 2, count( $claim->get_actions() ) );
$this->assertTrue( in_array( $action1, $claim->get_actions() ) );
$this->assertTrue( in_array( $action2, $claim->get_actions() ) );
$store->release_claim( $claim );
// Claiming two hooks should claim actions with either of those hooks
$claim = $store->stake_claim( 10, null, array( __METHOD__ . '_hook_3' ) );
$this->assertEquals( 0, count( $claim->get_actions() ) );
$this->assertFalse( in_array( $action1, $claim->get_actions() ) );
$this->assertFalse( in_array( $action2, $claim->get_actions() ) );
$store->release_claim( $claim );
}
/**
* @issue 121
*/
public function test_claim_actions_by_group() {
$group1 = md5( rand() );
$store = new ActionScheduler_wpPostStore();
$schedule = new ActionScheduler_SimpleSchedule( as_get_datetime_object( '-1 hour' ) );
$action1 = $store->save_action( new ActionScheduler_Action( __METHOD__, array(), $schedule, $group1 ) );
$action2 = $store->save_action( new ActionScheduler_Action( __METHOD__, array(), $schedule ) );
// Claiming no group should include all actions.
$claim = $store->stake_claim( 10 );
$this->assertEquals( 2, count( $claim->get_actions() ) );
$this->assertTrue( in_array( $action1, $claim->get_actions() ) );
$this->assertTrue( in_array( $action2, $claim->get_actions() ) );
$store->release_claim( $claim );
// Claiming a group should claim only actions in that group.
$claim = $store->stake_claim( 10, null, array(), $group1 );
$this->assertEquals( 1, count( $claim->get_actions() ) );
$this->assertTrue( in_array( $action1, $claim->get_actions() ) );
$store->release_claim( $claim );
}
public function test_claim_actions_by_hook_and_group() {
$hook1 = __FUNCTION__ . '_hook_1';
$hook2 = __FUNCTION__ . '_hook_2';
$hook3 = __FUNCTION__ . '_hook_3';
$group1 = 'group_' . md5( rand() );
$group2 = 'group_' . md5( rand() );
$store = new ActionScheduler_wpPostStore();
$schedule = new ActionScheduler_SimpleSchedule( as_get_datetime_object( '-1 hour' ) );
$action1 = $store->save_action( new ActionScheduler_Action( $hook1, array(), $schedule, $group1 ) );
$action2 = $store->save_action( new ActionScheduler_Action( $hook2, array(), $schedule ) );
$action3 = $store->save_action( new ActionScheduler_Action( $hook3, array(), $schedule, $group2 ) );
// Claiming no hooks or group should include all actions.
$claim = $store->stake_claim( 10 );
$this->assertEquals( 3, count( $claim->get_actions() ) );
$this->assertTrue( in_array( $action1, $claim->get_actions() ) );
$this->assertTrue( in_array( $action2, $claim->get_actions() ) );
$store->release_claim( $claim );
// Claiming a group and hook should claim only actions in that group.
$claim = $store->stake_claim( 10, null, array( $hook1 ), $group1 );
$this->assertEquals( 1, count( $claim->get_actions() ) );
$this->assertTrue( in_array( $action1, $claim->get_actions() ) );
$store->release_claim( $claim );
// Claiming a group and hook should claim only actions with that hook in that group.
$claim = $store->stake_claim( 10, null, array( $hook2 ), $group1 );
$this->assertEquals( 0, count( $claim->get_actions() ) );
$this->assertFalse( in_array( $action1, $claim->get_actions() ) );
$this->assertFalse( in_array( $action2, $claim->get_actions() ) );
$store->release_claim( $claim );
// Claiming a group and hook should claim only actions with that hook in that group.
$claim = $store->stake_claim( 10, null, array( $hook1, $hook2 ), $group2 );
$this->assertEquals( 0, count( $claim->get_actions() ) );
$this->assertFalse( in_array( $action1, $claim->get_actions() ) );
$this->assertFalse( in_array( $action2, $claim->get_actions() ) );
$store->release_claim( $claim );
}
}

View File

@ -1,185 +0,0 @@
<?php
/**
* Class ActionScheduler_wpCommentLogger_Test
* @package test_cases\logging
*/
class ActionScheduler_wpCommentLogger_Test extends ActionScheduler_UnitTestCase {
public function test_default_logger() {
$logger = ActionScheduler::logger();
$this->assertInstanceOf( 'ActionScheduler_Logger', $logger );
$this->assertInstanceOf( 'ActionScheduler_wpCommentLogger', $logger );
}
public function test_add_log_entry() {
$action_id = as_schedule_single_action( time(), 'a hook' );
$logger = ActionScheduler::logger();
$message = 'Logging that something happened';
$log_id = $logger->log( $action_id, $message );
$entry = $logger->get_entry( $log_id );
$this->assertEquals( $action_id, $entry->get_action_id() );
$this->assertEquals( $message, $entry->get_message() );
}
public function test_add_log_datetime() {
$action_id = as_schedule_single_action( time(), 'a hook' );
$logger = ActionScheduler::logger();
$message = 'Logging that something happened';
$date = new DateTime( 'now', new DateTimeZone( 'UTC' ) );
$log_id = $logger->log( $action_id, $message, $date );
$entry = $logger->get_entry( $log_id );
$this->assertEquals( $action_id, $entry->get_action_id() );
$this->assertEquals( $message, $entry->get_message() );
$date = new ActionScheduler_DateTime( 'now', new DateTimeZone( 'UTC' ) );
$log_id = $logger->log( $action_id, $message, $date );
$entry = $logger->get_entry( $log_id );
$this->assertEquals( $action_id, $entry->get_action_id() );
$this->assertEquals( $message, $entry->get_message() );
}
public function test_null_log_entry() {
$logger = ActionScheduler::logger();
$entry = $logger->get_entry( 1 );
$this->assertEquals( '', $entry->get_action_id() );
$this->assertEquals( '', $entry->get_message() );
}
public function test_erroneous_entry_id() {
$comment = wp_insert_comment(array(
'comment_post_ID' => 1,
'comment_author' => 'test',
'comment_content' => 'this is not a log entry',
));
$logger = ActionScheduler::logger();
$entry = $logger->get_entry( $comment );
$this->assertEquals( '', $entry->get_action_id() );
$this->assertEquals( '', $entry->get_message() );
}
public function test_storage_comments() {
$action_id = as_schedule_single_action( time(), 'a hook' );
$logger = ActionScheduler::logger();
$logs = $logger->get_logs( $action_id );
$expected = new ActionScheduler_LogEntry( $action_id, 'action created' );
$this->assertTrue( in_array( $this->log_entry_to_array( $expected ) , $this->log_entry_to_array( $logs ) ) );
}
protected function log_entry_to_array( $logs ) {
if ( $logs instanceof ActionScheduler_LogEntry ) {
return array( 'action_id' => $logs->get_action_id(), 'message' => $logs->get_message() );
}
foreach ( $logs as $id => $log) {
$logs[ $id ] = array( 'action_id' => $log->get_action_id(), 'message' => $log->get_message() );
}
return $logs;
}
public function test_execution_comments() {
$action_id = as_schedule_single_action( time(), 'a hook' );
$logger = ActionScheduler::logger();
$started = new ActionScheduler_LogEntry( $action_id, 'action started' );
$finished = new ActionScheduler_LogEntry( $action_id, 'action complete' );
$runner = new ActionScheduler_QueueRunner();
$runner->run();
$logs = $logger->get_logs( $action_id );
$this->assertTrue( in_array( $this->log_entry_to_array( $started ), $this->log_entry_to_array( $logs ) ) );
$this->assertTrue( in_array( $this->log_entry_to_array( $finished ), $this->log_entry_to_array( $logs ) ) );
}
public function test_failed_execution_comments() {
$hook = md5(rand());
add_action( $hook, array( $this, '_a_hook_callback_that_throws_an_exception' ) );
$action_id = as_schedule_single_action( time(), $hook );
$logger = ActionScheduler::logger();
$started = new ActionScheduler_LogEntry( $action_id, 'action started' );
$finished = new ActionScheduler_LogEntry( $action_id, 'action complete' );
$failed = new ActionScheduler_LogEntry( $action_id, 'action failed: Execution failed' );
$runner = new ActionScheduler_QueueRunner();
$runner->run();
$logs = $logger->get_logs( $action_id );
$this->assertTrue( in_array( $this->log_entry_to_array( $started ), $this->log_entry_to_array( $logs ) ) );
$this->assertFalse( in_array( $this->log_entry_to_array( $finished ), $this->log_entry_to_array( $logs ) ) );
$this->assertTrue( in_array( $this->log_entry_to_array( $failed ), $this->log_entry_to_array( $logs ) ) );
}
public function test_fatal_error_comments() {
$hook = md5(rand());
$action_id = as_schedule_single_action( time(), $hook );
$logger = ActionScheduler::logger();
do_action( 'action_scheduler_unexpected_shutdown', $action_id, array(
'type' => E_ERROR,
'message' => 'Test error',
'file' => __FILE__,
'line' => __LINE__,
));
$logs = $logger->get_logs( $action_id );
$found_log = FALSE;
foreach ( $logs as $l ) {
if ( strpos( $l->get_message(), 'unexpected shutdown' ) === 0 ) {
$found_log = TRUE;
}
}
$this->assertTrue( $found_log, 'Unexpected shutdown log not found' );
}
public function test_canceled_action_comments() {
$action_id = as_schedule_single_action( time(), 'a hook' );
as_unschedule_action( 'a hook' );
$logger = ActionScheduler::logger();
$logs = $logger->get_logs( $action_id );
$expected = new ActionScheduler_LogEntry( $action_id, 'action canceled' );
$this->assertTrue( in_array( $this->log_entry_to_array( $expected ), $this->log_entry_to_array( $logs ) ) );
}
public function _a_hook_callback_that_throws_an_exception() {
throw new RuntimeException('Execution failed');
}
public function test_filtering_of_get_comments() {
$post_id = $this->factory->post->create_object(array(
'post_title' => __FUNCTION__,
));
$comment_id = $this->factory->comment->create_object(array(
'comment_post_ID' => $post_id,
'comment_author' => __CLASS__,
'comment_content' => __FUNCTION__,
));
// Verify that we're getting the expected comment before we add logging comments
$comments = get_comments();
$this->assertCount( 1, $comments );
$this->assertEquals( $comment_id, $comments[0]->comment_ID );
$action_id = as_schedule_single_action( time(), 'a hook' );
$logger = ActionScheduler::logger();
$message = 'Logging that something happened';
$log_id = $logger->log( $action_id, $message );
// Verify that logging comments are excluded from general comment queries
$comments = get_comments();
$this->assertCount( 1, $comments );
$this->assertEquals( $comment_id, $comments[0]->comment_ID );
// Verify that logging comments are returned when asking for them specifically
$comments = get_comments(array(
'type' => ActionScheduler_wpCommentLogger::TYPE,
));
// Expecting two: one when the action is created, another when we added our custom log
$this->assertCount( 2, $comments );
$this->assertContains( $log_id, wp_list_pluck($comments, 'comment_ID'));
}
}

View File

@ -1,222 +0,0 @@
<?php
/**
* Class procedural_api_Test
*/
class procedural_api_Test extends ActionScheduler_UnitTestCase {
public function test_schedule_action() {
$time = time();
$hook = md5(rand());
$action_id = as_schedule_single_action( $time, $hook );
$store = ActionScheduler::store();
$action = $store->fetch_action($action_id);
$this->assertEquals( $time, $action->get_schedule()->next()->getTimestamp() );
$this->assertEquals( $hook, $action->get_hook() );
}
public function test_recurring_action() {
$time = time();
$hook = md5(rand());
$action_id = as_schedule_recurring_action( $time, HOUR_IN_SECONDS, $hook );
$store = ActionScheduler::store();
$action = $store->fetch_action($action_id);
$this->assertEquals( $time, $action->get_schedule()->next()->getTimestamp() );
$this->assertEquals( $time + HOUR_IN_SECONDS + 2, $action->get_schedule()->next(as_get_datetime_object($time + 2))->getTimestamp());
$this->assertEquals( $hook, $action->get_hook() );
}
public function test_cron_schedule() {
$time = as_get_datetime_object('2014-01-01');
$hook = md5(rand());
$action_id = as_schedule_cron_action( $time->getTimestamp(), '0 0 10 10 *', $hook );
$store = ActionScheduler::store();
$action = $store->fetch_action($action_id);
$expected_date = as_get_datetime_object('2014-10-10');
$this->assertEquals( $expected_date->getTimestamp(), $action->get_schedule()->next()->getTimestamp() );
$this->assertEquals( $hook, $action->get_hook() );
}
public function test_get_next() {
$time = as_get_datetime_object('tomorrow');
$hook = md5(rand());
as_schedule_recurring_action( $time->getTimestamp(), HOUR_IN_SECONDS, $hook );
$next = as_next_scheduled_action( $hook );
$this->assertEquals( $time->getTimestamp(), $next );
}
public function provider_time_hook_args_group() {
$time = time() + 60 * 2;
$hook = md5( rand() );
$args = array( rand(), rand() );
$group = 'test_group';
return array(
// Test with no args or group
array(
'time' => $time,
'hook' => $hook,
'args' => array(),
'group' => '',
),
// Test with args but no group
array(
'time' => $time,
'hook' => $hook,
'args' => $args,
'group' => '',
),
// Test with group but no args
array(
'time' => $time,
'hook' => $hook,
'args' => array(),
'group' => $group,
),
// Test with args & group
array(
'time' => $time,
'hook' => $hook,
'args' => $args,
'group' => $group,
),
);
}
/**
* @dataProvider provider_time_hook_args_group
*/
public function test_unschedule( $time, $hook, $args, $group ) {
$action_id_unscheduled = as_schedule_single_action( $time, $hook, $args, $group );
$action_scheduled_time = $time + 1;
$action_id_scheduled = as_schedule_single_action( $action_scheduled_time, $hook, $args, $group );
as_unschedule_action( $hook, $args, $group );
$next = as_next_scheduled_action( $hook, $args, $group );
$this->assertEquals( $action_scheduled_time, $next );
$store = ActionScheduler::store();
$unscheduled_action = $store->fetch_action( $action_id_unscheduled );
// Make sure the next scheduled action is unscheduled
$this->assertEquals( $hook, $unscheduled_action->get_hook() );
$this->assertNull( $unscheduled_action->get_schedule()->next() );
// Make sure other scheduled actions are not unscheduled
$scheduled_action = $store->fetch_action( $action_id_scheduled );
$this->assertEquals( $hook, $scheduled_action->get_hook() );
$this->assertEquals( $action_scheduled_time, $scheduled_action->get_schedule()->next()->getTimestamp() );
}
/**
* @dataProvider provider_time_hook_args_group
*/
public function test_unschedule_all( $time, $hook, $args, $group ) {
$hook = md5( $hook );
$action_ids = array();
for ( $i = 0; $i < 3; $i++ ) {
$action_ids[] = as_schedule_single_action( $time, $hook, $args, $group );
}
as_unschedule_all_actions( $hook, $args, $group );
$next = as_next_scheduled_action( $hook );
$this->assertFalse($next);
$store = ActionScheduler::store();
foreach ( $action_ids as $action_id ) {
$action = $store->fetch_action($action_id);
$this->assertNull($action->get_schedule()->next());
$this->assertEquals($hook, $action->get_hook() );
}
}
public function test_as_get_datetime_object_default() {
$utc_now = new ActionScheduler_DateTime(null, new DateTimeZone('UTC'));
$as_now = as_get_datetime_object();
// Don't want to use 'U' as timestamps will always be in UTC
$this->assertEquals($utc_now->format('Y-m-d H:i:s'),$as_now->format('Y-m-d H:i:s'));
}
public function test_as_get_datetime_object_relative() {
$utc_tomorrow = new ActionScheduler_DateTime('tomorrow', new DateTimeZone('UTC'));
$as_tomorrow = as_get_datetime_object('tomorrow');
$this->assertEquals($utc_tomorrow->format('Y-m-d H:i:s'),$as_tomorrow->format('Y-m-d H:i:s'));
$utc_tomorrow = new ActionScheduler_DateTime('yesterday', new DateTimeZone('UTC'));
$as_tomorrow = as_get_datetime_object('yesterday');
$this->assertEquals($utc_tomorrow->format('Y-m-d H:i:s'),$as_tomorrow->format('Y-m-d H:i:s'));
}
public function test_as_get_datetime_object_fixed() {
$utc_tomorrow = new ActionScheduler_DateTime('29 February 2016', new DateTimeZone('UTC'));
$as_tomorrow = as_get_datetime_object('29 February 2016');
$this->assertEquals($utc_tomorrow->format('Y-m-d H:i:s'),$as_tomorrow->format('Y-m-d H:i:s'));
$utc_tomorrow = new ActionScheduler_DateTime('1st January 2024', new DateTimeZone('UTC'));
$as_tomorrow = as_get_datetime_object('1st January 2024');
$this->assertEquals($utc_tomorrow->format('Y-m-d H:i:s'),$as_tomorrow->format('Y-m-d H:i:s'));
}
public function test_as_get_datetime_object_timezone() {
$timezone_au = 'Australia/Brisbane';
$timezone_default = date_default_timezone_get();
date_default_timezone_set( $timezone_au );
$au_now = new ActionScheduler_DateTime(null);
$as_now = as_get_datetime_object();
// Make sure they're for the same time
$this->assertEquals($au_now->getTimestamp(),$as_now->getTimestamp());
// But not in the same timezone, as $as_now should be using UTC
$this->assertNotEquals($au_now->format('Y-m-d H:i:s'),$as_now->format('Y-m-d H:i:s'));
$au_now = new ActionScheduler_DateTime(null);
$as_au_now = as_get_datetime_object();
$this->assertEquals($au_now->getTimestamp(),$as_now->getTimestamp());
// But not in the same timezone, as $as_now should be using UTC
$this->assertNotEquals($au_now->format('Y-m-d H:i:s'),$as_now->format('Y-m-d H:i:s'));
// Just in cases
date_default_timezone_set( $timezone_default );
}
public function test_as_get_datetime_object_type() {
$f = 'Y-m-d H:i:s';
$now = as_get_datetime_object();
$this->assertInstanceOf( 'ActionScheduler_DateTime', $now );
$dateTime = new DateTime( 'now', new DateTimeZone( 'UTC' ) );
$asDateTime = as_get_datetime_object( $dateTime );
$this->assertEquals( $dateTime->format( $f ), $asDateTime->format( $f ) );
}
}

View File

@ -1,100 +0,0 @@
<?php
/**
* Class as_get_scheduled_actions_Test
*/
class as_get_scheduled_actions_Test extends ActionScheduler_UnitTestCase {
private $hooks = array();
private $args = array();
private $groups = array();
public function setUp() {
parent::setUp();
$store = ActionScheduler::store();
for ( $i = 0 ; $i < 10 ; $i++ ) {
$this->hooks[$i] = md5(rand());
$this->args[$i] = md5(rand());
$this->groups[$i] = md5(rand());
}
for ( $i = 0 ; $i < 10 ; $i++ ) {
for ( $j = 0 ; $j < 10 ; $j++ ) {
$schedule = new ActionScheduler_SimpleSchedule( as_get_datetime_object( $j - 3 . 'days') );
$group = $this->groups[ ( $i + $j ) % 10 ];
$action = new ActionScheduler_Action( $this->hooks[$i], array($this->args[$j]), $schedule, $group );
$store->save_action( $action );
}
}
}
public function test_date_queries() {
$actions = as_get_scheduled_actions(array(
'date' => as_get_datetime_object(gmdate('Y-m-d 00:00:00')),
'per_page' => -1,
), 'ids');
$this->assertCount(30, $actions);
$actions = as_get_scheduled_actions(array(
'date' => as_get_datetime_object(gmdate('Y-m-d 00:00:00')),
'date_compare' => '>=',
'per_page' => -1,
), 'ids');
$this->assertCount(70, $actions);
}
public function test_hook_queries() {
$actions = as_get_scheduled_actions(array(
'hook' => $this->hooks[2],
'per_page' => -1,
), 'ids');
$this->assertCount(10, $actions);
$actions = as_get_scheduled_actions(array(
'hook' => $this->hooks[2],
'date' => as_get_datetime_object(gmdate('Y-m-d 00:00:00')),
'per_page' => -1,
), 'ids');
$this->assertCount(3, $actions);
}
public function test_args_queries() {
$actions = as_get_scheduled_actions(array(
'args' => array($this->args[5]),
'per_page' => -1,
), 'ids');
$this->assertCount(10, $actions);
$actions = as_get_scheduled_actions(array(
'args' => array($this->args[5]),
'hook' => $this->hooks[3],
'per_page' => -1,
), 'ids');
$this->assertCount(1, $actions);
$actions = as_get_scheduled_actions(array(
'args' => array($this->args[5]),
'hook' => $this->hooks[3],
'date' => as_get_datetime_object(gmdate('Y-m-d 00:00:00')),
'per_page' => -1,
), 'ids');
$this->assertCount(0, $actions);
}
public function test_group_queries() {
$actions = as_get_scheduled_actions(array(
'group' => $this->groups[1],
'per_page' => -1,
), 'ids');
$this->assertCount(10, $actions);
$actions = as_get_scheduled_actions(array(
'group' => $this->groups[1],
'hook' => $this->hooks[9],
'per_page' => -1,
), 'ids');
$this->assertCount(1, $actions);
}
}

View File

@ -1,151 +0,0 @@
<?php
/**
* Class ActionScheduler_QueueCleaner_Test
*/
class ActionScheduler_QueueCleaner_Test extends ActionScheduler_UnitTestCase {
public function test_delete_old_actions() {
$store = ActionScheduler::store();
$runner = new ActionScheduler_QueueRunner( $store );
$random = md5(rand());
$schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('1 day ago'));
$created_actions = array();
for ( $i = 0 ; $i < 5 ; $i++ ) {
$action = new ActionScheduler_Action( $random, array($random), $schedule );
$created_actions[] = $store->save_action( $action );
}
$runner->run();
add_filter( 'action_scheduler_retention_period', '__return_zero' ); // delete any finished job
$cleaner = new ActionScheduler_QueueCleaner( $store );
$cleaner->delete_old_actions();
remove_filter( 'action_scheduler_retention_period', '__return_zero' );
foreach ( $created_actions as $action_id ) {
$action = $store->fetch_action($action_id);
$this->assertFalse($action->is_finished()); // it's a NullAction
}
}
public function test_delete_canceled_actions() {
$store = ActionScheduler::store();
$random = md5(rand());
$schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('1 day ago'));
$created_actions = array();
for ( $i = 0 ; $i < 5 ; $i++ ) {
$action = new ActionScheduler_Action( $random, array($random), $schedule );
$action_id = $store->save_action( $action );
$store->cancel_action( $action_id );
$created_actions[] = $action_id;
}
// track the actions that are deleted
$mock_action = new MockAction();
add_action( 'action_scheduler_deleted_action', array( $mock_action, 'action' ), 10, 1 );
add_filter( 'action_scheduler_retention_period', '__return_zero' ); // delete any finished job
$cleaner = new ActionScheduler_QueueCleaner( $store );
$cleaner->delete_old_actions();
remove_filter( 'action_scheduler_retention_period', '__return_zero' );
remove_action( 'action_scheduler_deleted_action', array( $mock_action, 'action' ), 10 );
$deleted_actions = array_map( 'reset', $mock_action->get_args() );
$this->assertEqualSets( $created_actions, $deleted_actions );
}
public function test_do_not_delete_recent_actions() {
$store = ActionScheduler::store();
$runner = new ActionScheduler_QueueRunner( $store );
$random = md5(rand());
$schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('1 day ago'));
$created_actions = array();
for ( $i = 0 ; $i < 5 ; $i++ ) {
$action = new ActionScheduler_Action( $random, array($random), $schedule );
$created_actions[] = $store->save_action( $action );
}
$runner->run();
$cleaner = new ActionScheduler_QueueCleaner( $store );
$cleaner->delete_old_actions();
foreach ( $created_actions as $action_id ) {
$action = $store->fetch_action($action_id);
$this->assertTrue($action->is_finished()); // It's a FinishedAction
}
}
public function test_reset_unrun_actions() {
$store = ActionScheduler::store();
$random = md5(rand());
$schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('1 day ago'));
$created_actions = array();
for ( $i = 0 ; $i < 5 ; $i++ ) {
$action = new ActionScheduler_Action( $random, array($random), $schedule );
$created_actions[] = $store->save_action( $action );
}
$store->stake_claim(10);
// don't actually process the jobs, to simulate a request that timed out
add_filter( 'action_scheduler_timeout_period', '__return_zero' ); // delete any finished job
$cleaner = new ActionScheduler_QueueCleaner( $store );
$cleaner->reset_timeouts();
remove_filter( 'action_scheduler_timeout_period', '__return_zero' );
$claim = $store->stake_claim(10);
$this->assertEqualSets($created_actions, $claim->get_actions());
}
public function test_do_not_reset_failed_action() {
$store = ActionScheduler::store();
$random = md5(rand());
$schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('1 day ago'));
$created_actions = array();
for ( $i = 0 ; $i < 5 ; $i++ ) {
$action = new ActionScheduler_Action( $random, array($random), $schedule );
$created_actions[] = $store->save_action( $action );
}
$claim = $store->stake_claim(10);
foreach ( $claim->get_actions() as $action_id ) {
// simulate the first action interrupted by an uncatchable fatal error
$store->log_execution( $action_id );
break;
}
add_filter( 'action_scheduler_timeout_period', '__return_zero' ); // delete any finished job
$cleaner = new ActionScheduler_QueueCleaner( $store );
$cleaner->reset_timeouts();
remove_filter( 'action_scheduler_timeout_period', '__return_zero' );
$new_claim = $store->stake_claim(10);
$this->assertCount( 4, $new_claim->get_actions() );
add_filter( 'action_scheduler_failure_period', '__return_zero' );
$cleaner->mark_failures();
remove_filter( 'action_scheduler_failure_period', '__return_zero' );
$failed = $store->query_actions(array('status' => ActionScheduler_Store::STATUS_FAILED));
$this->assertEquals( $created_actions[0], $failed[0] );
$this->assertCount( 1, $failed );
}
}

View File

@ -1,262 +0,0 @@
<?php
/**
* Class ActionScheduler_QueueRunner_Test
* @group runners
*/
class ActionScheduler_QueueRunner_Test extends ActionScheduler_UnitTestCase {
public function test_create_runner() {
$store = ActionScheduler::store();
$runner = new ActionScheduler_QueueRunner( $store );
$actions_run = $runner->run();
$this->assertEquals( 0, $actions_run );
}
public function test_run() {
$store = ActionScheduler::store();
$runner = new ActionScheduler_QueueRunner( $store );
$mock = new MockAction();
$random = md5(rand());
add_action( $random, array( $mock, 'action' ) );
$schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('1 day ago'));
for ( $i = 0 ; $i < 5 ; $i++ ) {
$action = new ActionScheduler_Action( $random, array($random), $schedule );
$store->save_action( $action );
}
$actions_run = $runner->run();
remove_action( $random, array( $mock, 'action' ) );
$this->assertEquals( 5, $mock->get_call_count() );
$this->assertEquals( 5, $actions_run );
}
public function test_run_with_future_actions() {
$store = ActionScheduler::store();
$runner = new ActionScheduler_QueueRunner( $store );
$mock = new MockAction();
$random = md5(rand());
add_action( $random, array( $mock, 'action' ) );
$schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('1 day ago'));
for ( $i = 0 ; $i < 3 ; $i++ ) {
$action = new ActionScheduler_Action( $random, array($random), $schedule );
$store->save_action( $action );
}
$schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('tomorrow'));
for ( $i = 0 ; $i < 3 ; $i++ ) {
$action = new ActionScheduler_Action( $random, array($random), $schedule );
$store->save_action( $action );
}
$actions_run = $runner->run();
remove_action( $random, array( $mock, 'action' ) );
$this->assertEquals( 3, $mock->get_call_count() );
$this->assertEquals( 3, $actions_run );
}
public function test_completed_action_status() {
$store = ActionScheduler::store();
$runner = new ActionScheduler_QueueRunner( $store );
$random = md5(rand());
$schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('12 hours ago'));
$action = new ActionScheduler_Action( $random, array(), $schedule );
$action_id = $store->save_action( $action );
$runner->run();
$finished_action = $store->fetch_action( $action_id );
$this->assertTrue( $finished_action->is_finished() );
}
public function test_next_instance_of_action() {
$store = ActionScheduler::store();
$runner = new ActionScheduler_QueueRunner( $store );
$random = md5(rand());
$schedule = new ActionScheduler_IntervalSchedule(as_get_datetime_object('12 hours ago'), DAY_IN_SECONDS);
$action = new ActionScheduler_Action( $random, array(), $schedule );
$store->save_action( $action );
$runner->run();
$claim = $store->stake_claim(10, as_get_datetime_object((DAY_IN_SECONDS - 60).' seconds'));
$this->assertCount(0, $claim->get_actions());
$claim = $store->stake_claim(10, as_get_datetime_object(DAY_IN_SECONDS.' seconds'));
$actions = $claim->get_actions();
$this->assertCount(1, $actions);
$action_id = reset($actions);
$new_action = $store->fetch_action($action_id);
$this->assertEquals( $random, $new_action->get_hook() );
$this->assertEquals( $schedule->next(as_get_datetime_object())->getTimestamp(), $new_action->get_schedule()->next(as_get_datetime_object())->getTimestamp() );
}
public function test_hooked_into_wp_cron() {
$next = wp_next_scheduled( ActionScheduler_QueueRunner::WP_CRON_HOOK );
$this->assertNotEmpty($next);
}
public function test_batch_count_limit() {
$store = ActionScheduler::store();
$runner = new ActionScheduler_QueueRunner( $store );
$mock = new MockAction();
$random = md5(rand());
add_action( $random, array( $mock, 'action' ) );
$schedule = new ActionScheduler_SimpleSchedule(new ActionScheduler_DateTime('1 day ago'));
for ( $i = 0 ; $i < 30 ; $i++ ) {
$action = new ActionScheduler_Action( $random, array($random), $schedule );
$store->save_action( $action );
}
$claims = array();
for ( $i = 0 ; $i < 5 ; $i++ ) {
$claims[] = $store->stake_claim( 5 );
}
$actions_run = $runner->run();
$this->assertEquals( 0, $mock->get_call_count() );
$this->assertEquals( 0, $actions_run );
$first = reset($claims);
$store->release_claim( $first );
$actions_run = $runner->run();
$this->assertEquals( 10, $mock->get_call_count() );
$this->assertEquals( 10, $actions_run );
remove_action( $random, array( $mock, 'action' ) );
}
public function test_changing_batch_count_limit() {
$store = ActionScheduler::store();
$runner = new ActionScheduler_QueueRunner( $store );
$random = md5(rand());
$schedule = new ActionScheduler_SimpleSchedule(new ActionScheduler_DateTime('1 day ago'));
for ( $i = 0 ; $i < 30 ; $i++ ) {
$action = new ActionScheduler_Action( $random, array($random), $schedule );
$store->save_action( $action );
}
$claims = array();
for ( $i = 0 ; $i < 5 ; $i++ ) {
$claims[] = $store->stake_claim( 5 );
}
$mock1 = new MockAction();
add_action( $random, array( $mock1, 'action' ) );
$actions_run = $runner->run();
remove_action( $random, array( $mock1, 'action' ) );
$this->assertEquals( 0, $mock1->get_call_count() );
$this->assertEquals( 0, $actions_run );
add_filter( 'action_scheduler_queue_runner_concurrent_batches', array( $this, 'return_6' ) );
$mock2 = new MockAction();
add_action( $random, array( $mock2, 'action' ) );
$actions_run = $runner->run();
remove_action( $random, array( $mock2, 'action' ) );
$this->assertEquals( 5, $mock2->get_call_count() );
$this->assertEquals( 5, $actions_run );
remove_filter( 'action_scheduler_queue_runner_concurrent_batches', array( $this, 'return_6' ) );
for ( $i = 0 ; $i < 5 ; $i++ ) { // to make up for the actions we just processed
$action = new ActionScheduler_Action( $random, array($random), $schedule );
$store->save_action( $action );
}
$mock3 = new MockAction();
add_action( $random, array( $mock3, 'action' ) );
$actions_run = $runner->run();
remove_action( $random, array( $mock3, 'action' ) );
$this->assertEquals( 0, $mock3->get_call_count() );
$this->assertEquals( 0, $actions_run );
remove_filter( 'action_scheduler_queue_runner_concurrent_batches', array( $this, 'return_6' ) );
}
public function return_6() {
return 6;
}
public function test_store_fetch_action_failure_schedule_next_instance() {
$random = md5( rand() );
$schedule = new ActionScheduler_IntervalSchedule( as_get_datetime_object( '12 hours ago' ), DAY_IN_SECONDS );
$action = new ActionScheduler_Action( $random, array(), $schedule );
$action_id = ActionScheduler::store()->save_action( $action );
// Set up a mock store that will throw an exception when fetching actions.
$store = $this
->getMockBuilder( 'ActionScheduler_wpPostStore' )
->setMethods( array( 'fetch_action' ) )
->getMock();
$store
->method( 'fetch_action' )
->with( $action_id )
->will( $this->throwException( new Exception() ) );
// Set up a mock queue runner to verify that schedule_next_instance()
// isn't called for an undefined $action.
$runner = $this
->getMockBuilder( 'ActionScheduler_QueueRunner' )
->setConstructorArgs( array( $store ) )
->setMethods( array( 'schedule_next_instance' ) )
->getMock();
$runner
->expects( $this->never() )
->method( 'schedule_next_instance' );
$runner->run();
// Set up a mock store that will throw an exception when fetching actions.
$store2 = $this
->getMockBuilder( 'ActionScheduler_wpPostStore' )
->setMethods( array( 'fetch_action' ) )
->getMock();
$store2
->method( 'fetch_action' )
->with( $action_id )
->willReturn( null );
// Set up a mock queue runner to verify that schedule_next_instance()
// isn't called for an undefined $action.
$runner2 = $this
->getMockBuilder( 'ActionScheduler_QueueRunner' )
->setConstructorArgs( array( $store ) )
->setMethods( array( 'schedule_next_instance' ) )
->getMock();
$runner2
->expects( $this->never() )
->method( 'schedule_next_instance' );
$runner2->run();
}
}

View File

@ -1,45 +0,0 @@
<?php
/**
* Class ActionScheduler_CronSchedule_Test
* @group schedules
*/
class ActionScheduler_CronSchedule_Test extends ActionScheduler_UnitTestCase {
public function test_creation() {
$time = as_get_datetime_object('tomorrow');
$cron = CronExpression::factory('@daily');
$schedule = new ActionScheduler_CronSchedule(as_get_datetime_object(), $cron);
$this->assertEquals( $time, $schedule->next() );
}
public function test_next() {
$time = as_get_datetime_object('2013-06-14');
$cron = CronExpression::factory('@daily');
$schedule = new ActionScheduler_CronSchedule($time, $cron);
$this->assertEquals( as_get_datetime_object('tomorrow'), $schedule->next( as_get_datetime_object() ) );
}
public function test_is_recurring() {
$schedule = new ActionScheduler_CronSchedule(as_get_datetime_object('2013-06-14'), CronExpression::factory('@daily'));
$this->assertTrue( $schedule->is_recurring() );
}
public function test_cron_format() {
$time = as_get_datetime_object('2014-01-01');
$cron = CronExpression::factory('0 0 10 10 *');
$schedule = new ActionScheduler_CronSchedule($time, $cron);
$this->assertEquals( as_get_datetime_object('2014-10-10'), $schedule->next() );
$cron = CronExpression::factory('0 0 L 1/2 *');
$schedule = new ActionScheduler_CronSchedule($time, $cron);
$this->assertEquals( as_get_datetime_object('2014-01-31'), $schedule->next() );
$this->assertEquals( as_get_datetime_object('2014-07-31'), $schedule->next( as_get_datetime_object('2014-06-01') ) );
$this->assertEquals( as_get_datetime_object('2028-11-30'), $schedule->next( as_get_datetime_object('2028-11-01') ) );
$cron = CronExpression::factory('30 14 * * MON#3 *');
$schedule = new ActionScheduler_CronSchedule($time, $cron);
$this->assertEquals( as_get_datetime_object('2014-01-20 14:30:00'), $schedule->next() );
$this->assertEquals( as_get_datetime_object('2014-05-19 14:30:00'), $schedule->next( as_get_datetime_object('2014-05-01') ) );
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* Class ActionScheduler_IntervalSchedule_Test
* @group schedules
*/
class ActionScheduler_IntervalSchedule_Test extends ActionScheduler_UnitTestCase {
public function test_creation() {
$time = as_get_datetime_object();
$schedule = new ActionScheduler_IntervalSchedule($time, HOUR_IN_SECONDS);
$this->assertEquals( $time, $schedule->next() );
}
public function test_next() {
$now = time();
$start = $now - 30;
$schedule = new ActionScheduler_IntervalSchedule( as_get_datetime_object("@$start"), MINUTE_IN_SECONDS );
$this->assertEquals( $start, $schedule->next()->getTimestamp() );
$this->assertEquals( $now + MINUTE_IN_SECONDS, $schedule->next(as_get_datetime_object())->getTimestamp() );
$this->assertEquals( $start, $schedule->next(as_get_datetime_object("@$start"))->getTimestamp() );
}
public function test_is_recurring() {
$start = time() - 30;
$schedule = new ActionScheduler_IntervalSchedule( as_get_datetime_object("@$start"), MINUTE_IN_SECONDS );
$this->assertTrue( $schedule->is_recurring() );
}
}

View File

@ -1,18 +0,0 @@
<?php
/**
* Class ActionScheduler_NullSchedule_Test
* @group schedules
*/
class ActionScheduler_NullSchedule_Test extends ActionScheduler_UnitTestCase {
public function test_null_schedule() {
$schedule = new ActionScheduler_NullSchedule();
$this->assertNull( $schedule->next() );
}
public function test_is_recurring() {
$schedule = new ActionScheduler_NullSchedule();
$this->assertFalse( $schedule->is_recurring() );
}
}

View File

@ -1,37 +0,0 @@
<?php
/**
* Class ActionScheduler_SimpleSchedule_Test
* @group schedules
*/
class ActionScheduler_SimpleSchedule_Test extends ActionScheduler_UnitTestCase {
public function test_creation() {
$time = as_get_datetime_object();
$schedule = new ActionScheduler_SimpleSchedule($time);
$this->assertEquals( $time, $schedule->next() );
}
public function test_past_date() {
$time = as_get_datetime_object('-1 day');
$schedule = new ActionScheduler_SimpleSchedule($time);
$this->assertEquals( $time, $schedule->next() );
}
public function test_future_date() {
$time = as_get_datetime_object('+1 day');
$schedule = new ActionScheduler_SimpleSchedule($time);
$this->assertEquals( $time, $schedule->next() );
}
public function test_grace_period_for_next() {
$time = as_get_datetime_object('3 seconds ago');
$schedule = new ActionScheduler_SimpleSchedule($time);
$this->assertEquals( $time, $schedule->next() );
}
public function test_is_recurring() {
$schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('+1 day'));
$this->assertFalse( $schedule->is_recurring() );
}
}

View File

@ -1,43 +0,0 @@
<?php
/**
* Class ActionScheduler_Versions_Test
*/
class ActionScheduler_Versions_Test extends ActionScheduler_UnitTestCase {
public function test_register_version() {
$versions = new ActionScheduler_Versions();
$versions->register('1.0-dev', 'callback_1_dot_0_dev');
$versions->register('1.0', 'callback_1_dot_0');
$registered = $versions->get_versions();
$this->assertArrayHasKey( '1.0-dev', $registered );
$this->assertArrayHasKey( '1.0', $registered );
$this->assertCount( 2, $registered );
$this->assertEquals( 'callback_1_dot_0_dev', $registered['1.0-dev'] );
}
public function test_duplicate_version() {
$versions = new ActionScheduler_Versions();
$versions->register('1.0', 'callback_1_dot_0_a');
$versions->register('1.0', 'callback_1_dot_0_b');
$registered = $versions->get_versions();
$this->assertArrayHasKey( '1.0', $registered );
$this->assertCount( 1, $registered );
}
public function test_latest_version() {
$versions = new ActionScheduler_Versions();
$this->assertEquals('__return_null', $versions->latest_version_callback() );
$versions->register('1.2', 'callback_1_dot_2');
$versions->register('1.3', 'callback_1_dot_3');
$versions->register('1.0', 'callback_1_dot_0');
$this->assertEquals( '1.3', $versions->latest_version() );
$this->assertEquals( 'callback_1_dot_3', $versions->latest_version_callback() );
}
}

View File

@ -1,38 +0,0 @@
#!/bin/sh
# WordPress test setup script for Travis CI
#
# Author: Benjamin J. Balter ( ben@balter.com | ben.balter.com )
# License: GPL3
export WP_CORE_DIR=/tmp/wordpress
export WP_TESTS_DIR=/tmp/wordpress-tests/tests/phpunit
if [[ "$1" = "5.6" || "$1" > "5.6" ]]
then
wget -c https://phar.phpunit.de/phpunit-5.7.phar
chmod +x phpunit-5.7.phar
mv phpunit-5.7.phar `which phpunit`
fi
plugin_slug=$(basename $(pwd))
plugin_dir=$WP_CORE_DIR/wp-content/plugins/$plugin_slug
# Init database
mysql -e 'CREATE DATABASE wordpress_test;' -uroot
# Grab specified version of WordPress from github
wget -nv -O /tmp/wordpress.tar.gz https://github.com/WordPress/WordPress/tarball/$WP_VERSION
mkdir -p $WP_CORE_DIR
tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR
# Grab testing framework
svn co --quiet https://develop.svn.wordpress.org/tags/$WP_VERSION/ /tmp/wordpress-tests
# Put various components in proper folders
cp tests/travis/wp-tests-config.php $WP_TESTS_DIR/wp-tests-config.php
cd ..
mv $plugin_slug $plugin_dir
cd $plugin_dir

View File

@ -1,38 +0,0 @@
<?php
/* Path to the WordPress codebase you'd like to test. Add a backslash in the end. */
define( 'ABSPATH', getenv( 'WP_CORE_DIR' ) . '/' );
// Test with multisite enabled
define( 'WP_TESTS_MULTISITE', (bool) getenv( 'WP_MULTISITE' ) );
// Force known bugs
// define( 'WP_TESTS_FORCE_KNOWN_BUGS', true );
// Test with WordPress debug mode on
define( 'WP_DEBUG', true );
// ** MySQL settings ** //
// This configuration file will be used by the copy of WordPress being tested.
// wordpress/wp-config.php will be ignored.
// WARNING WARNING WARNING!
// These tests will DROP ALL TABLES in the database with the prefix named below.
// DO NOT use a production database or one that is shared with something else.
define( 'DB_NAME', 'wordpress_test' );
define( 'DB_USER', 'root' );
define( 'DB_PASSWORD', '' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8' );
define( 'DB_COLLATE', '' );
define( 'WP_TESTS_DOMAIN', 'example.org' );
define( 'WP_TESTS_EMAIL', 'admin@example.org' );
define( 'WP_TESTS_TITLE', 'Test Blog' );
define( 'WP_PHP_BINARY', 'php' );
define( 'WPLANG', '' );
$table_prefix = 'wptests_';