From c1e02e49239f132c534190aa79212dfe128d1ce9 Mon Sep 17 00:00:00 2001 From: Przemyslaw Motacki Date: Mon, 24 Feb 2025 14:14:57 +0100 Subject: [PATCH 1/5] SNOW-1883649 - wiremock integration --- package.json | 4 +- .../wiremock/testWiremockRunner.js | 43 ++++++++++++++ test/wiremockRunner.js | 58 +++++++++++++++++++ wiremock/mappings/testMapping.json | 34 +++++++++++ 4 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 test/integration/wiremock/testWiremockRunner.js create mode 100644 test/wiremockRunner.js create mode 100644 wiremock/mappings/testMapping.json diff --git a/package.json b/package.json index dce0a261b..065b93605 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,9 @@ "mocha": "^10.2.0", "mock-require": "^3.0.3", "nyc": "^15.1.0", - "test-console": "^2.0.0" + "test-console": "^2.0.0", + "wiremock": "^3.10.0", + "wiremock-rest-client": "^1.11.0" }, "peerDependencies": { "asn1.js": "^5.4.1" diff --git a/test/integration/wiremock/testWiremockRunner.js b/test/integration/wiremock/testWiremockRunner.js new file mode 100644 index 000000000..17d4f3f6b --- /dev/null +++ b/test/integration/wiremock/testWiremockRunner.js @@ -0,0 +1,43 @@ +const assert = require('assert'); +const fs = require('fs'); +const net = require('net'); +const axios = require('axios'); +const { runWireMockAsync } = require('../../wiremockRunner'); +const os = require('os'); + +async function getFreePort() { + return new Promise(res => { + const srv = net.createServer(); + srv.listen(0, () => { + const port = srv.address().port; + srv.close(() => res(port)); + }); + }); +} + +if (os.platform !== 'win32') { + describe('Wiremock test', function () { + let port, wireMock; + before(async () => { + port = await getFreePort(); + wireMock = await runWireMockAsync(port); + }); + after(async () => { + await wireMock.global.shutdown(); + }); + it('Run Wiremock instance, wait, verify connection and shutdown', async function () { + assert.doesNotReject(async () => await wireMock.mappings.getAllMappings()); + }); + it('Add mappings', async function () { + const requests = JSON.parse(fs.readFileSync('wiremock/mappings/testMapping.json', 'utf8')); + for (const mapping of requests.mappings) { + await wireMock.mappings.createMapping(mapping); + } + const mappings = await wireMock.mappings.getAllMappings(); + assert.strictEqual(mappings.mappings.length, 2); + const response = await axios.get(`http://localhost:${port}/test/authorize.html`); + assert.strictEqual(response.status, 200); + }); + }); + +} diff --git a/test/wiremockRunner.js b/test/wiremockRunner.js new file mode 100644 index 000000000..3db88d0dc --- /dev/null +++ b/test/wiremockRunner.js @@ -0,0 +1,58 @@ +const WireMockRestClient = require('wiremock-rest-client').WireMockRestClient; +const { exec } = require('child_process'); +const Logger = require('../lib/logger'); +const fs = require('fs'); + + +async function runWireMockAsync(port) { + let timeoutHandle; + const waitingWireMockPromise = new Promise( (resolve, reject) => { + try { + exec(`npx wiremock --enable-browser-proxying --proxy-pass-through false --port ${port} `); + const wireMock = new WireMockRestClient(`http://localhost:${port}`, { logLevel: 'debug' }); + const readyWireMock = waitForWiremockStarted(wireMock); + resolve(readyWireMock); + } catch (err) { + reject(err); + } + }); + + const timeout = new Promise((resolve, reject) => + timeoutHandle = setTimeout( + () => reject('Wiremock unavailable after 60s.'), + 60000)); + return Promise.race([waitingWireMockPromise, timeout]) + .then(result => { + clearTimeout(timeoutHandle); + return result; + }); +} + +async function waitForWiremockStarted(wireMock) { + return fetch(wireMock.baseUri) + .then(async (resp) => { + if (resp.ok) { + return Promise.resolve(wireMock); + } else { + await new Promise(resolve => setTimeout(resolve, 1000)); + Logger.getInstance().info(`Retry connection to WireMock after wrong response status: ${resp.status}`); + return await waitForWiremockStarted(wireMock); + } + }) + .catch(async (err) => { + await new Promise(resolve => setTimeout(resolve, 1000)); + Logger.getInstance().info(`Retry connection to WireMock after error: ${err}`); + return await waitForWiremockStarted(wireMock); + }); +} + +async function addWireMockMappingsFromFile(wireMock, filePath) { + const requests = JSON.parse(fs.readFileSync(filePath, 'utf8')); + for (const mapping of requests.mappings) { + await wireMock.mappings.createMapping(mapping); + } +} + +exports.runWireMockAsync = runWireMockAsync; +exports.addWireMockMappingsFromFile = addWireMockMappingsFromFile; + diff --git a/wiremock/mappings/testMapping.json b/wiremock/mappings/testMapping.json new file mode 100644 index 000000000..c3ce742a3 --- /dev/null +++ b/wiremock/mappings/testMapping.json @@ -0,0 +1,34 @@ +{ + "mappings": [ + { + "scenarioName": "Test wiremock endpoint", + "request": { + "urlPathPattern": "/test/authorize.*", + "method": "GET" + }, + "response": { + "status": 200, + "fixedDelayMilliseconds": 500 + + } + }, + { + "scenarioName": "Test wiremock endpoint", + "request": { + "urlPathPattern": "/session/v1/login-request.*", + "method": "POST" + }, + "response": { + "status": 200, + "fixedDelayMilliseconds": 500, + "jsonBody": { + "data": { + "masterToken": "master token", + "token": "session token", + "validityInSeconds": 3600 + } + } + } + } + ] +} \ No newline at end of file From 3c45739be1533bceb9a43f27ec4701e91c012490 Mon Sep 17 00:00:00 2001 From: Przemyslaw Motacki Date: Tue, 4 Mar 2025 16:10:53 +0100 Subject: [PATCH 2/5] SNOW-1883649 - wiremock integration --- ci/container/package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ci/container/package.json b/ci/container/package.json index d0cfe7667..c26fc8bb7 100644 --- a/ci/container/package.json +++ b/ci/container/package.json @@ -13,7 +13,9 @@ "mocha": "^10.2.0", "mock-require": "^3.0.3", "nyc": "^15.1.0", - "test-console": "^2.0.0" + "test-console": "^2.0.0", + "wiremock": "^3.10.0", + "wiremock-rest-client": "^1.11.0" }, "author": "Snowflake, Inc.", "license": "ISC" From 563d6c8e4ff4e4ab1e0858333f9666541eca02db Mon Sep 17 00:00:00 2001 From: Przemyslaw Motacki Date: Tue, 4 Mar 2025 16:26:28 +0100 Subject: [PATCH 3/5] SNOW-1883649 - wiremock integration --- ci/container/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/container/package.json b/ci/container/package.json index c26fc8bb7..2ce206b95 100644 --- a/ci/container/package.json +++ b/ci/container/package.json @@ -10,6 +10,7 @@ }, "devDependencies": { "async": "^3.2.3", + "https-proxy-agent": "^7.0.2", "mocha": "^10.2.0", "mock-require": "^3.0.3", "nyc": "^15.1.0", From e6fd54e4286ed969482d298f9539c226d9c535d2 Mon Sep 17 00:00:00 2001 From: Przemyslaw Motacki Date: Tue, 4 Mar 2025 17:20:23 +0100 Subject: [PATCH 4/5] SNOW-1883649 - wiremock integration --- .github/workflows/build-test.yml | 5 +++++ ci/_init.sh | 2 +- ci/image/Dockerfile | 4 +++- ci/test_authentication.sh | 2 +- test/wiremockRunner.js | 5 +++-- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 67b31a63c..c6a6058d7 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -90,6 +90,11 @@ jobs: nodeVersion: ['18.x', '20.x', '22.x'] steps: - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + java-package: 'jre' - uses: actions/setup-node@v4 with: node-version: ${{ matrix.nodeVersion }} diff --git a/ci/_init.sh b/ci/_init.sh index 9f5584b51..8a1672fa6 100755 --- a/ci/_init.sh +++ b/ci/_init.sh @@ -18,7 +18,7 @@ export DRIVER_NAME=nodejs BUILD_IMAGE_VERSION=1 # Test Images -TEST_IMAGE_VERSION=1 +TEST_IMAGE_VERSION=2 declare -A BUILD_IMAGE_NAMES=( [$DRIVER_NAME-chainguard-node18]=$DOCKER_REGISTRY_NAME/client-$DRIVER_NAME-chainguard-node18-build:$BUILD_IMAGE_VERSION diff --git a/ci/image/Dockerfile b/ci/image/Dockerfile index 8c7574950..01d6a4b59 100644 --- a/ci/image/Dockerfile +++ b/ci/image/Dockerfile @@ -3,9 +3,11 @@ FROM $IMAGE USER root -RUN apk update && apk add python3 jq aws-cli gosu +RUN apk update && apk add python3 python3-dev py3-pip jq aws-cli gosu openjdk-17 RUN pip install -U snowflake-connector-python +ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk + # workspace RUN mkdir -p /home/user && \ chmod 777 /home/user diff --git a/ci/test_authentication.sh b/ci/test_authentication.sh index c6545ad47..83406daa8 100755 --- a/ci/test_authentication.sh +++ b/ci/test_authentication.sh @@ -13,5 +13,5 @@ docker run \ -v $(cd $THIS_DIR/.. && pwd):/mnt/host \ -v $WORKSPACE:/mnt/workspace \ --rm \ - nexus.int.snowflakecomputing.com:8086/docker/snowdrivers-test-external-browser:3 \ + nexus.int.snowflakecomputing.com:8086/docker/snowdrivers-test-external-browser:7 \ "/mnt/host/ci/container/test_authentication.sh" \ No newline at end of file diff --git a/test/wiremockRunner.js b/test/wiremockRunner.js index 3db88d0dc..298690fcc 100644 --- a/test/wiremockRunner.js +++ b/test/wiremockRunner.js @@ -11,6 +11,7 @@ async function runWireMockAsync(port) { exec(`npx wiremock --enable-browser-proxying --proxy-pass-through false --port ${port} `); const wireMock = new WireMockRestClient(`http://localhost:${port}`, { logLevel: 'debug' }); const readyWireMock = waitForWiremockStarted(wireMock); + console.log("########## WIREMOCK STARTED ##############") resolve(readyWireMock); } catch (err) { reject(err); @@ -19,8 +20,8 @@ async function runWireMockAsync(port) { const timeout = new Promise((resolve, reject) => timeoutHandle = setTimeout( - () => reject('Wiremock unavailable after 60s.'), - 60000)); + () => reject('Wiremock unavailable after 30s.'), + 30000)); return Promise.race([waitingWireMockPromise, timeout]) .then(result => { clearTimeout(timeoutHandle); From c09713970f1c9788e78efc0af067f60d677a582a Mon Sep 17 00:00:00 2001 From: Przemyslaw Motacki Date: Wed, 5 Mar 2025 10:41:49 +0100 Subject: [PATCH 5/5] SNOW-1926267: Fix promise rejecting for file upload errors --- test/wiremockRunner.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/wiremockRunner.js b/test/wiremockRunner.js index 298690fcc..cfb078f89 100644 --- a/test/wiremockRunner.js +++ b/test/wiremockRunner.js @@ -11,7 +11,6 @@ async function runWireMockAsync(port) { exec(`npx wiremock --enable-browser-proxying --proxy-pass-through false --port ${port} `); const wireMock = new WireMockRestClient(`http://localhost:${port}`, { logLevel: 'debug' }); const readyWireMock = waitForWiremockStarted(wireMock); - console.log("########## WIREMOCK STARTED ##############") resolve(readyWireMock); } catch (err) { reject(err);