github.com/stolowski/snapd@v0.0.0-20210407085831-115137ce5a22/osutil/kcmdline_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2014-2015 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package osutil_test 21 22 import ( 23 "io/ioutil" 24 "path/filepath" 25 26 . "gopkg.in/check.v1" 27 28 "github.com/snapcore/snapd/osutil" 29 ) 30 31 type kcmdlineTestSuite struct{} 32 33 var _ = Suite(&kcmdlineTestSuite{}) 34 35 func (s *kcmdlineTestSuite) TestSplitKernelCommandLine(c *C) { 36 for idx, tc := range []struct { 37 cmd string 38 exp []string 39 errStr string 40 }{ 41 {cmd: ``, exp: nil}, 42 {cmd: `foo bar baz`, exp: []string{"foo", "bar", "baz"}}, 43 {cmd: `foo=" many spaces " bar`, exp: []string{`foo=" many spaces "`, "bar"}}, 44 {cmd: `foo="1$2"`, exp: []string{`foo="1$2"`}}, 45 {cmd: `foo=1$2`, exp: []string{`foo=1$2`}}, 46 {cmd: `foo= bar`, exp: []string{"foo=", "bar"}}, 47 {cmd: `foo=""`, exp: []string{`foo=""`}}, 48 {cmd: ` cpu=1,2,3 mem=0x2000;0x4000:$2 `, exp: []string{"cpu=1,2,3", "mem=0x2000;0x4000:$2"}}, 49 {cmd: "isolcpus=1,2,10-20,100-2000:2/25", exp: []string{"isolcpus=1,2,10-20,100-2000:2/25"}}, 50 // something more realistic 51 { 52 cmd: `BOOT_IMAGE=/vmlinuz-linux root=/dev/mapper/linux-root rw quiet loglevel=3 rd.udev.log_priority=3 vt.global_cursor_default=0 rd.luks.uuid=1a273f76-3118-434b-8597-a3b12a59e017 rd.luks.uuid=775e4582-33c1-423b-ac19-f734e0d5e21c rd.luks.options=discard,timeout=0 root=/dev/mapper/linux-root apparmor=1 security=apparmor`, 53 exp: []string{ 54 "BOOT_IMAGE=/vmlinuz-linux", 55 "root=/dev/mapper/linux-root", 56 "rw", "quiet", 57 "loglevel=3", 58 "rd.udev.log_priority=3", 59 "vt.global_cursor_default=0", 60 "rd.luks.uuid=1a273f76-3118-434b-8597-a3b12a59e017", 61 "rd.luks.uuid=775e4582-33c1-423b-ac19-f734e0d5e21c", 62 "rd.luks.options=discard,timeout=0", 63 "root=/dev/mapper/linux-root", 64 "apparmor=1", 65 "security=apparmor", 66 }, 67 }, 68 // this is actually ok, eg. rd.luks.options=discard,timeout=0 69 {cmd: `a=b=`, exp: []string{"a=b="}}, 70 // bad quoting, or otherwise malformed command line 71 {cmd: `foo="1$2`, errStr: "unbalanced quoting"}, 72 {cmd: `"foo"`, errStr: "unexpected quoting"}, 73 {cmd: `foo"foo"`, errStr: "unexpected quoting"}, 74 {cmd: `foo=foo"`, errStr: "unexpected quoting"}, 75 {cmd: `foo="a""b"`, errStr: "unexpected quoting"}, 76 {cmd: `foo="a foo="b`, errStr: "unexpected argument"}, 77 {cmd: `foo="a"="b"`, errStr: "unexpected assignment"}, 78 {cmd: `=`, errStr: "unexpected assignment"}, 79 {cmd: `a =`, errStr: "unexpected assignment"}, 80 {cmd: `="foo"`, errStr: "unexpected assignment"}, 81 {cmd: `a==`, errStr: "unexpected assignment"}, 82 {cmd: `foo ==a`, errStr: "unexpected assignment"}, 83 } { 84 c.Logf("%v: cmd: %q", idx, tc.cmd) 85 out, err := osutil.KernelCommandLineSplit(tc.cmd) 86 if tc.errStr != "" { 87 c.Assert(err, ErrorMatches, tc.errStr) 88 c.Check(out, IsNil) 89 } else { 90 c.Assert(err, IsNil) 91 c.Check(out, DeepEquals, tc.exp) 92 } 93 } 94 } 95 96 func (s *kcmdlineTestSuite) TestGetKernelCommandLineKeyValue(c *C) { 97 for _, t := range []struct { 98 cmdline string 99 keys []string 100 exp map[string]string 101 err string 102 comment string 103 }{ 104 { 105 cmdline: "", 106 comment: "empty cmdline", 107 keys: []string{"foo"}, 108 }, 109 { 110 cmdline: "foo", 111 comment: "cmdline non-key-value", 112 keys: []string{"foo"}, 113 }, 114 { 115 cmdline: "foo=1", 116 comment: "key-value pair", 117 keys: []string{"foo"}, 118 exp: map[string]string{ 119 "foo": "1", 120 }, 121 }, 122 { 123 cmdline: "foo=1 otherfoo=2", 124 comment: "multiple key-value pairs", 125 keys: []string{"foo", "otherfoo"}, 126 exp: map[string]string{ 127 "foo": "1", 128 "otherfoo": "2", 129 }, 130 }, 131 { 132 cmdline: "foo=", 133 comment: "empty value in key-value pair", 134 keys: []string{"foo"}, 135 exp: map[string]string{ 136 "foo": "", 137 }, 138 }, 139 { 140 cmdline: "foo=1 foo=2", 141 comment: "duplicated key-value pair uses last one", 142 keys: []string{"foo"}, 143 exp: map[string]string{ 144 "foo": "2", 145 }, 146 }, 147 { 148 cmdline: "foo=1 foo foo2=other", 149 comment: "cmdline key-value pair and non-key-value", 150 keys: []string{"foo"}, 151 exp: map[string]string{ 152 "foo": "1", 153 }, 154 }, 155 { 156 cmdline: "foo=a=1", 157 comment: "key-value pair with = in value", 158 keys: []string{"foo"}, 159 exp: map[string]string{ 160 "foo": "a=1", 161 }, 162 }, 163 { 164 cmdline: "=foo", 165 comment: "missing key", 166 keys: []string{"foo"}, 167 err: "unexpected assignment", 168 }, 169 { 170 cmdline: `"foo`, 171 comment: "invalid kernel cmdline", 172 keys: []string{"foo"}, 173 err: "unexpected quoting", 174 }, 175 } { 176 cmdlineFile := filepath.Join(c.MkDir(), "cmdline") 177 err := ioutil.WriteFile(cmdlineFile, []byte(t.cmdline), 0644) 178 c.Assert(err, IsNil) 179 r := osutil.MockProcCmdline(cmdlineFile) 180 defer r() 181 res, err := osutil.KernelCommandLineKeyValues(t.keys...) 182 if t.err != "" { 183 c.Assert(err, ErrorMatches, t.err, Commentf(t.comment)) 184 } else { 185 c.Assert(err, IsNil) 186 exp := t.exp 187 if t.exp == nil { 188 exp = map[string]string{} 189 } 190 c.Assert(res, DeepEquals, exp, Commentf(t.comment)) 191 } 192 } 193 } 194 195 func (s *kcmdlineTestSuite) TestKernelCommandLine(c *C) { 196 d := c.MkDir() 197 newProcCmdline := filepath.Join(d, "cmdline") 198 restore := osutil.MockProcCmdline(newProcCmdline) 199 defer restore() 200 201 cmd, err := osutil.KernelCommandLine() 202 c.Assert(err, ErrorMatches, `.*/cmdline: no such file or directory`) 203 c.Check(cmd, Equals, "") 204 205 err = ioutil.WriteFile(newProcCmdline, []byte("foo bar baz panic=-1\n"), 0644) 206 c.Assert(err, IsNil) 207 cmd, err = osutil.KernelCommandLine() 208 c.Assert(err, IsNil) 209 c.Check(cmd, Equals, "foo bar baz panic=-1") 210 }