From 77cccb83a5eb7faf6fea53b9c01c69d26bf3e013 Mon Sep 17 00:00:00 2001 From: Vitaly Puzrin Date: Fri, 20 Nov 2020 23:49:36 +0300 Subject: [PATCH] Restrict pathological tests execution time --- package.json | 1 + test/pathological.js | 96 +++++++++++++++++++++++++------------ test/pathological_worker.js | 7 +++ 3 files changed, 73 insertions(+), 31 deletions(-) create mode 100644 test/pathological_worker.js diff --git a/package.json b/package.json index afe84f1..05271e0 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "express": "^4.14.0", "gh-pages": "^3.1.0", "highlight.js": "^10.0.3", + "jest-worker": "^26.6.2", "markdown-it-abbr": "^1.0.4", "markdown-it-container": "^3.0.0", "markdown-it-deflist": "^2.0.0", diff --git a/test/pathological.js b/test/pathological.js index 2074513..fb7e44a 100644 --- a/test/pathological.js +++ b/test/pathological.js @@ -1,13 +1,47 @@ 'use strict'; -const markdownit = require('../'); const needle = require('needle'); const assert = require('assert'); const crypto = require('crypto'); +const Worker = require('jest-worker').default; + + +async function test_pattern(str) { + const worker = new Worker(require.resolve('./pathological_worker.js'), { + numWorkers: 1, + enableWorkerThreads: true + }); + + let result; + + try { + result = await Promise.race([ + worker.render(str), + + new Promise(function (resolve, reject){ + setTimeout(() => { reject(new Error('Terminated (timeout exceeded)')); }, 3000); + }) + ]); + } catch (e) { + throw e; + } finally { + await worker.end(); + } + + return result; +} + describe('Pathological sequences speed', () => { + it('Integrity check', async () => { + assert.strictEqual( + await test_pattern('foo'), + '

foo

\n' + ); + }); + // Ported from cmark, https://github.com/commonmark/cmark/blob/master/test/pathological_tests.py describe('Cmark', () => { @@ -23,64 +57,64 @@ describe('Pathological sequences speed', () => { ); }); - it('nested strong emph', () => { - markdownit().render('*a **a '.repeat(5000) + 'b' + ' a** a*'.repeat(5000)); + it('nested strong emph', async () => { + await test_pattern('*a **a '.repeat(5000) + 'b' + ' a** a*'.repeat(5000)); }); - it('many emph closers with no openers', () => { - markdownit().render('a_ '.repeat(30000)); + it('many emph closers with no openers', async () => { + await test_pattern('a_ '.repeat(30000)); }); - it('many emph openers with no closers', () => { - markdownit().render('_a '.repeat(30000)); + it('many emph openers with no closers', async () => { + await test_pattern('_a '.repeat(30000)); }); - it('many link closers with no openers', () => { - markdownit().render('a]'.repeat(10000)); + it('many link closers with no openers', async () => { + await test_pattern('a]'.repeat(10000)); }); - it('many link openers with no closers', () => { - markdownit().render('[a'.repeat(10000)); + it('many link openers with no closers', async () => { + await test_pattern('[a'.repeat(10000)); }); - it('mismatched openers and closers', () => { - markdownit().render('*a_ '.repeat(50000)); + it('mismatched openers and closers', async () => { + await test_pattern('*a_ '.repeat(50000)); }); - it('openers and closers multiple of 3', () => { - markdownit().render('a**b' + ('c* '.repeat(50000))); + it('openers and closers multiple of 3', async () => { + await test_pattern('a**b' + ('c* '.repeat(50000))); }); - it('link openers and emph closers', () => { - markdownit().render('[ a_'.repeat(10000)); + it('link openers and emph closers', async () => { + await test_pattern('[ a_'.repeat(10000)); }); - it('pattern [ (]( repeated', () => { - markdownit().render('[ (]('.repeat(40000)); + it('pattern [ (]( repeated', async () => { + await test_pattern('[ (]('.repeat(40000)); }); - it('nested brackets', () => { - markdownit().render('['.repeat(20000) + 'a' + ']'.repeat(20000)); + it('nested brackets', async () => { + await test_pattern('['.repeat(20000) + 'a' + ']'.repeat(20000)); }); - it('nested block quotes', () => { - markdownit().render('> '.repeat(50000) + 'a'); + it('nested block quotes', async () => { + await test_pattern('> '.repeat(50000) + 'a'); }); - it('deeply nested lists', () => { - markdownit().render(Array(1000).fill(0).map(function (_, x) { return ' '.repeat(x) + '* a\n'; }).join('')); + it('deeply nested lists', async () => { + await test_pattern(Array(1000).fill(0).map(function (_, x) { return ' '.repeat(x) + '* a\n'; }).join('')); }); - it('backticks', () => { - markdownit().render(Array(3000).fill(0).map(function (_, x) { return 'e' + '`'.repeat(x); }).join('')); + it('backticks', async () => { + await test_pattern(Array(3000).fill(0).map(function (_, x) { return 'e' + '`'.repeat(x); }).join('')); }); - it('unclosed links A', () => { - markdownit().render('[a]( { + await test_pattern('[a]( { - markdownit().render('[a](b'.repeat(30000)); + it('unclosed links B', async () => { + await test_pattern('[a](b'.repeat(30000)); }); }); }); diff --git a/test/pathological_worker.js b/test/pathological_worker.js new file mode 100644 index 0000000..a04e9e5 --- /dev/null +++ b/test/pathological_worker.js @@ -0,0 +1,7 @@ +'use strict'; + +const markdownit = require('../'); + +exports.render = (str) => { + return markdownit().render(str); +};