wallabyjs / public

Repository for Wallaby.js questions and issues
http://wallabyjs.com
760 stars 45 forks source link

Wallaby fails when testing database with transaction #2353

Closed HEYGUL closed 4 years ago

HEYGUL commented 4 years ago

Issue description or question

I am evaluating wallaby and it seems really a great tool to explore and improve an existing codebase. Unfortunately, I have a project based on hapi.js where all tests using database failed as the client is unable to get a pool connection.

I constantly get this error

Unable to acquire a connection

I am using knex, node and hapi.js. Any idea what I am missing ?

Wallaby diagnostics report

To get a shorter report, I focused on a single test file.

{
  editorVersion: 'IntelliJ IDEA 2019.3.3',
  pluginVersion: '1.0.162',
  editorType: 'IntelliJ',
  osVersion: 'darwin 18.7.0',
  nodeVersion: 'v12.14.1',
  coreVersion: '1.0.856',
  config: {
    files: [
      { pattern: 'bin/**/*.js', ignore: false, trigger: true, load: true, instrument: true, order: 1 },
      { pattern: 'lib/**/*.js', ignore: false, trigger: true, load: true, instrument: true, order: 2 },
      { pattern: 'db/**/*.js', ignore: false, trigger: true, load: true, instrument: true, order: 3 },
      { pattern: 'tests/tooling/**/*.js', ignore: false, trigger: true, load: true, instrument: true, order: 4 },
      { pattern: 'tests/test-helper.js', ignore: false, trigger: true, load: true, instrument: true, order: 5 },
      { pattern: 'server.js', ignore: false, trigger: true, load: true, instrument: true, order: 6 },
      { pattern: 'package.json', ignore: false, trigger: true, load: true, instrument: true, order: 7 },
      { pattern: 'scripts/*.js', ignore: false, trigger: true, load: true, instrument: true, order: 8 },
      { pattern: 'scripts/helpers/*.js', ignore: false, trigger: true, load: true, instrument: true, order: 9 },
      { pattern: 'scripts/database/*.js', ignore: false, trigger: true, load: true, instrument: true, order: 10 },
      { pattern: 'db/migrations', ignore: true, trigger: true, load: true, instrument: true },
      { pattern: 'db/seeds', ignore: true, trigger: true, load: true, instrument: true },
      { pattern: 'tests/acceptance/**/*.ods', ignore: false, trigger: true, load: true, instrument: true, order: 11 },
      { pattern: 'tests/integration/infrastructure/utils/ods/*.ods', ignore: false, trigger: true, load: true, instrument: true, order: 12 },
      { pattern: 'tests/unit/scripts/helpers/files/**', ignore: false, trigger: true, load: true, instrument: true, order: 13 }
    ],
    tests: [ { pattern: 'tests/**/*test.js', ignore: false, trigger: true, load: true, test: true, order: 14 } ],
    env: {
      type: 'node',
      runner: 'node',
      workers: { initial: 1, regular: 1, restart: true },
      params: {},
      viewportSize: { width: 800, height: 600 },
      options: { width: 800, height: 600 },
      bundle: true
    },
    diagnostics: {},
    filesWithNoCoverageCalculated: [],
    runAllTestsInAffectedTestFile: false,
    compilers: { '**/*.?(lit)coffee?(.md)': [Function] },
    preprocessors: {},
    maxConsoleMessagesPerTest: 100,
    autoConsoleLog: true,
    delays: { run: 0, edit: 100, update: 0 },
    workers: { initial: 0, regular: 0, recycle: false },
    teardown: undefined,
    hints: {
      ignoreCoverage: '__REGEXP /ignore coverage|istanbul ignore/',
      ignoreCoverageForFile: '__REGEXP /ignore file coverage/',
      commentAutoLog: '?',
      testFileSelection: { include: '__REGEXP /file\\.only/', exclude: '__REGEXP /file\\.skip/' }
    },
    automaticTestFileSelection: true,
    runSelectedTestsOnly: false,
    extensions: {},
    reportUnhandledPromises: true,
    testFramework: { version: 'mocha@2.1.0', configurator: 'mocha@2.1.0', reporter: 'mocha@2.1.0', starter: 'mocha@2.1.0' },
    slowTestThreshold: 75,
    lowCoverageThreshold: 80,
    loose: undefined,
    configCode: 'module.exports = function() {\n' +
      "  process.env.NODE_ENV = 'test';\n" +
      "  process.env.DEBUG = 'knex:query,knex:bindings,knex:tx';\n" +
      '\n' +
      '  return {\n' +
      '    files: [\n' +
      "      'bin/**/*.js',\n" +
      "      'lib/**/*.js',\n" +
      "      'db/**/*.js',\n" +
      "      'tests/tooling/**/*.js',\n" +
      "      'tests/test-helper.js',\n" +
      "      'server.js',\n" +
      "      'package.json',\n" +
      "      'scripts/*.js',\n" +
      "      'scripts/helpers/*.js',\n" +
      "      'scripts/database/*.js',\n" +
      "      { pattern: 'db/migrations', ignore: true },\n" +
      "      { pattern: 'db/seeds', ignore: true },\n" +
      "      'tests/acceptance/**/*.ods',\n" +
      "      'tests/integration/infrastructure/utils/ods/*.ods',\n" +
      "      'tests/unit/scripts/helpers/files/**',\n" +
      '    ],\n' +
      '    tests: [\n' +
      "      'tests/**/*test.js'\n" +
      '    ],\n' +
      '    env: {\n' +
      "      type: 'node',\n" +
      "      runner: 'node',\n" +
      '      workers: {\n' +
      '        initial: 1,\n' +
      '        regular: 1,\n' +
      '        restart: true\n' +
      '      }\n' +
      '    },\n' +
      '  };\n' +
      '};\n'
  },
  packageJSON: {
    dependencies: {
      '@hapi/hapi': '^18.4.1',
      '@hapi/inert': '^5.2.2',
      '@hapi/joi': '^16.1.8',
      '@hapi/joi-date': '^2.0.1',
      '@hapi/vision': '^5.5.4',
      airtable: '^0.8.0',
      bcrypt: '^3.0.7',
      blipp: '^4.0.1',
      bluebird: '^3.7.1',
      bookshelf: '^0.15.1',
      'bookshelf-page': '^0.3.2',
      'bookshelf-validate': '^2.0.3',
      boom: '^7.3.0',
      bunyan: '^1.8.12',
      catbox: '^10.0.6',
      'catbox-memory': '^4.0.1',
      dezalgo: '^1.0.3',
      dotenv: '^8.2.0',
      faker: '^4.1.0',
      'fast-levenshtein': '^2.0.6',
      good: '^8.1.2',
      'good-console': '^8.0.0',
      'good-squeeze': '^5.1.0',
      'hapi-sentry': '^2.1.0',
      'hapi-swagger': '^11.0.0',
      'hash-int': '^1.0.0',
      'heap-profile': '^0.4.0',
      heapdump: '^0.3.15',
      json2csv: '^4.5.4',
      'jsonapi-serializer': '^3.6.5',
      jsonwebtoken: '^8.5.1',
      jszip: '3.2.2',
      knex: '^0.20.2',
      lodash: '^4.17.15',
      moment: '^2.24.0',
      'moment-timezone': '^0.5.27',
      'node-cache': '^5.0.2',
      'node-cron': '^2.0.3',
      'node-mailjet': '^3.3.1',
      papaparse: '^5.1.0',
      path: '^0.12.7',
      pg: '^7.14.0',
      'prom-client': '^11.5.3',
      randomstring: '^1.1.5',
      redis: '^2.8.0',
      redlock: '^3.1.2',
      request: '^2.88.0',
      'request-promise-native': '^1.0.8',
      samlify: 'github:1024pix/samlify#no-xml-validation',
      'sib-api-v3-sdk': '^7.1.4',
      xlsx: '^0.15.3',
      'xml-buffer-tostring': '^0.2.0',
      'xml-crypto': '~1.0.2',
      xmldom: '0.1.27',
      xregexp: '^4.2.4',
      yamljs: '^0.3.0'
    },
    devDependencies: {
      chai: '^4.2.0',
      'chai-as-promised': '^7.1.1',
      'chai-sorted': '^0.2.0',
      eslint: '^6.7.1',
      'eslint-plugin-mocha': '^6.2.2',
      esm: '3.2.25',
      'iconv-lite': '^0.5.0',
      mocha: '^6.2.2',
      nock: '^11.7.0',
      nodemon: '^2.0.1',
      nyc: '^14.1.1',
      sinon: '^7.5.0',
      'sinon-chai': '^3.3.0',
      'stream-to-promise': '^2.2.0'
    }
  },
  fs: { numberOfFiles: 1241 },
  debug: [
    '2020-02-27T21:45:07.950Z project Wallaby Node version: v12.14.1\n',
    '2020-02-27T21:45:07.951Z project Wallaby config: <homeDir>/Documents/Missions/gip-pix/pix/api/wallaby.js\n',
    '2020-02-27T21:45:09.297Z project File cache: <homeDir>/Library/Caches/IntelliJIdea2019.3/wallaby/projects/e5dd3117c9272e74\n',
    '2020-02-27T21:45:09.310Z uiService Listening port 51235\n',
    '2020-02-27T21:45:09.393Z workers Parallelism for initial run: 10, for regular run: 5\n',
    '2020-02-27T21:45:09.393Z workers Starting run worker instance #0\n',
    '2020-02-27T21:45:09.393Z workers Starting run worker instance #1\n',
    '2020-02-27T21:45:09.393Z workers Starting run worker instance #2\n',
    '2020-02-27T21:45:09.393Z workers Starting run worker instance #3\n',
    '2020-02-27T21:45:09.394Z workers Starting run worker instance #4\n',
    '2020-02-27T21:45:09.394Z workers Starting run worker instance #5\n',
    '2020-02-27T21:45:09.394Z workers Starting run worker instance #6\n',
    '2020-02-27T21:45:09.394Z workers Starting run worker instance #7\n',
    '2020-02-27T21:45:09.394Z workers Starting run worker instance #8\n',
    '2020-02-27T21:45:09.394Z workers Starting run worker instance #9\n',
    '2020-02-27T21:45:09.424Z workers Web server is listening at 56633\n',
    '2020-02-27T21:45:09.692Z uiService UI client connected\n',
    '2020-02-27T21:45:09.692Z uiService Outgoing message ui:handshake\n',
    '2020-02-27T21:45:09.718Z uiService Incoming message ui:tests:resultsRequested\n',
    '2020-02-27T21:45:09.729Z uiService Outgoing message ui:tests:allResultsUpdated\n',
    '2020-02-27T21:45:09.730Z uiService Incoming message ui:start\n',
    '2020-02-27T21:45:09.733Z uiService Outgoing message ui:summary\n',
    '2020-02-27T21:45:09.740Z uiService Outgoing message ui:files\n',
    '2020-02-27T21:45:09.779Z project File cache requires some updates, waiting required files from IDE\n',
    '2020-02-27T21:45:09.783Z workers Started run worker instance (delayed) #1\n',
    '2020-02-27T21:45:09.783Z workers Started run worker instance (delayed) #3\n',
    '2020-02-27T21:45:09.784Z workers Started run worker instance (delayed) #0\n',
    '2020-02-27T21:45:09.785Z workers Started run worker instance (delayed) #2\n',
    '2020-02-27T21:45:09.785Z workers Started run worker instance (delayed) #4\n',
    '2020-02-27T21:45:09.785Z workers Started run worker instance (delayed) #5\n',
    '2020-02-27T21:45:09.787Z uiService Outgoing message ui:files\n',
    '2020-02-27T21:45:09.787Z uiService Outgoing message ui:busy\n',
    '2020-02-27T21:45:09.985Z workers Started run worker instance (delayed) #6\n',
    '2020-02-27T21:45:09.985Z workers Started run worker instance (delayed) #7\n',
    '2020-02-27T21:45:09.986Z workers Started run worker instance (delayed) #9\n',
    '2020-02-27T21:45:09.991Z workers Started run worker instance (delayed) #8\n',
    '2020-02-27T21:45:10.227Z project Stopping process pool\n',
    '2020-02-27T21:45:10.230Z uiService Outgoing message ui:busy\n',
    '2020-02-27T21:45:10.231Z project Running postprocessor\n',
    '2020-02-27T21:45:10.270Z postprocessor New TypeScript language service is required\n',
    "2020-02-27T21:45:10.284Z postprocessor TypeScript postprocessor will be removed because in 1241 project files none were found by patterns: [ '**/*.ts?(x)' ]\n",
    '2020-02-27T21:45:10.286Z project Postprocessor execution finished\n',
    '2020-02-27T21:45:10.286Z project Postprocessor is removed as requested by itself\n',
    '2020-02-27T21:45:10.286Z project Test run started; run priority: 3\n',
    '2020-02-27T21:45:10.286Z project Running all tests\n',
    '2020-02-27T21:45:10.293Z workers Starting test run, priority: 3\n',
    '2020-02-27T21:45:10.293Z nodeRunner Starting sandbox [worker #0, session #1nhhl]\n',
    '2020-02-27T21:45:10.293Z nodeRunner Preparing sandbox [worker #0, session #1nhhl]\n',
    '2020-02-27T21:45:10.293Z nodeRunner Prepared sandbox [worker #0, session #1nhhl]\n',
    '2020-02-27T21:45:10.293Z workers [worker #0, session #1nhhl] Running tests in sandbox\n',
    '2020-02-27T21:45:10.996Z workers [1nhhl] Loaded 8 test(s)\n',
    '2020-02-27T21:45:11.001Z workers [1nhhl] Test executed: should convert a Bookshelf object into a domain object\n',
    '2020-02-27T21:45:11.001Z workers Failed to map the stack to user code, entry message: Unable to acquire a connection, stack: Error: Unable to acquire a connection\n' +
      '    at Client_PG.acquireConnection (<homeDir>/Documents/Missions/gip-pix/pix/api/node_modules/knex/lib/client.js:343:30)\n' +
      '    at Runner.ensureConnection (<homeDir>/Documents/Missions/gip-pix/pix/api/node_modules/knex/lib/runner.js:243:8)\n' +
      '    at Runner.run (<homeDir>/Documents/Missions/gip-pix/pix/api/node_modules/knex/lib/runner.js:25:12)\n' +
      '    at Raw.Target.then (<homeDir>/Documents/Missions/gip-pix/pix/api/node_modules/knex/lib/interface.js:15:43)\n',
    '2020-02-27T21:45:11.006Z workers [1nhhl] Test executed: should populate the domain object with the matching Bookshelf properties\n',
    '2020-02-27T21:45:11.007Z workers [1nhhl] Test executed: should honor the domain object constructor\n',
    '2020-02-27T21:45:11.008Z workers [1nhhl] Test executed: should support has-one relationships\n',
    '2020-02-27T21:45:11.013Z workers [1nhhl] Test executed: should support has-many relationships\n',
    '2020-02-27T21:45:11.018Z workers [1nhhl] Test executed: should support belongs-to relationships\n',
    '2020-02-27T21:45:11.025Z workers [1nhhl] Test executed: should support domain object relationship’s name not matching the corresponding Bookshelf class name\n',
    '2020-02-27T21:45:11.026Z workers [1nhhl] Test executed: should support nested relationships\n',
    '2020-02-27T21:45:11.167Z workers [1nhhl] Run 8 test(s), skipped 0 test(s)\n',
    '2020-02-27T21:45:11.168Z workers [1nhhl] Sandbox is responsive, closing it\n',
    '2020-02-27T21:45:11.169Z project Test run finished\n',
    '2020-02-27T21:45:11.169Z project Processed console.log entries\n',
    '2020-02-27T21:45:11.170Z project Processed loading sequences\n',
    '2020-02-27T21:45:11.171Z project Processed executed tests\n',
    '2020-02-27T21:45:11.242Z project Processed code coverage\n',
    '2020-02-27T21:45:11.245Z project Processed code trace\n',
    '2020-02-27T21:45:11.541Z project Test run result processed and sent to IDE\n',
    '2020-02-27T21:45:11.541Z uiService Outgoing message ui:summary\n',
    '2020-02-27T21:45:11.543Z uiService Outgoing message ui:tests:allResultsUpdated\n',
    '2020-02-27T21:45:11.554Z uiService Outgoing message ui:coverageChanged\n'
  ]
}
smcenlly commented 4 years ago

