diff --git a/tests/phpunit/includes/abstract-testcase.php b/tests/phpunit/includes/abstract-testcase.php index 224929eb377a8..b6c82cc066efd 100644 --- a/tests/phpunit/includes/abstract-testcase.php +++ b/tests/phpunit/includes/abstract-testcase.php @@ -1694,4 +1694,119 @@ public static function touch( $file ) { touch( $file ); } + + /** + * Wrapper for `wp_safe_remote_request()` that retries on error and skips the test on timeout. + * + * @param string $url URL to retrieve. + * @param array $args Optional. Request arguments. Default empty array. + * @return array|WP_Error The response or WP_Error on failure. + */ + protected function wp_safe_remote_request( $url, $args = array() ) { + return self::retry_on_error( 'wp_safe_remote_request', $url, $args ); + } + + /** + * Wrapper for `wp_safe_remote_get()` that retries on error and skips the test on timeout. + * + * @param string $url URL to retrieve. + * @param array $args Optional. Request arguments. Default empty array. + * @return array|WP_Error The response or WP_Error on failure. + */ + protected function wp_safe_remote_get( $url, $args = array() ) { + return self::retry_on_error( 'wp_safe_remote_get', $url, $args ); + } + + /** + * Wrapper for `wp_safe_remote_post()` that retries on error and skips the test on timeout. + * + * @param string $url URL to retrieve. + * @param array $args Optional. Request arguments. Default empty array. + * @return array|WP_Error The response or WP_Error on failure. + */ + protected function wp_safe_remote_post( $url, $args = array() ) { + return self::retry_on_error( 'wp_safe_remote_post', $url, $args ); + } + + /** + * Wrapper for `wp_safe_remote_head()` that retries on error and skips the test on timeout. + * + * @param string $url URL to retrieve. + * @param array $args Optional. Request arguments. Default empty array. + * @return array|WP_Error The response or WP_Error on failure. + */ + protected function wp_safe_remote_head( $url, $args = array() ) { + return self::retry_on_error( 'wp_safe_remote_head', $url, $args ); + } + + /** + * Wrapper for `wp_remote_request()` that retries on error and skips the test on timeout. + * + * @param string $url URL to retrieve. + * @param array $args Optional. Request arguments. Default empty array. + * @return array|WP_Error The response or WP_Error on failure. + */ + protected function wp_remote_request( $url, $args = array() ) { + return self::retry_on_error( 'wp_remote_request', $url, $args ); + } + + /** + * Wrapper for `wp_remote_get()` that retries on error and skips the test on timeout. + * + * @param string $url URL to retrieve. + * @param array $args Optional. Request arguments. Default empty array. + * @return array|WP_Error The response or WP_Error on failure. + */ + protected function wp_remote_get( $url, $args = array() ) { + return self::retry_on_error( 'wp_remote_get', $url, $args ); + } + + /** + * Wrapper for `wp_remote_post()` that retries on error and skips the test on timeout. + * + * @param string $url URL to retrieve. + * @param array $args Optional. Request arguments. Default empty array. + * @return array|WP_Error The response or WP_Error on failure. + */ + protected function wp_remote_post( $url, $args = array() ) { + return self::retry_on_error( 'wp_remote_post', $url, $args ); + } + + /** + * Wrapper for `wp_remote_head()` that retries on error and skips the test on timeout. + * + * @param string $url URL to retrieve. + * @param array $args Optional. Request arguments. Default empty array. + * @return array|WP_Error The response or WP_Error on failure. + */ + protected function wp_remote_head( $url, $args = array() ) { + return self::retry_on_error( 'wp_remote_head', $url, $args ); + } + + /** + * Retries an HTTP API request up to three times and skips the test on timeout. + * + * @param callable $callback The HTTP API request function to call. + * @param string $url URL to retrieve. + * @param array $args Request arguments. + * @return array|WP_Error The response or WP_Error on failure. + */ + private function retry_on_error( callable $callback, $url, $args ) { + $attempts = 0; + + while ( $attempts < 3 ) { + $result = call_user_func( $callback, $url, $args ); + + if ( ! is_wp_error( $result ) ) { + return $result; + } + + ++$attempts; + sleep( 5 ); + } + + $this->skipTestOnTimeout( $result ); + + return $result; + } } diff --git a/tests/phpunit/tests/http/base.php b/tests/phpunit/tests/http/base.php index 2e73b0de94431..49e4672ad2941 100644 --- a/tests/phpunit/tests/http/base.php +++ b/tests/phpunit/tests/http/base.php @@ -44,9 +44,8 @@ public function filter_http_request_args( array $args ) { */ public function test_redirect_on_301() { // 5 : 5 & 301. - $res = wp_remote_request( $this->redirection_script . '?code=301&rt=' . 5, array( 'redirection' => 5 ) ); + $res = $this->wp_remote_request( $this->redirection_script . '?code=301&rt=' . 5, array( 'redirection' => 5 ) ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( 200, (int) $res['response']['code'] ); } @@ -56,9 +55,8 @@ public function test_redirect_on_301() { */ public function test_redirect_on_302() { // 5 : 5 & 302. - $res = wp_remote_request( $this->redirection_script . '?code=302&rt=' . 5, array( 'redirection' => 5 ) ); + $res = $this->wp_remote_request( $this->redirection_script . '?code=302&rt=' . 5, array( 'redirection' => 5 ) ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( 200, (int) $res['response']['code'] ); } @@ -70,9 +68,8 @@ public function test_redirect_on_302() { */ public function test_redirect_on_301_no_redirect() { // 5 > 0 & 301. - $res = wp_remote_request( $this->redirection_script . '?code=301&rt=' . 5, array( 'redirection' => 0 ) ); + $res = $this->wp_remote_request( $this->redirection_script . '?code=301&rt=' . 5, array( 'redirection' => 0 ) ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( 301, (int) $res['response']['code'] ); } @@ -84,9 +81,8 @@ public function test_redirect_on_301_no_redirect() { */ public function test_redirect_on_302_no_redirect() { // 5 > 0 & 302. - $res = wp_remote_request( $this->redirection_script . '?code=302&rt=' . 5, array( 'redirection' => 0 ) ); + $res = $this->wp_remote_request( $this->redirection_script . '?code=302&rt=' . 5, array( 'redirection' => 0 ) ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( 302, (int) $res['response']['code'] ); } @@ -96,9 +92,8 @@ public function test_redirect_on_302_no_redirect() { */ public function test_redirections_equal() { // 5 - 5. - $res = wp_remote_request( $this->redirection_script . '?rt=' . 5, array( 'redirection' => 5 ) ); + $res = $this->wp_remote_request( $this->redirection_script . '?rt=' . 5, array( 'redirection' => 5 ) ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( 200, (int) $res['response']['code'] ); } @@ -108,9 +103,8 @@ public function test_redirections_equal() { */ public function test_no_head_redirections() { // No redirections on HEAD request. - $res = wp_remote_request( $this->redirection_script . '?code=302&rt=' . 1, array( 'method' => 'HEAD' ) ); + $res = $this->wp_remote_request( $this->redirection_script . '?code=302&rt=' . 1, array( 'method' => 'HEAD' ) ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( 302, (int) $res['response']['code'] ); } @@ -122,7 +116,7 @@ public function test_no_head_redirections() { */ public function test_redirect_on_head() { // Redirections on HEAD request when Requested. - $res = wp_remote_request( + $res = $this->wp_remote_request( $this->redirection_script . '?rt=' . 5, array( 'redirection' => 5, @@ -130,7 +124,6 @@ public function test_redirect_on_head() { ) ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( 200, (int) $res['response']['code'] ); } @@ -140,9 +133,8 @@ public function test_redirect_on_head() { */ public function test_redirections_greater() { // 10 > 5. - $res = wp_remote_request( $this->redirection_script . '?rt=' . 10, array( 'redirection' => 5 ) ); + $res = $this->wp_remote_request( $this->redirection_script . '?rt=' . 10, array( 'redirection' => 5 ) ); - $this->skipTestOnTimeout( $res ); $this->assertWPError( $res ); } @@ -151,9 +143,8 @@ public function test_redirections_greater() { */ public function test_redirections_greater_edgecase() { // 6 > 5 (close edge case). - $res = wp_remote_request( $this->redirection_script . '?rt=' . 6, array( 'redirection' => 5 ) ); + $res = $this->wp_remote_request( $this->redirection_script . '?rt=' . 6, array( 'redirection' => 5 ) ); - $this->skipTestOnTimeout( $res ); $this->assertWPError( $res ); } @@ -162,9 +153,8 @@ public function test_redirections_greater_edgecase() { */ public function test_redirections_less_edgecase() { // 4 < 5 (close edge case). - $res = wp_remote_request( $this->redirection_script . '?rt=' . 4, array( 'redirection' => 5 ) ); + $res = $this->wp_remote_request( $this->redirection_script . '?rt=' . 4, array( 'redirection' => 5 ) ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); } @@ -175,9 +165,8 @@ public function test_redirections_less_edgecase() { */ public function test_redirections_zero_redirections_specified() { // 0 redirections asked for, should return the document? - $res = wp_remote_request( $this->redirection_script . '?code=302&rt=' . 5, array( 'redirection' => 0 ) ); + $res = $this->wp_remote_request( $this->redirection_script . '?code=302&rt=' . 5, array( 'redirection' => 0 ) ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( 302, (int) $res['response']['code'] ); } @@ -191,9 +180,8 @@ public function test_redirections_zero_redirections_specified() { */ public function test_location_header_on_201() { // Prints PASS on initial load, FAIL if the client follows the specified redirection. - $res = wp_remote_request( $this->redirection_script . '?201-location=true' ); + $res = $this->wp_remote_request( $this->redirection_script . '?201-location=true' ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( 'PASS', $res['body'] ); } @@ -210,7 +198,7 @@ public function test_no_redirection_on_PUT() { $url = 'http://api.wordpress.org/core/tests/1.0/redirection.php?201-location=1'; // Test 301 - POST to POST. - $res = wp_remote_request( + $res = $this->wp_remote_request( $url, array( 'method' => 'PUT', @@ -218,7 +206,6 @@ public function test_no_redirection_on_PUT() { ) ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( 'PASS', wp_remote_retrieve_body( $res ) ); $this->assertNotEmpty( $res['headers']['location'] ); @@ -236,9 +223,8 @@ public function test_send_headers() { 'test2' => 0, 'test3' => '', ); - $res = wp_remote_request( $this->redirection_script . '?header-check', array( 'headers' => $headers ) ); + $res = $this->wp_remote_request( $this->redirection_script . '?header-check', array( 'headers' => $headers ) ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $headers = array(); @@ -267,7 +253,7 @@ public function test_send_headers() { public function test_file_stream() { $url = $this->file_stream_url; $size = 153204; - $res = wp_remote_request( + $res = $this->wp_remote_request( $url, array( 'stream' => true, @@ -281,7 +267,6 @@ public function test_file_stream() { unlink( $res['filename'] ); } - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( '', $res['body'] ); // The body should be empty. $this->assertEquals( $size, $res['headers']['Content-Length'] ); // Check the headers are returned (and the size is the same). @@ -297,7 +282,7 @@ public function test_file_stream() { public function test_file_stream_limited_size() { $url = $this->file_stream_url; $size = 10000; - $res = wp_remote_request( + $res = $this->wp_remote_request( $url, array( 'stream' => true, @@ -312,7 +297,6 @@ public function test_file_stream_limited_size() { unlink( $res['filename'] ); } - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( $size, $filesize ); // Check that the file is written to disk correctly without any extra characters. } @@ -328,7 +312,7 @@ public function test_request_limited_size() { $url = $this->file_stream_url; $size = 10000; - $res = wp_remote_request( + $res = $this->wp_remote_request( $url, array( 'timeout' => 30, @@ -336,7 +320,6 @@ public function test_request_limited_size() { ) ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( $size, strlen( $res['body'] ) ); } @@ -354,9 +337,8 @@ public function test_request_limited_size() { public function test_post_redirect_to_method_300( $response_code, $method ) { $url = 'http://api.wordpress.org/core/tests/1.0/redirection.php?post-redirect-to-method=1'; - $res = wp_remote_post( add_query_arg( 'response_code', $response_code, $url ), array( 'timeout' => 30 ) ); + $res = $this->wp_remote_post( add_query_arg( 'response_code', $response_code, $url ), array( 'timeout' => 30 ) ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( $method, wp_remote_retrieve_body( $res ) ); } @@ -405,9 +387,8 @@ public function test_ip_url_with_host_header() { 'redirection' => 0, ); - $res = wp_remote_get( $url, $args ); + $res = $this->wp_remote_get( $url, $args ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( 'PASS', wp_remote_retrieve_body( $res ) ); } @@ -427,11 +408,10 @@ public function test_https_url_without_ssl_verification() { add_filter( 'http_request_args', array( $this, 'filter_http_request_args' ) ); - $res = wp_remote_head( $url, $args ); + $res = $this->wp_remote_head( $url, $args ); remove_filter( 'http_request_args', array( $this, 'filter_http_request_args' ) ); - $this->skipTestOnTimeout( $res ); $this->assertNotEmpty( $this->http_request_args['sslcertificates'] ); $this->assertNotWPError( $res ); } @@ -447,9 +427,8 @@ public function test_https_url_without_ssl_verification() { public function test_cookie_handling() { $url = 'http://api.wordpress.org/core/tests/1.0/redirection.php?cookie-test=1'; - $res = wp_remote_get( $url ); + $res = $this->wp_remote_get( $url ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); $this->assertSame( 'PASS', wp_remote_retrieve_body( $res ) ); } @@ -467,9 +446,8 @@ public function test_ssl() { $this->fail( 'This installation of PHP does not support SSL.' ); } - $res = wp_remote_get( 'https://wordpress.org/' ); + $res = $this->wp_remote_get( 'https://wordpress.org/' ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); } @@ -484,9 +462,8 @@ public function test_url_with_double_slashes_path() { $path = parse_url( $url, PHP_URL_PATH ); $url = str_replace( $path, '/' . $path, $url ); - $res = wp_remote_request( $url ); + $res = $this->wp_remote_request( $url ); - $this->skipTestOnTimeout( $res ); $this->assertNotWPError( $res ); } } diff --git a/tests/phpunit/tests/http/functions.php b/tests/phpunit/tests/http/functions.php index 9c3e54a8b8911..96c6e4db2f496 100644 --- a/tests/phpunit/tests/http/functions.php +++ b/tests/phpunit/tests/http/functions.php @@ -12,9 +12,8 @@ class Tests_HTTP_Functions extends WP_UnitTestCase { public function test_head_request() { // This URL gives a direct 200 response. $url = 'https://s.w.org/screenshots/3.9/dashboard.png'; - $response = wp_remote_head( $url ); + $response = $this->wp_remote_head( $url ); - $this->skipTestOnTimeout( $response ); $this->assertNotWPError( $response ); $headers = wp_remote_retrieve_headers( $response ); @@ -31,9 +30,8 @@ public function test_head_request() { public function test_head_redirect() { // This URL will 301 redirect. $url = 'https://wp.org/screenshots/3.9/dashboard.png'; - $response = wp_remote_head( $url ); + $response = $this->wp_remote_head( $url ); - $this->skipTestOnTimeout( $response ); $this->assertNotWPError( $response ); $this->assertSame( 301, wp_remote_retrieve_response_code( $response ) ); } @@ -43,9 +41,8 @@ public function test_head_redirect() { */ public function test_head_404() { $url = 'https://wordpress.org/screenshots/3.9/awefasdfawef.jpg'; - $response = wp_remote_head( $url ); + $response = $this->wp_remote_head( $url ); - $this->skipTestOnTimeout( $response ); $this->assertNotWPError( $response ); $this->assertSame( 404, wp_remote_retrieve_response_code( $response ) ); } @@ -58,9 +55,8 @@ public function test_head_404() { public function test_get_request() { $url = 'https://s.w.org/screenshots/3.9/dashboard.png'; - $response = wp_remote_get( $url ); + $response = $this->wp_remote_get( $url ); - $this->skipTestOnTimeout( $response ); $this->assertNotWPError( $response ); $headers = wp_remote_retrieve_headers( $response ); @@ -80,9 +76,8 @@ public function test_get_redirect() { // This will redirect to wordpress.org. $url = 'https://wp.org/screenshots/3.9/dashboard.png'; - $response = wp_remote_get( $url ); + $response = $this->wp_remote_get( $url ); - $this->skipTestOnTimeout( $response ); $this->assertNotWPError( $response ); $headers = wp_remote_retrieve_headers( $response ); @@ -101,9 +96,8 @@ public function test_get_redirect_limit_exceeded() { $url = 'https://wp.org/screenshots/3.9/dashboard.png'; // Pretend we've already redirected 5 times. - $response = wp_remote_get( $url, array( 'redirection' => -1 ) ); + $response = $this->wp_remote_get( $url, array( 'redirection' => -1 ) ); - $this->skipTestOnTimeout( $response ); $this->assertWPError( $response ); } @@ -118,9 +112,8 @@ public function test_get_redirect_limit_exceeded() { public function test_get_response_cookies() { $url = 'https://login.wordpress.org/wp-login.php'; - $response = wp_remote_head( $url ); + $response = $this->wp_remote_head( $url ); - $this->skipTestOnTimeout( $response ); $this->assertNotWPError( $response ); $cookies = wp_remote_retrieve_cookies( $response ); @@ -152,7 +145,7 @@ public function test_get_response_cookies() { public function test_get_response_cookies_with_wp_http_cookie_object() { $url = 'https://login.wordpress.org/wp-login.php'; - $response = wp_remote_get( + $response = $this->wp_remote_get( $url, array( 'cookies' => array( @@ -166,7 +159,6 @@ public function test_get_response_cookies_with_wp_http_cookie_object() { ) ); - $this->skipTestOnTimeout( $response ); $this->assertNotWPError( $response ); $cookies = wp_remote_retrieve_cookies( $response ); @@ -189,7 +181,7 @@ public function test_get_response_cookies_with_wp_http_cookie_object() { public function test_get_response_cookies_with_name_value_array() { $url = 'https://login.wordpress.org/wp-login.php'; - $response = wp_remote_get( + $response = $this->wp_remote_get( $url, array( 'cookies' => array( @@ -198,7 +190,6 @@ public function test_get_response_cookies_with_name_value_array() { ) ); - $this->skipTestOnTimeout( $response ); $this->assertNotWPError( $response ); $cookies = wp_remote_retrieve_cookies( $response ); diff --git a/tests/phpunit/tests/readme.php b/tests/phpunit/tests/readme.php index 04faecbb368bf..85ffffcdf69e7 100644 --- a/tests/phpunit/tests/readme.php +++ b/tests/phpunit/tests/readme.php @@ -91,9 +91,8 @@ public function test_readme_mariadb_version() { * @return string The response body. */ public function get_response_body( $url ) { - $response = wp_remote_get( $url ); + $response = $this->wp_remote_get( $url ); - $this->skipTestOnTimeout( $response ); $this->assertNotWPError( $response ); $response_code = wp_remote_retrieve_response_code( $response );