Skip to content

Migrate integration tests to built JS files #2750

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Apr 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
07d431f
WIP: Switch integration tests to build code instead of run dynamically
JoshMock Apr 10, 2025
e06b54b
Pass test cert when running https locally
JoshMock Apr 14, 2025
caeee83
Don't try to reinitialize existing variables
JoshMock Apr 14, 2025
133b361
Support for overriding HTTP headers
JoshMock Apr 14, 2025
b3b9262
Add support for 'exists' action
JoshMock Apr 15, 2025
38d2383
Add a bunch of skips to stack tests
JoshMock Apr 15, 2025
2b304f7
Tweaks to try/catch tests
JoshMock Apr 15, 2025
07b22e2
Improve accuracy of value lookup generation
JoshMock Apr 15, 2025
6f0bee8
Improve accuracy of value literal generation
JoshMock Apr 15, 2025
f76037d
Improvements to $body value expression
JoshMock Apr 15, 2025
52c9053
More test skips
JoshMock Apr 15, 2025
51e8557
Ensure test runner pulls correct tests by version
JoshMock Apr 15, 2025
e7fb0e6
Update CI pipeline to reflect changes to integration tests
JoshMock Apr 15, 2025
4218b88
Merge branch 'main' into clients-test-repo
JoshMock Apr 15, 2025
3d83998
Add back deleted module that is used elsewhere
JoshMock Apr 16, 2025
67a7fad
Merge branch 'main' into clients-test-repo
JoshMock Apr 16, 2025
8c542fc
Ensure tests are reported in JUnit format
JoshMock Apr 21, 2025
ba82559
Add debugging info to Buildkite step to figure out why it's failing
JoshMock Apr 21, 2025
e9129cb
Make sure to mount the repo, silly
JoshMock Apr 21, 2025
6f33457
Turn off JUnit debugging
JoshMock Apr 21, 2025
f60388f
Let pipeline manage stack/serverless env vars
JoshMock Apr 21, 2025
c789bb1
Adjustments to CI agent specs
JoshMock Apr 21, 2025
d806f41
Don't commit downloaded artifacts
JoshMock Apr 21, 2025
54b6f29
Use GCP as agent provider
JoshMock Apr 21, 2025
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
22 changes: 11 additions & 11 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
---
agents:
provider: "gcp"
image: family/core-ubuntu-2204
memory: "8G"
cpu: "2"

steps:
- label: ":elasticsearch: :javascript: ES JavaScript ({{ matrix.nodejs }}) Test Suite: {{ matrix.suite }}"
agents:
provider: "gcp"
- label: ":elasticsearch: :javascript: ES JavaScript ({{ matrix.nodejs }})"
env:
NODE_VERSION: "{{ matrix.nodejs }}"
TEST_SUITE: "{{ matrix.suite }}"
STACK_VERSION: 8.16.0
TEST_SUITE: "platinum"
STACK_VERSION: 9.0.0
GITHUB_TOKEN_PATH: "secret/ci/elastic-elasticsearch-js/github-token"
TEST_ES_STACK: "1"
matrix:
setup:
suite:
- "free"
- "platinum"
nodejs:
- "18"
- "20"
Expand All @@ -21,9 +24,6 @@ steps:
- wait: ~
continue_on_failure: true
- label: ":junit: Test results"
agents:
provider: "gcp"
image: family/core-ubuntu-2204
plugins:
- junit-annotate#v2.6.0:
artifacts: "junit-output/junit-*.xml"
Expand Down
39 changes: 23 additions & 16 deletions .buildkite/run-client.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,29 @@ export NODE_VERSION=${NODE_VERSION:-18}

echo "--- :javascript: Building Docker image"
docker build \
--file "$script_path/Dockerfile" \
--tag elastic/elasticsearch-js \
--build-arg NODE_VERSION="$NODE_VERSION" \
.
--file "$script_path/Dockerfile" \
--tag elastic/elasticsearch-js \
--build-arg NODE_VERSION="$NODE_VERSION" \
.

echo "--- :javascript: Running $TEST_SUITE tests"
GITHUB_TOKEN=$(vault read -field=token "$GITHUB_TOKEN_PATH")
export GITHUB_TOKEN

