-
Notifications
You must be signed in to change notification settings - Fork 0
samples(storage): add samples and test cases for bucket soft delete policy #14
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
base: main
Are you sure you want to change the base?
Changes from all commits
761cac9
4920b0b
6339875
554be98
5e1d4b6
7fc30d5
2cc3446
c4f2702
ebcf624
71d7948
d30994c
b0a7f9e
417fa41
5499151
b0e0b69
09fe7d9
3773bac
2aa53a6
12fc516
12067f3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| // Copyright 2025 Google LLC | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| using Google; | ||
| using System.Net; | ||
| using Xunit; | ||
|
|
||
| [Collection(nameof(StorageFixture))] | ||
| public class BucketDisableSoftDeletePolicyTest | ||
| { | ||
| private readonly StorageFixture _fixture; | ||
|
|
||
| public BucketDisableSoftDeletePolicyTest(StorageFixture fixture) | ||
| { | ||
| _fixture = fixture; | ||
| } | ||
|
|
||
| [Fact] | ||
| public void TestBucketDisableSoftDeletePolicy() | ||
| { | ||
| BucketDisableSoftDeletePolicySample disableSample = new BucketDisableSoftDeletePolicySample(); | ||
| var bucketName = _fixture.GenerateBucketName(); | ||
| var bucketWithDefaultSoftDeletePolicy = _fixture.CreateBucket(bucketName, multiVersion: false, softDelete: true, registerForDeletion: true); | ||
|
|
||
| // Initializing zero with a value 0 indicates the retention duration for the bucket. | ||
| long zero = 0; | ||
| Assert.NotEqual(bucketWithDefaultSoftDeletePolicy.SoftDeletePolicy.RetentionDurationSeconds, zero); | ||
| // Disable soft-delete policy for the bucket. | ||
| var bucketPostDisableSoftDeletePolicy = disableSample.BucketDisableSoftDeletePolicy(bucketName); | ||
| Assert.Equal(bucketPostDisableSoftDeletePolicy.SoftDeletePolicy.RetentionDurationSeconds, zero); | ||
| // After disabling soft-delete policy for the bucket, EffectiveTimeRaw property will be null. | ||
| Assert.Null(bucketPostDisableSoftDeletePolicy.SoftDeletePolicy.EffectiveTimeRaw); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| // Copyright 2025 Google LLC | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| using Newtonsoft.Json; | ||
| using Xunit; | ||
|
|
||
| [Collection(nameof(StorageFixture))] | ||
| public class BucketGetSoftDeletePolicyTest | ||
| { | ||
| private readonly StorageFixture _fixture; | ||
|
|
||
| public BucketGetSoftDeletePolicyTest(StorageFixture fixture) | ||
| { | ||
| _fixture = fixture; | ||
| } | ||
|
|
||
| [Fact] | ||
| public void TestBucketGetSoftDeletePolicy() | ||
| { | ||
| BucketGetSoftDeletePolicySample getSample = new BucketGetSoftDeletePolicySample(); | ||
| var bucketName = _fixture.GenerateBucketName(); | ||
| var bucket = _fixture.CreateBucket(bucketName, multiVersion: false, softDelete: true, registerForDeletion: true); | ||
| var softPolicyData = getSample.BucketGetSoftDeletePolicy(bucketName); | ||
| var bucketSoftDeletePolicy = JsonConvert.SerializeObject(bucket.SoftDeletePolicy); | ||
| var softDeletePolicyData = JsonConvert.SerializeObject(softPolicyData); | ||
| Assert.Equal(bucketSoftDeletePolicy, softDeletePolicyData); | ||
|
Comment on lines
+35
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comparing objects by serializing them to JSON can make tests brittle. For example, a change in property order in the JSON output could break the test, even if the objects are semantically equivalent. It's better to assert the properties of the objects directly. Assert.Equal(bucket.SoftDeletePolicy.RetentionDurationSeconds, softPolicyData.RetentionDurationSeconds);
Assert.Equal(bucket.SoftDeletePolicy.EffectiveTime, softPolicyData.EffectiveTime); |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| // Copyright 2025 Google LLC | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| using System; | ||
| using Xunit; | ||
|
|
||
| [Collection(nameof(StorageFixture))] | ||
| public class BucketSetSoftDeletePolicyTest | ||
| { | ||
| private readonly StorageFixture _fixture; | ||
|
|
||
| public BucketSetSoftDeletePolicyTest(StorageFixture fixture) | ||
| { | ||
| _fixture = fixture; | ||
| } | ||
|
|
||
| [Fact] | ||
| public void TestBucketSetSoftDeletePolicy() | ||
| { | ||
| BucketSetSoftDeletePolicySample setSample = new BucketSetSoftDeletePolicySample(); | ||
| var bucketName = _fixture.GenerateBucketName(); | ||
| var bucketWithDefaultSoftDeletePolicy = _fixture.CreateBucket(bucketName, multiVersion: false, softDelete: true, registerForDeletion: true); | ||
|
|
||
| int retentionDurationInDays = 10; | ||
| long retentionDurationInSeconds = (long) TimeSpan.FromDays(retentionDurationInDays).TotalSeconds; | ||
|
|
||
| Assert.NotEqual(bucketWithDefaultSoftDeletePolicy.SoftDeletePolicy.RetentionDurationSeconds, retentionDurationInSeconds); | ||
|
|
||
| // Set soft-delete policy for the bucket with a retention duration of 10 days. | ||
| var bucketPostSetSoftDeletePolicy = setSample.BucketSetSoftDeletePolicy(bucketName, retentionDurationInDays); | ||
|
|
||
| Assert.Equal(bucketPostSetSoftDeletePolicy.SoftDeletePolicy.RetentionDurationSeconds, retentionDurationInSeconds); | ||
| // After setting soft-delete policy for the bucket, EffectiveTimeRaw property will be not null. | ||
| Assert.NotNull(bucketPostSetSoftDeletePolicy.SoftDeletePolicy.EffectiveTimeRaw); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -92,7 +92,6 @@ public StorageFixture() | |
|
|
||
| public void Dispose() | ||
| { | ||
| DeleteBucketSample deleteBucketSample = new DeleteBucketSample(); | ||
| DeleteFileSample deleteFileSample = new DeleteFileSample(); | ||
| DeleteFileArchivedGenerationSample deleteFileArchivedGenerationSample = new DeleteFileArchivedGenerationSample(); | ||
| foreach (var bucket in TempBucketFiles) | ||
|
|
@@ -132,7 +131,7 @@ public void Dispose() | |
| { | ||
| try | ||
| { | ||
| deleteBucketSample.DeleteBucket(bucketName); | ||
| Client.DeleteBucket(bucketName, new DeleteBucketOptions { DeleteObjects = true }); | ||
| SleepAfterBucketCreateUpdateDelete(); | ||
| } | ||
| catch (Exception) | ||
|
|
@@ -258,6 +257,12 @@ internal Bucket CreateBucket(string name, bool multiVersion, bool softDelete = f | |
| /// <returns>The objectContent.</returns> | ||
| internal string GenerateContent() => Guid.NewGuid().ToString(); | ||
|
|
||
| /// <summary> | ||
| /// Generates a new globally unique identifier (GUID). | ||
| /// </summary> | ||
| /// <returns>A new randomly generated GUID as string.</returns> | ||
| internal string GenerateGuid() => Guid.NewGuid().ToString(); | ||
|
Comment on lines
+260
to
+264
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new method |
||
|
|
||
| /// <summary> | ||
| /// Bucket creation/update/deletion is rate-limited. To avoid making the tests flaky, we sleep after each operation. | ||
| /// </summary> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| // Copyright 2025 Google LLC | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| // [START storage_disable_soft_delete] | ||
|
|
||
| using Google.Apis.Storage.v1.Data; | ||
| using Google.Cloud.Storage.V1; | ||
| using System; | ||
|
|
||
| public class BucketDisableSoftDeletePolicySample | ||
| { | ||
| /// <summary> | ||
| /// Disable soft delete policy for the bucket. | ||
| /// </summary> | ||
| /// <param name="bucketName">The name of the bucket.</param> | ||
| public Bucket BucketDisableSoftDeletePolicy(string bucketName = "your-unique-bucket-name") | ||
| { | ||
| var storage = StorageClient.Create(); | ||
| var bucket = storage.GetBucket(bucketName); | ||
| // To disable soft-delete policy for the bucket, set the soft delete retention duration to 0 seconds. | ||
| bucket.SoftDeletePolicy = new Bucket.SoftDeletePolicyData { RetentionDurationSeconds = 0L }; | ||
| bucket = storage.UpdateBucket(bucket); | ||
| Console.WriteLine($"The Soft Delete Policy for the Bucket (Bucket Name: {bucketName}) is disabled"); | ||
| return bucket; | ||
|
Comment on lines
+29
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current implementation uses A better approach is to use var storage = StorageClient.Create();
var bucket = new Bucket { Name = bucketName, SoftDeletePolicy = new Bucket.SoftDeletePolicyData { RetentionDurationSeconds = 0L } };
bucket = storage.PatchBucket(bucket);
Console.WriteLine($"The Soft Delete Policy for the Bucket (Bucket Name: {bucketName}) is disabled");
return bucket; |
||
| } | ||
| } | ||
| // [END storage_disable_soft_delete] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| // Copyright 2025 Google LLC | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| // [START storage_get_soft_delete_policy] | ||
|
|
||
| using Google.Apis.Storage.v1.Data; | ||
| using Google.Cloud.Storage.V1; | ||
| using System; | ||
|
|
||
| public class BucketGetSoftDeletePolicySample | ||
| { | ||
| /// <summary> | ||
| /// Get soft delete policy of the bucket. | ||
| /// </summary> | ||
| /// <param name="bucketName">The name of the bucket.</param> | ||
| public Bucket.SoftDeletePolicyData BucketGetSoftDeletePolicy(string bucketName = "your-unique-bucket-name") | ||
| { | ||
| var storage = StorageClient.Create(); | ||
| var bucket = storage.GetBucket(bucketName); | ||
| if (bucket.SoftDeletePolicy.RetentionDurationSeconds == 0) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The if (bucket.SoftDeletePolicy is null || bucket.SoftDeletePolicy.RetentionDurationSeconds == 0) |
||
| { | ||
| Console.WriteLine($"The Soft Delete Policy for the Bucket (Bucket Name: {bucketName}) is disabled"); | ||
| } | ||
| else | ||
| { | ||
| int retentionDuration = (int) TimeSpan.FromSeconds((double) bucket.SoftDeletePolicy.RetentionDurationSeconds).TotalDays; | ||
| Console.WriteLine($"The Soft Delete Policy for the Bucket (Bucket Name: {bucketName}) is : {retentionDuration} days"); | ||
| } | ||
| return bucket.SoftDeletePolicy; | ||
| } | ||
| } | ||
| // [END storage_get_soft_delete_policy] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| // Copyright 2025 Google LLC | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| // [START storage_set_soft_delete_policy] | ||
|
|
||
| using Google.Apis.Storage.v1.Data; | ||
| using Google.Cloud.Storage.V1; | ||
| using System; | ||
|
|
||
| public class BucketSetSoftDeletePolicySample | ||
| { | ||
| /// <summary> | ||
| /// Set soft delete policy for the bucket. | ||
| /// </summary> | ||
| /// <param name="bucketName">The name of the bucket.</param> | ||
| /// <param name="retentionDurationInDays">The retention duration in days to set soft-delete policy for the bucket.</param> | ||
| public Bucket BucketSetSoftDeletePolicy(string bucketName = "your-unique-bucket-name", | ||
| int retentionDurationInDays = 10) | ||
| { | ||
| var storage = StorageClient.Create(); | ||
| var bucket = storage.GetBucket(bucketName); | ||
| long retentionDurationInSeconds = (long) TimeSpan.FromDays(retentionDurationInDays).TotalSeconds; | ||
| if (retentionDurationInDays < 7 || retentionDurationInDays > 90) | ||
| { | ||
| // The maximum retention duration you can set is 90 days and the minimum retention duration you can set is 7 days. | ||
| // For more information, please refer to https://cloud.google.com/storage/docs/soft-delete#retention-duration | ||
| Console.WriteLine($"The Soft Delete Policy for the Bucket (Bucket Name: {bucketName}) must have a retention duration between 7 days and 90 days"); | ||
| return bucket; | ||
| } | ||
| bucket.SoftDeletePolicy = new Bucket.SoftDeletePolicyData { RetentionDurationSeconds = retentionDurationInSeconds }; | ||
| bucket = storage.UpdateBucket(bucket); | ||
| Console.WriteLine($"The Soft Delete Policy for the Bucket (Bucket Name: {bucketName}) is set to the {retentionDurationInDays} days retention duration"); | ||
| return bucket; | ||
|
Comment on lines
+31
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method uses Additionally, for invalid input, returning the unmodified bucket object is inefficient as it requires a if (retentionDurationInDays < 7 || retentionDurationInDays > 90)
{
// The maximum retention duration you can set is 90 days and the minimum retention duration you can set is 7 days.
// For more information, please refer to https://cloud.google.com/storage/docs/soft-delete#retention-duration
Console.WriteLine($"The Soft Delete Policy for the Bucket (Bucket Name: {bucketName}) must have a retention duration between 7 days and 90 days");
throw new ArgumentOutOfRangeException(nameof(retentionDurationInDays), "Retention duration must be between 7 and 90 days.");
}
var storage = StorageClient.Create();
long retentionDurationInSeconds = (long) TimeSpan.FromDays(retentionDurationInDays).TotalSeconds;
var bucket = new Bucket { Name = bucketName, SoftDeletePolicy = new Bucket.SoftDeletePolicyData { RetentionDurationSeconds = retentionDurationInSeconds } };
bucket = storage.PatchBucket(bucket);
Console.WriteLine($"The Soft Delete Policy for the Bucket (Bucket Name: {bucketName}) is set to the {retentionDurationInDays} days retention duration");
return bucket; |
||
| } | ||
| } | ||
| // [END storage_set_soft_delete_policy] | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
zerovariable and its preceding comment are unnecessary. You can use the literal0Ldirectly in the assertions for better readability and conciseness. Additionally, it's a common convention in xUnit to have the expected value as the first argument inAssert.EqualandAssert.NotEqual.