'use strict'; /* global it:false */ /* global describe:false */ /* global before:false */ /* global after:false */ const constants = require('../../constants.js'), common = require('./common.js'), expect = require('expect.js'), fs = require('fs'), http = require('http'), os = require('os'), paths = require('../../paths.js'), safe = require('safetydance'), superagent = require('superagent'); describe('System', function () { const { setup, cleanup, serverUrl, owner, user, waitForTask } = common; before(setup); after(cleanup); describe('cpus', function () { it('succeeds', async function () { const response = await superagent.get(`${serverUrl}/api/v1/system/cpus`) .query({ access_token: owner.token }); expect(response.statusCode).to.equal(200); expect(response.body.cpus).to.be.ok(); expect(response.body.cpus.every(c => typeof c.model === 'string')).to.be(true); }); }); describe('info', function () { it('succeeds', async function () { const response = await superagent.get(`${serverUrl}/api/v1/system/info`) .query({ access_token: owner.token }); expect(response.statusCode).to.equal(200); expect(response.body.info).to.be.ok(); expect(response.body.info.sysVendor).to.be.a('string'); expect(response.body.info.productName).to.be.a('string'); expect(response.body.info.uptimeSecs).to.be.a('number'); expect(response.body.info.rebootRequired).to.be.a('boolean'); expect(response.body.info.activationTime).to.be.a('string'); }); }); describe('logs', function () { before(function () { console.log(paths.BOX_LOG_FILE); fs.writeFileSync(paths.BOX_LOG_FILE, '2022-11-06T15:06:20.009Z box:apphealthmonitor app health: 0 alive / 0 dead.\n', 'utf8'); }); it('logStream - requires event-stream accept header', async function () { const response = await superagent.get(`${serverUrl}/api/v1/system/logstream/box`) .query({ access_token: owner.token, fromLine: 0 }) .ok(() => true); expect(response.statusCode).to.be(400); }); it('logStream - stream logs', function (done) { const options = { host: 'localhost', port: constants.PORT, path: '/api/v1/system/logstream/box?lines=10&access_token=' + owner.token, headers: { 'Accept': 'text/event-stream', 'Connection': 'keep-alive' } }; // superagent doesn't work. maybe https://github.com/visionmedia/superagent/issues/420 const req = http.get(options, function (res) { let data = ''; res.on('data', function (d) { data += d.toString('utf8'); }); setTimeout(function checkData() { let dataMessageFound = false; expect(data.length).to.not.be(0); data.split('\n').forEach(function (line) { if (line.indexOf('id: ') === 0) { expect(parseInt(line.substr('id: '.length), 10)).to.be.a('number'); } else if (line.indexOf('data: ') === 0) { const message = JSON.parse(line.slice('data: '.length)).message; if (Array.isArray(message) || typeof message === 'string') dataMessageFound = true; } }); expect(dataMessageFound).to.be.ok(); res.destroy(); req.destroy(); done(); }, 1000); res.on('error', done); }); req.on('error', done); }); }); describe('memory', function () { it('cannot get without token', async function () { const response = await superagent.get(`${serverUrl}/api/v1/system/memory`) .ok(() => true); expect(response.statusCode).to.equal(401); }); it('succeeds (admin)', async function () { const response = await superagent.get(`${serverUrl}/api/v1/system/memory`) .query({ access_token: owner.token }); expect(response.statusCode).to.equal(200); expect(response.body.memory).to.eql(os.totalmem()); expect(response.body.swap).to.be.a('number'); }); it('succeeds (admin)', async function () { const response = await superagent.get(`${serverUrl}/api/v1/system/memory`) .query({ access_token: user.token }); expect(response.statusCode).to.equal(200); expect(response.body.memory).to.eql(os.totalmem()); expect(response.body.swap).to.be.a('number'); }); }); describe('disk usage', function () { it('get succeeds with no cache', async function () { safe.fs.unlinkSync(paths.DISK_USAGE_FILE); const response = await superagent.get(`${serverUrl}/api/v1/system/disk_usage`) .query({ access_token: owner.token }) .send({}); expect(response.statusCode).to.equal(200); expect(response.body).to.eql({ usage: null }); }); it('update the cache', async function () { const response = await superagent.post(`${serverUrl}/api/v1/system/disk_usage`) .query({ access_token: owner.token }); expect(response.statusCode).to.equal(201); expect(response.body.taskId).to.be.ok(); await waitForTask(response.body.taskId); }); it('get succeeds with cache', async function () { const response = await superagent.get(`${serverUrl}/api/v1/system/disk_usage`) .query({ access_token: owner.token }) .send({}); expect(response.statusCode).to.equal(200); expect(response.body.usage.ts).to.be.a('number'); const filesystems = Object.keys(response.body.usage.disks); let dockerUsage = null; for (const fs of filesystems) { for (const content of response.body.usage.disks[fs].contents) { if (content.id === 'docker') dockerUsage = content; } } expect(dockerUsage).to.be.ok(); expect(dockerUsage.usage).to.be.a('number'); }); }); describe('blockdevices', function () { it('succeeds', async function () { const response = await superagent.get(`${serverUrl}/api/v1/system/block_devices`) .query({ access_token: owner.token }); expect(response.statusCode).to.equal(200); expect(response.body.devices).to.be.ok(); expect(response.body.devices.some(d => d.mountpoint === '/')).to.be(true); }); }); });