echo "--- :javascript: Running tests"
mkdir -p "$repo/junit-output"
docker run \
--network="${network_name}" \
--env "TEST_ES_SERVER=${elasticsearch_url}" \
--env "ELASTIC_PASSWORD=${elastic_password}" \
--env "TEST_SUITE=${TEST_SUITE}" \
--env "ELASTIC_USER=elastic" \
--env "BUILDKITE=true" \
--volume "$repo/junit-output:/junit-output" \
--name elasticsearch-js \
--rm \
elastic/elasticsearch-js \
bash -c "npm run test:integration; [ -f ./$TEST_SUITE-report-junit.xml ] && mv ./$TEST_SUITE-report-junit.xml /junit-output/junit-$BUILDKITE_JOB_ID.xml || echo 'No JUnit artifact found'"
--network="${network_name}" \
--env TEST_ES_STACK \
--env STACK_VERSION \
--env GITHUB_TOKEN \
--env "TEST_ES_SERVER=${elasticsearch_url}" \
--env "ELASTIC_PASSWORD=${elastic_password}" \
--env "ELASTIC_USER=elastic" \
--env "BUILDKITE=true" \
--volume "/usr/src/app/node_modules" \
--volume "$repo:/usr/src/app" \
--volume "$repo/junit-output:/junit-output" \
--name elasticsearch-js \
--rm \
elastic/elasticsearch-js \
bash -c "npm run test:integration; [ -f ./report-junit.xml ] && mv ./report-junit.xml /junit-output/junit-$BUILDKITE_JOB_ID.xml || echo 'No JUnit artifact found'"
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ elasticsearch
lib
junit-output
.tap
rest-api-spec
yaml-rest-tests
generated-tests
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,7 @@ bun.lockb
test-results
processinfo
.tap
rest-api-spec
yaml-rest-tests
generated-tests
schema
3 changes: 3 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,6 @@ CONTRIBUTING.md
src
bun.lockb
.tap
rest-api-spec
yaml-rest-tests
generated-tests
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"test:coverage-100": "npm run build && tap --coverage --100",
"test:coverage-report": "npm run build && tap --coverage && nyc report --reporter=text-lcov > coverage.lcov",
"test:coverage-ui": "npm run build && tap --coverage --coverage-report=html",
"test:integration": "tsc && node test/integration/index.js",
"test:integration-build": "npm run build && node test/integration/index.js",
"test:integration": "npm run test:integration-build && env tap run --jobs=1 --reporter=junit --reporter-file=report-junit.xml generated-tests/",
"lint": "ts-standard src",
"lint:fix": "ts-standard --fix src",
"license-checker": "license-checker --production --onlyAllow='MIT;Apache-2.0;Apache1.1;ISC;BSD-3-Clause;BSD-2-Clause;0BSD'",
Expand Down Expand Up @@ -77,7 +78,7 @@
"node-fetch": "2.7.0",
"ora": "5.4.1",
"proxy": "1.0.2",
"rimraf": "3.0.2",
"rimraf": "5.0.10",
"semver": "7.7.1",
"split2": "4.2.0",
"stoppable": "1.1.0",
Expand Down
170 changes: 55 additions & 115 deletions scripts/download-artifacts.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,162 +3,102 @@
* SPDX-License-Identifier: Apache-2.0
*/

'use strict'

const { join } = require('path')
const minimist = require('minimist')
const stream = require('stream')
const { promisify } = require('util')
const { createWriteStream, promises } = require('fs')
const rimraf = require('rimraf')
const { rimraf } = require('rimraf')
const fetch = require('node-fetch')
const crossZip = require('cross-zip')
const ora = require('ora')

const { mkdir, writeFile } = promises
const { mkdir, cp } = promises
const pipeline = promisify(stream.pipeline)
const unzip = promisify(crossZip.unzip)
const rm = promisify(rimraf)

const esFolder = join(__dirname, '..', 'elasticsearch')
const zipFolder = join(esFolder, 'artifacts.zip')
const specFolder = join(esFolder, 'rest-api-spec', 'api')
const freeTestFolder = join(esFolder, 'rest-api-spec', 'test', 'free')
const xPackTestFolder = join(esFolder, 'rest-api-spec', 'test', 'platinum')
const artifactInfo = join(esFolder, 'info.json')

