Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions run/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

| Sample | Description | Deploy |
| --------------------------------------- | ------------------------ | ------------- |
|[Hello World][helloworld]&nbsp;&#10149; | Quickstart | [<img src="https://storage.googleapis.com/cloudrun/button.svg" alt="Run on Google Cloud" height="30">][run_button_helloworld] |
| [Image Processing][image_processing] | Event-driven image analysis & transformation | [<img src="https://storage.googleapis.com/cloudrun/button.svg" alt="Run on Google Cloud" height="30">][run_button_image_processing] |
|[Manual Logging][manual_logging] | Structured logging without client library | [<img src="https://storage.googleapis.com/cloudrun/button.svg" alt="Run on Google Cloud" height="30">][run_button_manual_logging] |
|[Pub/Sub][pubsub] | Event-driven service with a Pub/Sub push subscription | [<img src="https://storage.googleapis.com/cloudrun/button.svg" alt="Run on Google Cloud" height="30">][run_button_pubsub] |
|[Hello World][helloworld]&nbsp;&#10149; | Quickstart | [<img src="https://storage.googleapis.com/cloudrun/button.svg" alt="Run on Google Cloud" height="30"/>][run_button_helloworld] |
|[Hello Broken][hello_broken] | Something is wrong, how do you fix it? | [<img src="https://storage.googleapis.com/cloudrun/button.svg" alt="Run on Google Cloud" height="30"/>][run_button_hello_broken] |
|[Pub/Sub][pubsub] | Event-driven service with a Pub/Sub push subscription | [<img src="https://storage.googleapis.com/cloudrun/button.svg" alt="Run on Google Cloud" height="30"/>][run_button_pubsub] |
|[Image Processing][image_processing] | Event-driven image analysis & transformation | [<img src="https://storage.googleapis.com/cloudrun/button.svg" alt="Run on Google Cloud" height="30"/>][run_button_image_processing] |
|[Manual Logging][manual_logging] | Structured logging without client library | [<img src="https://storage.googleapis.com/cloudrun/button.svg" alt="Run on Google Cloud" height="30"/>][run_button_manual_logging] |

