-
Notifications
You must be signed in to change notification settings - Fork 372
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
feat(storage): support bucket restore in soft delete phase 2 #13894
base: main
Are you sure you want to change the base?
feat(storage): support bucket restore in soft delete phase 2 #13894
Conversation
… related test cases
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.
This is not a full code review by any means, but I'm hoping that this little bit will reduce the number of iterations required after Amanda is back from Thanksgiving.
Ok |
…version for Google.Cloud.Storage.V1 in apis.json
Unassigning myself from review - I'm on vacation until Tuesday. (I expect Amanda will review before then.) |
I'll review today. @mahendra-google if you can rebase on main to remove conflicts, that'd be great, thanks. |
|
|
@amanda-tarafa Storage Samples requires latest package of Google.Cloud.Storage.V1 having properties of GetBucketOptions , ListBucketOptions, RestoreBucketOptions to work sample as expected. So for samples can I proceed with lastest dlls? |
public long? Generation { get; set; } | ||
|
||
/// <summary> | ||
/// (Optional) Set to true to retrieve a soft-deleted bucket .It will return the bucket metadata only if the bucket exists and is in a soft-deleted state. |
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.
Nit while I spot it: the period after the first sentence is in the wrong place.
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.
You need to add unit tests for all the option classes that you modified. See #12060 for examples.
@@ -4967,7 +4967,7 @@ | |||
"description": "Recommended Google client library to access the Google Cloud Storage API. It wraps the Google.Apis.Storage.v1 client library, making common operations simpler in client code. Google Cloud Storage stores and retrieves potentially large, immutable data objects.", | |||
"dependencies": { | |||
"Google.Api.Gax.Rest": "default", | |||
"Google.Apis.Storage.v1": "1.68.0.3431" | |||
"Google.Apis.Storage.v1": "1.68.0.3604" |
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.
This file is now on the generator-input
folder
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.
This comment hasn't been addressed. This file is now in a different location to when you started this PR. That's the source of the conflict that github is signaling.
You need to rebase this PR on the repo's HEAD, and while you are at it, please squash all the commits. We are very keen on keeping a clean history on the repo and commits like "fixing this" or "addressing that" don't help.
@@ -9,8 +9,8 @@ | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="ConfigureAwaitChecker.Analyzer" PrivateAssets="All" /> | |||
<PackageReference Include="Google.Api.Gax.Rest" /> | |||
<PackageReference Include="Google.Apis.Storage.v1" VersionOverride="[1.68.0.3431, 2.0.0.0)" /> | |||
<PackageReference Include="Google.Api.Gax.Rest" VersionOverride="[4.9.0, 5.0.0)" /> |
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.
I don't think we need this.
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.
This comment hasn't been addressed.
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/StorageClientImpl.RestoreBucket.cs
Show resolved
Hide resolved
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/StorageClientImpl.RestoreBucket.cs
Show resolved
Hide resolved
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/StorageClientImpl.RestoreBucket.cs
Show resolved
Hide resolved
|
||
foreach (var bucket in actualBuckets) | ||
{ | ||
// Check if list contains only soft deleted buckets created in storage fixture |
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.
This is not what you are checking here. You are only saying to tests assertions on buckets whose names en with soft-delete.
Ain't there a metadata field indicating that the bucket has been softdeleted?
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.
Before further filtering soft deleted buckets with soft-delete, I have added SoftDeletedOnly metatdata for ListBucketsOptions to check if bucket has been softdeleted or not.
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.
There are several things wrong with this test
- When this test executes there's absolutely no guaratee that you have run a test that has created a soft delete bucket.
- You want to test that setting the SoftDeleteOnly option works, so you cannot rely on it working to test it works (as per your comment: "I have added SoftDeletedOnly metatdata for ListBucketsOptions to check if bucket has been softdeleted or not.")
- You are not testing that only soft-deleted buckets were returned, you are testing that if a bucket whose name ends in "soft-delete" is returned, then: its name is not null, its generation is not null, it has a soft delete time, and a hard delete time. If this test is passing anywhere it's because there's no "soft-deleted" bucket that has been created.
} | ||
catch (Exception) | ||
{ | ||
// If bucket is not empty, we delete on a best effort basis. |
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.
Same comment as in the other test. You won't need this one you create the bucket in the test.
(And also there's an option that can be passed to indicate "delete the bucket and all its contents", so you really wouldn't even need this).
} | ||
await _fixture.Client.DeleteBucketAsync(_fixture.SoftDeleteBucketOne); | ||
} | ||
// We get softDeleted object using get bucket async method for soft deleted bucket. |
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.
You are not getting an object.
Assert.NotNull(bucket.Generation); | ||
Assert.NotNull(softDeleted.Generation); |
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.
I'm not sure what these are meant to be testing, shouldn't you test they are the same value?
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.
Yes I added that here (I was checking that in the second test) also checking that bucket generations before and after delete are not null.
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.
You can remove the null check then.
} | ||
|
||
[Fact] | ||
public async Task GetSoftDeletedBucket() |
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.
What's the difference between this test and the one above? What are the different cases they are testing?
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 above test is for checking generation explicitly and this test is for checking bucket name along with soft delete and hard delete time.
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.
We don't need two tests for that.
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.
I will share design doc let me know so that I will add everything in single test
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.
Yes, everything in a single test please.
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.
Ok I will add in single test
…tsOptions.cs Co-authored-by: Amanda Tarafa Mas <[email protected]>
…tsOptions.cs Co-authored-by: Amanda Tarafa Mas <[email protected]>
…ientImpl.RestoreBucket.cs Co-authored-by: Amanda Tarafa Mas <[email protected]>
@@ -4967,7 +4967,7 @@ | |||
"description": "Recommended Google client library to access the Google Cloud Storage API. It wraps the Google.Apis.Storage.v1 client library, making common operations simpler in client code. Google Cloud Storage stores and retrieves potentially large, immutable data objects.", | |||
"dependencies": { | |||
"Google.Api.Gax.Rest": "default", | |||
"Google.Apis.Storage.v1": "1.68.0.3431" | |||
"Google.Apis.Storage.v1": "1.68.0.3604" |
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.
This comment hasn't been addressed. This file is now in a different location to when you started this PR. That's the source of the conflict that github is signaling.
You need to rebase this PR on the repo's HEAD, and while you are at it, please squash all the commits. We are very keen on keeping a clean history on the repo and commits like "fixing this" or "addressing that" don't help.
@@ -9,8 +9,8 @@ | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="ConfigureAwaitChecker.Analyzer" PrivateAssets="All" /> | |||
<PackageReference Include="Google.Api.Gax.Rest" /> | |||
<PackageReference Include="Google.Apis.Storage.v1" VersionOverride="[1.68.0.3431, 2.0.0.0)" /> | |||
<PackageReference Include="Google.Api.Gax.Rest" VersionOverride="[4.9.0, 5.0.0)" /> |
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.
This comment hasn't been addressed.
{ | ||
ValidateBucketName(bucket); | ||
var request = Service.Buckets.Restore(bucket, generation); | ||
ApplyEncryptionKey(options?.EncryptionKey, kmsNameFromOptions: null, request); |
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.
@JesseLovelace Can you confirm that RestoreBucket supports encryption? I seem to remember this was just for object related operations.
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.
Buckets can have a default encryption key, but that wouldn't be relevant to the restore bucket request. No need to support it as a RestoreBucketOption
var request = Service.Buckets.Restore(bucket, generation); | ||
ApplyEncryptionKey(options?.EncryptionKey, kmsNameFromOptions: null, request); | ||
options?.ModifyRequest(request); | ||
RetryOptions retryOptions = options?.RetryOptions ?? RetryOptions.IdempotentRetryOptions; |
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.
@JesseLovelace can you confirm that RestoreBucket is idempotent and retryable?
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.
Restore Bucket doesn't support the common idempotency params (ifGenerationMatch etc) but it is safely retryable, so it can probably use the same retry handler
/// except for the bucket's access controls. This only affects | ||
/// what information is returned when restoration is successful. | ||
/// </summary> | ||
public Projection? Projection { get; set; } |
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.
Please leave a blank line between one property and the next.
Assert.NotNull(bucket.Generation); | ||
Assert.NotNull(softDeleted.Generation); |
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.
You can remove the null check then.
var softDeleted = await _fixture.Client.GetBucketAsync(softDeleteBucket.Name, new GetBucketOptions { SoftDeleted = true, Generation = bucket.Generation }); | ||
Assert.NotNull(bucket.Generation); | ||
Assert.NotNull(softDeleted.Generation); | ||
Assert.Equal(bucket.Generation, softDeleted.Generation); |
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.
Can you also check that the soft delete timespan is set, that is the real confirmation that this is a soft deleted bucket.
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.
As per design doc I have added soft delete timespan in GetSoftDeletedBucket test. I will share design doc
} | ||
|
||
[Fact] | ||
public async Task GetSoftDeletedBucket() |
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.
We don't need two tests for that.
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1.IntegrationTests/GetBucketTest.cs
Outdated
Show resolved
Hide resolved
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1.Tests/RestoreBucketOptionsTest.cs
Outdated
Show resolved
Hide resolved
…onTests/GetBucketTest.cs Co-authored-by: Amanda Tarafa Mas <[email protected]>
…onTests/ListBucketsTest.cs Co-authored-by: Amanda Tarafa Mas <[email protected]>
…Options.cs Co-authored-by: Amanda Tarafa Mas <[email protected]>
…Options.cs Co-authored-by: Amanda Tarafa Mas <[email protected]>
…toreBucketOptionsTest.cs Co-authored-by: Amanda Tarafa Mas <[email protected]>
[Fact] | ||
public async Task GetBucketGeneration() | ||
{ | ||
var softDeleteBucket = _fixture.CreateBucket(Guid.NewGuid().ToString() + "-soft-delete", false, true); |
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.
Yes, you still need to create the bucket using CreateBucket, but you should generate de bucket name using GenerateBucketName. (here and everywhere)
public async Task GetBucketGeneration() | ||
{ | ||
var softDeleteBucket = _fixture.CreateBucket(Guid.NewGuid().ToString() + "-soft-delete", false, true); | ||
var bucket = await _fixture.Client.GetBucketAsync(softDeleteBucket.Name, new GetBucketOptions { SoftDeleted = false }); |
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.
I'm pretty sure you have the generation already in softDeleteBucket
. The metadata returned on bucket creation should be the same as the one you are obtaining here, as the bucket shouldn't have changed because it's owned by this test.
} | ||
|
||
[Fact] | ||
public async Task GetSoftDeletedBucket() |
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.
Yes, everything in a single test please.
Feature request includes the following:-