Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 0 additions & 7 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,3 @@ jobs:
CLICKHOUSE_CLOUD_PASSWORD: ${{ secrets.INTEGRATIONS_TEAM_TESTS_CLOUD_PASSWORD_SMT_PROD }}
run: |
npm run run-examples

success:
needs: ["code-quality", "run-examples"]
runs-on: ubuntu-latest
steps:
- name: All examples checks passed
run: echo "All examples checks passed! 🎉"
14 changes: 14 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,14 @@ jobs:
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3

- name: Start ClickHouse (stable) in Docker
uses: hoverkraft-tech/compose-action@11beaa1c2dae4e8ed7b1665aa074723b6cecb0e4 # v3.0.0
env:
CLICKHOUSE_VERSION: latest
with:
compose-file: "docker-compose.yml"
down-flags: "--volumes"

- name: Setup NodeJS ${{ matrix.node }}
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
Expand Down Expand Up @@ -401,3 +409,9 @@ jobs:
env:
EXPECTED_VERSION: ${{ env.PUBLISHED_VERSION }}
run: node src/index.ts

# End-to-end integration against the installed package and a live
# single-node ClickHouse (started above): create/insert/select, stream,
# and confirm a bad query surfaces as a ClickHouseError.
- name: Run integration tests against the published package
run: node src/integration.ts
112 changes: 112 additions & 0 deletions .github/workflows/tests-dist.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: "dist"

permissions: {}
on:
workflow_dispatch:
push:
branches:
- main
- release
paths:
- "packages/**"
- "tests/**"
- "package.json"
- "package-lock.json"
- "tsconfig.base.json"
- "tsconfig.dev.json"
- "eslint.config.base.mjs"
- "docker-compose.yml"
- "vitest.node.config.ts"
- "vitest.node.setup.ts"
- "vitest.web.config.ts"
- "vitest.web.setup.ts"
- ".github/workflows/tests-dist.yml"
pull_request:
paths:
- "packages/**"
- "tests/**"
- "package.json"
- "package-lock.json"
- "tsconfig.base.json"
- "tsconfig.dev.json"
- "eslint.config.base.mjs"
- "docker-compose.yml"
- "vitest.node.config.ts"
- "vitest.node.setup.ts"
- "vitest.web.config.ts"
- "vitest.web.setup.ts"
- ".github/workflows/tests-dist.yml"

schedule:
- cron: "0 9 * * *"

concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true

# Integration tests resolved against the BUILT `dist` packages (TEST_TARGET=dist)
# instead of the workspace `src`. This is the published-surface / bundle guard:
# it catches build output, packaging, and single-bundle module-identity issues
# (e.g. a value class like SettingsMap/TupleParam resolving to a second copy and
# breaking the client's internal `instanceof` checks) that the fast, build-free
# `src` loop cannot. Behavioural coverage across Node/ClickHouse versions already
# runs in the `node`/`web` workflows, so this targets only the stable ClickHouse
# release on a local single-node instance with the canonical Node.js version.
jobs:
node-dist-integration:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3

- name: Start ClickHouse (stable) in Docker
uses: hoverkraft-tech/compose-action@11beaa1c2dae4e8ed7b1665aa074723b6cecb0e4 # v3.0.0
env:
CLICKHOUSE_VERSION: latest
with:
compose-file: "docker-compose.yml"
down-flags: "--volumes"

- name: Setup NodeJS
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 24

- name: Install dependencies
run: npm ci

# test:node:integration:dist builds the workspace packages first, then runs
# the node integration suite with TEST_TARGET=dist.
- name: Run node integration tests against dist
run: npm run test:node:integration:dist

web-dist-integration:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3

- name: Start ClickHouse (stable) in Docker
uses: hoverkraft-tech/compose-action@11beaa1c2dae4e8ed7b1665aa074723b6cecb0e4 # v3.0.0
env:
CLICKHOUSE_VERSION: latest
with:
compose-file: "docker-compose.yml"
down-flags: "--volumes"

- name: Setup NodeJS
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 24

- name: Install dependencies
run: |
npm ci
npx playwright install chromium

# test:web:integration:dist builds the workspace packages first, then runs
# the web integration suite with TEST_TARGET=dist.
- name: Run web integration tests against dist
env:
BROWSER: chromium
run: npm run test:web:integration:dist
21 changes: 0 additions & 21 deletions .github/workflows/tests-node.yml
Original file line number Diff line number Diff line change
Expand Up @@ -357,24 +357,3 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage/lcov.info
fail_ci_if_error: true

