Skip to content

Commit 6b04ea3

Browse files
committed
chore(dremio-driver): add basic integration tests for dremio cloud
1 parent d2c2fcd commit 6b04ea3

File tree

9 files changed

+188
-1
lines changed

9 files changed

+188
-1
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/bin/bash
2+
set -eo pipefail
3+
4+
# Debug log for test containers
5+
export DEBUG=testcontainers
6+
7+
echo "::group::Dremio [cloud]"
8+
yarn lerna run --concurrency 1 --stream --no-prefix integration:dremio
9+
10+
echo "::endgroup::"

.github/workflows/push.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ jobs:
316316
env:
317317
CLOUD_DATABASES: >
318318
firebolt
319+
dremio
319320
# Athena (just to check for secrets availability)
320321
DRIVERS_TESTS_ATHENA_CUBEJS_AWS_KEY: ${{ secrets.DRIVERS_TESTS_ATHENA_CUBEJS_AWS_KEY }}
321322

@@ -324,7 +325,7 @@ jobs:
324325
node-version: [20.x]
325326
db: [
326327
'clickhouse', 'druid', 'elasticsearch', 'mssql', 'mysql', 'postgres', 'prestodb',
327-
'mysql-aurora-serverless', 'crate', 'mongobi', 'firebolt'
328+
'mysql-aurora-serverless', 'crate', 'mongobi', 'firebolt', 'dremio'
328329
]
329330
fail-fast: false
330331

@@ -386,6 +387,10 @@ jobs:
386387
DRIVERS_TESTS_FIREBOLT_CUBEJS_FIREBOLT_ACCOUNT: ${{ secrets.DRIVERS_TESTS_FIREBOLT_CUBEJS_FIREBOLT_ACCOUNT }}
387388
DRIVERS_TESTS_FIREBOLT_CUBEJS_DB_USER: ${{ secrets.DRIVERS_TESTS_FIREBOLT_CUBEJS_DB_USER }}
388389
DRIVERS_TESTS_FIREBOLT_CUBEJS_DB_PASS: ${{ secrets.DRIVERS_TESTS_FIREBOLT_CUBEJS_DB_PASS }}
390+
# Dremio Integration
391+
DRIVERS_TESTS_DREMIO_CUBEJS_DB_URL: ${{ secrets.DRIVERS_TESTS_DREMIO_CUBEJS_DB_URL }}
392+
DRIVERS_TESTS_DREMIO_CUBEJS_DB_NAME: ${{ secrets.DRIVERS_TESTS_DREMIO_CUBEJS_DB_NAME }}
393+
DRIVERS_TESTS_DREMIO_CUBEJS_DB_DREMIO_AUTH_TOKEN: ${{ secrets.DRIVERS_TESTS_DREMIO_CUBEJS_DB_DREMIO_AUTH_TOKEN }}
389394

390395
integration-smoke:
391396
needs: [ latest-tag-sha, build-cubestore ]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dist

