Skip to content

Commit dc12a27

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

File tree

9 files changed

+193
-1
lines changed

9 files changed

+193
-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",
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: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { DriverTests } from '@cubejs-backend/testing-shared';
2+
3+
const DremioDriver = require('../../driver/DremioDriver');
4+
5+
describe('DremioDriver', () => {
6+
let tests: DriverTests;
7+
8+
jest.setTimeout(10 * 60 * 1000); // Engine needs to spin up
9+
10+
beforeAll(async () => {
11+
tests = new DriverTests(new DremioDriver({}), { expectStringFields: false });
12+
});
13+
14+
afterAll(async () => {
15+
await tests.release();
16+
});
17+
18+
test('query', async () => {
19+
await tests.testQuery();
20+
});
21+
});
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { prepareCompiler as originalPrepareCompiler } from '@cubejs-backend/schema-compiler';
2+
3+
const DremioQuery = require('../../driver/DremioQuery');
4+
5+
const prepareCompiler = (content: string) => originalPrepareCompiler({
6+
localPath: () => __dirname,
7+
dataSchemaFiles: () => Promise.resolve([{ fileName: 'main.js', content }]),
8+
});
9+
10+
describe('DremioQuery', () => {
11+
12+
jest.setTimeout(10 * 60 * 1000); // Engine needs to spin up
13+
14+
const { compiler, joinGraph, cubeEvaluator } = prepareCompiler(
15+
`
16+
cube(\`sales\`, {
17+
sql: \` select * from public.sales \`,
18+
19+
measures: {
20+
count: {
21+
type: 'count'
22+
}
23+
},
24+
dimensions: {
25+
category: {
26+
type: 'string',
27+
sql: 'category'
28+
},
29+
salesDatetime: {
30+
type: 'time',
31+
sql: 'sales_datetime'
32+
},
33+
isShiped: {
34+
type: 'boolean',
35+
sql: 'is_shiped',
36+
},
37+
}
38+
});
39+
`,
40+
);
41+
42+
it('should use DATE_TRUNC for time granularity dimensions', () => compiler.compile().then(() => {
43+
const query = new DremioQuery(
44+
{ joinGraph, cubeEvaluator, compiler },
45+
{
46+
measures: ['sales.count'],
47+
timeDimensions: [
48+
{
49+
dimension: 'sales.salesDatetime',
50+
granularity: 'day',
51+
dateRange: ['2017-01-01', '2017-01-02'],
52+
},
53+
],
54+
timezone: 'America/Los_Angeles',
55+
order: [
56+
{
57+
id: 'sales.salesDatetime',
58+
},
59+
],
60+
}
61+
);
62+
63+
const queryAndParams = query.buildSqlAndParams();
64+
65+
expect(queryAndParams[0]).toContain(
66+
'DATE_TRUNC(\'day\', CONVERT_TIMEZONE(\'-08:00\', "sales".sales_datetime))'
67+
);
68+
}));
69+
70+
it('should cast BOOLEAN', () => compiler.compile().then(() => {
71+
const query = new DremioQuery(
72+
{ joinGraph, cubeEvaluator, compiler },
73+
{
74+
measures: ['sales.count'],
75+
filters: [
76+
{
77+
member: 'sales.isShiped',
78+
operator: 'equals',
79+
values: ['true']
80+
}
81+
]
82+
}
83+
);
84+
85+
const queryAndParams = query.buildSqlAndParams();
86+
87+
expect(queryAndParams[0]).toContain(
88+
'("sales".is_shiped = CAST(? AS BOOLEAN))'
89+
);
90+
91+
expect(queryAndParams[1]).toEqual(['true']);
92+
}));
93+
94+
it('should cast timestamp', () => compiler.compile().then(() => {
95+
const query = new DremioQuery(
96+
{ joinGraph, cubeEvaluator, compiler },
97+
{
98+
measures: ['sales.count'],
99+
timeDimensions: [
100+
{
101+
dimension: 'sales.salesDatetime',
102+
granularity: 'day',
103+
dateRange: ['2017-01-01', '2017-01-02'],
104+
},
105+
],
106+
timezone: 'America/Los_Angeles',
107+
order: [
108+
{
109+
id: 'sales.salesDatetime',
110+
},
111+
],
112+
}
113+
);
114+
115+
const queryAndParams = query.buildSqlAndParams();
116+
117+
expect(queryAndParams[0]).toContain(
118+
'("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\'))'
119+
);
120+
}));
121+
});
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_DREMIO_${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)