From 894a2bb646e6202ee58e70792b38f42e0580a008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Fri, 16 Aug 2024 09:11:13 +0000 Subject: [PATCH] Add seconds precision to scheduledAt --- app/controllers/api/functions.php | 2 +- composer.json | 2 +- composer.lock | 39 ++++++++++------- .../Functions/FunctionsCustomClientTest.php | 43 +++++++++++++++++-- 4 files changed, 65 insertions(+), 21 deletions(-) diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index c55650bdc6..05cdc95a2e 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -1643,7 +1643,7 @@ App::post('/v1/functions/:functionId/executions') ->param('path', '/', new Text(2048), 'HTTP path of execution. Path can include query params. Default value is /', true) ->param('method', 'POST', new Whitelist(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], true), 'HTTP method of execution. Default value is GET.', true) ->param('headers', [], new AnyOf([new Text(65535), new Assoc()], AnyOf::TYPE_MIXED), 'HTTP headers of execution. Defaults to empty.', true) - ->param('scheduledAt', null, new DatetimeValidator(requireDateInFuture: true), 'Scheduled execution time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true) + ->param('scheduledAt', null, new DatetimeValidator(true, DateTimeValidator::PRECISION_MINUTES, 60), 'Scheduled execution time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future with precision in minutes.', true) ->inject('response') ->inject('request') ->inject('project') diff --git a/composer.json b/composer.json index 4cbb395bda..352e522fd2 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ "utopia-php/cache": "0.10.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.50.*", + "utopia-php/database": "dev-feat-datetime-validator-precision as 0.50.99", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", diff --git a/composer.lock b/composer.lock index 696e32c685..18d78400e6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "340aae0879435fc71eac688d47033eb4", + "content-hash": "805f7e1ff986ab086b516ce351a7750a", "packages": [ { "name": "adhocore/jwt", @@ -1721,16 +1721,16 @@ }, { "name": "utopia-php/database", - "version": "0.50.4", + "version": "dev-feat-datetime-validator-precision", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "fd3b856be77bd643bc8a9e3572ee11e4185b9230" + "reference": "22e52918240f0e7da814497ab04e83cfb4ab89a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/fd3b856be77bd643bc8a9e3572ee11e4185b9230", - "reference": "fd3b856be77bd643bc8a9e3572ee11e4185b9230", + "url": "https://api.github.com/repos/utopia-php/database/zipball/22e52918240f0e7da814497ab04e83cfb4ab89a1", + "reference": "22e52918240f0e7da814497ab04e83cfb4ab89a1", "shasum": "" }, "require": { @@ -1771,9 +1771,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.50.4" + "source": "https://github.com/utopia-php/database/tree/feat-datetime-validator-precision" }, - "time": "2024-08-13T03:18:26+00:00" + "time": "2024-08-16T09:10:30+00:00" }, { "name": "utopia-php/domains", @@ -1923,16 +1923,16 @@ }, { "name": "utopia-php/framework", - "version": "0.33.7", + "version": "0.33.8", "source": { "type": "git", "url": "https://github.com/utopia-php/http.git", - "reference": "78d293d99a262bd63ece750bbf989c7e0643b825" + "reference": "a7f577540a25cb90896fef2b64767bf8d700f3c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/http/zipball/78d293d99a262bd63ece750bbf989c7e0643b825", - "reference": "78d293d99a262bd63ece750bbf989c7e0643b825", + "url": "https://api.github.com/repos/utopia-php/http/zipball/a7f577540a25cb90896fef2b64767bf8d700f3c5", + "reference": "a7f577540a25cb90896fef2b64767bf8d700f3c5", "shasum": "" }, "require": { @@ -1962,9 +1962,9 @@ ], "support": { "issues": "https://github.com/utopia-php/http/issues", - "source": "https://github.com/utopia-php/http/tree/0.33.7" + "source": "https://github.com/utopia-php/http/tree/0.33.8" }, - "time": "2024-08-01T14:01:04+00:00" + "time": "2024-08-15T14:10:09+00:00" }, { "name": "utopia-php/image", @@ -5592,9 +5592,18 @@ "time": "2023-11-21T18:54:41+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/database", + "version": "dev-feat-datetime-validator-precision", + "alias": "0.50.99", + "alias_normalized": "0.50.99.0" + } + ], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "utopia-php/database": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 754eff792c..3f6587ca79 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -219,7 +219,8 @@ class FunctionsCustomClientTest extends Scope // Schedule execution for the future \date_default_timezone_set('UTC'); - $futureTime = (new \DateTime())->add(new \DateInterval('PT10S')); + $futureTime = (new \DateTime())->add(new \DateInterval('PT2M')); + $futureTime->setTime($futureTime->format('H'), $futureTime->format('i'), 0, 0); $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/executions', array_merge([ 'content-type' => 'application/json', @@ -236,7 +237,7 @@ class FunctionsCustomClientTest extends Scope $executionId = $execution['body']['$id']; - sleep(10); + sleep(60 + 60 + 15); // up to 1 minute round up, 1 minute schedule postpone, 15s cold start safety $start = \microtime(true); while (true) { @@ -251,7 +252,7 @@ class FunctionsCustomClientTest extends Scope } if (\microtime(true) - $start > 10) { - $this->fail('Execution did not complete within 10 seconds of schedule in status ' . $execution['body']['status'] . ': ' . \json_encode($execution)); + $this->fail('Scheduled execution did not complete with status ' . $execution['body']['status'] . ': ' . \json_encode($execution)); } usleep(500000); // 0.5 seconds @@ -267,7 +268,6 @@ class FunctionsCustomClientTest extends Scope /* Test for FAILURE */ // Schedule synchronous execution - $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/executions', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -278,6 +278,41 @@ class FunctionsCustomClientTest extends Scope $this->assertEquals(400, $execution['headers']['status-code']); + // Execution with seconds precision + $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/executions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'async' => true, + 'scheduledAt' => (new \DateTime("2100-12-08 16:12:02"))->format(\DateTime::ATOM) + ]); + + $this->assertEquals(400, $execution['headers']['status-code']); + + // Execution with milliseconds precision + $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/executions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'async' => true, + 'scheduledAt' => (new \DateTime("2100-12-08 16:12:02.255"))->format(\DateTime::ATOM) + ]); + + $this->assertEquals(400, $execution['headers']['status-code']); + + // Execution too soon + $futureTime = (new \DateTime())->add(new \DateInterval('PT1M')); + $futureTime->setTime($futureTime->format('H'), $futureTime->format('i'), 0, 0); + $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $function['body']['$id'] . '/executions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'async' => true, + 'scheduledAt' => (new \DateTime("2100-12-08 16:12:02.255"))->format(\DateTime::ATOM) + ]); + + $this->assertEquals(400, $execution['headers']['status-code']); + // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $function['body']['$id'], [ 'content-type' => 'application/json',