wallabyjs / public

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

Wallaby constantly using 20% cpu when used in docker wiv devcontainer #3351

Closed eephyne closed 5 months ago

eephyne commented 5 months ago

I'm not sure its directly related to docker and devcontainer but I do not have the hardware to test it under native linux system right now.

I use vscode with devContainer. Wallaby works well in the docker container but I noticed a constant 20% cpu usage when I'm not coding (I leave vscode open and do something else). If I stop wallaby, the cpu usage drop to 0 and the node process who was eating 20% disappear.

I don't know how wallaby is working under the hood, but I may assume that those 20% are related to watching for file changes ? Is that a normal behavior ? Is there anything I can do to tweak that ( I was thinking about delays settings but I don't think thats directly related).

I'm using : wallaby v1.0.174 the node version in the container : v20.0.11

smcenlly commented 5 months ago

Wallaby does use polling for its file system watcher when using Linux. Having said that, it shouldn't cause performance issues unless you have a lot of files.

RE: CPU usage, did you check / isolate this to Wallaby (e.g. using top)?

Can you please capture your Wallaby Diagnostic report after you see the 20% CPU usage and provide it to us?

Wallaby's Diagnostics Report is a simple JSON text report that contains some basic information about your Wallaby config and project that is required to start troubleshooting most of Wallaby issues.

To share the report:

eephyne commented 5 months ago

Yes I did check with top in the container, and the process that take 20% is shutting down as soon as I stop wallaby and come up again if I restart it (it stabilize to 20% after all the test are done again).

