-
Notifications
You must be signed in to change notification settings - Fork 377
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
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 |
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? |
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/GetBucketOptions.cs
Outdated
Show resolved
Hide resolved
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.
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1.csproj
Outdated
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
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.IntegrationTests/ListBucketsTest.cs
Outdated
Show resolved
Hide resolved
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.IntegrationTests/GetBucketTest.cs
Outdated
Show resolved
Hide resolved
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.IntegrationTests/GetBucketTest.cs
Outdated
Show resolved
Hide resolved
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1.csproj
Outdated
Show resolved
Hide resolved
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/StorageClientImpl.RestoreBucket.cs
Outdated
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/RestoreBucketOptions.cs
Show resolved
Hide resolved
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.IntegrationTests/GetBucketTest.cs
Outdated
Show resolved
Hide resolved
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.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
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.IntegrationTests/GetBucketTest.cs
Outdated
Show resolved
Hide resolved
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1.IntegrationTests/GetBucketTest.cs
Outdated
Show resolved
Hide resolved
cb1650a
to
db71efc
Compare
|
…ly.github.com> Co-authored-by: Amanda Tarafa Mas <14878252+amanda-tarafa@users.noreply.github.com> modified: generator-input/apis.json
…val of package version override
0957b16
to
7efe472
Compare
This is ready for a re-review @amanda-tarafa |
Thanks, I'll do a pass tomorrow. |
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.
Almost there, thanks!
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/RestoreBucketOptions.cs
Outdated
Show resolved
Hide resolved
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1.csproj
Show resolved
Hide resolved
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1.IntegrationTests/RestoreBucketTest.cs
Outdated
Show resolved
Hide resolved
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1.Tests/ListBucketsOptionsTest.cs
Outdated
Show resolved
Hide resolved
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1.IntegrationTests/ListBucketsTest.cs
Outdated
Show resolved
Hide resolved
foreach (var bucket in actualBuckets) | ||
{ // Verify if the bucket is soft-deleted only | ||
Assert.NotNull(bucket.Generation); | ||
Assert.NotNull(bucket.SoftDeleteTimeDateTimeOffset); | ||
Assert.NotNull(bucket.HardDeleteTimeDateTimeOffset); | ||
|
||
if (bucket.Name == softDeleteBucket.Name) | ||
{ // Compare the generation number | ||
Assert.Equal(bucket.Generation, softDeleteBucket.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.
Please use Assert.All and Assert.Contains instead of a loop here.
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.
@amanda-tarafa Is it not working as expected ? because these changes are approved by My team's silver language leads using the Internal PR review approval process.
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 different ways to achieve the same result, some are clearer than others. Please use Assert.All and Asssert.Contains.
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.
Actually, is not only about clarity, this test is not sufficient as it is. It will pass even if actualBuckets
is empty or if it does not contains softDeleteBucket
. Using Assert.All and Assert.Contains will make the test sufficient.
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.
@amanda-tarafa If actualBuckets
is made empty (actualBuckets = new List<Bucket>();
), count will be zero , it will not go inside foreach loop , So it will not pass , I would rather say it will skip assert. Let me know your thoughts on 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.
@amanda-tarafa On the same lines , if I don't create a soft delete bucket in test itself (which I already created if I remove that piece of code of creation of soft delete bucket ) and hypothetically assuming storage fixture has also not created any soft delete bucket in any other tests , According to me in that case also actualBuckets
count will be zero and it will not go inside loop. So it will skip asserts. Does that mean test should fail rather skip ?
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.
A test that executes no asserts, assuming there are no exceptions (none in this case), is a passing test, it's not a skipped test. A passing test indicates that the feature has been tested and everything is working as expected, whereas a skipped test indicates that nothing was tested. This test is wrong because it may pass even when nothing is tested.
Explicitly, if there is a bug in production code that has the effect of the list returning empty (even when you have just created a soft deleted bucket), this test will pass, when it shouldn't have. That's because this test is saying:
- Create a soft deleted bucket (correct, we guarantee there's at least one soft deleted bucket so we can test).
- Fetch soft deleted buckets (the feature we want to test).
- If there happens to be elements in the list, make sure they are all soft deleted. (hmm, if the feature we want to test is broken so that the list is empty, then we really don't test anything and we don't find out the feature is broken)
- If the recently created bucket happens to be on the list, make sure all its fields have the expected values and that it is indeed soft deleted. (hmm, if the feature we want to test is broken so that the list is empty, then we really don't test anything and we don't find out the feature is broken)
The key being the "if it happens" where a test needs to make certain "it happened", no ifs and no buts.
What this test needs to do is:
- Create a soft deleted bucket
- Fetch soft deleted buckets
- Make sure the recently created bucket is on the list, and all its fields have the expected values.
- Make sure all the elements on the list are indeed soft deleted. Apart from the test own bucket, these may be buckets created by the fixture or by other tests, we don't care if there are none of these, or many, because we don't care about the order in which tests execute. The only thing that we care is that all tests in the list are soft deleted because that's the feature we are testing.
See those two last points describing the correct test, how they very naturally transalate to:
- Assert.Contains recently created bucket with the right fields.
- Assert.All are soft deletede buckets
You can certainly express the same semantic with a loop and some checks, but, it's way less naturally readable plus, errors like the one currently in this test are harder to spot and harder to explain, as this very thread demonstrates. Using the right assert statements makes the tests robust and correct more easily, plus way clearer.
Please fix.
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.
Thanks for the elaborated reply it clears some of my doubts about the test as well especially the production bug scenario.
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1/GetBucketOptions.cs
Outdated
Show resolved
Hide resolved
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1.Tests/GetBucketOptionsTest.cs
Outdated
Show resolved
Hide resolved
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1.Tests/GetBucketOptionsTest.cs
Outdated
Show resolved
Hide resolved
apis/Google.Cloud.Storage.V1/Google.Cloud.Storage.V1.IntegrationTests/GetBucketTest.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: Amanda Tarafa Mas <14878252+amanda-tarafa@users.noreply.github.com>
…BucketOptionsTest.cs Co-authored-by: Amanda Tarafa Mas <14878252+amanda-tarafa@users.noreply.github.com>
…Options.cs Co-authored-by: Amanda Tarafa Mas <14878252+amanda-tarafa@users.noreply.github.com>
…tBucketsOptionsTest.cs Co-authored-by: Amanda Tarafa Mas <14878252+amanda-tarafa@users.noreply.github.com>
foreach (var bucket in actualBuckets) | ||
{ // Verify if the bucket is soft-deleted only | ||
Assert.NotNull(bucket.Generation); | ||
Assert.NotNull(bucket.SoftDeleteTimeDateTimeOffset); | ||
Assert.NotNull(bucket.HardDeleteTimeDateTimeOffset); | ||
|
||
if (bucket.Name == softDeleteBucket.Name) | ||
{ // Compare the generation number | ||
Assert.Equal(bucket.Generation, softDeleteBucket.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.
There are different ways to achieve the same result, some are clearer than others. Please use Assert.All and Asssert.Contains.
foreach (var bucket in actualBuckets) | ||
{ // Verify if the bucket is soft-deleted only | ||
Assert.NotNull(bucket.Generation); | ||
Assert.NotNull(bucket.SoftDeleteTimeDateTimeOffset); | ||
Assert.NotNull(bucket.HardDeleteTimeDateTimeOffset); | ||
|
||
if (bucket.Name == softDeleteBucket.Name) | ||
{ // Compare the generation number | ||
Assert.Equal(bucket.Generation, softDeleteBucket.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.
Actually, is not only about clarity, this test is not sufficient as it is. It will pass even if actualBuckets
is empty or if it does not contains softDeleteBucket
. Using Assert.All and Assert.Contains will make the test sufficient.
foreach (var bucket in actualBuckets) | ||
{ // Verify if the bucket is soft-deleted only | ||
Assert.NotNull(bucket.Generation); | ||
Assert.NotNull(bucket.SoftDeleteTimeDateTimeOffset); | ||
Assert.NotNull(bucket.HardDeleteTimeDateTimeOffset); | ||
|
||
if (bucket.Name == softDeleteBucket.Name) | ||
{ // Compare the generation number | ||
Assert.Equal(bucket.Generation, softDeleteBucket.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.
A test that executes no asserts, assuming there are no exceptions (none in this case), is a passing test, it's not a skipped test. A passing test indicates that the feature has been tested and everything is working as expected, whereas a skipped test indicates that nothing was tested. This test is wrong because it may pass even when nothing is tested.
Explicitly, if there is a bug in production code that has the effect of the list returning empty (even when you have just created a soft deleted bucket), this test will pass, when it shouldn't have. That's because this test is saying:
- Create a soft deleted bucket (correct, we guarantee there's at least one soft deleted bucket so we can test).
- Fetch soft deleted buckets (the feature we want to test).
- If there happens to be elements in the list, make sure they are all soft deleted. (hmm, if the feature we want to test is broken so that the list is empty, then we really don't test anything and we don't find out the feature is broken)
- If the recently created bucket happens to be on the list, make sure all its fields have the expected values and that it is indeed soft deleted. (hmm, if the feature we want to test is broken so that the list is empty, then we really don't test anything and we don't find out the feature is broken)
The key being the "if it happens" where a test needs to make certain "it happened", no ifs and no buts.
What this test needs to do is:
- Create a soft deleted bucket
- Fetch soft deleted buckets
- Make sure the recently created bucket is on the list, and all its fields have the expected values.
- Make sure all the elements on the list are indeed soft deleted. Apart from the test own bucket, these may be buckets created by the fixture or by other tests, we don't care if there are none of these, or many, because we don't care about the order in which tests execute. The only thing that we care is that all tests in the list are soft deleted because that's the feature we are testing.
See those two last points describing the correct test, how they very naturally transalate to:
- Assert.Contains recently created bucket with the right fields.
- Assert.All are soft deletede buckets
You can certainly express the same semantic with a loop and some checks, but, it's way less naturally readable plus, errors like the one currently in this test are harder to spot and harder to explain, as this very thread demonstrates. Using the right assert statements makes the tests robust and correct more easily, plus way clearer.
Please fix.
@mahendra-google Do let me know here when this is ready for review again. No rush on my part, but just know I won't review until you have said so here. Thanks! |
|
That's perfect, thanks! |
Feature request includes the following:-