github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/cmdline/cmdline_test.go (about) 1 // Copyright 2018 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package cmdline 6 7 import ( 8 "io" 9 "os" 10 "strings" 11 "testing" 12 ) 13 14 func TestCmdline(t *testing.T) { 15 exampleCmdLine := `BOOT_IMAGE=/vmlinuz-4.11.2 ro ` + 16 `test-flag test2-flag=8 ` + 17 `uroot.initflags="systemd test-flag=3 test2-flag runlevel=2" ` + 18 `root=LABEL=/ biosdevname=0 net.ifnames=0 fsck.repair=yes ` + 19 `ipv6.autoconf=0 erst_disable nox2apic crashkernel=128M ` + 20 `systemd.unified_cgroup_hierarchy=1 cgroup_no_v1=all console=tty0 ` + 21 `console=ttyS0,115200 security=selinux selinux=1 enforcing=0` 22 23 exampleCmdLineNoInitFlags := `BOOT_IMAGE=/vmlinuz-4.11.2 ro ` + 24 `root=LABEL=/ biosdevname=0 net.ifnames=0 fsck.repair=yes ` + 25 `console=ttyS0,115200 security=selinux selinux=1 enforcing=0` 26 27 c := parse(strings.NewReader(exampleCmdLine)) 28 wantLen := len(exampleCmdLine) 29 if len(c.Raw) != wantLen { 30 t.Errorf("c.Raw wrong length: %v != %d", len(c.Raw), wantLen) 31 } 32 33 if len(c.AsMap) != 21 { 34 t.Errorf("c.AsMap wrong length: %v != 21", len(c.AsMap)) 35 } 36 37 if c.ContainsFlag("biosdevname") == false { 38 t.Errorf("couldn't find biosdevname in kernel flags: map is %v", c.AsMap) 39 } 40 41 if c.ContainsFlag("biosname") == true { 42 t.Error("could find biosname in kernel flags, but shouldn't") 43 } 44 45 if security, present := c.Flag("security"); !present || security != "selinux" { 46 t.Errorf("Flag 'security' is %v instead of 'selinux'", security) 47 } 48 49 initFlagMap := c.GetInitFlagMap() 50 if testflag, present := initFlagMap["test-flag"]; !present || testflag != "3" { 51 t.Errorf("init test-flag == %v instead of test-flag == 3\nMAP: %v", testflag, initFlagMap) 52 } 53 54 c = parse(strings.NewReader(exampleCmdLineNoInitFlags)) 55 if initFlagMap = c.GetInitFlagMap(); len(initFlagMap) != 0 { 56 t.Errorf("initFlagMap should be empty, is actually %v", initFlagMap) 57 } 58 } 59 60 func TestCmdlineModules(t *testing.T) { 61 exampleCmdlineModules := `BOOT_IMAGE=/vmlinuz-4.11.2 ro ` + 62 `my_module.flag1=8 my-module.flag2-string=hello ` + 63 `otherMod.opt1=world otherMod.opt_2=22-22` 64 65 c := parse(strings.NewReader(exampleCmdlineModules)) 66 67 // Check flags using contains to not rely on map iteration order 68 flags := c.FlagsForModule("my-module") 69 if !strings.Contains(flags, "flag1=8 ") || !strings.Contains(flags, "flag2_string=hello ") { 70 t.Errorf("my-module flags got: %v, want flag1=8 flag2_string=hello ", flags) 71 } 72 flags = c.FlagsForModule("my_module") 73 if !strings.Contains(flags, "flag1=8 ") || !strings.Contains(flags, "flag2_string=hello ") { 74 t.Errorf("my_module flags got: %v, want flag1=8 flag2_string=hello ", flags) 75 } 76 77 flags = c.FlagsForModule("otherMod") 78 if !strings.Contains(flags, "opt1=world ") || !strings.Contains(flags, "opt_2=22-22 ") { 79 t.Errorf("my_module flags got: %v, want opt1=world opt_2=22-22 ", flags) 80 } 81 } 82 83 // Functional tests are done elsewhere. This test is purely to 84 // call the package level functions. 85 func TestCmdLineClassic(t *testing.T) { 86 c := getCmdLine() 87 if c.Err != nil { 88 t.Skipf("getCmdLine(): got %v, want nil, skipping test", c.Err) 89 } 90 91 c = cmdLine("/proc/cmdlinexyzzy") 92 // There is no good reason for an open like this to succeed. 93 // But, in virtual environments, it seems to at times. 94 // Just log it. 95 if c.Err == nil { 96 t.Logf(`cmdLine("/proc/cmdlinexyzzy"): got nil, want %v`, os.ErrNotExist) 97 } 98 NewCmdLine() 99 FullCmdLine() 100 // These functions call functions that are already tested, but 101 // this is our way of boosting coverage :-) 102 FlagsForModule("something") 103 GetUinitArgs() 104 GetInitFlagMap() 105 Flag("noflag") 106 ContainsFlag("noflag") 107 } 108 109 type badreader struct{} 110 111 // Read implements io.Reader, always returning io.ErrClosedPipe 112 func (*badreader) Read([]byte) (int, error) { 113 // Interesting. If you return a -1 for the length, 114 // it tickles a bug in io.ReadAll. It uses the returned 115 // length BEFORE seeing if there was an error. 116 // Note to self: file an issue on Go. 117 return 0, io.ErrClosedPipe 118 } 119 120 func TestBadRead(t *testing.T) { 121 if err := parse(&badreader{}); err == nil { 122 t.Errorf("parse(&badreader{}): got nil, want %v", io.ErrClosedPipe) 123 } 124 }