Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support PHP 8.3 #2

Merged
merged 4 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Autodetect text files, normalize to LF on commit
* text=auto

# Explicitly define files which should be LF when checked out and on commit
*.md text eol=lf
*.sh text eol=lf
*.rb text eol=lf diff=ruby
*.php text eol=lf diff=php
*.yml text eol=lf
*.sql text eol=lf
*.xml text eol=lf
*.xsd text eol=lf
*.css text eol=lf
*.js text eol=lf
*.pem text eol=lf
LICENSE text eol=lf
README text eol=lf

# Declare files that will always have CRLF line endings on checkout (still stored LF)
*.bat text eol=crlf

# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
*.gif binary
*.ttf binary
*.swf binary
*.zip binary
*.sqlite binary

# Ignore paths that should not be included in an archive (eg for a distribution version)
/.github export-ignore
/test export-ignore
phpunit.xml export-ignore
7 changes: 5 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ jobs:
matrix:
php_version:
- '8.2'
- '8.3'
dependencies:
- 'default'
include:
- php_version: '8.2'
dependencies: 'lowest'
- php_version: '8.3'
dependencies: 'lowest'
steps:
- name: Setup PHP
uses: shivammathur/setup-php@v2
Expand Down Expand Up @@ -55,12 +58,12 @@ jobs:

- name: Run unit tests
run: |
vendor/bin/phpunit --testsuite=unit --verbose
vendor/bin/phpunit --testsuite=unit

- name: Start MySQL server
run: |
sudo systemctl start mysql.service

- name: Run integration tests
run: |
vendor/bin/phpunit --testsuite=integration --verbose
vendor/bin/phpunit --testsuite=integration
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Unreleased

## v1.1.0 (2024-10-03)

* Support PHP 8.3

## v1.0.0 (2024-02-06)

