Skip to content

Commit b896cd8

Browse files
committed
chore: attempt to add next.js tests
1 parent 4243576 commit b896cd8

File tree

5 files changed

+270
-0
lines changed

5 files changed

+270
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
steps:
2+
3+
- id: 'Delete image and service'
4+
name: 'gcr.io/cloud-builders/gcloud'
5+
entrypoint: '/bin/bash'
6+
args:
7+
- '-c'
8+
- |
9+
./test/retry.sh "gcloud container images describe gcr.io/${PROJECT_ID}/${_SERVICE}:${_VERSION}" \
10+
"gcloud container images delete gcr.io/${PROJECT_ID}/${_SERVICE}:${_VERSION} --quiet"
11+
12+
./test/retry.sh "gcloud run services describe ${_SERVICE} --region ${_REGION} --platform ${_PLATFORM}" \
13+
"gcloud run services delete ${_SERVICE} --region ${_REGION} --platform ${_PLATFORM} --quiet"
14+
15+
substitutions:
16+
_SERVICE: logging-manual
17+
_VERSION: manual
18+
_REGION: us-central1
19+
_PLATFORM: managed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
steps:
2+
3+
- id: 'Build Container Image'
4+
name: 'gcr.io/cloud-builders/docker'
5+
entrypoint: '/bin/bash'
6+
args:
7+
- '-c'
8+
- |
9+
./test/retry.sh "docker build -t gcr.io/${PROJECT_ID}/${_SERVICE}:${_VERSION} ."
10+
11+
- id: 'Push Container Image'
12+
name: 'gcr.io/cloud-builders/docker'
13+
entrypoint: '/bin/bash'
14+
args:
15+
- '-c'
16+
- |
17+
./test/retry.sh "docker push gcr.io/${PROJECT_ID}/${_SERVICE}:${_VERSION}"
18+
19+
- id: 'Deploy to Cloud Run'
20+
name: 'gcr.io/cloud-builders/gcloud:latest'
21+
entrypoint: /bin/bash
22+
args:
23+
- '-c'
24+
- |
25+
./test/retry.sh "gcloud run deploy ${_SERVICE} \
26+
--image gcr.io/${PROJECT_ID}/${_SERVICE}:${_VERSION} \
27+
--no-allow-unauthenticated \
28+
--region ${_REGION} \
29+
--platform ${_PLATFORM} \
30+
--set-env-vars NAME=${_NAME}"
31+
32+
33+
images:
34+
- gcr.io/${PROJECT_ID}/${_SERVICE}:${_VERSION}
35+
36+
substitutions:
37+
_SERVICE: logging-manual
38+
_VERSION: manual
39+
_REGION: us-central1
40+
_PLATFORM: managed
41+
_NAME: Cloud
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import assert from 'assert';
16+
import supertest from 'supertest';
17+
import app from '../index.js';
18+
19+
let request;
20+
describe('Unit Tests', () => {
21+
before(() => {
22+
request = supertest(app);
23+
});
24+
25+
it('Service uses the NAME override', async () => {
26+
process.env.NAME = 'Cloud';
27+
const response = await request.get('/').retry(3).expect(200);
28+
assert.equal(response.text, 'Hello Cloud!');
29+
});
30+
31+
it('Service uses the NAME default', async () => {
32+
process.env.NAME = '';
33+
const response = await request.get('/').retry(3).expect(200);
34+
assert.equal(response.text, 'Hello World!');
35+
});
36+
});

