-
Notifications
You must be signed in to change notification settings - Fork 29
/
system.ts
162 lines (149 loc) · 4.73 KB
/
system.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/**
* Copyright 2018 Google LLC
*
* Distributed under MIT license.
* See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
import * as assert from 'assert';
import {before, after, describe, it} from 'mocha';
import * as fs from 'fs';
import * as gcbuild from 'gcbuild';
import * as gcx from 'gcx';
import {cloudfunctions_v1, google} from 'googleapis';
import * as path from 'path';
import {promisify} from 'util';
import * as uuid from 'uuid';
import {execSync} from 'child_process';
import {request, GaxiosError, Gaxios} from 'gaxios';
const copy = promisify(fs.copyFile);
const pkg = require('../../package.json'); // eslint-disable-line
let gcf: cloudfunctions_v1.Cloudfunctions;
const shortPrefix = 'gcloud-tests';
const fullPrefix = `${shortPrefix}-${uuid.v4().split('-')[0]}`;
describe('gcp metadata', () => {
before(async () => {
// pack up the gcp-metadata module and copy to the target dir
await packModule();
});
describe('cloud functions', () => {
before(async () => {
// Clean up any old cloud functions just hanging out
gcf = await getGCFClient();
await pruneFunctions(false);
// deploy the function to GCF
await deployApp();
});
it('should access the metadata service on GCF', async () => {
const projectId = await google.auth.getProjectId();
const url = `https://us-central1-${projectId}.cloudfunctions.net/${fullPrefix}`;
try {
const res = await request({url});
// tslint:disable-next-line no-any
const metadata = res.data as any;
console.log(metadata);
assert.strictEqual(metadata.isAvailable, true);
} catch (e) {
console.error((e as GaxiosError).response!.data);
assert.fail('Request to the deployed cloud function failed.');
}
});
after(() => pruneFunctions(true));
});
describe('cloud build', () => {
it('should access the metadata service on GCB', async () => {
try {
const result = await gcbuild.build({
sourcePath: path.join(
__dirname,
'../../system-test/fixtures/cloudbuild'
),
});
console.log(result.log);
assert.ok(/isAvailable: true/.test(result.log));
assert.ok(
result.log.includes('"default":{"aliases":["default"],"email"')
);
} catch (e) {
console.error(e.log);
throw e;
}
});
});
});
/**
* Create a new GCF client using googleapis, and ensure it's
* properly authenticated.
*/
async function getGCFClient() {
const auth = new google.auth.GoogleAuth({
scopes: 'https://www.googleapis.com/auth/cloud-platform',
});
const client = await auth.getClient();
return google.cloudfunctions({
version: 'v1',
auth: client,
});
}
/**
* Delete all cloud functions created in the project by this
* test suite. It can delete ones created in this session, and
* also delete any of them created > 7 days ago by tests.
* @param sessionOnly Only prune functions created in this session.
*/
async function pruneFunctions(sessionOnly: boolean) {
console.log('Pruning leaked functions...');
const projectId = await google.auth.getProjectId();
const res = await gcf.projects.locations.functions.list({
parent: `projects/${projectId}/locations/-`,
});
const fns = res.data.functions || [];
await Promise.all(
fns
.filter(fn => {
if (sessionOnly) {
return fn.name!.includes(fullPrefix);
}
const updateDate = new Date(fn.updateTime!).getTime();
const currentDate = Date.now();
const minutesSinceUpdate = (currentDate - updateDate) / 1000 / 60;
return minutesSinceUpdate > 60 && fn.name!.includes(shortPrefix);
})
.map(async fn => {
await gcf.projects.locations.functions
.delete({name: fn.name as string})
.catch(e => {
console.error(`There was a problem deleting function ${fn.name}.`);
console.error(e);
});
})
);
}
/**
* Deploy the hook app to GCF.
*/
async function deployApp() {
const targetDir = path.join(__dirname, '../../system-test/fixtures/hook');
await gcx.deploy({
name: fullPrefix,
entryPoint: 'getMetadata',
triggerHTTP: true,
runtime: 'nodejs8',
region: 'us-central1',
targetDir,
});
}
/**
* Runs `npm pack` on the root directory, and copies the resulting
* `gcp-metadata.tgz` over to the target directories in fixtures.
*/
async function packModule() {
execSync('npm pack', {stdio: 'inherit'});
const from = `${pkg.name}-${pkg.version}.tgz`;
const targets = ['hook', 'cloudbuild'];
await Promise.all(
targets.map(target => {
const to = `system-test/fixtures/${target}/${pkg.name}.tgz`;
return copy(from, to);
})
);
}