For more Cloud Run samples beyond Node.js, see the main list in the [Cloud Run Samples repository](https://github.com/GoogleCloudPlatform/cloud-run-samples).

Expand Down Expand Up @@ -99,7 +100,7 @@ For more Cloud Run samples beyond Node.js, see the main list in the [Cloud Run S
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SAMPLE}
gcloud beta run deploy $SAMPLE \
# Needed for Manual Logging sample.
--set-env-var GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT}
--set-env-var GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT} \
--image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SAMPLE}
```

Expand All @@ -110,10 +111,12 @@ for more information.
[run_build]: https://cloud.google.com/run/docs/building/containers
[run_deploy]: https://cloud.google.com/run/docs/deploying
[helloworld]: https://github.com/knative/docs/tree/master/docs/serving/samples/hello-world/helloworld-nodejs
[hello_broken]: hello-broken/
[pubsub]: pubsub/
[image_processing]: image-processing/
[manual_logging]: logging-manual/
[pubsub]: pubsub/
[run_button_helloworld]: https://console.cloud.google.com/cloudshell/editor?shellonly=true&cloudshell_image=gcr.io/cloudrun/button&cloudshell_git_repo=https://github.com/knative/docs&cloudshell_working_dir=docs/serving/samples/hello-world/helloworld-nodejs
[run_button_hello_broken]: https://console.cloud.google.com/cloudshell/editor?shellonly=true&cloudshell_image=gcr.io/cloudrun/button&cloudshell_git_repo=https://github.com/GoogleCloudPlatform/nodejs-docs-samples&cloudshell_working_dir=run/hello-broken
[run_button_pubsub]: https://console.cloud.google.com/cloudshell/editor?shellonly=true&cloudshell_image=gcr.io/cloudrun/button&cloudshell_git_repo=https://github.com/GoogleCloudPlatform/nodejs-docs-samples&cloudshell_working_dir=run/pubsub
[run_button_image_processing]: https://console.cloud.google.com/cloudshell/editor?shellonly=true&cloudshell_image=gcr.io/cloudrun/button&cloudshell_git_repo=https://github.com/GoogleCloudPlatform/nodejs-docs-samples&cloudshell_working_dir=run/image-processing
[run_button_manual_logging]: https://console.cloud.google.com/cloudshell/editor?shellonly=true&cloudshell_image=gcr.io/cloudrun/button&cloudshell_git_repo=https://github.com/GoogleCloudPlatform/nodejs-docs-samples&cloudshell_working_dir=run/logging-manual
[run_button_pubsub]: https://console.cloud.google.com/cloudshell/editor?shellonly=true&cloudshell_image=gcr.io/cloudrun/button&cloudshell_git_repo=https://github.com/GoogleCloudPlatform/nodejs-docs-samples&cloudshell_working_dir=run/pubsub
40 changes: 40 additions & 0 deletions run/hello-broken/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# [START run_broken_dockerfile]

# Use the official lightweight Node.js 10 image.
# https://hub.docker.com/_/node
FROM node:10-slim

# Create and change to the app directory.
WORKDIR /usr/src/app

# Copy application dependency manifests to the container image.
# A wildcard is used to ensure copying both package.json AND package-lock.json (when available).
# Copying this first prevents re-running npm install on every code change.
COPY package*.json ./

# Install production dependencies.
# If you add a package-lock.json, speed your build by switching to 'npm ci'.
# RUN npm ci --only=production
RUN npm install --only=production

# Copy local code to the container image.
COPY . ./
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need a forward slash here.

Copy link
Collaborator Author

@grayside grayside Sep 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the previous practice was to use COPY . ., this is a newer practice I think we should use in COPY statements. The issue is COPY supports having multiple source arguments and one destination argument, but if the source arguments are:

  • A directory
  • More than one file

Then the destination needs to have the trailing slash otherwise it will error.

This is intended to future proof the use of the Dockerfile should a developer use it as a template.


# Run the web service on container startup.
CMD [ "npm", "start" ]

# [END run_broken_dockerfile]
71 changes: 71 additions & 0 deletions run/hello-broken/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Cloud Run Broken Sample

This sample presents broken code in need of troubleshooting. An alternate
resource at `/improved` shows a more stable implementation with more informative
errors and default values.

Use it with the [Local Container Troubleshooting tutorial](http://cloud.google.com/run/docs/tutorials/local-troubleshooting).

For more details on how to work with this sample read the [Google Cloud Run Node.js Samples README](https://github.com/GoogleCloudPlatform/nodejs-docs-samples/run).

## Local Development

### `npm run e2e-test`

```
export SERVICE_NAME=broken
export CONTAINER_IMAGE=gcr.io/${GOOGLE_CLOUD_PROJECT}/broken
npm run e2e-test
```

## Using Testing Scripts

### url.sh

The `url.sh` script derives the automatically provisioned URL of a deployed
Cloud Run service.

```sh
export SERVICE_NAME=broken
export REGION=us-central1
test/url.sh
```

### deploy.sh

The `deploy.sh` script deploys a Cloud Run service.

```sh
export SERVICE_NAME=broken
export CONTAINER_IMAGE=gcr.io/${GOOGLE_CLOUD_PROJECT}/broken
export REGION=us-central1
test/deploy.sh
```

### runner.sh

The `runner.sh` script will:

* Deploy the service to Cloud Run based on the `deploy.sh` script.
* Set the `BASE_URL` and `ID_TOKEN` environment variables.
* Run any arguments passed to the `runner.sh` script.
* Tear down the Cloud Run service on completion.

```sh
test/runner.sh sleep 20
```

## Environment Variables (Testing)

* `BASE_URL`: Specifies the Cloud Run service URL for end-to-end tests.
The default assigned URL of a Cloud Run service must be derived after deployment.
* `ID_TOKEN`: JWT token used to authenticate with Cloud Run's IAM-based authentication.
* `REGION`: [`us-central1`] Optional override region for the location of the Cloud Run service.
* `SERVICE_NAME`: Specify the name of the deployed service, used in some API calls and test assertions.
* `GOOGLE_CLOUD_PROJECT`: Required for local testing, overrides use of the GCP metadata server to determine the current GCP project.
Required by the logging client library.

## Dependencies

* **express**: Web server framework.
* **got**: [Testing] Used to make HTTP requests of the running service in end-to-end testing.
58 changes: 58 additions & 0 deletions run/hello-broken/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// [START run_broken_service]
const express = require('express');
const app = express();

app.get('/', (req, res) => {
console.log('hello: received request.');

// [START run_broken_service_problem]
const {NAME} = process.env;
if (!NAME) {
// Plain error logs do not appear in Stackdriver Error Reporting.
console.error('Environment validation failed.');
console.error(new Error('Missing required server parameter'));
res.status(500).send('Internal Server Error');
return;
}
// [END run_broken_service_problem]
res.send(`Hello ${NAME}!`);
});
// [END run_broken_service]

app.get('/improved', (req, res) => {
console.log('hello: received request.');

// [START run_broken_service_upgrade]
const NAME = process.env.NAME || 'World';
if (!process.env.NAME) {
console.log(
JSON.stringify({
severity: 'WARNING',
message: `NAME not set, default to '${NAME}'`,
})
);
}
// [END run_broken_service_upgrade]
res.send(`Hello ${NAME}!`);
});

// [START run_broken_service]
const port = process.env.PORT || 8080;
app.listen(port, () => {
console.log(`hello: listening on port ${port}`);
});
// [END run_broken_service]
23 changes: 23 additions & 0 deletions run/hello-broken/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "hello-broken",
"private": true,
"description": "Broken Cloud Run service for troubleshooting practice",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 0",
"e2e-test": "TARGET=Cloud test/runner.sh mocha test/system.test.js --timeout=20000"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth it to just put this script as test so you may npm test instead of npm run e2e-test.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope of this PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, now that I see your point about npm test being a no-op, this bears some follow-up. I will file an issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've looked at the other samples that include script e2e-test in this repo as well as the cDPE test guide and squad notes.

If we consider this change out of scope, then I oppose adding this line then:

"test": "echo \"Error: no test specified\" && exit 0",

We do specify a test in this repo. We don't specify a config for specifying a test as the error suggests.

If we're going to add this script:

"e2e-test": ...

We should either consider using the Node way of npm test or fix the error message for npm test to be more accurate.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

},
"author": "Google LLC",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
},
"dependencies": {
"express": "^4.17.1"
},
"devDependencies": {
"got": "^9.6.0"
}
}
37 changes: 37 additions & 0 deletions run/hello-broken/test/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env bash

# Copyright 2019 Google LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -eo pipefail;

requireEnv() {
test "${!1}" || (echo "Environment Variable '$1' not found" && exit 1)
}

requireEnv SERVICE_NAME
requireEnv CONTAINER_IMAGE

# Deploy the service
set -x
gcloud beta run deploy "${SERVICE_NAME}" \
--image="${CONTAINER_IMAGE}" \
--region="${REGION:-us-central1}" \
${FLAGS} \
--platform=managed \
--quiet

echo 'Cloud Run Links:'
echo "- Logs: https://console.cloud.google.com/logs/viewer?project=${GOOGLE_CLOUD_PROJECT}&resource=cloud_run_revision%2Fservice_name%2F${SERVICE_NAME}"
echo "- Console: https://console.cloud.google.com/run/detail/${REGION:-us-central1}/${SERVICE_NAME}/metrics?project=${GOOGLE_CLOUD_PROJECT}"
56 changes: 56 additions & 0 deletions run/hello-broken/test/runner.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env bash

# Copyright 2019 Google LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -eo pipefail;

requireEnv() {
test "${!1}" || (echo "Environment Variable '$1' not found" && exit 1)
}
requireEnv SERVICE_NAME

# The hello-broken sample needs to be tested with the NAME environment variable
# both set and unset.
SERVICE_OVERRIDE="${SERVICE_NAME}-override"

echo '---'
test/deploy.sh
FLAGS="--set-env-vars NAME=$NAME" SERVICE_NAME=${SERVICE_OVERRIDE} test/deploy.sh

echo
echo '---'
echo

# Register post-test cleanup.
# Only needed if deploy completed.
function cleanup {
set -x
gcloud beta run services delete ${SERVICE_NAME} \
--platform=managed \
--region="${REGION:-us-central1}" \
--quiet
gcloud beta run services delete ${SERVICE_OVERRIDE} \
--platform=managed \
--region="${REGION:-us-central1}" \
--quiet
}
trap cleanup EXIT

# TODO: Perform authentication inside the test.
export ID_TOKEN=$(gcloud auth print-identity-token)
export BASE_URL=$(test/url.sh)
export BASE_URL_OVERRIDE=$(SERVICE_NAME=${SERVICE_OVERRIDE} test/url.sh)
# Do not use exec to preserve trap behavior.
"$@"
Loading