* Initial version
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"issues": "https://github.com/ingenerator/scheduled-task-runner/issues"
},
"require": {
"php": "~8.2.0",
"php": "~8.2.0 || ~8.3.0",
"ext-pcntl": "*",
"ext-pdo": "*",
"dragonmantank/cron-expression": "^3.3.2",
Expand All @@ -36,7 +36,7 @@
"symfony/process": "^5.4 || ^6.0 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5.5"
"phpunit/phpunit": "^10.5"
},
"autoload": {
"psr-4": {
Expand Down
22 changes: 11 additions & 11 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
beStrictAboutChangesToGlobalState="true"
bootstrap="test/phpunit-bootstrap.php"
cacheResultFile="test/.phpunit.result.cache"
colors="true"
convertDeprecationsToExceptions="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage>
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
failOnDeprecation="true"
failOnNotice="true"
failOnWarning="true"
failOnRisky="true"
displayDetailsOnIncompleteTests="true"
displayDetailsOnSkippedTests="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerErrors="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd">
<testsuites>
<testsuite name="unit">
<directory>test/unit</directory>
Expand Down
7 changes: 3 additions & 4 deletions test/integration/CronExecutionIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Closure;
use DateInterval;
use DateTimeImmutable;
use Ingenerator\PHPUtils\DateTime\Clock\RealtimeClock;
use Ingenerator\PHPUtils\Monitoring\NullMetricsAgent;
use Ingenerator\ScheduledTaskRunner\CronConfigLoader;
use Ingenerator\ScheduledTaskRunner\CronStatusReporter;
Expand All @@ -14,12 +15,10 @@
use Ingenerator\ScheduledTaskRunner\PDOPausedTaskListChecker;
use Ingenerator\ScheduledTaskRunner\SymfonyCronTaskProcessRunner;
use Ingenerator\ScheduledTaskRunner\TaskExecutionState;
use Ingenerator\PHPUtils\DateTime\Clock\RealtimeClock;
use PHPUnit\Framework\TestCase;
use Psr\Log\AbstractLogger;
use Psr\Log\NullLogger;
use RuntimeException;
use test\mock\Ingenerator\ScheduledTaskRunner\Logging\SpyingLoggerStub;
use function fwrite;
use function is_file;
use function sprintf;
Expand Down Expand Up @@ -47,7 +46,7 @@ class CronExecutionIntegrationTest extends TestCase

private $output_stream;

public function test_it_runs_expected_processes_correctly_and_identifies_completion_as_expected()
public function test_it_runs_expected_processes_correctly_and_identifies_completion_as_expected(): void
{
$script = $this->getTestScriptRelativePath();

Expand Down Expand Up @@ -286,7 +285,7 @@ private function newSubject(): CronTaskExecutionManager
);
}

private function initState(string $group_name, Closure $initialiser)
private function initState(string $group_name, Closure $initialiser): void
{
$state = $this->state_repo->getState($group_name);
$initialiser($state);
Expand Down
4 changes: 2 additions & 2 deletions test/integration/CronjobRunnerIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
namespace test\integration\Ingenerator\ScheduledTaskRunner;

use DateTimeImmutable;
use Ingenerator\PHPUtils\DateTime\Clock\RealtimeClock;
use Ingenerator\ScheduledTaskRunner\CronController;
use Ingenerator\ScheduledTaskRunner\PDOCronTaskStateRepository;
use Ingenerator\PHPUtils\DateTime\Clock\RealtimeClock;
use PDO;
use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\TestCase;
Expand All @@ -28,7 +28,7 @@ class CronjobRunnerIntegrationTest extends TestCase

private array $tmpfiles = [];

public function test_it_can_launch_and_complete_without_errors()
public function test_it_can_launch_and_complete_without_errors(): void
{
// Create a temporary config and make sure the task is due to run
$tmp_output = $this->getTemporaryFilename('job-file');
Expand Down
31 changes: 24 additions & 7 deletions test/integration/PDOCronExecutionHistoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,39 @@
use DateTimeImmutable;
use Ingenerator\ScheduledTaskRunner\PDOCronExecutionHistoryRepository;
use PDO;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;

class PDOCronExecutionHistoryTest extends TestCase
{
private PDO $pdo;

public function test_it_is_initialisable()
public function test_it_is_initialisable(): void
{
$this->assertInstanceOf(PDOCronExecutionHistoryRepository::class, $this->newSubject());
}

/**
* @testWith [0, {"group_name": "my-group", "step_name": "whatever", "last_exit_code": 0, "last_success_at": "2021-03-02 03:02:04", "last_failure_at": null}]
* [15, {"group_name": "my-group", "step_name": "whatever", "last_exit_code": 15, "last_success_at": null, "last_failure_at": "2021-03-02 03:02:04"}]
*/
public function test_it_inserts_new_task_states_if_required($exit, $expect)
#[TestWith([
0,
[
'group_name' => 'my-group',
'step_name' => 'whatever',
'last_exit_code' => 0,
'last_success_at' => '2021-03-02 03:02:04',
'last_failure_at' => NULL,
],
])]
#[TestWith([
15,
[
'group_name' => 'my-group',
'step_name' => 'whatever',
'last_exit_code' => 15,
'last_success_at' => NULL,
'last_failure_at' => '2021-03-02 03:02:04',
],
])]
public function test_it_inserts_new_task_states_if_required($exit, $expect): void
{
$this->newSubject()->recordCompletion(
'my-group',
Expand All @@ -32,7 +49,7 @@ public function test_it_inserts_new_task_states_if_required($exit, $expect)
$this->assertSame([$expect], $this->newSubject()->listCurrentStates());
}

public function test_it_updates_correct_task_with_correct_status()
public function test_it_updates_correct_task_with_correct_status(): void
{
$s = $this->newSubject();

Expand Down
25 changes: 12 additions & 13 deletions test/integration/PDOCronTaskStateRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
use DateInterval;
use DateTimeImmutable;
use DateTimeInterface;
use Ingenerator\ScheduledTaskRunner\PDOCronTaskStateRepository;
use Ingenerator\ScheduledTaskRunner\TaskExecutionState;
use Ingenerator\PHPUtils\DateTime\Clock\RealtimeClock;
use Ingenerator\PHPUtils\DateTime\Clock\StoppedMockClock;
use Ingenerator\PHPUtils\DateTime\DateString;
use Ingenerator\PHPUtils\Object\ObjectPropertyRipper;
use Ingenerator\ScheduledTaskRunner\PDOCronTaskStateRepository;
use Ingenerator\ScheduledTaskRunner\TaskExecutionState;
use InvalidArgumentException;
use PDO;
use PHPUnit\Framework\Attributes\TestWith;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Psr\Log\NullLogger;
Expand All @@ -28,12 +29,12 @@ class PDOCronTaskStateRepositoryTest extends BaseTestCase

private LoggerInterface $log;

public function test_it_is_initialisable()
public function test_it_is_initialisable(): void
{
$this->assertInstanceOf(PDOCronTaskStateRepository::class, $this->newSubject());
}

public function test_its_get_state_returns_existing_state_from_db()
public function test_its_get_state_returns_existing_state_from_db(): void
{
$this->log = $this->getDummyExpectingNoCalls(LoggerInterface::class);
$this->insertDbState(
Expand Down Expand Up @@ -63,7 +64,7 @@ public function test_its_get_state_returns_existing_state_from_db()
);
}

public function test_its_get_state_never_reloads_from_db_if_task_was_not_running()
public function test_its_get_state_never_reloads_from_db_if_task_was_not_running(): void
{
$this->log = $this->getDummyExpectingNoCalls(LoggerInterface::class);
$this->insertDbState(['group_name' => 'anything', 'is_running' => 0]);
Expand All @@ -81,7 +82,7 @@ public function test_its_get_state_never_reloads_from_db_if_task_was_not_running
$this->assertFalse($state2->isRunning(), 'Still not running as far as we\'re concerned');
}

public function test_its_get_state_refreshes_from_db_every_minute_if_it_was_running_when_first_loaded()
public function test_its_get_state_refreshes_from_db_every_minute_if_it_was_running_when_first_loaded(): void
{
$this->log = $this->getDummyExpectingNoCalls(LoggerInterface::class);
$this->insertDbState(['group_name' => 'anything', 'is_running' => 1]);
Expand Down Expand Up @@ -109,7 +110,7 @@ public function test_its_get_state_refreshes_from_db_every_minute_if_it_was_runn
$this->assertNull($state3->getRefreshAt(), 'No need to refresh once it stops running');
}

public function test_its_get_state_lazily_creates_database_state_for_tasks_that_do_not_exist()
public function test_its_get_state_lazily_creates_database_state_for_tasks_that_do_not_exist(): void
{
$this->log = new SpyingLoggerStub();
$this->clock = StoppedMockClock::at('2022-03-01 19:38:29');
Expand Down Expand Up @@ -151,11 +152,9 @@ public function test_its_get_state_lazily_creates_database_state_for_tasks_that_
);
}

/**
* @testWith [true]
* [false]
*/
public function test_its_save_throws_if_state_not_in_local_collection($knows_task)
#[TestWith([TRUE])]
#[TestWith([FALSE])]
public function test_its_save_throws_if_state_not_in_local_collection($knows_task): void
{
// Guard against randomly passing in states that do not belong to the repo
$state = TaskExecutionState::forNewTask('dunno', new DateTimeImmutable());
Expand All @@ -169,7 +168,7 @@ public function test_its_save_throws_if_state_not_in_local_collection($knows_tas
$subject->save($state);
}

public function test_its_save_can_update_existing_state()
public function test_its_save_can_update_existing_state(): void
{
$this->clock = StoppedMockClock::at('2022-01-03 20:30:02');
$subject = $this->newSubject();
Expand Down
25 changes: 12 additions & 13 deletions test/unit/CronConfigLoaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,25 @@
use Ingenerator\ScheduledTaskRunner\CronTaskGroupDefinition;
use Ingenerator\ScheduledTaskRunner\CronTaskStepDefinition;
use InvalidArgumentException;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;

class CronConfigLoaderTest extends TestCase
{
private array $definitions = [];

public function test_it_is_initialisable()
public function test_it_is_initialisable(): void
{
$this->assertInstanceOf(CronConfigLoader::class, $this->newSubject());
}

public function test_it_has_empty_definitions_with_no_tasks()
public function test_it_has_empty_definitions_with_no_tasks(): void
{
$this->definitions = [];
$this->assertSame([], $this->newSubject()->getActiveTaskDefinitions());
}

public function test_it_filters_enabled_and_disabled_tasks()
public function test_it_filters_enabled_and_disabled_tasks(): void
{
$this->definitions = [
'task-1' => [
Expand All @@ -49,12 +50,10 @@ public function test_it_filters_enabled_and_disabled_tasks()
);
}

/**
* @testWith ["some-old-string"]
* [{"some":"junk"}]
* [{"name": "mine", "cmd":["whatever"], "extra": "foo"}]
*/
public function test_it_cannot_be_constructed_with_invalid_steps($step)
#[TestWith(['some-old-string'])]
#[TestWith([['some' => 'junk']])]
#[TestWith([['name' => 'mine', 'cmd' => ['whatever'], 'extra' => 'foo']])]
public function test_it_cannot_be_constructed_with_invalid_steps($step): void
{
$this->definitions = [
'task1' => [
Expand All @@ -68,7 +67,7 @@ public function test_it_cannot_be_constructed_with_invalid_steps($step)
$this->newSubject();
}

public function test_it_can_create_steps_from_array_with_valid_keys()
public function test_it_can_create_steps_from_array_with_valid_keys(): void
{
$this->definitions = [
'task1' => [
Expand All @@ -91,17 +90,17 @@ public function test_it_can_create_steps_from_array_with_valid_keys()
);
}

public function test_it_cannot_be_constructed_if_task_has_missing_key()
public function test_it_cannot_be_constructed_if_task_has_missing_key(): void
{
$this->markTestIncomplete();
}

public function test_its_tasks_have_default_values_for_optional_keys()
public function test_its_tasks_have_default_values_for_optional_keys(): void
{
$this->markTestIncomplete();
}

public function test_its_tasks_can_have_values_for_optional_keys()
public function test_its_tasks_can_have_values_for_optional_keys(): void
{
$this->markTestIncomplete();
}
Expand Down
Loading
Loading