From c7a231ad72c4150d4d9d96b8d97b0fc08a5a510e Mon Sep 17 00:00:00 2001 From: Sneha Sahu Date: Mon, 2 Nov 2026 13:09:12 +0000 Subject: [PATCH 1/2] feat(storagecontrol): add Rapid Cache samples Adds create, get, list, update and disable Rapid Cache samples for Storage Control, with tests. Bumps google/cloud-storage-control to ^1.12. b/482946642 [Generated-by: AI] --- storagecontrol/composer.json | 2 +- storagecontrol/src/create_rapid_cache.php | 72 +++++++++ storagecontrol/src/disable_rapid_cache.php | 64 ++++++++ storagecontrol/src/get_rapid_cache.php | 60 ++++++++ storagecontrol/src/list_rapid_caches.php | 59 ++++++++ storagecontrol/src/update_rapid_cache.php | 81 +++++++++++ storagecontrol/test/rapidCacheTest.php | 162 +++++++++++++++++++++ 7 files changed, 499 insertions(+), 1 deletion(-) create mode 100644 storagecontrol/src/create_rapid_cache.php create mode 100644 storagecontrol/src/disable_rapid_cache.php create mode 100644 storagecontrol/src/get_rapid_cache.php create mode 100644 storagecontrol/src/list_rapid_caches.php create mode 100644 storagecontrol/src/update_rapid_cache.php create mode 100644 storagecontrol/test/rapidCacheTest.php diff --git a/storagecontrol/composer.json b/storagecontrol/composer.json index 76be4bb14..9514b416d 100644 --- a/storagecontrol/composer.json +++ b/storagecontrol/composer.json @@ -1,6 +1,6 @@ { "require": { - "google/cloud-storage-control": "^1.9" + "google/cloud-storage-control": "^1.12" }, "require-dev": { "google/cloud-storage": "^1.48.1" diff --git a/storagecontrol/src/create_rapid_cache.php b/storagecontrol/src/create_rapid_cache.php new file mode 100644 index 000000000..199aa5d9c --- /dev/null +++ b/storagecontrol/src/create_rapid_cache.php @@ -0,0 +1,72 @@ +bucketName('_', $bucketName); + + // Rapid Cache Ultra requires a bucket with hierarchical namespace enabled. + $rapidCache = new RapidCache([ + 'zone' => $zone, + 'cache_type' => 'rapid-cache-ultra', + ]); + + $request = new CreateRapidCacheRequest([ + 'parent' => $formattedName, + 'rapid_cache' => $rapidCache, + ]); + + // Creating a Rapid Cache is a long-running operation. This sample blocks + // until it completes. + $operation = $storageControlClient->createRapidCache($request); + $operation->pollUntilComplete(); + + /** @var RapidCache $rapidCacheResult */ + $rapidCacheResult = $operation->getResult(); + printf('Created Rapid Cache: %s' . PHP_EOL, $rapidCacheResult->getName()); +} +# [END storage_control_create_rapid_cache] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/storagecontrol/src/disable_rapid_cache.php b/storagecontrol/src/disable_rapid_cache.php new file mode 100644 index 000000000..1faf0f0e9 --- /dev/null +++ b/storagecontrol/src/disable_rapid_cache.php @@ -0,0 +1,64 @@ +rapidCacheName('_', $bucketName, $rapidCacheId); + + $request = new DisableRapidCacheRequest([ + 'name' => $formattedName, + ]); + + // Disabling a Rapid Cache starts a long-running operation. The cache moves + // to the "disabled" state within seconds, but the operation only completes + // once the cache has been fully removed, which can take more than an hour. + // This sample does not wait for the operation to complete; use + // get_rapid_cache to check the cache state. + $operation = $storageControlClient->disableRapidCache($request); + + printf('Disabling Rapid Cache: %s' . PHP_EOL, $formattedName); + printf('Operation: %s' . PHP_EOL, $operation->getName()); +} +# [END storage_control_disable_rapid_cache] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/storagecontrol/src/get_rapid_cache.php b/storagecontrol/src/get_rapid_cache.php new file mode 100644 index 000000000..a6fca0394 --- /dev/null +++ b/storagecontrol/src/get_rapid_cache.php @@ -0,0 +1,60 @@ +rapidCacheName('_', $bucketName, $rapidCacheId); + + $request = new GetRapidCacheRequest([ + 'name' => $formattedName, + ]); + + $response = $storageControlClient->getRapidCache($request); + + printf('Got Rapid Cache: %s' . PHP_EOL, $response->getName()); + printf('Zone: %s' . PHP_EOL, $response->getZone()); + printf('State: %s' . PHP_EOL, $response->getState()); +} +# [END storage_control_get_rapid_cache] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/storagecontrol/src/list_rapid_caches.php b/storagecontrol/src/list_rapid_caches.php new file mode 100644 index 000000000..e2bbe8f9a --- /dev/null +++ b/storagecontrol/src/list_rapid_caches.php @@ -0,0 +1,59 @@ +bucketName('_', $bucketName); + + $request = new ListRapidCachesRequest([ + 'parent' => $formattedName, + ]); + + $response = $storageControlClient->listRapidCaches($request); + + // The iterator handles pagination automatically. + foreach ($response as $rapidCache) { + printf('Rapid Cache name: %s' . PHP_EOL, $rapidCache->getName()); + } +} +# [END storage_control_list_rapid_caches] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/storagecontrol/src/update_rapid_cache.php b/storagecontrol/src/update_rapid_cache.php new file mode 100644 index 000000000..e18207317 --- /dev/null +++ b/storagecontrol/src/update_rapid_cache.php @@ -0,0 +1,81 @@ +rapidCacheName('_', $bucketName, $rapidCacheId); + + $rapidCache = new RapidCache([ + 'name' => $formattedName, + 'ttl' => new Duration(['seconds' => $ttlSeconds]), + ]); + + // Only the fields listed in the update mask are changed. + $updateMask = new FieldMask([ + 'paths' => ['ttl'], + ]); + + $request = new UpdateRapidCacheRequest([ + 'rapid_cache' => $rapidCache, + 'update_mask' => $updateMask, + ]); + + // Updating a Rapid Cache is a long-running operation. This sample blocks + // until it completes. + $operation = $storageControlClient->updateRapidCache($request); + $operation->pollUntilComplete(); + + /** @var RapidCache $rapidCacheResult */ + $rapidCacheResult = $operation->getResult(); + printf('Updated Rapid Cache: %s' . PHP_EOL, $rapidCacheResult->getName()); + printf('TTL: %d seconds' . PHP_EOL, $rapidCacheResult->getTtl()->getSeconds()); +} +# [END storage_control_update_rapid_cache] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/storagecontrol/test/rapidCacheTest.php b/storagecontrol/test/rapidCacheTest.php new file mode 100644 index 000000000..1e8e25fae --- /dev/null +++ b/storagecontrol/test/rapidCacheTest.php @@ -0,0 +1,162 @@ +createBucket( + sprintf('php-gcscontrol-rc-%s', $uniqueBucketId), + [ + 'location' => self::$location, + 'hierarchicalNamespace' => ['enabled' => true], + 'iamConfiguration' => ['uniformBucketLevelAccess' => ['enabled' => true]] + ] + ); + } + + public static function tearDownAfterClass(): void + { + if (!self::$sourceBucket) { + return; + } + // A bucket cannot be deleted until its disabled Rapid Cache has been + // fully removed, which can take more than two hours. Cleanup is + // best-effort: a short retry, after which the bucket is left behind + // for later cleanup. + for ($attempt = 1; $attempt <= self::DELETE_RETRY_ATTEMPTS; $attempt++) { + try { + self::$sourceBucket->delete(); + return; + } catch (ConflictException $e) { + if ($attempt < self::DELETE_RETRY_ATTEMPTS) { + sleep(self::DELETE_RETRY_INTERVAL_SECONDS); + } + } catch (\Exception $e) { + break; + } + } + fwrite(STDERR, sprintf( + 'Could not delete bucket %s: %s' . PHP_EOL, + self::$sourceBucket->name(), + isset($e) ? $e->getMessage() : 'unknown error' + )); + } + + public function testRapidCacheLifecycle() + { + $bucketName = self::$sourceBucket->name(); + + // Test create Rapid Cache + $output = $this->runFunctionSnippet('create_rapid_cache', [ + $bucketName, + self::$zone, + ]); + $this->assertMatchesRegularExpression('/Created Rapid Cache: (\S+)/', $output); + preg_match('/Created Rapid Cache: (\S+)/', $output, $matches); + $cacheName = $matches[1]; + // The Rapid Cache ID is assigned by the server; parse it from the name. + $cacheId = StorageControlClient::parseName($cacheName, 'rapidCache')['rapid_cache']; + $this->assertNotEmpty($cacheId); + + try { + // Test get Rapid Cache + $output = $this->runFunctionSnippet('get_rapid_cache', [ + $bucketName, + $cacheId, + ]); + $this->assertStringContainsString(sprintf('Got Rapid Cache: %s', $cacheName), $output); + $this->assertStringContainsString(sprintf('Zone: %s', self::$zone), $output); + + // Test list Rapid Caches + $output = $this->runFunctionSnippet('list_rapid_caches', [ + $bucketName, + ]); + $this->assertStringContainsString(sprintf('Rapid Cache name: %s', $cacheName), $output); + + // Test update Rapid Cache + $output = $this->runFunctionSnippet('update_rapid_cache', [ + $bucketName, + $cacheId, + 172800, + ]); + $this->assertStringContainsString(sprintf('Updated Rapid Cache: %s', $cacheName), $output); + $this->assertStringContainsString('TTL: 172800 seconds', $output); + } finally { + // Disable the Rapid Cache. This also cleans up the cache so that + // the bucket can be deleted once the cache has been fully removed. + $disableOutput = $this->runFunctionSnippet('disable_rapid_cache', [ + $bucketName, + $cacheId, + ]); + } + + // Test disable Rapid Cache + $this->assertStringContainsString(sprintf('Disabling Rapid Cache: %s', $cacheName), $disableOutput); + $this->assertStringContainsString('Operation: ', $disableOutput); + + // The cache moves to the "disabled" state shortly after the request. + for ($attempt = 0; $attempt < self::DISABLE_POLL_ATTEMPTS; $attempt++) { + $output = $this->runFunctionSnippet('get_rapid_cache', [ + $bucketName, + $cacheId, + ]); + if (str_contains($output, 'State: disabled')) { + break; + } + if ($attempt < self::DISABLE_POLL_ATTEMPTS - 1) { + sleep(self::DISABLE_POLL_INTERVAL_SECONDS); + } + } + $this->assertStringContainsString('State: disabled', $output); + } +} From 15c1b329c5337cd353085d5572bb588b7306136c Mon Sep 17 00:00:00 2001 From: Sneha Sahu Date: Mon, 2 Nov 2026 18:10:38 +0000 Subject: [PATCH 2/2] docs(storagecontrol): align rapid cache samples with reference integration test Set the explicit cache name (ID = zone), cache_type rapid-cache-ultra and ttl 24h on create; wait for the disable LRO; tests assert running state, cache type, list membership and the updated ttl, and bound the disable wait. Aligns with googleapis/google-cloud-java#14529. b/482946642 [Generated-by: AI] --- storagecontrol/src/create_rapid_cache.php | 22 +++- storagecontrol/src/disable_rapid_cache.php | 32 ++++-- storagecontrol/src/get_rapid_cache.php | 1 + storagecontrol/src/update_rapid_cache.php | 10 +- storagecontrol/test/rapidCacheTest.php | 115 ++++++++++++--------- 5 files changed, 115 insertions(+), 65 deletions(-) diff --git a/storagecontrol/src/create_rapid_cache.php b/storagecontrol/src/create_rapid_cache.php index 199aa5d9c..4e9b5993d 100644 --- a/storagecontrol/src/create_rapid_cache.php +++ b/storagecontrol/src/create_rapid_cache.php @@ -28,6 +28,7 @@ use Google\Cloud\Storage\Control\V2\Client\StorageControlClient; use Google\Cloud\Storage\Control\V2\CreateRapidCacheRequest; use Google\Cloud\Storage\Control\V2\RapidCache; +use Google\Protobuf\Duration; /** * Creates a Rapid Cache instance. @@ -43,27 +44,40 @@ function create_rapid_cache(string $bucketName, string $zone): void $storageControlClient = new StorageControlClient(); // Set project to "_" to signify global bucket - $formattedName = $storageControlClient->bucketName('_', $bucketName); + $formattedParent = $storageControlClient->bucketName('_', $bucketName); + + // The Rapid Cache ID must be the same as the zone. + $formattedName = $storageControlClient->rapidCacheName('_', $bucketName, $zone); // Rapid Cache Ultra requires a bucket with hierarchical namespace enabled. $rapidCache = new RapidCache([ + 'name' => $formattedName, 'zone' => $zone, 'cache_type' => 'rapid-cache-ultra', + // Time to live (TTL) for cache entries: 86400 seconds (24 hours). + 'ttl' => new Duration(['seconds' => 86400]), ]); $request = new CreateRapidCacheRequest([ - 'parent' => $formattedName, + 'parent' => $formattedParent, 'rapid_cache' => $rapidCache, ]); // Creating a Rapid Cache is a long-running operation. This sample blocks - // until it completes. + // until it completes. A totalPollTimeoutMillis of 0 waits with no time + // limit, instead of the client library default of 5 minutes. $operation = $storageControlClient->createRapidCache($request); - $operation->pollUntilComplete(); + $operation->pollUntilComplete(['totalPollTimeoutMillis' => 0]); + + if (!$operation->operationSucceeded()) { + printf('Error: %s' . PHP_EOL, $operation->getError()->getMessage()); + return; + } /** @var RapidCache $rapidCacheResult */ $rapidCacheResult = $operation->getResult(); printf('Created Rapid Cache: %s' . PHP_EOL, $rapidCacheResult->getName()); + printf('State: %s' . PHP_EOL, $rapidCacheResult->getState()); } # [END storage_control_create_rapid_cache] diff --git a/storagecontrol/src/disable_rapid_cache.php b/storagecontrol/src/disable_rapid_cache.php index 1faf0f0e9..3f46e6c99 100644 --- a/storagecontrol/src/disable_rapid_cache.php +++ b/storagecontrol/src/disable_rapid_cache.php @@ -27,6 +27,7 @@ # [START storage_control_disable_rapid_cache] use Google\Cloud\Storage\Control\V2\Client\StorageControlClient; use Google\Cloud\Storage\Control\V2\DisableRapidCacheRequest; +use Google\Cloud\Storage\Control\V2\RapidCache; /** * Disables a Rapid Cache instance. @@ -35,8 +36,11 @@ * (e.g. 'my-bucket') * @param string $rapidCacheId The ID of the Rapid Cache. * (e.g. 'us-central1-a') + * @param int $timeoutMillis Optional. The maximum time to wait for the + * operation to complete, in milliseconds. 0 waits until it completes. + * (e.g. 600000 for 10 minutes) */ -function disable_rapid_cache(string $bucketName, string $rapidCacheId): void +function disable_rapid_cache(string $bucketName, string $rapidCacheId, int $timeoutMillis = 0): void { $storageControlClient = new StorageControlClient(); @@ -47,15 +51,27 @@ function disable_rapid_cache(string $bucketName, string $rapidCacheId): void 'name' => $formattedName, ]); - // Disabling a Rapid Cache starts a long-running operation. The cache moves - // to the "disabled" state within seconds, but the operation only completes - // once the cache has been fully removed, which can take more than an hour. - // This sample does not wait for the operation to complete; use - // get_rapid_cache to check the cache state. + // Disabling a Rapid Cache is a long-running operation. This sample waits + // for the long-running operation to complete. A totalPollTimeoutMillis of + // 0 waits with no time limit. $operation = $storageControlClient->disableRapidCache($request); + $completed = $operation->pollUntilComplete([ + 'totalPollTimeoutMillis' => $timeoutMillis, + ]); + + if (!$completed) { + printf('Disable operation is still running: %s' . PHP_EOL, $operation->getName()); + return; + } + + if (!$operation->operationSucceeded()) { + printf('Error: %s' . PHP_EOL, $operation->getError()->getMessage()); + return; + } - printf('Disabling Rapid Cache: %s' . PHP_EOL, $formattedName); - printf('Operation: %s' . PHP_EOL, $operation->getName()); + /** @var RapidCache $rapidCacheResult */ + $rapidCacheResult = $operation->getResult(); + printf('Disabled Rapid Cache: %s' . PHP_EOL, $rapidCacheResult->getName()); } # [END storage_control_disable_rapid_cache] diff --git a/storagecontrol/src/get_rapid_cache.php b/storagecontrol/src/get_rapid_cache.php index a6fca0394..6960afab9 100644 --- a/storagecontrol/src/get_rapid_cache.php +++ b/storagecontrol/src/get_rapid_cache.php @@ -51,6 +51,7 @@ function get_rapid_cache(string $bucketName, string $rapidCacheId): void printf('Got Rapid Cache: %s' . PHP_EOL, $response->getName()); printf('Zone: %s' . PHP_EOL, $response->getZone()); + printf('Cache type: %s' . PHP_EOL, $response->getCacheType()); printf('State: %s' . PHP_EOL, $response->getState()); } # [END storage_control_get_rapid_cache] diff --git a/storagecontrol/src/update_rapid_cache.php b/storagecontrol/src/update_rapid_cache.php index e18207317..6425505f9 100644 --- a/storagecontrol/src/update_rapid_cache.php +++ b/storagecontrol/src/update_rapid_cache.php @@ -65,9 +65,15 @@ function update_rapid_cache(string $bucketName, string $rapidCacheId, int $ttlSe ]); // Updating a Rapid Cache is a long-running operation. This sample blocks - // until it completes. + // until it completes. A totalPollTimeoutMillis of 0 waits with no time + // limit, instead of the client library default of 5 minutes. $operation = $storageControlClient->updateRapidCache($request); - $operation->pollUntilComplete(); + $operation->pollUntilComplete(['totalPollTimeoutMillis' => 0]); + + if (!$operation->operationSucceeded()) { + printf('Error: %s' . PHP_EOL, $operation->getError()->getMessage()); + return; + } /** @var RapidCache $rapidCacheResult */ $rapidCacheResult = $operation->getResult(); diff --git a/storagecontrol/test/rapidCacheTest.php b/storagecontrol/test/rapidCacheTest.php index 1e8e25fae..83dc1c26a 100644 --- a/storagecontrol/test/rapidCacheTest.php +++ b/storagecontrol/test/rapidCacheTest.php @@ -20,6 +20,7 @@ use Google\Cloud\Core\Exception\ConflictException; use Google\Cloud\Storage\Control\V2\Client\StorageControlClient; +use Google\Cloud\Storage\Control\V2\DisableRapidCacheRequest; use Google\Cloud\Storage\StorageClient; use Google\Cloud\TestUtils\TestTrait; use PHPUnit\Framework\TestCase; @@ -31,9 +32,13 @@ class rapidCacheTest extends TestCase { use TestTrait; - // Poll for up to 2 minutes for the cache to reach the "disabled" state. - private const DISABLE_POLL_ATTEMPTS = 12; - private const DISABLE_POLL_INTERVAL_SECONDS = 10; + // Wait for bucket metadata to propagate before creating the Rapid Cache. + private const BUCKET_PROPAGATION_SECONDS = 20; + + // Maximum time to wait for the disable operation (10 minutes). The cache + // moves to the "disabled" state within seconds, but the operation itself + // can run for more than an hour. + private const DISABLE_TIMEOUT_MILLIS = 600000; // Best-effort bucket cleanup: retry for up to ~2 minutes. private const DELETE_RETRY_ATTEMPTS = 6; @@ -43,6 +48,8 @@ class rapidCacheTest extends TestCase private static $storage; private static $location; private static $zone; + private static $cacheName; + private static $cacheDisabled = false; public static function setUpBeforeClass(): void { @@ -62,6 +69,7 @@ public static function setUpBeforeClass(): void 'iamConfiguration' => ['uniformBucketLevelAccess' => ['enabled' => true]] ] ); + sleep(self::BUCKET_PROPAGATION_SECONDS); } public static function tearDownAfterClass(): void @@ -69,6 +77,18 @@ public static function tearDownAfterClass(): void if (!self::$sourceBucket) { return; } + // Disable the Rapid Cache if the test did not, so that the bucket can + // be deleted once the cache has been removed. Errors are ignored. + if (self::$cacheName && !self::$cacheDisabled) { + try { + $storageControlClient = new StorageControlClient(); + $storageControlClient->disableRapidCache(new DisableRapidCacheRequest([ + 'name' => self::$cacheName, + ])); + } catch (\Exception $e) { + // Ignore errors: the cache may already be disabled. + } + } // A bucket cannot be deleted until its disabled Rapid Cache has been // fully removed, which can take more than two hours. Cleanup is // best-effort: a short retry, after which the bucket is left behind @@ -95,68 +115,61 @@ public static function tearDownAfterClass(): void public function testRapidCacheLifecycle() { $bucketName = self::$sourceBucket->name(); + // The Rapid Cache ID must be the same as the zone. + $cacheId = self::$zone; + $cacheName = StorageControlClient::rapidCacheName('_', $bucketName, $cacheId); + self::$cacheName = $cacheName; // Test create Rapid Cache $output = $this->runFunctionSnippet('create_rapid_cache', [ $bucketName, self::$zone, ]); - $this->assertMatchesRegularExpression('/Created Rapid Cache: (\S+)/', $output); - preg_match('/Created Rapid Cache: (\S+)/', $output, $matches); - $cacheName = $matches[1]; - // The Rapid Cache ID is assigned by the server; parse it from the name. - $cacheId = StorageControlClient::parseName($cacheName, 'rapidCache')['rapid_cache']; - $this->assertNotEmpty($cacheId); - - try { - // Test get Rapid Cache - $output = $this->runFunctionSnippet('get_rapid_cache', [ - $bucketName, - $cacheId, - ]); - $this->assertStringContainsString(sprintf('Got Rapid Cache: %s', $cacheName), $output); - $this->assertStringContainsString(sprintf('Zone: %s', self::$zone), $output); + $this->assertStringContainsString(sprintf('Created Rapid Cache: %s', $cacheName), $output); - // Test list Rapid Caches - $output = $this->runFunctionSnippet('list_rapid_caches', [ - $bucketName, - ]); - $this->assertStringContainsString(sprintf('Rapid Cache name: %s', $cacheName), $output); + // Test get Rapid Cache + $output = $this->runFunctionSnippet('get_rapid_cache', [ + $bucketName, + $cacheId, + ]); + $this->assertStringContainsString(sprintf('Got Rapid Cache: %s', $cacheName), $output); + $this->assertStringContainsString(sprintf('Zone: %s', self::$zone), $output); + $this->assertStringContainsString('Cache type: rapid-cache-ultra', $output); + $this->assertStringContainsString('State: running', $output); - // Test update Rapid Cache - $output = $this->runFunctionSnippet('update_rapid_cache', [ - $bucketName, - $cacheId, - 172800, - ]); - $this->assertStringContainsString(sprintf('Updated Rapid Cache: %s', $cacheName), $output); - $this->assertStringContainsString('TTL: 172800 seconds', $output); - } finally { - // Disable the Rapid Cache. This also cleans up the cache so that - // the bucket can be deleted once the cache has been fully removed. - $disableOutput = $this->runFunctionSnippet('disable_rapid_cache', [ - $bucketName, - $cacheId, - ]); - } + // Test list Rapid Caches + $output = $this->runFunctionSnippet('list_rapid_caches', [ + $bucketName, + ]); + $this->assertStringContainsString(sprintf('Rapid Cache name: %s', $cacheName), $output); - // Test disable Rapid Cache - $this->assertStringContainsString(sprintf('Disabling Rapid Cache: %s', $cacheName), $disableOutput); - $this->assertStringContainsString('Operation: ', $disableOutput); + // Test update Rapid Cache + $output = $this->runFunctionSnippet('update_rapid_cache', [ + $bucketName, + $cacheId, + 172800, + ]); + $this->assertStringContainsString(sprintf('Updated Rapid Cache: %s', $cacheName), $output); + $this->assertStringContainsString('TTL: 172800 seconds', $output); - // The cache moves to the "disabled" state shortly after the request. - for ($attempt = 0; $attempt < self::DISABLE_POLL_ATTEMPTS; $attempt++) { + // Test disable Rapid Cache, with a bounded wait so that the test + // cannot hang on the long-running operation. + $output = $this->runFunctionSnippet('disable_rapid_cache', [ + $bucketName, + $cacheId, + self::DISABLE_TIMEOUT_MILLIS, + ]); + self::$cacheDisabled = true; + if (str_contains($output, 'Disable operation is still running')) { + // The operation did not finish in time; the cache state must + // already show "disabled". $output = $this->runFunctionSnippet('get_rapid_cache', [ $bucketName, $cacheId, ]); - if (str_contains($output, 'State: disabled')) { - break; - } - if ($attempt < self::DISABLE_POLL_ATTEMPTS - 1) { - sleep(self::DISABLE_POLL_INTERVAL_SECONDS); - } + $this->assertStringContainsString('State: disabled', $output); + } else { + $this->assertStringContainsString(sprintf('Disabled Rapid Cache: %s', $cacheName), $output); } - $this->assertStringContainsString('State: disabled', $output); } }