We'll need a bit more information about your project in order to be able to help, can you please answer the following:

1) We're assuming that your tests run outside of wallaby (e.g. from the CLI), is that correct? If so, what test runner are you using, can you please share your config/scripts? 2) When running your tests, are you doing anything special to set up your database for your database tests? If so, you'll need to do a similar thing for Wallaby, the setup function in your Wallaby configuration may be the right place to initialize your database.

Is it possible for you to provide us with a cut-down repo that has a single database test failing in Wallaby but passing from the CLI for us to look at for you (you should be able to strip out all of your application code so it's just a sample instead of any proprietary code)? This will allow us to see how your database is being initialized outside of wallaby and provide a Wallaby configuration for you that does the same.

HEYGUL commented 4 years ago

We'll need a bit more information about your project in order to be able to help, can you please answer the following:

  1. We're assuming that your tests run outside of wallaby (e.g. from the CLI), is that correct? If so, what test runner are you using, can you please share your config/scripts?

We use mocha. I confirm tests are ok from the CLI.

  1. When running your tests, are you doing anything special to set up your database for your database tests? If so, you'll need to do a similar thing for Wallaby, the setup function in your Wallaby configuration may be the right place to initialize your database.

I will have a closer look to this part.

Is it possible for you to provide us with a cut-down repo that has a single database test failing in Wallaby but passing from the CLI for us to look at for you (you should be able to strip out all of your application code so it's just a sample instead of any proprietary code)? This will allow us to see how your database is being initialized outside of wallaby and provide a Wallaby configuration for you that does the same.

The code base is open source : github.com/1024pix/pix I am working on the api subdir for the moment.

Thank you for the quick reply.

smcenlly commented 4 years ago

Thanks for sharing your repo. We've taken a look at your project and can see that you have database set up and initialization logic that needs to be reflected in your wallaby configuration.

Unfortunately we can't get your repo working on our PCs (we're using Windows and expect that is most of the reason why it's not working) so we can't provide specific instructions as to what you'll need to do.

When you run your tests using npm run test on the api project, it is running other scripts (node, and kflex that drop, create, and migrate your database). You'll need to replicate this logic in Wallaby's setup function. If you keep the worker settings that you already have (workers: { initial: 1, regular: 1, restart: true }) then that is all you should need to do. If some of this logic is asynchronous then you will need to use the delayStart() and start() methods described in the setup function docs.

If you get stuck or have problems, let us know. I'll close the issue for now but will re-open it if you run into problems or have further related issues.