feat: generate fake machine IDs instead of client certificates

This commit is contained in:
siiky 2025-05-20 18:05:49 +01:00
parent 6443eafeed
commit 0642ee301e
2 changed files with 48 additions and 36 deletions

View file

@ -29,10 +29,9 @@ $ lamassu-server-stress-testing db
You also need to create fake machines that will be used later in the actual You also need to create fake machines that will be used later in the actual
stress tests (including certificates, and pairing each to the server). The stress tests (including certificates, and pairing each to the server). The
following command creates 10 fake machines, and saves their device IDs in following command creates 10 fake machines, and saves their device IDs in
path/to/machine-ids.txt. path/to/real/machine/code/ is the path to the root of path/to/machine-ids.txt.
the machine's code.
$ lamassu-server-stress-testing machines -n 10 --device_ids_path path/to/machine-ids.txt --machine path/to/real/machine/code/ --replace_existing $ lamassu-server-stress-testing machines -n 10 --device_ids_path path/to/machine-ids.txt --replace_existing
Finally, use the following to start the lamassu-server in stress-testing mode: Finally, use the following to start the lamassu-server in stress-testing mode:

View file

@ -1,7 +1,5 @@
const { createHash } = require('node:crypto')
const { createWriteStream } = require('node:fs') const { createWriteStream } = require('node:fs')
const { EOL } = require('node:os') const { EOL } = require('node:os')
const { join } = require('node:path')
require('../../lib/environment-helper') require('../../lib/environment-helper')
const db = require('../../lib/db') const db = require('../../lib/db')
@ -14,7 +12,6 @@ const help_message = 'Create and insert fake machines into the DB.'
const cli = CLI({ const cli = CLI({
grammar: [ grammar: [
[['--help'], 'Show this help message'], [['--help'], 'Show this help message'],
[['--machine', 'PATH'], "Path to the machine's source code root"],
[['--device_ids_path', 'PATH'], 'Where to save the list of device IDs'], [['--device_ids_path', 'PATH'], 'Where to save the list of device IDs'],
[['-n', 'NUMBER'], 'Number of fake machines to create'], [['-n', 'NUMBER'], 'Number of fake machines to create'],
[['--replace_existing'], 'Remove machines of previous runs'], [['--replace_existing'], 'Remove machines of previous runs'],
@ -33,27 +30,51 @@ const close_stream = stream =>
stream.close(err => (err ? reject(err) : resolve())), stream.close(err => (err ? reject(err) : resolve())),
) )
const compute_machine_id = cert => { const leftpad = (s, w, c) => c.repeat(Math.max(w - s.length, 0)) + s
cert = cert.split('\r\n')
const raw = Buffer.from(cert.slice(1, cert.length - 2).join(''), 'base64') function* chunk(arr, n) {
return createHash('sha256').update(raw).digest('hex') for (let i = 0; i < arr.length; i += n) {
yield arr.slice(i, i + n)
}
} }
const create_fake_machine = async (device_ids_file, self_sign, i) => { const fake_machine_id = i => 'machine_' + i
console.log('creating machine', i)
const { cert } = await self_sign.generateCertificate() const save_machines_to_db = async (machines, replace_existing) => {
const device_id = compute_machine_id(cert) if (replace_existing) await db.none('DELETE FROM devices')
await db.none(
console.log('inserting machines into DB')
db.tx(tx =>
tx.batch(
machines.map(device_id =>
tx.none(
`INSERT INTO devices (device_id, cassette1, cassette2, paired, display, created, name, last_online, location) `INSERT INTO devices (device_id, cassette1, cassette2, paired, display, created, name, last_online, location)
VALUES ($1, 0, 0, 't', 't', now(), $2, now(), '{}'::json)`, VALUES ($1, 0, 0, 't', 't', now(), $2, now(), '{}'::json)`,
[device_id, `machine_${i}`], [device_id, device_id],
),
),
),
) )
device_ids_file.write(device_id + EOL) }
console.log('created machine', i, 'with device ID', device_id)
const save_device_ids_to_file = async (
machines,
{ device_ids_path, replace_existing },
) => {
const device_ids_file = createWriteStream(device_ids_path, {
flags: replace_existing ? 'w' : 'a',
mode: 0o640,
flush: true,
})
console.log('saving machine IDs to file')
for (const ids of chunk(machines, 20))
await device_ids_file.write(ids.join(EOL) + EOL)
await close_stream(device_ids_file)
} }
const create_fake_machines = async ({ const create_fake_machines = async ({
machine,
device_ids_path, device_ids_path,
n, n,
replace_existing, replace_existing,
@ -63,19 +84,13 @@ const create_fake_machines = async ({
console.error('Expected n to be a positive number, got', n) console.error('Expected n to be a positive number, got', n)
return help(EXIT.BADARGS) return help(EXIT.BADARGS)
} }
const width = Math.log10(n)
const device_ids_file = createWriteStream(device_ids_path, { const machines = Array(n)
flags: replace_existing ? 'w' : 'a', .fill(0)
mode: 0o640, .map((x, i) => fake_machine_id(leftpad(i.toString(), width, '0')))
flush: true, await save_machines_to_db(machines, replace_existing)
}) await save_device_ids_to_file(machines, { device_ids_path, replace_existing })
if (replace_existing) await db.none('DELETE FROM devices')
const self_sign = require(join(process.cwd(), machine, 'lib', 'self_sign'))
for (let i = 0; i < n; i++)
await create_fake_machine(device_ids_file, self_sign, i)
await close_stream(device_ids_file)
return EXIT.OK return EXIT.OK
} }
@ -89,9 +104,7 @@ const run = async args => {
if (options.help) return help(EXIT.OK) if (options.help) return help(EXIT.OK)
const missing_options = ['n', 'machine', 'device_ids_path'].filter( const missing_options = ['n', 'device_ids_path'].filter(opt => !options[opt])
opt => !options[opt],
)
if (missing_options.length > 0) { if (missing_options.length > 0) {
console.error( console.error(
'The following options are required:', 'The following options are required:',