From 335144e50bd6d1dace7e494bc69a98f391302b69 Mon Sep 17 00:00:00 2001 From: Saw-jan Date: Mon, 2 Jan 2023 16:20:53 +0545 Subject: [PATCH] add tests to check 425 too early behavior add tests to check 425 too early behavior add delay postprocessing suite pipeline add step def --- .drone.star | 10 ++ tests/TestHelpers/HttpRequestHelper.php | 92 +++++++++++++++---- tests/acceptance/config/behat.yml | 16 ++++ ...ected-failures-localAPI-on-OCIS-storage.md | 10 ++ .../delayPostprocessing.feature | 26 ++++++ .../features/bootstrap/AuthContext.php | 30 ++++++ 6 files changed, 165 insertions(+), 19 deletions(-) create mode 100644 tests/acceptance/features/apiAsyncUpload/delayPostprocessing.feature diff --git a/.drone.star b/.drone.star index 610b29a852..9c7d0f7252 100644 --- a/.drone.star +++ b/.drone.star @@ -115,6 +115,16 @@ config = { "OCIS_CORS_ALLOW_ORIGINS": "https://aphno.badal", }, }, + "apiDelayPostprocessing": { + "suites": [ + "apiAsyncUpload", + ], + "skip": False, + "earlyFail": True, + "extraServerEnvironment": { + "POSTPROCESSING_DELAY": "30s", + }, + }, }, "apiTests": { "numberOfParts": 10, diff --git a/tests/TestHelpers/HttpRequestHelper.php b/tests/TestHelpers/HttpRequestHelper.php index c6b567b7a4..bf701b6f95 100644 --- a/tests/TestHelpers/HttpRequestHelper.php +++ b/tests/TestHelpers/HttpRequestHelper.php @@ -103,7 +103,7 @@ class HttpRequestHelper { * @return ResponseInterface * @throws GuzzleException */ - public static function sendRequest( + public static function sendRequestOnce( ?string $url, ?string $xRequestId, ?string $method = 'GET', @@ -144,36 +144,90 @@ class HttpRequestHelper { $debugRequests = false; } - if ((\getenv('DEBUG_ACCEPTANCE_RESPONSES') !== false) || (\getenv('DEBUG_ACCEPTANCE_API_CALLS') !== false)) { - $debugResponses = true; - } else { - $debugResponses = false; + // The exceptions that might happen here include: + // ConnectException - in that case there is no response. Don't catch the exception. + // RequestException - if there is something in the response then pass it back. + // otherwise re-throw the exception. + // GuzzleException - something else unexpected happened. Don't catch the exception. + try { + $response = $client->send($request); + } catch (RequestException $ex) { + $response = $ex->getResponse(); + + //if the response was null for some reason do not return it but re-throw + if ($response === null) { + throw $ex; + } } if ($debugRequests) { self::debugRequest($request, $user, $password); } + return $response; + } + + /** + * + * @param string|null $url + * @param string|null $xRequestId + * @param string|null $method + * @param string|null $user + * @param string|null $password + * @param array|null $headers ['X-MyHeader' => 'value'] + * @param mixed $body + * @param array|null $config + * @param CookieJar|null $cookies + * @param bool $stream Set to true to stream a response rather + * than download it all up-front. + * @param int|null $timeout + * @param Client|null $client + * + * @return ResponseInterface + * @throws GuzzleException + */ + public static function sendRequest( + ?string $url, + ?string $xRequestId, + ?string $method = 'GET', + ?string $user = null, + ?string $password = null, + ?array $headers = null, + $body = null, + ?array $config = null, + ?CookieJar $cookies = null, + bool $stream = false, + ?int $timeout = 0, + ?Client $client = null + ):ResponseInterface { + if ((\getenv('DEBUG_ACCEPTANCE_RESPONSES') !== false) || (\getenv('DEBUG_ACCEPTANCE_API_CALLS') !== false)) { + $debugResponses = true; + } else { + $debugResponses = false; + } + $sendRetryLimit = self::numRetriesOnHttpTooEarly(); $sendCount = 0; $sendExceptionHappened = false; do { - // The exceptions that might happen here include: - // ConnectException - in that case there is no response. Don't catch the exception. - // RequestException - if there is something in the response then pass it back. - // otherwise re-throw the exception. - // GuzzleException - something else unexpected happened. Don't catch the exception. - try { - $response = $client->send($request); - } catch (RequestException $ex) { - $sendExceptionHappened = true; - $response = $ex->getResponse(); + $response = self::sendRequestOnce( + $url, + $xRequestId, + $method, + $user, + $password, + $headers, + $body, + $config, + $cookies, + $stream, + $timeout, + $client + ); - //if the response was null for some reason do not return it but re-throw - if ($response === null) { - throw $ex; - } + if ($response->getStatusCode() >= 400) { + $sendExceptionHappened = true; } if ($debugResponses) { diff --git a/tests/acceptance/config/behat.yml b/tests/acceptance/config/behat.yml index 3a9fc84427..41c6d2f417 100644 --- a/tests/acceptance/config/behat.yml +++ b/tests/acceptance/config/behat.yml @@ -152,6 +152,22 @@ default: - OCSContext: - TrashbinContext: + apiAsyncUpload: + paths: + - '%paths.base%/../features/apiAsyncUpload' + context: *common_ldap_suite_context + contexts: + - SpacesContext: + - FeatureContext: *common_feature_context_params + - OccContext: + - WebDavPropertiesContext: + - FavoritesContext: + - ChecksumContext: + - FilesVersionsContext: + - OCSContext: + - TrashbinContext: + + extensions: rdx\behatvars\BehatVariablesExtension: ~ diff --git a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md index 4ac319d5da..5f10f770c5 100644 --- a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md +++ b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md @@ -93,3 +93,13 @@ The expected failures in this file are from features in the owncloud/ocis repo. #### [A User can get information of another user with Graph API](https://github.com/owncloud/ocis/issues/5125) - [apiGraph/getUser.feature:23](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/getUser.feature#L23) + +#### [GET a file while it's in processing doesn't return 425 code (async uploads)](https://github.com/owncloud/ocis/issues/5326) +- [apiAsyncUpload/delayPostprocessing.feature:14](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiAsyncUpload/delayPostprocessing.feature#L14) +- [apiAsyncUpload/delayPostprocessing.feature:15](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiAsyncUpload/delayPostprocessing.feature#L15) +- [apiAsyncUpload/delayPostprocessing.feature:16](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiAsyncUpload/delayPostprocessing.feature#L16) + +#### [PROPFIND a file while it's in processing doesn't return 425 code (async uploads)](https://github.com/owncloud/ocis/issues/5327) +- [apiAsyncUpload/delayPostprocessing.feature:24](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiAsyncUpload/delayPostprocessing.feature#L24) +- [apiAsyncUpload/delayPostprocessing.feature:25](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiAsyncUpload/delayPostprocessing.feature#L25) +- [apiAsyncUpload/delayPostprocessing.feature:26](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiAsyncUpload/delayPostprocessing.feature#L26) \ No newline at end of file diff --git a/tests/acceptance/features/apiAsyncUpload/delayPostprocessing.feature b/tests/acceptance/features/apiAsyncUpload/delayPostprocessing.feature new file mode 100644 index 0000000000..c62148b87b --- /dev/null +++ b/tests/acceptance/features/apiAsyncUpload/delayPostprocessing.feature @@ -0,0 +1,26 @@ +@api +Feature: delay post-processing of uploaded files + + Background: + Given user "Alice" has been created with default attributes and without skeleton files + And user "Alice" has uploaded file with content "uploaded content" to "/file.txt" + + + Scenario Outline: user sends GET request to the file while it's still being processed + When user "Alice" requests "" with "GET" without retrying + Then the HTTP status code should be "425" + Examples: + | dav_path | + | /remote.php/webdav/file.txt | + | /remote.php/dav/files/%username%/file.txt | + | /dav/spaces/%spaceid%/file.txt | + + + Scenario Outline: user sends PROPFIND request to the file while it's still being processed + When user "Alice" requests "" with "PROPFIND" without retrying + Then the HTTP status code should be "425" + Examples: + | dav_path | + | /remote.php/webdav/file.txt | + | /remote.php/dav/files/%username%/file.txt | + | /dav/spaces/%spaceid%/file.txt | \ No newline at end of file diff --git a/tests/acceptance/features/bootstrap/AuthContext.php b/tests/acceptance/features/bootstrap/AuthContext.php index 24c57b657d..796eb2bc56 100644 --- a/tests/acceptance/features/bootstrap/AuthContext.php +++ b/tests/acceptance/features/bootstrap/AuthContext.php @@ -1155,4 +1155,34 @@ class AuthContext implements Context { $this->tokenAuthHasBeenSetTo = ''; } } + + /** + * @When user :user requests :endpoint with :method without retrying + * + * @param string $user + * @param string $endpoint + * @param string $method + * + * @return void + */ + public function userRequestsURLWithoutRetry( + string $user, + string $endpoint, + string $method + ):void { + $username = $this->featureContext->getActualUsername($user); + $endpoint = $this->featureContext->substituteInLineCodes( + $endpoint, + $username + ); + $fullUrl = $this->featureContext->getBaseUrl() . $endpoint; + $response = HttpRequestHelper::sendRequestOnce( + $fullUrl, + $this->featureContext->getStepLineRef(), + $method, + $username, + $this->featureContext->getPasswordForUser($user) + ); + $this->featureContext->setResponse($response); + } }