{
  editorVersion: '1.87.2',
  pluginVersion: '1.0.371',
  editorType: 'VSCode',
  osVersion: 'linux 5.15.133.1-microsoft-standard-WSL2',
  nodeVersion: 'v20.11.0',
  coreVersion: '1.0.1549',
  checksum: 'MjYzNjMyZDVmNTc0ODA3MTBkNGI4NjZlMjA5ZGI5YjgsMTcyNjcwNDAwMDAwMCww',
  config: {
    diagnostics: {
      vitest: {
        file: {
          config: '/// <reference types="vitest" />\n' +
            '\n' +
            "import { defineConfig } from 'vite';\n" +
            "import react from '@vitejs/plugin-react-swc';\n" +
            "import tsconfigPaths from 'vite-tsconfig-paths';\n" +
            '\n' +
            '// https://vitejs.dev/config/\n' +
            'export default defineConfig({\n' +
            '  plugins: [react(), tsconfigPaths()],\n' +
            '  test: {\n' +
            '    globals: true,\n' +
            "    environment: 'jsdom',\n" +
            "    setupFiles: 'src/__e2e__/setup.ts',\n" +
            '  },\n' +
            '});\n'
        },
        config: {
          config: {
            allowOnly: true,
            isolate: true,
            watch: true,
            globals: true,
            environment: 'jsdom',
            pool: 'threads',
            clearMocks: false,
            restoreMocks: false,
            mockReset: false,
            include: [ '**/*.{test,spec}.?(c|m)[jt]s?(x)' ],
            exclude: [
              '**/node_modules/**',
              '**/dist/**',
              '**/cypress/**',
              '**/.{idea,git,cache,output,temp}/**',
              '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*'
            ],
            testTimeout: 5000,
            hookTimeout: 10000,
            teardownTimeout: 10000,
            watchExclude: [ '**/node_modules/**', '**/dist/**' ],
            forceRerunTriggers: [ '**/package.json/**', '**/{vitest,vite}.config.*/**', '<rootDir>/src/__e2e__/setup.ts' ],
            update: false,
            reporters: [ [ 'default', {} ] ],
            silent: false,
            hideSkippedTests: false,
            api: { middlewareMode: true },
            ui: false,
            uiBase: '/__vitest__/',
            open: true,
            css: { include: [], modules: { classNameStrategy: 'stable' } },
            coverage: {
              provider: 'v8',
              enabled: false,
              all: true,
              clean: true,
              cleanOnRerun: true,
              reportsDirectory: './coverage',
              exclude: [
                'coverage/**',
                'dist/**',
                '**/[.]**',
                'packages/*/test?(s)/**',
                '**/*.d.ts',
                '**/virtual:*',
                '**/__x00__*',
                '**/\x00*',
                'cypress/**',
                'test?(s)/**',
                'test?(-*).?(c|m)[jt]s?(x)',
                '**/*{.,-}{test,spec}.?(c|m)[jt]s?(x)',
                '**/__tests__/**',
                '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*',
                '**/vitest.{workspace,projects}.[jt]s?(on)',
                '**/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}',
                'src/__e2e__/setup.ts'
              ],
              reportOnFailure: false,
              reporter: [ [ 'text', {} ], [ 'html', {} ], [ 'clover', {} ], [ 'json', {} ] ],
              extension: [
                '.js',    '.cjs',
                '.mjs',   '.ts',
                '.mts',   '.cts',
                '.tsx',   '.jsx',
                '.vue',   '.svelte',
                '.marko'
              ],
              allowExternal: false,
              processingConcurrency: 16
            },
            fakeTimers: { loopLimit: 10000, shouldClearNativeTimers: true, toFake: [ 'setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'setImmediate', 'clearImmediate', 'Date' ] },
            maxConcurrency: 5,
            dangerouslyIgnoreUnhandledErrors: false,
            typecheck: {
              checker: 'tsc',
              include: [ '**/*.{test,spec}-d.?(c|m)[jt]s?(x)' ],
              exclude: [
                '**/node_modules/**',
                '**/dist/**',
                '**/cypress/**',
                '**/.{idea,git,cache,output,temp}/**',
                '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*'
              ],
              enabled: false
            },
            slowTestThreshold: 300,
            disableConsoleIntercept: false,
            setupFiles: [ '<rootDir>/src/__e2e__/setup.ts' ],
            poolOptions: { threads: {}, forks: {} },
            config: '<rootDir>/vite.config.ts',
            defines: {},
            root: '<rootDir>',
            mode: [],
            inspect: false,
            inspectBrk: false,
            fileParallelism: true,
            deps: {
              moduleDirectories: [ '/node_modules/' ],
              optimizer: { ssr: { enabled: true }, web: { enabled: true } },
              web: { transformAssets: true, transformCss: true, transformGlobPattern: [] }
            },
            server: { deps: { inline: [ {}, {}, {}, '@nuxt/test-utils' ], moduleDirectories: [ '/node_modules/' ], cacheDir: 'node_modules/.vite' } },
            snapshotOptions: { expand: false, snapshotFormat: {}, updateSnapshot: 'new', snapshotEnvironment: null },
            snapshotSerializers: [],
            poolMatchGlobs: [],
            globalSetup: [],
            cache: { dir: '<rootDir>/node_modules/.vitest' },
            sequence: { hooks: 'parallel' },
            environmentMatchGlobs: [],
            browser: { enabled: false, headless: false, slowHijackESM: false, isolate: true, api: { middlewareMode: true } },
            testTransformMode: {}
          },
          projects: [
            {
              path: '<rootDir>',
              config: {
                allowOnly: true,
                isolate: true,
                watch: true,
                globals: true,
                environment: 'jsdom',
                pool: 'threads',
                clearMocks: false,
                restoreMocks: false,
                mockReset: false,
                include: [ '**/*.{test,spec}.?(c|m)[jt]s?(x)' ],
                exclude: [
                  '**/node_modules/**',
                  '**/dist/**',
                  '**/cypress/**',
                  '**/.{idea,git,cache,output,temp}/**',
                  '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*'
                ],
                testTimeout: 5000,
                hookTimeout: 10000,
                teardownTimeout: 10000,
                watchExclude: [ '**/node_modules/**', '**/dist/**' ],
                forceRerunTriggers: [ '**/package.json/**', '**/{vitest,vite}.config.*/**', '<rootDir>/src/__e2e__/setup.ts' ],
                update: false,
                reporters: [ [ 'default', {} ] ],
                silent: false,
                hideSkippedTests: false,
                api: { middlewareMode: true },
                ui: false,
                uiBase: '/__vitest__/',
                open: true,
                css: { include: [], modules: { classNameStrategy: 'stable' } },
                coverage: {
                  provider: 'v8',
                  enabled: false,
                  all: true,
                  clean: true,
                  cleanOnRerun: true,
                  reportsDirectory: './coverage',
                  exclude: [
                    'coverage/**',
                    'dist/**',
                    '**/[.]**',
                    'packages/*/test?(s)/**',
                    '**/*.d.ts',
                    '**/virtual:*',
                    '**/__x00__*',
                    '**/\x00*',
                    'cypress/**',
                    'test?(s)/**',
                    'test?(-*).?(c|m)[jt]s?(x)',
                    '**/*{.,-}{test,spec}.?(c|m)[jt]s?(x)',
                    '**/__tests__/**',
                    '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*',
                    '**/vitest.{workspace,projects}.[jt]s?(on)',
                    '**/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}',
                    'src/__e2e__/setup.ts'
                  ],
                  reportOnFailure: false,
                  reporter: [ [ 'text', {} ], [ 'html', {} ], [ 'clover', {} ], [ 'json', {} ] ],
                  extension: [
                    '.js',    '.cjs',
                    '.mjs',   '.ts',
                    '.mts',   '.cts',
                    '.tsx',   '.jsx',
                    '.vue',   '.svelte',
                    '.marko'
                  ],
                  allowExternal: false,
                  processingConcurrency: 16
                },
                fakeTimers: { loopLimit: 10000, shouldClearNativeTimers: true, toFake: [ 'setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'setImmediate', 'clearImmediate', 'Date' ] },
                maxConcurrency: 5,
                dangerouslyIgnoreUnhandledErrors: false,
                typecheck: {
                  checker: 'tsc',
                  include: [ '**/*.{test,spec}-d.?(c|m)[jt]s?(x)' ],
                  exclude: [
                    '**/node_modules/**',
                    '**/dist/**',
                    '**/cypress/**',
                    '**/.{idea,git,cache,output,temp}/**',
                    '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*'
                  ],
                  enabled: false
                },
                slowTestThreshold: 300,
                disableConsoleIntercept: false,
                setupFiles: [ '<rootDir>/src/__e2e__/setup.ts' ],
                poolOptions: { threads: {}, forks: {} },
                config: '<rootDir>/vite.config.ts',
                defines: {},
                root: '<rootDir>',
                mode: [],
                inspect: false,
                inspectBrk: false,
                fileParallelism: true,
                deps: {
                  moduleDirectories: [ '/node_modules/' ],
                  optimizer: { ssr: { enabled: true }, web: { enabled: true } },
                  web: { transformAssets: true, transformCss: true, transformGlobPattern: [] }
                },
                server: { deps: { inline: [ {}, {}, {}, '@nuxt/test-utils' ], moduleDirectories: [ '/node_modules/' ], cacheDir: 'node_modules/.vite' } },
                snapshotOptions: { expand: false, snapshotFormat: {}, updateSnapshot: 'new', snapshotEnvironment: null },
                snapshotSerializers: [],
                poolMatchGlobs: [],
                globalSetup: [],
                cache: { dir: '<rootDir>/node_modules/.vitest' },
                sequence: { hooks: 'parallel' },
                environmentMatchGlobs: [],
                browser: { enabled: false, headless: false, slowHijackESM: false, isolate: true, api: { middlewareMode: true } },
                testTransformMode: {}
              }
            }
          ],
          package: {
            version: '1.3.1',
            urls: { hooks: 'file://<homeDir>/.vscode-server/extensions/wallabyjs.wallaby-vscode-1.0.371/wallaby02af8e/runners/node/hooks.mjs' },
            paths: { root: '<rootDir>/node_modules/vitest', dist: '<rootDir>/node_modules/vitest/dist' }
          }
        }
      }
    },
    testFramework: { version: 'vitest@0.14.0', configurator: 'vitest@0.14.0', reporter: 'vitest@0.14.0', starter: 'vitest@0.14.0', autoDetected: true },
    preserveComments: false,
    extractComments: true,
    files: [
      { pattern: '**/*.{test,spec}.?(c|m)[jt]s?(x)', ignore: true, trigger: true, load: true, file: true },
      { pattern: '**/node_modules/**', ignore: true, trigger: true, load: true, file: true, test: true },
      { pattern: '**/dist/**', ignore: true, trigger: true, load: true, file: true, test: true },
      { pattern: '**/cypress/**', ignore: true, trigger: true, load: true, file: true, test: true },
      { pattern: '**/.{idea,git,cache,output,temp}/**', ignore: true, trigger: true, load: true, file: true, test: true },
      { pattern: '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*', ignore: true, trigger: true, load: true, file: true, test: true },
      { pattern: '**/*.*', ignore: false, trigger: true, load: true, order: 1 }
    ],
    tests: [
      { pattern: '**/node_modules/**', ignore: true, trigger: true, load: true, test: true, file: false },
      { pattern: '**/dist/**', ignore: true, trigger: true, load: true, test: true, file: false },
      { pattern: '**/cypress/**', ignore: true, trigger: true, load: true, test: true, file: false },
      { pattern: '**/.{idea,git,cache,output,temp}/**', ignore: true, trigger: true, load: true, test: true, file: false },
      { pattern: '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*', ignore: true, trigger: true, load: true, test: true, file: false },
      { pattern: '**/*.{test,spec}.?(c|m)[jt]s?(x)', ignore: false, trigger: true, load: true, test: true, order: 2 }
    ],
    workers: { initial: 1, regular: 1, recycle: false },
    dot: true,
    captureConsoleLog: true,
    filesWithNoCoverageCalculated: [],
    runAllTestsInAffectedTestFile: false,
    updateNoMoreThanOneSnapshotPerTestFileRun: false,
    compilers: {},
    logLimits: { inline: { depth: 5, elements: 5000 }, values: { default: { stringLength: 8192 }, autoExpand: { elements: 5000, stringLength: 8192, depth: 10 } } },
    preprocessors: {},
    maxConsoleMessagesPerTest: 100,
    autoConsoleLog: true,
    delays: { run: 0, edit: 100, update: 0 },
    teardown: undefined,
    hints: {
      ignoreCoverage: '__REGEXP /ignore coverage|istanbul ignore|c8 ignore/',
      ignoreCoverageForFile: '__REGEXP /ignore file coverage/',
      commentAutoLog: '?',
      testFileSelection: { include: '__REGEXP /file\\.only/', exclude: '__REGEXP /file\\.skip/' }
    },
    automaticTestFileSelection: true,
    runSelectedTestsOnly: false,
    mapConsoleMessagesStackTrace: false,
    extensions: {},
    env: { type: 'node', params: {}, runner: '/usr/local/bin/node', viewportSize: { width: 800, height: 600 }, options: { width: 800, height: 600 }, bundle: true },
    reportUnhandledPromises: true,
    slowTestThreshold: 75,
    lowCoverageThreshold: 80,
    runAllTestsWhenNoAffectedTests: true,
    symlinkNodeModules: true,
    configCode: 'auto.detect#-869259263'
  },
  packageJSON: {
    dependencies: {
      '@chakra-ui/react': '^2.6.1',
      '@emotion/react': '^11.11.0',
      '@emotion/styled': '^11.11.0',
      '@reduxjs/toolkit': '^2.2.1',
      'framer-motion': '^10.12.11',
      react: '^18.2.0',
      'react-dom': '^18.2.0',
      'react-icons': '^4.8.0',
      'react-redux': '^9.1.0',
      'react-router-dom': '^6.11.1',
      'timeago.js': '^4.0.2'
    },
    devDependencies: {
      '@testing-library/jest-dom': '^6.4.2',
      '@testing-library/react': '^14.2.1',
      '@testing-library/user-event': '^14.5.2',
      '@total-typescript/ts-reset': '^0.4.2',
      '@types/react': '^18.0.28',
      '@types/react-dom': '^18.0.11',
      '@types/user-event': '^4.1.3',
      '@typescript-eslint/eslint-plugin': '^5.57.1',
      '@typescript-eslint/parser': '^5.57.1',
      '@vitejs/plugin-react-swc': '^3.6.0',
      eslint: '^8.38.0',
      'eslint-plugin-react-hooks': '^4.6.0',
      'eslint-plugin-react-refresh': '^0.3.4',
      jsdom: '^24.0.0',
      typescript: '^5.0.2',
      vite: '^5.1.4',
      'vite-tsconfig-paths': '^4.3.1',
      vitest: '^1.3.1'
    }
  },
  fs: { numberOfFiles: 63 },
  debug: [
    '2024-03-30T15:35:42.570Z project waiting for initial run signal\n',
    '2024-03-30T15:35:42.578Z config Attempting automatic configuration for vitest\n',
    '2024-03-30T15:35:42.579Z vitest/config Detected Vitest (1.3.1).\n',
    '2024-03-30T15:35:43.127Z config Finished attempting automatic configuration for vitest (549ms)\n',
    '2024-03-30T15:35:43.129Z project Wallaby Node version: v20.11.0\n',
    '2024-03-30T15:35:43.129Z project Wallaby config: <rootDir>/auto.detect\n',
    '2024-03-30T15:35:43.167Z fs File system starting\n',
    '2024-03-30T15:35:43.257Z fs File system scan completed\n',
    '2024-03-30T15:35:43.265Z project File cache: <homeDir>/.vscode-server/extensions/wallabyjs.wallaby-vscode-1.0.371/projects/8bb3a6356ebdcef7\n',
    '2024-03-30T15:35:43.336Z uiService Listening port 51235\n',
    '2024-03-30T15:35:43.348Z workers Parallelism for initial run: 1, for regular run: 1\n',
    '2024-03-30T15:35:43.348Z workers Starting run worker instance #0\n',
    '2024-03-30T15:35:43.349Z workers Web server is listening at 44637\n',
    '2024-03-30T15:35:43.354Z project Stopping process pool\n',
    '2024-03-30T15:35:43.354Z project File cache is up-to-date, starting full test run\n',
    '2024-03-30T15:35:43.357Z project Test run started; run priority: 3\n',
    '2024-03-30T15:35:43.358Z project Running all tests\n',
    '2024-03-30T15:35:43.361Z workers Starting test run, priority: 3\n',
    '2024-03-30T15:35:43.361Z nodeRunner Starting sandbox [worker #0, session #0t3lq]\n',
    '2024-03-30T15:35:43.361Z nodeRunner Preparing sandbox [worker #0, session #0t3lq]\n',
    '2024-03-30T15:35:43.485Z workers Started run worker instance (delayed) #0\n',
    '2024-03-30T15:35:43.486Z nodeRunner Prepared sandbox [worker #0, session #0t3lq]\n',
    '2024-03-30T15:35:43.486Z workers [worker #0, session #0t3lq] Running tests in sandbox\n',
    "2024-03-30T15:35:43.943Z workers 'Scheduling Vitest Run (0t3lq): 2024-03-30T15:35:43.942Z'\n",
    '2024-03-30T15:35:45.814Z workers [0t3lq.5] Loaded unknown number of test(s)\n',
    '2024-03-30T15:35:45.820Z workers [0t3lq.5] Test executed: should dispatch an userAuthenticated action when auth gateway notifies the user is authenticated\n',
    '2024-03-30T15:35:45.826Z workers [0t3lq.3] Loaded unknown number of test(s)\n',
    '2024-03-30T15:35:45.827Z workers [0t3lq.4] Loaded unknown number of test(s)\n',
    '2024-03-30T15:35:45.833Z workers [0t3lq.3] Test executed: Exemple:Alice authenticates with Github successfully\n',
    '2024-03-30T15:35:45.834Z workers [0t3lq.4] Test executed: Exemple:Alice authenticates with Google successfully\n',
    '2024-03-30T15:35:45.834Z workers [0t3lq.6] Loaded unknown number of test(s)\n',
    '2024-03-30T15:35:45.836Z workers [0t3lq.6] Test executed: Exemple: Alice is authenticated and can see her timeline\n',
    '2024-03-30T15:35:45.847Z workers [0t3lq.7] Loaded unknown number of test(s)\n',
    '2024-03-30T15:35:45.853Z workers [0t3lq.7] Test executed: Exemple: there is no timeline in the store\n',
    '2024-03-30T15:35:45.856Z workers [0t3lq.7] Test executed: Exemple: The Timeline is loading\n',
    '2024-03-30T15:35:45.858Z workers [0t3lq.7] Test executed: Exemple: there is no message in the timeline in the store\n',
    '2024-03-30T15:35:45.860Z workers [0t3lq.7] Test executed: Exemple: there is one message in the timeline in the store\n',
    '2024-03-30T15:35:45.863Z workers [0t3lq.7] Test executed: Exemple: there are two message in the timeline in the store\n',
    '2024-03-30T15:35:46.786Z workers [0t3lq.2] Loaded unknown number of test(s)\n',
    '2024-03-30T15:35:46.849Z workers [0t3lq.1] Loaded unknown number of test(s)\n',
    '2024-03-30T15:35:46.860Z workers [0t3lq.1] Test executed: displays the authenticated user timeline on the home page\n',
    '2024-03-30T15:35:47.016Z workers [0t3lq.2] Test executed: should show login page when no user is logged in\n',
    '2024-03-30T15:35:47.116Z workers [0t3lq.2] Test executed: should show homepage when user is logged in\n',
    "2024-03-30T15:35:47.144Z workers 'Vitest Run Complete (0t3lq): 2024-03-30T15:35:47.144Z'\n",
    '2024-03-30T15:35:47.146Z workers [0t3lq] Run 12 test(s), skipped 0 test(s)\n',
    '2024-03-30T15:35:47.147Z workers [0t3lq] Sandbox is responsive, closing it\n',
    '2024-03-30T15:35:47.150Z project Test run finished\n',
    '2024-03-30T15:35:47.151Z project Processed console.log entries\n',
    '2024-03-30T15:35:47.151Z project Processed loading sequences\n',
    '2024-03-30T15:35:47.152Z project Processed executed tests\n',
    '2024-03-30T15:35:47.154Z project Processed code coverage\n',
    '2024-03-30T15:35:47.170Z project Test run result processed and sent to IDE\n'
  ]
}
ArtemGovorov commented 5 months ago

Thanks for providing the report. Can you please try updating to the latest core v1.0.1551 to check if it fixes the issue?

eephyne commented 5 months ago

I updated the core and the issue don't seem to be here anymore, tried running some test, modifying files, and after the tests are run it go back to 0-1%.

Thanks a lot. Can I ask what did you modified do solve this ?

smcenlly commented 5 months ago

Glad to hear it's working for you.

Prior to v1.0.1551, Wallaby was using polling to identify changes on linux because of the 8K default iNotify limit on many *nix operating systems. Wallaby now uses iNotify by default for file system watching with a new configuration option to use polling instead for anyone who requires it.

Closing the issue.