From d0986e06e420ddbc3639f9daf9bf4f492f747a2c Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Thu, 3 Apr 2025 14:22:27 +1100 Subject: [PATCH 1/9] debug: trial folder-level separation (DONOTMERGE) --- .github/config/nodejs-dev.jsonc | 1 + .github/config/nodejs-prod.jsonc | 1 - compute/custom-hostname-instance/package.json | 25 ++++++ .../test/customHostnameInstance.test.js | 77 +++++++++++++++++++ 4 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 compute/custom-hostname-instance/package.json create mode 100644 compute/custom-hostname-instance/test/customHostnameInstance.test.js diff --git a/.github/config/nodejs-dev.jsonc b/.github/config/nodejs-dev.jsonc index b2192a0525..6970754883 100644 --- a/.github/config/nodejs-dev.jsonc +++ b/.github/config/nodejs-dev.jsonc @@ -75,6 +75,7 @@ "functions/pubsub", // parent directory "memorystore/redis", // parent directory "recaptcha_enterprise/demosite/app", // no tests exist + "compute", // parent directory // These tests are already passing in prod, so skip them in dev. "appengine/building-an-app/build", diff --git a/.github/config/nodejs-prod.jsonc b/.github/config/nodejs-prod.jsonc index da7625698a..1d2a0e755a 100644 --- a/.github/config/nodejs-prod.jsonc +++ b/.github/config/nodejs-prod.jsonc @@ -79,7 +79,6 @@ "automl", // (untested) FAILED_PRECONDITION: Google Cloud AutoML Natural Language was retired on March 15, 2024. Please migrate to Vertex AI instead "cloud-sql/sqlserver/mssql", // (untested) TypeError: The "config.server" property is required and must be of type string. "cloud-sql/sqlserver/tedious", // (untested) TypeError: The "config.server" property is required and must be of type string. - "compute", // GoogleError: The resource 'projects/long-door-651/zones/us-central1-a/disks/disk-from-pool-name' was not found "dataproc", // GoogleError: Error submitting create cluster request: Multiple validation errors "datastore/functions", // [ERR_REQUIRE_ESM]: require() of ES Module "dialogflow-cx", // NOT_FOUND: com.google.apps.framework.request.NotFoundException: Agent 'undefined' does not exist diff --git a/compute/custom-hostname-instance/package.json b/compute/custom-hostname-instance/package.json new file mode 100644 index 0000000000..67eff22929 --- /dev/null +++ b/compute/custom-hostname-instance/package.json @@ -0,0 +1,25 @@ +{ + "name": "nodejs-docs-samples-compute", + "license": "Apache-2.0", + "author": "Google Inc.", + "engines": { + "node": ">=16.0.0" + }, + "repository": "googleapis/nodejs-compute", + "private": true, + "files": [ + "*.js" + ], + "scripts": { + "test": "c8 mocha -p -j 2 test --timeout 1200000" + }, + "dependencies": { + "@google-cloud/compute": "^4.0.0" + }, + "devDependencies": { + "c8": "^10.0.0", + "chai": "^4.5.0", + "mocha": "^10.0.0", + "uuid": "^10.0.0" + } +} diff --git a/compute/custom-hostname-instance/test/customHostnameInstance.test.js b/compute/custom-hostname-instance/test/customHostnameInstance.test.js new file mode 100644 index 0000000000..56985dc9aa --- /dev/null +++ b/compute/custom-hostname-instance/test/customHostnameInstance.test.js @@ -0,0 +1,77 @@ +// Copyright 2021 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. + +'use strict'; + +const compute = require('@google-cloud/compute'); + +const {describe, it} = require('mocha'); +const uuid = require('uuid'); +const cp = require('child_process'); +const {assert} = require('chai'); + +const instancesClient = new compute.InstancesClient(); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); + +const getInstance = async (projectId, zone, instanceName) => { + const [instance] = await instancesClient.get({ + project: projectId, + zone, + instance: instanceName, + }); + return instance; +}; + +describe('Instance with a custom hostname samples', () => { + const instanceName = `gcloud-test-instance-${uuid.v4().split('-')[0]}`; + const zone = 'europe-central2-b'; + const custom_hostname = 'host.domain.com'; + + it('should create instance with a custom hostname and return correct hostname', async () => { + const projectId = await instancesClient.getProjectId(); + let output = execSync( + `node custom-hostname-instance/createInstanceWithCustomHostname ${projectId} ${zone} ${instanceName} ${custom_hostname}` + ); + + const instance = await getInstance(projectId, zone, instanceName); + + assert.equal(instance.hostname, custom_hostname); + assert.match(output, /Instance created./); + + output = execSync( + `node custom-hostname-instance/getInstanceHostname ${projectId} ${zone} ${instanceName}` + ); + + assert.include( + output, + `Instance ${instanceName} has hostname: ${custom_hostname}` + ); + + execSync(`node deleteInstance ${projectId} ${zone} ${instanceName}`); + }); + + it('should return undefined if hostname is not set', async () => { + const projectId = await instancesClient.getProjectId(); + + execSync(`node createInstance ${projectId} ${zone} ${instanceName}`); + const output = execSync( + `node custom-hostname-instance/getInstanceHostname ${projectId} ${zone} ${instanceName}` + ); + + assert.include(output, `Instance ${instanceName} has hostname: undefined`); + + execSync(`node deleteInstance ${projectId} ${zone} ${instanceName}`); + }); +}); From 2e6d8960d1d5bd757c875aa47e5fbcfaee8b1183 Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Thu, 3 Apr 2025 14:26:51 +1100 Subject: [PATCH 2/9] update namespace --- .../test/customHostnameInstance.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compute/custom-hostname-instance/test/customHostnameInstance.test.js b/compute/custom-hostname-instance/test/customHostnameInstance.test.js index 56985dc9aa..0a5df6d7c3 100644 --- a/compute/custom-hostname-instance/test/customHostnameInstance.test.js +++ b/compute/custom-hostname-instance/test/customHostnameInstance.test.js @@ -42,7 +42,7 @@ describe('Instance with a custom hostname samples', () => { it('should create instance with a custom hostname and return correct hostname', async () => { const projectId = await instancesClient.getProjectId(); let output = execSync( - `node custom-hostname-instance/createInstanceWithCustomHostname ${projectId} ${zone} ${instanceName} ${custom_hostname}` + `node createInstanceWithCustomHostname ${projectId} ${zone} ${instanceName} ${custom_hostname}` ); const instance = await getInstance(projectId, zone, instanceName); @@ -51,7 +51,7 @@ describe('Instance with a custom hostname samples', () => { assert.match(output, /Instance created./); output = execSync( - `node custom-hostname-instance/getInstanceHostname ${projectId} ${zone} ${instanceName}` + `node getInstanceHostname ${projectId} ${zone} ${instanceName}` ); assert.include( @@ -67,7 +67,7 @@ describe('Instance with a custom hostname samples', () => { execSync(`node createInstance ${projectId} ${zone} ${instanceName}`); const output = execSync( - `node custom-hostname-instance/getInstanceHostname ${projectId} ${zone} ${instanceName}` + `node getInstanceHostname ${projectId} ${zone} ${instanceName}` ); assert.include(output, `Instance ${instanceName} has hostname: undefined`); From e7b7e5b578da470ecf4b1c600aed86fc00030c51 Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Thu, 3 Apr 2025 14:29:03 +1100 Subject: [PATCH 3/9] call client direct instead of using sample implementation --- .../test/customHostnameInstance.test.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/compute/custom-hostname-instance/test/customHostnameInstance.test.js b/compute/custom-hostname-instance/test/customHostnameInstance.test.js index 0a5df6d7c3..084fae9591 100644 --- a/compute/custom-hostname-instance/test/customHostnameInstance.test.js +++ b/compute/custom-hostname-instance/test/customHostnameInstance.test.js @@ -59,7 +59,11 @@ describe('Instance with a custom hostname samples', () => { `Instance ${instanceName} has hostname: ${custom_hostname}` ); - execSync(`node deleteInstance ${projectId} ${zone} ${instanceName}`); + await instancesClient.delete({ + project: projectId, + zone: zone, + instance: instanceName, + }); }); it('should return undefined if hostname is not set', async () => { @@ -72,6 +76,10 @@ describe('Instance with a custom hostname samples', () => { assert.include(output, `Instance ${instanceName} has hostname: undefined`); - execSync(`node deleteInstance ${projectId} ${zone} ${instanceName}`); + await instancesClient.delete({ + project: projectId, + zone: zone, + instance: instanceName, + }); }); }); From ad5d5d2797058b308acdcccea33d958f4fea8178 Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Thu, 3 Apr 2025 14:30:01 +1100 Subject: [PATCH 4/9] ensure unique 'package' name --- compute/custom-hostname-instance/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compute/custom-hostname-instance/package.json b/compute/custom-hostname-instance/package.json index 67eff22929..7bb3674307 100644 --- a/compute/custom-hostname-instance/package.json +++ b/compute/custom-hostname-instance/package.json @@ -1,5 +1,5 @@ { - "name": "nodejs-docs-samples-compute", + "name": "nodejs-docs-samples-compute-custom-hostname-instance", "license": "Apache-2.0", "author": "Google Inc.", "engines": { From 9880ddfdde39c54761ee60ec490ffca9539565ab Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Thu, 3 Apr 2025 15:02:45 +1100 Subject: [PATCH 5/9] copy createInstance helper, unique instance names --- .../test/customHostnameInstance.test.js | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/compute/custom-hostname-instance/test/customHostnameInstance.test.js b/compute/custom-hostname-instance/test/customHostnameInstance.test.js index 084fae9591..6f1e5ee395 100644 --- a/compute/custom-hostname-instance/test/customHostnameInstance.test.js +++ b/compute/custom-hostname-instance/test/customHostnameInstance.test.js @@ -34,12 +34,50 @@ const getInstance = async (projectId, zone, instanceName) => { return instance; }; + +// DEBUG: copied from createInstance.js, could be simplified. +const createInstance = async (projectId, zone, instanceName) => { + + const machineType = 'n1-standard-1'; + const sourceImage = 'projects/debian-cloud/global/images/family/debian-11'; + const networkName = 'global/networks/default'; + console.log(`Creating the ${instanceName} instance in ${zone}...`); + + const [response] = await instancesClient.insert({ + instanceResource: { + name: instanceName, + disks: [ + { + initializeParams: { + diskSizeGb: '10', + sourceImage, + }, + autoDelete: true, + boot: true, + type: 'PERSISTENT', + }, + ], + machineType: `zones/${zone}/machineTypes/${machineType}`, + networkInterfaces: [ + { + name: networkName, + }, + ], + }, + project: projectId, + zone, + }); + +} + describe('Instance with a custom hostname samples', () => { - const instanceName = `gcloud-test-instance-${uuid.v4().split('-')[0]}`; const zone = 'europe-central2-b'; const custom_hostname = 'host.domain.com'; + + it('should create instance with a custom hostname and return correct hostname', async () => { + const instanceName = `gcloud-test-instance-${uuid.v4().split('-')[0]}`; const projectId = await instancesClient.getProjectId(); let output = execSync( `node createInstanceWithCustomHostname ${projectId} ${zone} ${instanceName} ${custom_hostname}` @@ -67,9 +105,12 @@ describe('Instance with a custom hostname samples', () => { }); it('should return undefined if hostname is not set', async () => { + + const instanceName = `gcloud-test-instance-${uuid.v4().split('-')[0]}`; const projectId = await instancesClient.getProjectId(); - execSync(`node createInstance ${projectId} ${zone} ${instanceName}`); + await createInstance(projectId, zone, instanceName); + console.log("Instance", instanceName, "created") const output = execSync( `node getInstanceHostname ${projectId} ${zone} ${instanceName}` ); From 55935480cd41ac2f252477433113c71b7c00af1a Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Thu, 3 Apr 2025 15:03:52 +1100 Subject: [PATCH 6/9] change timeout to 5 minutes --- compute/custom-hostname-instance/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compute/custom-hostname-instance/package.json b/compute/custom-hostname-instance/package.json index 7bb3674307..515a13313c 100644 --- a/compute/custom-hostname-instance/package.json +++ b/compute/custom-hostname-instance/package.json @@ -11,7 +11,7 @@ "*.js" ], "scripts": { - "test": "c8 mocha -p -j 2 test --timeout 1200000" + "test": "c8 mocha -p -j 2 test --timeout 300000" }, "dependencies": { "@google-cloud/compute": "^4.0.0" From 3783a3335c9896a75edc7fdd471fa128a9989d55 Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Thu, 3 Apr 2025 15:13:04 +1100 Subject: [PATCH 7/9] gts --- .../test/customHostnameInstance.test.js | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/compute/custom-hostname-instance/test/customHostnameInstance.test.js b/compute/custom-hostname-instance/test/customHostnameInstance.test.js index 6f1e5ee395..0c77fee332 100644 --- a/compute/custom-hostname-instance/test/customHostnameInstance.test.js +++ b/compute/custom-hostname-instance/test/customHostnameInstance.test.js @@ -34,16 +34,14 @@ const getInstance = async (projectId, zone, instanceName) => { return instance; }; - // DEBUG: copied from createInstance.js, could be simplified. -const createInstance = async (projectId, zone, instanceName) => { - +const createInstance = async (projectId, zone, instanceName) => { const machineType = 'n1-standard-1'; const sourceImage = 'projects/debian-cloud/global/images/family/debian-11'; const networkName = 'global/networks/default'; console.log(`Creating the ${instanceName} instance in ${zone}...`); - const [response] = await instancesClient.insert({ + await instancesClient.insert({ instanceResource: { name: instanceName, disks: [ @@ -67,15 +65,12 @@ const createInstance = async (projectId, zone, instanceName) => { project: projectId, zone, }); - -} +}; describe('Instance with a custom hostname samples', () => { const zone = 'europe-central2-b'; const custom_hostname = 'host.domain.com'; - - it('should create instance with a custom hostname and return correct hostname', async () => { const instanceName = `gcloud-test-instance-${uuid.v4().split('-')[0]}`; const projectId = await instancesClient.getProjectId(); @@ -105,12 +100,11 @@ describe('Instance with a custom hostname samples', () => { }); it('should return undefined if hostname is not set', async () => { - const instanceName = `gcloud-test-instance-${uuid.v4().split('-')[0]}`; const projectId = await instancesClient.getProjectId(); await createInstance(projectId, zone, instanceName); - console.log("Instance", instanceName, "created") + console.log('Instance', instanceName, 'created'); const output = execSync( `node getInstanceHostname ${projectId} ${zone} ${instanceName}` ); From 5600ffb8ae28797eb4a184a537c0db28f5dad935 Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Thu, 3 Apr 2025 15:22:33 +1100 Subject: [PATCH 8/9] important dir --- .github/config/nodejs-prod.jsonc | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/config/nodejs-prod.jsonc b/.github/config/nodejs-prod.jsonc index 1d2a0e755a..6b06b2956d 100644 --- a/.github/config/nodejs-prod.jsonc +++ b/.github/config/nodejs-prod.jsonc @@ -73,6 +73,7 @@ "functions/pubsub", // parent directory "memorystore/redis", // parent directory "recaptcha_enterprise/demosite/app", // no tests exist + "compute", // parent directory // TODO: fix these "ai-platform/snippets", // PERMISSION_DENIED: Permission denied: Consumer 'projects/undefined' has been suspended. From 15c69c760eee38827abb77c3f2c41ec6092ac6ad Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Thu, 3 Apr 2025 15:25:02 +1100 Subject: [PATCH 9/9] remove old workflow --- .github/workflows/compute.yaml | 52 ---------------------------------- 1 file changed, 52 deletions(-) delete mode 100644 .github/workflows/compute.yaml diff --git a/.github/workflows/compute.yaml b/.github/workflows/compute.yaml deleted file mode 100644 index ceb504fe8e..0000000000 --- a/.github/workflows/compute.yaml +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright 2023 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. - -name: compute -on: - push: - branches: - - main - paths: - - 'compute/**' - - '.github/workflows/compute.yaml' - - '.github/workflows/test.yaml' - pull_request: - types: - - opened - - reopened - - synchronize - - labeled - paths: - - 'compute/**' - - '.github/workflows/compute.yaml' - - '.github/workflows/test.yaml' - schedule: - - cron: '0 0 * * 0' -jobs: - test: - permissions: - contents: 'read' - id-token: 'write' - if: github.event.action != 'labeled' || github.event.label.name == 'actions:force-run' - uses: ./.github/workflows/test.yaml - with: - name: 'compute' - path: 'compute' - flakybot: - permissions: - contents: 'read' - id-token: 'write' - if: github.event_name == 'schedule' && always() # always() submits logs even if tests fail - uses: ./.github/workflows/flakybot.yaml - needs: [test]