success:
needs:
[
"code-quality",
"common-unit-tests",
"unit-tests",
"integration-tests-local-single-node",
"integration-tests-local-cluster",
"integration-tests-cloud",
]
# Run even if some needed jobs were skipped (e.g. cloud jobs on PRs from forks),
# but still fail if any of them failed or were cancelled.
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Fail if any needed job failed or was cancelled
if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
run: exit 1
- name: All tests passed
run: echo "All tests passed! 🎉"
11 changes: 0 additions & 11 deletions .github/workflows/tests-oss-dependents.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,3 @@ jobs:
- name: Run OSS-dependent integration tests
run: |
npm run test:node:oss-dependents

success:
needs: ["oss-dependents-tests"]
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Fail if any needed job failed or was cancelled
if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
run: exit 1
- name: All OSS-dependent tests passed
run: echo "All OSS-dependent tests passed! 🎉"
19 changes: 0 additions & 19 deletions .github/workflows/tests-web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -255,22 +255,3 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage/lcov.info
fail_ci_if_error: true

success:
needs:
[
"common-unit-tests",
"all-tests-local-single-node",
"integration-tests-local-cluster",
"integration-tests-cloud",
]
# Run even if some needed jobs were skipped (e.g. cloud jobs on PRs from forks),
# but still fail if any of them failed or were cancelled.
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Fail if any needed job failed or was cancelled
if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
run: exit 1
- name: All tests passed
run: echo "All tests passed! 🎉"
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@
"test:node:unit:bun": "CLICKHOUSE_TEST_SKIP_INIT=1 TEST_MODE=unit bun --bun vitest -c vitest.node.config.ts",
"test:node:integration:tls": "TEST_MODE=tls vitest -c vitest.node.config.ts",
"test:node:integration": "TEST_MODE=integration vitest -c vitest.node.config.ts",
"test:node:integration:dist": "npm run build && TEST_TARGET=dist TEST_MODE=integration vitest -c vitest.node.config.ts",
"test:node:oss-dependents": "TEST_MODE=oss-dependents vitest -c vitest.node.config.ts",
"test:node:integration:local_cluster": "CLICKHOUSE_TEST_ENVIRONMENT=local_cluster TEST_MODE=integration vitest -c vitest.node.config.ts",
"test:node:integration:cloud": "CLICKHOUSE_TEST_ENVIRONMENT=cloud TEST_MODE=integration vitest -c vitest.node.config.ts",
"test:node:all": "TEST_MODE=all vitest -c vitest.node.config.ts",
"test:node:coverage": "VITEST_COVERAGE=true TEST_MODE=all vitest -c vitest.node.config.ts",
"test:web:unit": "CLICKHOUSE_TEST_SKIP_INIT=1 TEST_MODE=unit vitest -c vitest.web.config.ts",
"test:web:integration": "TEST_MODE=integration vitest -c vitest.web.config.ts",
"test:web:integration:dist": "npm run build && TEST_TARGET=dist TEST_MODE=integration vitest -c vitest.web.config.ts",
"test:web:integration:local_cluster": "TEST_MODE=integration CLICKHOUSE_TEST_ENVIRONMENT=local_cluster vitest -c vitest.web.config.ts",
"test:web:integration:cloud": "TEST_MODE=integration CLICKHOUSE_TEST_ENVIRONMENT=cloud vitest -c vitest.web.config.ts",
"test:web:integration:cloud:jwt": "TEST_MODE=jwt CLICKHOUSE_TEST_ENVIRONMENT=cloud vitest -c vitest.web.config.ts",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, vi } from "vitest";
import { TestEnv, isOnEnv } from "@test/utils/test_env";
import http from "http";
import Http from "http";
import { createClient } from "../../src";
import { createClient } from "@clickhouse/client";

/** HTTPS agent tests are in tls.test.ts as it requires a secure connection. */

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import { createTestClient } from "@test/utils/client";
import * as http from "http";
import { AddressInfo } from "net";
import type { NodeClickHouseClientConfigOptions } from "../../src/config";
import type { ClickHouseClientConfigOptions } from "@clickhouse/client";