packages/cubejs-dremio-driver/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
},
1414
"main": "driver/DremioDriver.js",
1515
"scripts": {
16+
"tsc": "tsc",
17+
"watch": "tsc -w",
18+
"test": "yarn integration",
19+
"integration": "npm run integration:dremio",
20+
"integration:dremio": "jest --verbose dist/test --runInBand",
1621
"lint": "eslint driver/*.js",
1722
"lint:fix": "eslint driver/*.js"
1823
},
@@ -26,6 +31,7 @@
2631
},
2732
"devDependencies": {
2833
"@cubejs-backend/linter": "^1.0.0",
34+
"@cubejs-backend/testing-shared": "1.1.9",
2935
"jest": "^27"
3036
},
3137
"license": "Apache-2.0",
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { DriverTests } from '@cubejs-backend/testing-shared';
2+
const DremioDriver = require('../../driver/DremioDriver');
3+
4+
describe('DremioDriver', () => {
5+
let tests: DriverTests;
6+
7+
jest.setTimeout(3 * 60 * 1000); // Engine needs to spin up
8+
9+
beforeAll(async () => {
10+
tests = new DriverTests(new DremioDriver({}), { expectStringFields: false });
11+
});
12+
13+
afterAll(async () => {
14+
await tests.release();
15+
});
16+
17+
test('query', async () => {
18+
await tests.testQuery();
19+
});
20+
});
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import { prepareCompiler as originalPrepareCompiler } from '@cubejs-backend/schema-compiler';
2+
const DremioQuery = require('../../driver/DremioQuery');
3+
4+
const prepareCompiler = (content: string) => originalPrepareCompiler({
5+
localPath: () => __dirname,
6+
dataSchemaFiles: () => Promise.resolve([{ fileName: 'main.js', content }]),
7+
});
8+
9+
describe('DremioQuery', () => {
10+
const { compiler, joinGraph, cubeEvaluator } = prepareCompiler(
11+
`
12+
cube(\`sales\`, {
13+
sql: \` select * from public.sales \`,
14+
15+
measures: {
16+
count: {
17+
type: 'count'
18+
}
19+
},
20+
dimensions: {
21+
category: {
22+
type: 'string',
23+
sql: 'category'
24+
},
25+
salesDatetime: {
26+
type: 'time',
27+
sql: 'sales_datetime'
28+
},
29+
isShiped: {
30+
type: 'boolean',
31+
sql: 'is_shiped',
32+
},
33+
}
34+
});
35+
`,
36+
);
37+
38+
it('should use DATE_TRUNC for time granularity dimensions', () => compiler.compile().then(() => {
39+
const query = new DremioQuery(
40+
{ joinGraph, cubeEvaluator, compiler },
41+
{
42+
measures: ['sales.count'],
43+
timeDimensions: [
44+
{
45+
dimension: 'sales.salesDatetime',
46+
granularity: 'day',
47+
dateRange: ['2017-01-01', '2017-01-02'],
48+
},
49+
],
50+
timezone: 'America/Los_Angeles',
51+
order: [
52+
{
53+
id: 'sales.salesDatetime',
54+
},
55+
],
56+
}
57+
);
58+
59+
const queryAndParams = query.buildSqlAndParams();
60+
61+
expect(queryAndParams[0]).toContain(
62+
'DATE_TRUNC(\'day\', CONVERT_TIMEZONE(\'-08:00\', "sales".sales_datetime))'
63+
);
64+
}));
65+
66+
it('should cast BOOLEAN', () => compiler.compile().then(() => {
67+
const query = new DremioQuery(
68+
{ joinGraph, cubeEvaluator, compiler },
69+
{
70+
measures: ['sales.count'],
71+
filters: [
72+
{
73+
member: 'sales.isShiped',
74+
operator: 'equals',
75+
values: ['true']
76+
}
77+
]
78+
}
79+
);
80+
81+
const queryAndParams = query.buildSqlAndParams();
82+
83+
expect(queryAndParams[0]).toContain(
84+
'("sales".is_shiped = CAST(? AS BOOLEAN))'
85+
);
86+
87+
expect(queryAndParams[1]).toEqual(['true']);
88+
}));
89+
90+
it('should cast timestamp', () => compiler.compile().then(() => {
91+
const query = new DremioQuery(
92+
{ joinGraph, cubeEvaluator, compiler },
93+
{
94+
measures: ['sales.count'],
95+
timeDimensions: [
96+
{
97+
dimension: 'sales.salesDatetime',
98+
granularity: 'day',
99+
dateRange: ['2017-01-01', '2017-01-02'],
100+
},
101+
],
102+
timezone: 'America/Los_Angeles',
103+
order: [
104+
{
105+
id: 'sales.salesDatetime',
106+
},
107+
],
108+
}
109+
);
110+
111+
const queryAndParams = query.buildSqlAndParams();
112+
113+
expect(queryAndParams[0]).toContain(
114+
'("sales".sales_datetime >= TO_TIMESTAMP(?, \'YYYY-MM-DD"T"HH24:MI:SS.FFF\') AND "sales".sales_datetime <= TO_TIMESTAMP(?, \'YYYY-MM-DD"T"HH24:MI:SS.FFF\'))'
115+
);
116+
}));
117+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const REQUIRED_ENV_VARS = [
2+
'CUBEJS_DB_URL',
3+
'CUBEJS_DB_NAME',
4+
'CUBEJS_DB_DREMIO_AUTH_TOKEN',
5+
];
6+
7+
REQUIRED_ENV_VARS.forEach((key) => {
8+
// Trying to populate from DRIVERS_TESTS_DREMIO_* vars
9+
if (process.env[`DRIVERS_TESTS_FIREBOLT_${key}`] !== undefined) {
10+
process.env[key] = process.env[`DRIVERS_TESTS_DREMIO_${key}`];
11+
}
12+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"extends": "../../tsconfig.base.json",
3+
"include": [
4+
"src",
5+
"test"
6+
],
7+
"compilerOptions": {
8+
"outDir": "dist",
9+
"rootDir": ".",
10+
"baseUrl": ".",
11+
"resolveJsonModule": true
12+
}
13+
}

tsconfig.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@
5555
{
5656
"path": "packages/cubejs-duckdb-driver"
5757
},
58+
{
59+
"path": "packages/cubejs-dremio-driver"
60+
},
5861
{
5962
"path": "packages/cubejs-questdb-driver"
6063
},

0 commit comments

Comments
 (0)