Skip to content

Commit 86d0b81

Browse files
authored
test: improvements to requester pays tests and bucket metadata updates (#2414)
* test: improvements to requester pays tests and bucket metadata updates test: improvements to requester pays tests and bucket metadata updates * remove console.log statements * adjust wait time slightly * add retries to failed tests
1 parent 55ff53b commit 86d0b81

File tree

1 file changed

+60
-68
lines changed

1 file changed

+60
-68
lines changed

system-test/storage.ts

Lines changed: 60 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,18 @@ const RUNNING_IN_VPCSC = !!process.env['GOOGLE_CLOUD_TESTS_IN_VPCSC'];
6060

6161
const UNIFORM_ACCESS_TIMEOUT = 60 * 1000; // 60s see: https://cloud.google.com/storage/docs/consistency#eventually_consistent_operations
6262
const UNIFORM_ACCESS_WAIT_TIME = 5 * 1000; // 5s
63-
const BUCKET_METADATA_UPDATE_WAIT_TIME = 1000; // 1s buckets have a max rate of one metadata update per second.
63+
const BUCKET_METADATA_UPDATE_WAIT_TIME = 1250; // 1.25s buckets have a max rate of one metadata update per second.
6464

6565
// block all attempts to chat with the metadata server (kokoro runs on GCE)
6666
nock('http://metadata.google.internal')
6767
.get(() => true)
6868
.replyWithError({code: 'ENOTFOUND'})
6969
.persist();
7070

71-
describe('storage', () => {
71+
// eslint-disable-next-line prefer-arrow-callback
72+
describe('storage', function () {
73+
this.retries(3);
74+
7275
const USER_ACCOUNT = '[email protected]';
7376
const TESTS_PREFIX = `storage-tests-${shortUUID()}-`;
7477
const RETENTION_DURATION_SECONDS = 10;
@@ -110,23 +113,18 @@ describe('storage', () => {
110113
},
111114
};
112115

113-
before(() => {
114-
return bucket
115-
.create()
116-
.then(() => {
117-
return pubsub.createTopic(generateName());
118-
})
119-
.then(data => {
120-
topic = data[0];
121-
return topic.iam.setPolicy({
122-
bindings: [
123-
{
124-
role: 'roles/pubsub.editor',
125-
members: ['allUsers'],
126-
},
127-
],
128-
});
129-
});
116+
before(async () => {
117+
await bucket.create();
118+
const data = await pubsub.createTopic(generateName());
119+
topic = data[0];
120+
await topic.iam.setPolicy({
121+
bindings: [
122+
{
123+
role: 'roles/pubsub.editor',
124+
members: ['allUsers'],
125+
},
126+
],
127+
});
130128
});
131129

132130
after(() => {
@@ -231,8 +229,10 @@ describe('storage', () => {
231229
describe('buckets', () => {
232230
// Some bucket update operations have a rate limit.
233231
// Introduce a delay between tests to avoid getting an error.
234-
beforeEach(done => {
235-
setTimeout(done, 1000);
232+
beforeEach(async () => {
233+
await new Promise(resolve =>
234+
setTimeout(resolve, BUCKET_METADATA_UPDATE_WAIT_TIME)
235+
);
236236
});
237237

238238
it('should get access controls', async () => {
@@ -296,6 +296,9 @@ describe('storage', () => {
296296
entity: 'allUsers',
297297
role: 'READER',
298298
});
299+
await new Promise(resolve =>
300+
setTimeout(resolve, BUCKET_METADATA_UPDATE_WAIT_TIME)
301+
);
299302
await bucket.acl.delete({entity: 'allUsers'});
300303
});
301304

@@ -319,6 +322,9 @@ describe('storage', () => {
319322
it('should make a bucket private', async () => {
320323
try {
321324
await bucket.makePublic();
325+
await new Promise(resolve =>
326+
setTimeout(resolve, BUCKET_METADATA_UPDATE_WAIT_TIME)
327+
);
322328
await bucket.makePrivate();
323329
assert.rejects(bucket.acl.get({entity: 'allUsers'}), err => {
324330
assert.strictEqual((err as ApiError).code, 404);
@@ -1727,40 +1733,31 @@ describe('storage', () => {
17271733
//
17281734
// - file.save()
17291735
// -> file.createWriteStream()
1730-
before(() => {
1736+
before(async () => {
17311737
file = bucketNonAllowList.file(generateName());
17321738

1733-
return bucket
1734-
.enableRequesterPays()
1735-
.then(() => bucket.iam.getPolicy())
1736-
.then(data => {
1737-
const policy = data[0];
1738-
1739-
// Allow an absolute or relative path (from project root)
1740-
// for the key file.
1741-
let key2 = process.env.GCN_STORAGE_2ND_PROJECT_KEY;
1742-
if (key2 && key2.charAt(0) === '.') {
1743-
key2 = `${getDirName()}/../../../${key2}`;
1744-
}
1745-
1746-
// Get the service account for the "second" account (the
1747-
// one that will read the requester pays file).
1748-
const clientEmail = JSON.parse(
1749-
fs.readFileSync(key2!, 'utf-8')
1750-
).client_email;
1751-
1752-
policy.bindings.push({
1753-
role: 'roles/storage.admin',
1754-
members: [`serviceAccount:${clientEmail}`],
1755-
});
1756-
1757-
return bucket.iam.setPolicy(policy);
1758-
})
1759-
.then(() => file.save('abc', USER_PROJECT_OPTIONS))
1760-
.then(() => topic.getMetadata())
1761-
.then(data => {
1762-
topicName = data[0].name!;
1763-
});
1739+
await bucket.enableRequesterPays();
1740+
const data = await bucket.iam.getPolicy();
1741+
const policy = data[0];
1742+
// Allow an absolute or relative path (from project root)
1743+
// for the key file.
1744+
let key2 = process.env.GCN_STORAGE_2ND_PROJECT_KEY;
1745+
if (key2 && key2.charAt(0) === '.') {
1746+
key2 = `${getDirName()}/../../../${key2}`;
1747+
}
1748+
// Get the service account for the "second" account (the
1749+
// one that will read the requester pays file).
1750+
const clientEmail = JSON.parse(
1751+
fs.readFileSync(key2!, 'utf-8')
1752+
).client_email;
1753+
policy.bindings.push({
1754+
role: 'roles/storage.admin',
1755+
members: [`serviceAccount:${clientEmail}`],
1756+
});
1757+
await bucket.iam.setPolicy(policy);
1758+
await file.save('abc', USER_PROJECT_OPTIONS);
1759+
const data_2 = await topic.getMetadata();
1760+
topicName = data_2[0].name!;
17641761
});
17651762

17661763
// This acts as a test for the following methods:
@@ -1788,7 +1785,7 @@ describe('storage', () => {
17881785
type requesterPaysFunction<
17891786
T = {} | typeof USER_PROJECT_OPTIONS,
17901787
R = {} | void,
1791-
> = (options: T) => Promise<R>;
1788+
> = (options?: T) => Promise<R>;
17921789

17931790
/**
17941791
* Accepts a function and runs 2 tests - a test where the requester pays
@@ -1805,20 +1802,15 @@ describe('storage', () => {
18051802
const failureMessage =
18061803
'Bucket is a requester pays bucket but no user project provided.';
18071804

1808-
let expectedError: unknown = null;
1809-
1810-
try {
1811-
// Should raise an error on requester pays bucket
1812-
await testFunction({});
1813-
} catch (e) {
1814-
expectedError = e;
1815-
}
1816-
1817-
assert(expectedError instanceof Error);
1818-
assert(
1819-
expectedError.message.includes(failureMessage),
1820-
`Expected '${expectedError.message}' to include '${failureMessage}'`
1821-
);
1805+
await assert.rejects(testFunction(), err => {
1806+
assert(
1807+
(err as Error).message.includes(failureMessage),
1808+
`Expected '${
1809+
(err as Error).message
1810+
}' to include '${failureMessage}'`
1811+
);
1812+
return true;
1813+
});
18221814

18231815
// Validate the desired functionality
18241816
const results = await testFunction(USER_PROJECT_OPTIONS);

0 commit comments

Comments
 (0)