async function downloadArtifacts (opts) {
if (typeof opts.version !== 'string') {
throw new Error('Missing version')
}

const log = ora('Checking out spec and test').start()
const testYamlFolder = join(__dirname, '..', 'yaml-rest-tests')
const zipFile = join(__dirname, '..', 'elasticsearch-clients-tests.zip')

log.text = 'Resolving versions'
let resolved
try {
resolved = await resolve(opts.version, opts.hash)
} catch (err) {
log.fail(err.message)
process.exit(1)
}
const schemaFolder = join(__dirname, '..', 'schema')
const schemaJson = join(schemaFolder, 'schema.json')

opts.id = opts.id || resolved.id
opts.hash = opts.hash || resolved.hash
opts.version = resolved.version
async function downloadArtifacts (localTests, version = 'main') {
const log = ora('Checking out spec and test').start()

const info = loadInfo()
const { GITHUB_TOKEN } = process.env

if (info && info.version === opts.version) {
if (info.hash === opts.hash && info.id === opts.id) {
log.succeed('The artifact copy present locally is already up to date')
return
}
if (version !== 'main') {
version = version.split('.').slice(0, 2).join('.')
}

log.text = 'Cleanup checkouts/elasticsearch'
await rm(esFolder)
await mkdir(esFolder, { recursive: true })
log.text = 'Clean tests folder'
await rimraf(testYamlFolder)
await mkdir(testYamlFolder, { recursive: true })

log.text = 'Downloading artifacts'
const response = await fetch(resolved.url)
if (!response.ok) {
log.fail(`unexpected response ${response.statusText}`)
process.exit(1)
}
await pipeline(response.body, createWriteStream(zipFolder))
log.text = `Fetch test YAML files for version ${version}`

log.text = 'Unzipping'
await unzip(zipFolder, esFolder)
if (localTests) {
log.text = `Copying local tests from ${localTests}`
await cp(localTests, testYamlFolder, { recursive: true })
} else {
if (!GITHUB_TOKEN) {
log.fail("Missing required environment variable 'GITHUB_TOKEN'")
process.exit(1)
}

log.text = 'Cleanup'
await rm(zipFolder)
const response = await fetch(`https://api.github.com/repos/elastic/elasticsearch-clients-tests/zipball/${version}`, {
headers: {
Authorization: `Bearer ${GITHUB_TOKEN}`,
Accept: 'application/vnd.github+json'
}
})

log.text = 'Update info'
await writeFile(artifactInfo, JSON.stringify(opts), 'utf8')
if (!response.ok) {
log.fail(`unexpected response ${response.statusText}`)
process.exit(1)
}

log.succeed('Done')
}
log.text = 'Downloading tests zipball'
await pipeline(response.body, createWriteStream(zipFile))

function loadInfo () {
try {
return require(artifactInfo)
} catch (err) {
return null
}
}
log.text = 'Unzipping tests'
await unzip(zipFile, testYamlFolder)

async function resolve (version, hash) {
const response = await fetch(`https://artifacts-api.elastic.co/v1/versions/${version}`)
if (!response.ok) {
throw new Error(`unexpected response ${response.statusText}`)
log.text = 'Cleanup'
await rimraf(zipFile)
}

const data = await response.json()
const esBuilds = data.version.builds
.filter(build => build.projects.elasticsearch != null)
.map(build => {
return {
projects: build.projects.elasticsearch,
buildId: build.build_id,
date: build.start_time,
version: build.version
}
})
.sort((a, b) => {
const dA = new Date(a.date)
const dB = new Date(b.date)
if (dA > dB) return -1
if (dA < dB) return 1
return 0
})
log.text = 'Fetching Elasticsearch specification'
await rimraf(schemaFolder)
await mkdir(schemaFolder, { recursive: true })

if (hash != null) {
const build = esBuilds.find(build => build.projects.commit_hash === hash)
if (!build) {
throw new Error(`Can't find any build with hash '${hash}'`)
}
const zipKey = Object.keys(build.projects.packages).find(key => key.startsWith('rest-resources-zip-') && key.endsWith('.zip'))
return {
url: build.projects.packages[zipKey].url,
id: build.buildId,
hash: build.projects.commit_hash,
version: build.version
}
const response = await fetch(`https://raw.githubusercontent.com/elastic/elasticsearch-specification/${version}/output/schema/schema.json`)
if (!response.ok) {
log.fail(`unexpected response ${response.statusText}`)
process.exit(1)
}

const lastBuild = esBuilds[0]
const zipKey = Object.keys(lastBuild.projects.packages).find(key => key.startsWith('rest-resources-zip-') && key.endsWith('.zip'))
return {
url: lastBuild.projects.packages[zipKey].url,
id: lastBuild.buildId,
hash: lastBuild.projects.commit_hash,
version: lastBuild.version
}
log.text = 'Downloading schema.json'
await pipeline(response.body, createWriteStream(schemaJson))

log.succeed('Done')
}

async function main (options) {
delete options._
await downloadArtifacts(options)
async function main () {
await downloadArtifacts()
}

if (require.main === module) {
process.on('unhandledRejection', function (err) {
console.error(err)
process.exit(1)
})

const options = minimist(process.argv.slice(2), {
string: ['id', 'version', 'hash']
})
main(options).catch(t => {
main().catch(t => {
console.log(t)
process.exit(2)
})
}

module.exports = downloadArtifacts
module.exports.locations = {
specFolder,
freeTestFolder,
xPackTestFolder
}
module.exports.locations = { testYamlFolder, zipFile, schemaJson }
2 changes: 1 addition & 1 deletion scripts/generate-docs-examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
const { join } = require('path')
const { writeFile } = require('fs/promises')
const fetch = require('node-fetch')
const rimraf = require('rimraf')
const { rimraf } = require('rimraf')
const ora = require('ora')
const { convertRequests } = require('@elastic/request-converter')
const minimist = require('minimist')
Expand Down
Loading
Loading