balena-supervisor/test/integration/config/config-txt.spec.ts
Felipe Lalanne 6e6a796da5 Add special case for base DTO params on RPI config
While ordering is important in the RPI firmware configuration file (config.txt),
some dt params are by default considered part of the base dt overlay
if they are not used by other overlays.
Unfortunately the [list of dtparams](https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README#L133)
is too long to add all of them as exceptions, but we can add the params
used in the default config.txt provided in OS images, to avoid reboots
when updating to this new supervisor and correctly parsing the
provisioning config.txt as variables.

While this addition handles most common scenarios, there is still a
chance a user may have use other base overlay dt params in the initial
config, in which case those will be interpreted according to the
relative ordering

Change-type: patch
2024-02-08 15:48:10 -03:00

246 lines
6.3 KiB
TypeScript

import { testfs } from 'mocha-pod';
import { stripIndent } from 'common-tags';
import { expect } from 'chai';
import * as hostUtils from '~/lib/host-utils';
import { promises as fs } from 'fs';
import { ConfigTxt } from '~/src/config/backends/config-txt';
describe('config/config-txt', () => {
it('correctly parses a config.txt file', async () => {
const tfs = await testfs({
[hostUtils.pathOnBoot('config.txt')]: stripIndent`
initramfs initramf.gz 0x00800000
dtparam=i2c=on
dtparam=audio=on
dtoverlay=ads7846
enable_uart=1
avoid_warnings=1
gpu_mem=16
hdmi_force_hotplug:1=1
dtoverlay=lirc-rpi,gpio_out_pin=17,gpio_in_pin=13
dtparam=gpio_out_pin=17`,
}).enable();
const configTxt = new ConfigTxt();
// Will try to parse /test/data/mnt/boot/config.txt
await expect(configTxt.getBootConfig()).to.eventually.deep.equal({
dtparam: ['i2c=on', 'audio=on'],
dtoverlay: [
'ads7846',
'lirc-rpi,gpio_out_pin=17,gpio_in_pin=13,gpio_out_pin=17',
],
enable_uart: '1',
avoid_warnings: '1',
gpu_mem: '16',
initramfs: 'initramf.gz 0x00800000',
'hdmi_force_hotplug:1': '1',
});
await tfs.restore();
});
it('correctly parses a config.txt file with an empty overlay', async () => {
const tfs = await testfs({
[hostUtils.pathOnBoot('config.txt')]: stripIndent`
initramfs initramf.gz 0x00800000
dtoverlay=lirc-rpi,gpio_out_pin=17,gpio_in_pin=13
dtparam=gpio_out_pin=17
enable_uart=1
avoid_warnings=1
dtoverlay=
dtparam=i2c=on
dtparam=audio=on
dtoverlay=ads7846
gpu_mem=16
hdmi_force_hotplug:1=1
`,
}).enable();
const configTxt = new ConfigTxt();
// Will try to parse /test/data/mnt/boot/config.txt
await expect(configTxt.getBootConfig()).to.eventually.deep.equal({
dtparam: ['i2c=on', 'audio=on'],
dtoverlay: [
'lirc-rpi,gpio_out_pin=17,gpio_in_pin=13,gpio_out_pin=17',
'ads7846',
],
enable_uart: '1',
avoid_warnings: '1',
gpu_mem: '16',
initramfs: 'initramf.gz 0x00800000',
'hdmi_force_hotplug:1': '1',
});
await tfs.restore();
});
it('correctly parses default params on config.txt', async () => {
const tfs = await testfs({
[hostUtils.pathOnBoot('config.txt')]: stripIndent`
initramfs initramf.gz 0x00800000
dtoverlay=lirc-rpi,gpio_out_pin=17,gpio_in_pin=13
dtparam=gpio_out_pin=17
enable_uart=1
avoid_warnings=1
dtparam=i2c_arm=on
dtparam=spi=on
dtparam=audio=on
dtoverlay=ads7846
gpu_mem=16
hdmi_force_hotplug:1=1
`,
}).enable();
const configTxt = new ConfigTxt();
// Will try to parse /test/data/mnt/boot/config.txt
await expect(configTxt.getBootConfig()).to.eventually.deep.equal({
dtparam: ['i2c_arm=on', 'spi=on', 'audio=on'],
dtoverlay: [
'lirc-rpi,gpio_out_pin=17,gpio_in_pin=13,gpio_out_pin=17',
'ads7846',
],
enable_uart: '1',
avoid_warnings: '1',
gpu_mem: '16',
initramfs: 'initramf.gz 0x00800000',
'hdmi_force_hotplug:1': '1',
});
await tfs.restore();
});
it('maintains ordering of dtoverlays and dtparams', async () => {
const tfs = await testfs({
[hostUtils.pathOnBoot('config.txt')]: stripIndent`
initramfs initramf.gz 0x00800000
dtparam=i2c=on
dtparam=audio=on
dtoverlay=ads7846
enable_uart=1
avoid_warnings=1
gpu_mem=16
hdmi_force_hotplug:1=1
dtoverlay=lirc-rpi,gpio_out_pin=17,gpio_in_pin=13
dtoverlay=ads1015,addr=0x48,cha_enable=true
dtparam=chb_enable=true
dtparam=chc_enable=true
`,
}).enable();
const configTxt = new ConfigTxt();
// Will try to parse /test/data/mnt/boot/config.txt
await expect(configTxt.getBootConfig()).to.eventually.deep.equal({
dtparam: ['i2c=on', 'audio=on'],
dtoverlay: [
'ads7846',
'lirc-rpi,gpio_out_pin=17,gpio_in_pin=13',
'ads1015,addr=0x48,cha_enable=true,chb_enable=true,chc_enable=true',
],
enable_uart: '1',
avoid_warnings: '1',
gpu_mem: '16',
initramfs: 'initramf.gz 0x00800000',
'hdmi_force_hotplug:1': '1',
});
await tfs.restore();
});
it('splits dtoverlays into params to stay under the 80 char limit', async () => {
const tfs = await testfs({
[hostUtils.pathOnBoot('config.txt')]: stripIndent`
enable_uart=1
dtparam=i2c_arm=on
dtparam=spi=on
disable_splash=1
dtparam=audio=on
gpu_mem=16
`,
}).enable();
const configTxt = new ConfigTxt();
await configTxt.setBootConfig({
dtparam: ['i2c=on', 'audio=on'],
dtoverlay: [
'ads7846',
'lirc-rpi,gpio_out_pin=17,gpio_in_pin=13',
'ads1015,addr=0x48,cha_enable=true,chb_enable=true',
],
enable_uart: '1',
avoid_warnings: '1',
gpu_mem: '256',
initramfs: 'initramf.gz 0x00800000',
'hdmi_force_hotplug:1': '1',
});
// Confirm that the file was written correctly
await expect(
fs.readFile(hostUtils.pathOnBoot('config.txt'), 'utf8'),
).to.eventually.equal(
stripIndent`
dtparam=i2c=on
dtparam=audio=on
enable_uart=1
avoid_warnings=1
gpu_mem=256
initramfs initramf.gz 0x00800000
hdmi_force_hotplug:1=1
dtoverlay=ads7846
dtoverlay=lirc-rpi
dtparam=gpio_out_pin=17
dtparam=gpio_in_pin=13
dtoverlay=ads1015
dtparam=addr=0x48
dtparam=cha_enable=true
dtparam=chb_enable=true
` + '\n',
);
await tfs.restore();
});
it('ensures required fields are written to config.txt', async () => {
const tfs = await testfs({
[hostUtils.pathOnBoot('config.txt')]: stripIndent`
enable_uart=1
dtparam=i2c_arm=on
dtparam=spi=on
disable_splash=1
dtparam=audio=on
gpu_mem=16
`,
}).enable();
const configTxt = new ConfigTxt();
await configTxt.setBootConfig({
dtparam: ['i2c=on', 'audio=on'],
dtoverlay: ['ads7846', 'lirc-rpi,gpio_out_pin=17,gpio_in_pin=13'],
enable_uart: '1',
avoid_warnings: '1',
gpu_mem: '256',
initramfs: 'initramf.gz 0x00800000',
'hdmi_force_hotplug:1': '1',
});
// Will try to parse /test/data/mnt/boot/config.txt
await expect(configTxt.getBootConfig()).to.eventually.deep.equal({
dtparam: ['i2c=on', 'audio=on'],
dtoverlay: ['ads7846', 'lirc-rpi,gpio_out_pin=17,gpio_in_pin=13'],
enable_uart: '1',
avoid_warnings: '1',
gpu_mem: '256',
initramfs: 'initramf.gz 0x00800000',
'hdmi_force_hotplug:1': '1',
});
await tfs.restore();
});
});