Skip to content

Commit 1e52d3e

Browse files
authored
Adds v2 test lab triggers (#1017)
* converting test lab samples to v2 * replacing functions config with secrets
1 parent cc56467 commit 1e52d3e

File tree

10 files changed

+303
-0
lines changed

10 files changed

+303
-0
lines changed

2nd-gen/test-complete/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Log test complete
2+
3+
This sample demonstrates how to trigger a function in response to the
4+
completion of a Test Matrix in Firebase Test Lab.
5+
6+
## Setting up the sample
7+
8+
1. Clone or download this repo and open the `2nd-gen/test-complete`
9+
directory.
10+
1. You must have the Firebase CLI installed. If you don't have it install it
11+
with `npm install -g firebase-tools` and then configure it with
12+
`firebase login`.
13+
1. Configure the CLI locally by using `firebase use --add` and select your
14+
project in the list.
15+
1. Install Cloud Functions dependencies locally by running:
16+
`cd functions; npm install; cd -`
17+
18+
## Deploy and test
19+
20+
1. Deploy your function using `firebase deploy --only functions`
21+
1. Navigate to the
22+
[Test Lab](https://console.firebase.google.com/u/0/project/_/testlab/histories)
23+
section of the Firebase Console and start a test.
24+
1. Once the test finishes running,
25+
[view the functions logs](https://console.firebase.google.com/u/0/project/_/functions/logs?severity=DEBUG)
26+
for your project, and check that the test run status was logged.
27+
28+
## Next Steps
29+
30+
To see how to post to Slack instead of just `console.log`-ing, check out
31+
[this sample](https://github.com/firebase/functions-samples/tree/main/2nd-gen/testlab-to-slack).

2nd-gen/test-complete/firebase.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module.exports = {
2+
root: true,
3+
env: {
4+
es6: true,
5+
node: true,
6+
},
7+
extends: [
8+
"eslint:recommended",
9+
"google",
10+
],
11+
rules: {
12+
quotes: ["error", "double"],
13+
},
14+
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Copyright 2022 Google Inc. All Rights Reserved.
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+
'use strict';
17+
18+
// [START all]
19+
// [START import]
20+
// The Cloud Functions for Firebase SDK to create v2 Cloud Functions and set up triggers.
21+
const { onTestMatrixCompleted } = require('firebase-functions/v2/testLab');
22+
const { logger } = require('firebase-functions');
23+
// [END import]
24+
25+
// [START logtestcomplete]
26+
exports.logtestcomplete = onTestMatrixCompleted((event) => {
27+
// Obtain Test Matrix properties from the CloudEvent
28+
const { testMatrixId, createTime, state, outcomeSummary } = event.data;
29+
30+
// Log the properties of the completed Test Matrix
31+
logger.log(
32+
`TEST ${testMatrixId} (created at ${createTime}): ${state}. ${
33+
outcomeSummary || ''
34+
}`
35+
);
36+
});
37+
// [END logtestcomplete]
38+
// [END all]
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "functions",
3+
"description": "Cloud Functions for Firebase",
4+
"scripts": {
5+
"lint": "eslint .",
6+
"serve": "firebase emulators:start --only functions",
7+
"shell": "firebase functions:shell",
8+
"start": "npm run shell",
9+
"deploy": "firebase deploy --only functions",
10+
"logs": "firebase functions:log",
11+
"compile": "cp ../../../tsconfig.template.json ./tsconfig-compile.json && tsc --project tsconfig-compile.json"
12+
},
13+
"engines": {
14+
"node": "16"
15+
},
16+
"dependencies": {
17+
"firebase-admin": "^10.2.0",
18+
"firebase-functions": "^4.0.0"
19+
},
20+
"devDependencies": {
21+
"eslint": "^6.8.0",
22+
"eslint-plugin-promise": "^4.2.1",
23+
"firebase-functions-test": "^2.0.0"
24+
},
25+
"private": true
26+
}

2nd-gen/testlab-to-slack/README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Post Test Lab Results to Slack channel
2+
3+
This sample demonstrates how to post to a Slack channel in response to the
4+
completion of a Test Matrix in Firebase Test Lab. The message will look like
5+
this:
6+
7+
![example Slack message with Test Lab status](https://i.imgur.com/9DTL19x.png)
8+
9+
## Setting up the sample
10+
11+
1. [Add an **Incoming Webhook**](https://my.slack.com/services/new/incoming-webhook/) to your Slack channel and take note of the **Webhook URL**.
12+
1. Clone or download this repo and open this directory in a terminal:
13+
14+
```shell
15+
cd 2nd-gen/testlab-to-slack
16+
```
17+
18+
1. You must have the latest Firebase CLI installed. If you don't have it,
19+
install it with `npm install -g firebase-tools` and then sign in with
20+
`firebase login`.
21+
1. Configure the CLI locally by using `firebase use --add` and select your
22+
project in the list.
23+
1. Install Cloud Functions dependencies locally by running:
24+
`cd functions; npm install; cd -`
25+
1. Set the following environment variables so that the function can
26+
authenticate with Slack and post to the correct room:
27+
28+
```bash
29+
firebase functions:secrets:set SLACK_WEBHOOK_URL
30+
```
31+
32+
Enter the value of your Slack url to save it into Secret Manager.
33+
34+
## Deploy and test
35+
36+
This sample comes with a web-based UI for testing the function. To test it out:
37+
38+
1. Deploy your function using `firebase deploy --only functions`
39+
1. Navigate to the
40+
[Test Lab](https://console.firebase.google.com/u/0/project/_/testlab/histories)
41+
section of the Firebase Console and start a test.
42+
1. Once the test finishes running, check your Slack channel and view the new
43+
post!
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module.exports = {
2+
root: true,
3+
env: {
4+
es6: true,
5+
node: true,
6+
},
7+
extends: [
8+
"eslint:recommended",
9+
"google",
10+
],
11+
rules: {
12+
quotes: ["error", "double"],
13+
},
14+
};
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/**
2+
* Copyright 2022 Google Inc. All Rights Reserved.
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+
'use strict';
17+
18+
// [START all]
19+
// [START import]
20+
// The Cloud Functions for Firebase SDK to create v2 Cloud Functions and set up triggers.
21+
const { onTestMatrixCompleted } = require('firebase-functions/v2/testLab');
22+
const { logger } = require('firebase-functions');
23+
// The Axios client to send web requests to Slack.
24+
const axios = require('axios');
25+
// [END import]
26+
27+
// [START postToSlack]
28+
function postToSlack(title, details) {
29+
return axios.post(
30+
process.env.SLACK_WEBHOOK_URL,
31+
{
32+
blocks: [
33+
{
34+
type: 'section',
35+
text: {
36+
type: 'mrkdwn',
37+
text: title
38+
}
39+
},
40+
{
41+
type: 'divider'
42+
},
43+
{
44+
type: 'section',
45+
text: {
46+
type: 'mrkdwn',
47+
text: details
48+
}
49+
}
50+
]
51+
}
52+
);
53+
}
54+
// [END postToSlack]
55+
56+
// [START getSlackmoji]
57+
function getSlackmoji(term) {
58+
switch (term) {
59+
case 'SUCCESS':
60+
return ':tada:';
61+
case 'FAILURE':
62+
return ':broken_heart:';
63+
case 'INCONCLUSIVE':
64+
return ':question:';
65+
case 'SKIPPED':
66+
return ':arrow_heading_down:';
67+
case 'VALIDATING':
68+
return ':thought_balloon:';
69+
case 'PENDING':
70+
return ':soon:';
71+
case 'FINISHED':
72+
return ':white_check_mark:';
73+
case 'ERROR':
74+
return ':red_circle:';
75+
case 'INVALID':
76+
return ':large_orange_diamond:';
77+
default:
78+
return '';
79+
}
80+
}
81+
// [END getSlackmoji]
82+
83+
// [START posttestresultstoslack]
84+
exports.posttestresultstoslack = onTestMatrixCompleted(
85+
{ secrets: ["SLACK_WEBHOOK_URL"] },
86+
async (event) => {
87+
// Obtain Test Matrix properties from the CloudEvent
88+
const { testMatrixId, state, outcomeSummary } = event.data;
89+
90+
// Create the title of the message
91+
const title = `${getSlackmoji(state)} ${getSlackmoji(
92+
outcomeSummary
93+
)} ${testMatrixId}`;
94+
95+
// Create the details of the message
96+
const details = `Status: *${state}* ${getSlackmoji(
97+
state
98+
)}\nOutcome: *${outcomeSummary}* ${getSlackmoji(outcomeSummary)}
99+
`;
100+
101+
// Post the message to slack
102+
const slackResponse = await postToSlack(title, details);
103+
104+
// Log the response
105+
logger.log(JSON.stringify(slackResponse.data));
106+
});
107+
// [END posttestresultstoslack]
108+
// [END all]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "functions",
3+
"description": "Cloud Functions for Firebase",
4+
"scripts": {
5+
"lint": "eslint .",
6+
"serve": "firebase emulators:start --only functions",
7+
"shell": "firebase functions:shell",
8+
"start": "npm run shell",
9+
"deploy": "firebase deploy --only functions",
10+
"logs": "firebase functions:log",
11+
"compile": "cp ../../tsconfig.template.json ./tsconfig-compile.json && tsc --project tsconfig-compile.json"
12+
},
13+
"engines": {
14+
"node": "16"
15+
},
16+
"dependencies": {
17+
"axios": "^0.19.2",
18+
"firebase-admin": "^10.2.0",
19+
"firebase-functions": "^4.0.0"
20+
},
21+
"devDependencies": {
22+
"firebase-functions-test": "^2.0.0",
23+
"eslint": "^6.8.0",
24+
"eslint-plugin-promise": "^4.2.1"
25+
},
26+
"private": true
27+
}

0 commit comments

Comments
 (0)