| // Copyright 2026 Google LLC | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| package cosboot | |
| import ( | |
| "os" | |
| "path/filepath" | |
| "testing" | |
| "cos.googlesource.com/cos/tools.git/src/pkg/utils" | |
| ) | |
| func TestNextGRUBCmdLine(t *testing.T) { | |
| tests := []struct { | |
| name string | |
| input string | |
| want string | |
| }{ | |
| { | |
| name: "BootA", | |
| input: "testdata/grubcfgA.img", | |
| want: `/syslinux/vmlinuz.A init=/usr/lib/systemd/systemd rootwait ro noresume loglevel=7 console=tty1 console=ttyS0,115200 security=apparmor virtio_net.napi_tx=1 nmi_watchdog=0 csm.disabled=1 loadpin.exclude=kernel-module,firmware modules-load=loadpin_trigger firmware_class.path=/var/lib/nvidia/firmware module.sig_enforce=1 dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=1 i915.modeset=1 cros_efi root=/dev/dm-0 dm-mod.create="vroot,,,ro,0 4077568 verity 0 PARTUUID=D4A2048A-D85B-C146-A5E0-08A1251A55C2 PARTUUID=D4A2048A-D85B-C146-A5E0-08A1251A55C2 4096 4096 509696 509696 sha256 cd98fb63a9a93194d8465937c46fce496143b4441be776bf504d9f09093e308d ad6ac492b67f319a8ebf86f034af467d207bffb20483a039b80e6c2e4572e0b4"`, | |
| }, | |
| { | |
| name: "BootB", | |
| input: "testdata/grubcfgB.img", | |
| want: `/syslinux/vmlinuz.B init=/usr/lib/systemd/systemd rootwait ro noresume loglevel=7 console=tty1 console=ttyS0,115200 security=apparmor virtio_net.napi_tx=1 nmi_watchdog=0 csm.disabled=1 loadpin.exclude=kernel-module,firmware modules-load=loadpin_trigger firmware_class.path=/var/lib/nvidia/firmware module.sig_enforce=1 dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=1 i915.modeset=1 cros_efi root=/dev/dm-0 dm-mod.create="vroot,,,ro,0 4077568 verity 0 PARTUUID=336A62C8-AF4C-F54C-AEB8-322675266630 PARTUUID=336A62C8-AF4C-F54C-AEB8-322675266630 4096 4096 509696 509696 sha256 cd98fb63a9a93194d8465937c46fce496143b4441be776bf504d9f09093e308d ad6ac492b67f319a8ebf86f034af467d207bffb20483a039b80e6c2e4572e0b4"`, | |
| }, | |
| } | |
| for _, test := range tests { | |
| test := test | |
| t.Run(test.name, func(t *testing.T) { | |
| got, err := NextGRUBCmdLine(test.input) | |
| if err != nil { | |
| t.Fatalf("NextGRUBCmdLine(%q) = %v; want nil", test.input, err) | |
| } | |
| if got != test.want { | |
| t.Errorf("NextGRUBCmdLine(%q) = %q; want %q", test.input, got, test.want) | |
| } | |
| }) | |
| } | |
| } | |
| func TestEditGRUBConfig(t *testing.T) { | |
| tests := []struct { | |
| name string | |
| input string | |
| sedCmd string | |
| want string | |
| }{ | |
| { | |
| name: "BootA", | |
| input: "testdata/grubcfgA.img", | |
| sedCmd: "s|cros_efi|cros_efi mitigations=off|g", | |
| want: `/syslinux/vmlinuz.A init=/usr/lib/systemd/systemd rootwait ro noresume loglevel=7 console=tty1 console=ttyS0,115200 security=apparmor virtio_net.napi_tx=1 nmi_watchdog=0 csm.disabled=1 loadpin.exclude=kernel-module,firmware modules-load=loadpin_trigger firmware_class.path=/var/lib/nvidia/firmware module.sig_enforce=1 dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=1 i915.modeset=1 cros_efi mitigations=off root=/dev/dm-0 dm-mod.create="vroot,,,ro,0 4077568 verity 0 PARTUUID=D4A2048A-D85B-C146-A5E0-08A1251A55C2 PARTUUID=D4A2048A-D85B-C146-A5E0-08A1251A55C2 4096 4096 509696 509696 sha256 cd98fb63a9a93194d8465937c46fce496143b4441be776bf504d9f09093e308d ad6ac492b67f319a8ebf86f034af467d207bffb20483a039b80e6c2e4572e0b4"`, | |
| }, | |
| { | |
| name: "BootB", | |
| input: "testdata/grubcfgB.img", | |
| sedCmd: "s|cros_efi|cros_efi mitigations=off|g", | |
| want: `/syslinux/vmlinuz.B init=/usr/lib/systemd/systemd rootwait ro noresume loglevel=7 console=tty1 console=ttyS0,115200 security=apparmor virtio_net.napi_tx=1 nmi_watchdog=0 csm.disabled=1 loadpin.exclude=kernel-module,firmware modules-load=loadpin_trigger firmware_class.path=/var/lib/nvidia/firmware module.sig_enforce=1 dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=1 i915.modeset=1 cros_efi mitigations=off root=/dev/dm-0 dm-mod.create="vroot,,,ro,0 4077568 verity 0 PARTUUID=336A62C8-AF4C-F54C-AEB8-322675266630 PARTUUID=336A62C8-AF4C-F54C-AEB8-322675266630 4096 4096 509696 509696 sha256 cd98fb63a9a93194d8465937c46fce496143b4441be776bf504d9f09093e308d ad6ac492b67f319a8ebf86f034af467d207bffb20483a039b80e6c2e4572e0b4"`, | |
| }, | |
| } | |
| for _, test := range tests { | |
| test := test | |
| t.Run(test.name, func(t *testing.T) { | |
| tmpDir, err := os.MkdirTemp("", "cosboot-test-") | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| defer os.RemoveAll(tmpDir) | |
| copiedInput := filepath.Join(tmpDir, "input") | |
| if err := utils.CopyFile(test.input, copiedInput); err != nil { | |
| t.Fatal(err) | |
| } | |
| if err := EditGRUBConfig(copiedInput, test.sedCmd); err != nil { | |
| t.Fatalf("EditGRUBConfig(%q, %q) = %v; want nil", test.input, test.sedCmd, err) | |
| } | |
| got, err := NextGRUBCmdLine(copiedInput) | |
| if err != nil { | |
| t.Fatalf("NextGRUBCmdLine(%q) = %v; want nil", test.input, err) | |
| } | |
| if got != test.want { | |
| t.Errorf("NextGRUBCmdLine(%q) = %q; want %q", test.input, got, test.want) | |
| } | |
| }) | |
| } | |
| } |