run/nextjs-helloworld/test/retry.sh

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2020 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
##
17+
# retry.sh
18+
# Provides utility function commonly needed across Cloud Build pipelines to
19+
# retry commands on failure.
20+
#
21+
# Usage:
22+
# 1. Retry single command:
23+
#
24+
# ./retry.sh "CMD"
25+
#
26+
# 2. Retry with check:
27+
#
28+
# ./retry.sh "gcloud RESOURCE EXISTS?" "gcloud ACTION"
29+
#
30+
##
31+
32+
# Usage: try "cmd1" "cmd2"
33+
# If first cmd executes successfully then execute second cmd
34+
runIfSuccessful() {
35+
echo "running: $1"
36+
$($1 > /dev/null)
37+
if [ $? -eq 0 ]; then
38+
echo "running: $2"
39+
$($2 > /dev/null)
40+
fi
41+
}
42+
43+
# Define max retries
44+
max_attempts=3;
45+
attempt_num=1;
46+
47+
arg1="$1"
48+
arg2="$2"
49+
50+
if [ $# -eq 1 ]
51+
then
52+
cmd="$arg1"
53+
else
54+
cmd="runIfSuccessful \"$arg1\" \"$arg2\""
55+
fi
56+
57+
until eval $cmd
58+
do
59+
if ((attempt_num==max_attempts))
60+
then
61+
echo "Attempt $attempt_num / $max_attempts failed! No more retries left!"
62+
exit 1
63+
else
64+
echo "Attempt $attempt_num / $max_attempts failed!"
65+
sleep $((attempt_num++))
66+
fi
67+
done
+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import assert from 'assert';
16+
import {execSync} from 'child_process';
17+
import request from 'got';
18+
import {GoogleAuth} from 'google-auth-library';
19+
const auth = new GoogleAuth();
20+
21+
const get = (route, base_url) => {
22+
if (!ID_TOKEN) {
23+
throw Error('"ID_TOKEN" environment variable is required.');
24+
}
25+
26+
return request(new URL(route, base_url.trim()), {
27+
headers: {
28+
Authorization: `${ID_TOKEN.trim()}`,
29+
},
30+
throwHttpErrors: false,
31+
});
32+
};
33+
34+
let BASE_URL, ID_TOKEN;
35+
describe('End-to-End Tests', () => {
36+
const {GOOGLE_CLOUD_PROJECT} = process.env;
37+
if (!GOOGLE_CLOUD_PROJECT) {
38+
throw Error('"GOOGLE_CLOUD_PROJECT" env var not found.');
39+
}
40+
let {SERVICE_NAME} = process.env;
41+
if (!SERVICE_NAME) {
42+
SERVICE_NAME = 'helloworld';
43+
console.log(
44+
`"SERVICE_NAME" env var not found. Defaulting to "${SERVICE_NAME}"`
45+
);
46+
}
47+
let {NAME} = process.env;
48+
if (!NAME) {
49+
NAME = 'Cloud';
50+
console.log(`"NAME" env var not found. Defaulting to "${NAME}"`);
51+
}
52+
const {SAMPLE_VERSION} = process.env;
53+
const PLATFORM = 'managed';
54+
const REGION = 'us-central1';
55+
before(async () => {
56+
// Deploy service using Cloud Build
57+
let buildCmd =
58+
`gcloud builds submit --project ${GOOGLE_CLOUD_PROJECT} ` +
59+
'--config ./test/e2e_test_setup.yaml ' +
60+
`--substitutions _SERVICE=${SERVICE_NAME},_PLATFORM=${PLATFORM},_REGION=${REGION}` +
61+
`,_NAME=${NAME}`;
62+
if (SAMPLE_VERSION) buildCmd += `,_VERSION=${SAMPLE_VERSION}`;
63+
64+
console.log('Starting Cloud Build...');
65+
execSync(buildCmd, {timeout: 240000}); // timeout at 4 mins
66+
console.log('Cloud Build completed.');
67+
68+
// Retrieve URL of Cloud Run service
69+
const url = execSync(
70+
`gcloud run services describe ${SERVICE_NAME} --project=${GOOGLE_CLOUD_PROJECT} ` +
71+
`--platform=${PLATFORM} --region=${REGION} --format='value(status.url)'`
72+
);
73+
74+
BASE_URL = url.toString('utf-8').trim();
75+
if (!BASE_URL) throw Error('Cloud Run service URL not found');
76+
77+
// Retrieve ID token for testing
78+
const client = await auth.getIdTokenClient(BASE_URL);
79+
const clientHeaders = await client.getRequestHeaders();
80+
ID_TOKEN = clientHeaders['Authorization'].trim();
81+
if (!ID_TOKEN) throw Error('Unable to acquire an ID token.');
82+
});
83+
84+
after(() => {
85+
let cleanUpCmd =
86+
`gcloud builds submit --project ${GOOGLE_CLOUD_PROJECT} ` +
87+
'--config ./test/e2e_test_cleanup.yaml ' +
88+
`--substitutions _SERVICE=${SERVICE_NAME},_PLATFORM=${PLATFORM},_REGION=${REGION}`;
89+
if (SAMPLE_VERSION) cleanUpCmd += `,_VERSION=${SAMPLE_VERSION}`;
90+
91+
execSync(cleanUpCmd);
92+
});
93+
94+
it('Service uses the NAME override', async () => {
95+
const response = await get('/', BASE_URL);
96+
assert.strictEqual(
97+
response.statusCode,
98+
200,
99+
'Did not fallback to default as expected'
100+
);
101+
assert.strictEqual(
102+
response.body,
103+
`Hello ${NAME}!`,
104+
`Expected override "${NAME}" not found`
105+
);
106+
});
107+
});

0 commit comments

Comments
 (0)