From 8fc321aca3c0be5ecbff42b303095861bca7e755 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat <ariya@metabase.com> Date: Thu, 4 Nov 2021 12:35:09 -0700 Subject: [PATCH] CI with GitHub Action: run tokenizer fuzzing tests (#18841) --- .github/workflows/fuzzing.yml | 43 +++++++++++++++++++ .../expressions/fuzz.tokenizer.unit.spec.js | 27 ++++++++++++ .../lib/expressions/tokenizer.unit.spec.js | 19 -------- 3 files changed, 70 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/fuzzing.yml create mode 100644 frontend/test/metabase/lib/expressions/fuzz.tokenizer.unit.spec.js diff --git a/.github/workflows/fuzzing.yml b/.github/workflows/fuzzing.yml new file mode 100644 index 00000000000..64ff87ab6b8 --- /dev/null +++ b/.github/workflows/fuzzing.yml @@ -0,0 +1,43 @@ +name: Fuzzing + +on: + push: + branches: + - '**' + paths: + - 'frontend/**' + - 'shared/**' + - 'enterprise/frontend/**' + - 'docs/**' + - '**/package.json' + - '**/yarn.lock' + - '**/.eslintrc' + - '.github/workflows/**' + pull_request: + +jobs: + + fe-fuzz-tokenizer: + runs-on: ubuntu-20.04 + timeout-minutes: 7 + steps: + - uses: actions/checkout@v2 + - name: Prepare Node.js + uses: actions/setup-node@v1 + with: + node-version: 14.x + - name: Get M2 cache + uses: actions/cache@v2 + with: + path: ~/.m2 + key: ${{ runner.os }}-cljs-${{ hashFiles('**/shadow-cljs.edn') }} + - name: Get yarn cache + uses: actions/cache@v2 + with: + path: ~/.cache/yarn + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + - run: yarn install --frozen-lockfile --prefer-offline + - run: yarn test-unit frontend/test/metabase/lib/expressions/fuzz.tokenizer.unit.spec.js + env: + MB_FUZZ: 1 + name: Run fuzz testing on the tokenizer diff --git a/frontend/test/metabase/lib/expressions/fuzz.tokenizer.unit.spec.js b/frontend/test/metabase/lib/expressions/fuzz.tokenizer.unit.spec.js new file mode 100644 index 00000000000..1867aa885c5 --- /dev/null +++ b/frontend/test/metabase/lib/expressions/fuzz.tokenizer.unit.spec.js @@ -0,0 +1,27 @@ +import { tokenize } from "metabase/lib/expressions/tokenizer"; + +import { generateExpression } from "./generator"; + +const fuzz = process.env.MB_FUZZ ? describe : describe.skip; + +describe("metabase/lib/expressions/tokenizer", () => { + // quick sanity check before the real fuzzing + it("should tokenize custom expresssion", () => { + expect(() => tokenize("CASE([Deal],[Price]*7e-1,[Price]")).not.toThrow(); + }); +}); + +fuzz("FUZZING metabase/lib/expressions/tokenizer", () => { + const MAX_SEED = 5e4; + + for (let seed = 0; seed < MAX_SEED; ++seed) { + it("should handle generated expression from seed " + seed, () => { + const { expression } = generateExpression(seed); + expect(() => tokenize(expression)).not.toThrow(); + }); + it("should not error on generated expression from seed " + seed, () => { + const { expression } = generateExpression(seed); + expect(tokenize(expression).errors).toEqual([]); + }); + } +}); diff --git a/frontend/test/metabase/lib/expressions/tokenizer.unit.spec.js b/frontend/test/metabase/lib/expressions/tokenizer.unit.spec.js index dad7655c5ee..91a2163cbe8 100644 --- a/frontend/test/metabase/lib/expressions/tokenizer.unit.spec.js +++ b/frontend/test/metabase/lib/expressions/tokenizer.unit.spec.js @@ -4,8 +4,6 @@ import { OPERATOR as OP, } from "metabase/lib/expressions/tokenizer"; -import { generateExpression } from "./generator"; - describe("metabase/lib/expressions/tokenizer", () => { const types = expr => tokenize(expr).tokens.map(t => t.type); const ops = expr => tokenize(expr).tokens.map(t => t.op); @@ -142,20 +140,3 @@ describe("metabase/lib/expressions/tokenizer", () => { expect(errors(" #")[0].pos).toEqual(4); }); }); - -if (process.env.MB_FUZZ) { - describe("FUZZING metabase/lib/expressions/tokenizer", () => { - const MAX_SEED = 5e4; - - for (let seed = 0; seed < MAX_SEED; ++seed) { - it("should handle generated expression from seed " + seed, () => { - const { expression } = generateExpression(seed); - expect(() => tokenize(expression)).not.toThrow(); - }); - it("should not error on generated expression from seed " + seed, () => { - const { expression } = generateExpression(seed); - expect(tokenize(expression).errors).toEqual([]); - }); - } - }); -} -- GitLab