• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict'
2var path = require('path')
3var test = require('tap').test
4var Tacks = require('tacks')
5var glob = require('glob')
6var asyncMap = require('slide').asyncMap
7var File = Tacks.File
8var Dir = Tacks.Dir
9var common = require('../common-tap.js')
10
11var basedir = common.pkg
12var testdir = path.join(basedir, 'testdir')
13var cachedir = common.cache
14var globaldir = path.join(basedir, 'global')
15var tmpdir = path.join(basedir, 'tmp')
16
17var conf = {
18  cwd: testdir,
19  env: Object.assign({}, process.env, {
20    npm_config_tmp: tmpdir,
21    npm_config_prefix: globaldir,
22    npm_config_registry: common.registry,
23    npm_config_loglevel: 'warn'
24  })
25}
26
27var fixture = new Tacks(Dir({
28  global: Dir(),
29  tmp: Dir(),
30  testdir: Dir({
31    'package.json': File({
32      name: 'debug-logs',
33      version: '1.0.0',
34      scripts: {
35        true: 'node -e "process.exit(0)"',
36        false: 'node -e "process.exit(1)"'
37      }
38    })
39  })
40}))
41
42test('setup', function (t) {
43  fixture.create(basedir)
44  t.done()
45})
46
47test('example', function (t) {
48  common.npm(['run', 'false'], conf, function (err, code, stdout, stderr) {
49    if (err) throw err
50    t.is(code, 1, 'command errored')
51    const re = /A complete log of this run can be found in:.*\nnpm ERR! {5,5}(.*)/
52    const matches = stderr.match(re)
53    t.match(stderr, re, 'debug log mentioned in error message')
54    if (matches) {
55      var logfile = matches[1]
56      t.matches(path.relative(cachedir, logfile), /^_logs/, 'debug log is inside the cache in _logs')
57    }
58
59    // we run a bunch concurrently, this will actually create > than our limit
60    // as the check is done when the command starts
61    //
62    // It has to be > the log count (10) but also significantly higher than
63    // the number of cores on the machine, or else some might be able to get
64    // to the log folder pruning logic in parallel, resulting in FEWER files
65    // than we expect being present at the end.
66    var procCount = Math.max(require('os').cpus().length * 2, 12)
67    var todo = new Array(procCount).join(',').split(',').map((v, k) => k)
68    asyncMap(todo, function (num, next) {
69      // another way would be to just simulate this?
70      // var f = path.join(cachedir, '_logs', num + '-debug.log')
71      // require('fs').writeFile(f, 'log ' + num, next)
72      common.npm(['run', '--logs-max=10', 'false'], conf, function (err, code) {
73        if (err) throw err
74        t.is(code, 1, 'run #' + num + ' errored as expected')
75        next()
76      })
77    }, function () {
78      var files = glob.sync(path.join(cachedir, '_logs', '*'))
79      t.ok(files.length > 10, 'there should be more than 10 log files')
80
81      // now we do one more and that should clean up the list
82      common.npm(['run', '--logs-max=10', 'false'], conf, function (err, code) {
83        if (err) throw err
84        t.is(code, 1, 'final run errored as expected')
85        var files = glob.sync(path.join(cachedir, '_logs', '*'))
86        t.is(files.length, 10, 'there should never be more than 10 log files')
87        common.npm(['run', '--logs-max=5', 'true'], conf, function (err, code) {
88          if (err) throw err
89          t.is(code, 0, 'success run is ok')
90          var files = glob.sync(path.join(cachedir, '_logs', '*'))
91          t.is(files.length, 4, 'after success there should be logs-max - 1 log files')
92          t.done()
93        })
94      })
95    })
96  })
97})
98