describe("[Node.js] Eager socket destruction", () => {
afterEach(() => {
Expand Down Expand Up @@ -52,7 +52,7 @@ describe("[Node.js] Eager socket destruction", () => {
LoggerClass: CapturingLogger,
level: ClickHouseLogLevel.TRACE,
},
} as NodeClickHouseClientConfigOptions);
} as ClickHouseClientConfigOptions);

try {
// Capture the current timestamp before the first request so that
Expand Down Expand Up @@ -130,7 +130,7 @@ describe("[Node.js] Eager socket destruction", () => {
LoggerClass: CapturingLogger,
level: ClickHouseLogLevel.WARN,
},
} as NodeClickHouseClientConfigOptions);
} as ClickHouseClientConfigOptions);

try {
// Capture the current timestamp before the first request so that
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, it, expect } from "vitest";
import { createClient } from "../../src";
import { createClient } from "@clickhouse/client";

describe("[Node.js] errors parsing", () => {
it("should return an error when URL is unreachable", async () => {
Expand Down
58 changes: 7 additions & 51 deletions packages/client-node/__tests__/integration/node_exec.test.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,17 @@
import {
DefaultLogger,
LogWriter,
type ClickHouseClient,
ClickHouseLogLevel,
} from "@clickhouse/client-common";
import type { ClickHouseClient } from "@clickhouse/client-common";
import { describe, it, beforeEach, afterEach, expect } from "vitest";
import { createSimpleTable } from "@test/fixtures/simple_table";
import { createTestClient } from "@test/utils/client";
import { guid } from "@test/utils/guid";
import Stream from "stream";
import Zlib from "zlib";
import { ResultSet } from "../../src";
import { drainStreamInternal } from "../../src/connection/stream";
import { getAsText } from "../../src/utils";
import { ResultSet, drainStream } from "@clickhouse/client";
import { getAsText } from "../utils/stream";

describe("[Node.js] exec", () => {
let client: ClickHouseClient<Stream.Readable>;
let log_writer: LogWriter;
beforeEach(() => {
client = createTestClient();
log_writer = new LogWriter(
new DefaultLogger(),
"Connection",
ClickHouseLogLevel.OFF,
);
});
afterEach(async () => {
await client.close();
Expand Down Expand Up @@ -99,15 +87,7 @@ describe("[Node.js] exec", () => {
values: stream,
});
// the result stream contains nothing useful for an insert and should be immediately drained to release the socket
await drainStreamInternal(
{
op: "Insert",
query_id: execResult.query_id,
log_writer,
log_level: ClickHouseLogLevel.OFF,
},
execResult.stream,
);
await drainStream(execResult.stream);
await checkInsertedValues([
{
id: "42",
Expand All @@ -132,15 +112,7 @@ describe("[Node.js] exec", () => {
stream.push(null);
// the result stream contains nothing useful for an insert and should be immediately drained to release the socket
const execResult = await execPromise;
await drainStreamInternal(
{
op: "Insert",
query_id: execResult.query_id,
log_writer,
log_level: ClickHouseLogLevel.OFF,
},
execResult.stream,
);
await drainStream(execResult.stream);
await checkInsertedValues([]);
});

Expand All @@ -159,15 +131,7 @@ describe("[Node.js] exec", () => {
values: stream,
});
// the result stream contains nothing useful for an insert and should be immediately drained to release the socket
await drainStreamInternal(
{
op: "Insert",
query_id: execResult.query_id,
log_writer,
log_level: ClickHouseLogLevel.OFF,
},
execResult.stream,
);
await drainStream(execResult.stream);
await checkInsertedValues([
{
id: "42",
Expand All @@ -191,15 +155,7 @@ describe("[Node.js] exec", () => {
values: stream,
});
// the result stream contains nothing useful for an insert and should be immediately drained to release the socket
await drainStreamInternal(
{
op: "Insert",
query_id: execResult.query_id,
log_writer,
log_level: ClickHouseLogLevel.OFF,
},
execResult.stream,
);
await drainStream(execResult.stream);
await checkInsertedValues([]);
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { describe, it, expect, beforeAll, afterEach } from "vitest";
import { TestEnv, isOnEnv } from "@test/utils/test_env";
import { EnvKeys, getFromEnv, maybeGetFromEnv } from "@test/utils/env";
import { createClient } from "../../src";
import type { NodeClickHouseClient } from "../../src/client";
import { createClient } from "@clickhouse/client";
import type { ClickHouseClient } from "@clickhouse/client";

describe.skipIf(!isOnEnv(TestEnv.Cloud))("[Node.js] JWT auth", () => {
let jwtClient: NodeClickHouseClient;
let jwtClient: ClickHouseClient;
let url: string;
let jwt: string | undefined;

Expand Down
Loading