github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/gadget/validate_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2019 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 gadget_test 21 22 import ( 23 "fmt" 24 "os" 25 "path/filepath" 26 27 . "gopkg.in/check.v1" 28 29 "github.com/snapcore/snapd/gadget" 30 ) 31 32 type validateGadgetTestSuite struct { 33 dir string 34 } 35 36 var _ = Suite(&validateGadgetTestSuite{}) 37 38 func (s *validateGadgetTestSuite) SetUpTest(c *C) { 39 s.dir = c.MkDir() 40 } 41 42 func (s *validateGadgetTestSuite) TestValidateMissingRawContent(c *C) { 43 var gadgetYamlContent = ` 44 volumes: 45 pc: 46 bootloader: grub 47 structure: 48 - name: foo 49 type: DA,21686148-6449-6E6F-744E-656564454649 50 size: 1M 51 offset: 1M 52 content: 53 - image: foo.img 54 55 ` 56 makeSizedFile(c, filepath.Join(s.dir, "meta/gadget.yaml"), 0, []byte(gadgetYamlContent)) 57 58 err := gadget.Validate(s.dir, nil) 59 c.Assert(err, ErrorMatches, `invalid layout of volume "pc": cannot lay out structure #0 \("foo"\): content "foo.img": stat .*/foo.img: no such file or directory`) 60 } 61 62 func (s *validateGadgetTestSuite) TestValidateMultiVolumeContent(c *C) { 63 var gadgetYamlContent = ` 64 volumes: 65 first: 66 bootloader: grub 67 structure: 68 - name: first-foo 69 type: DA,21686148-6449-6E6F-744E-656564454649 70 size: 1M 71 content: 72 - image: first.img 73 second: 74 structure: 75 - name: second-foo 76 type: DA,21686148-6449-6E6F-744E-656564454649 77 size: 1M 78 content: 79 - image: second.img 80 81 ` 82 makeSizedFile(c, filepath.Join(s.dir, "meta/gadget.yaml"), 0, []byte(gadgetYamlContent)) 83 // only content for the first volume 84 makeSizedFile(c, filepath.Join(s.dir, "first.img"), 1, nil) 85 86 err := gadget.Validate(s.dir, nil) 87 c.Assert(err, ErrorMatches, `invalid layout of volume "second": cannot lay out structure #0 \("second-foo"\): content "second.img": stat .*/second.img: no such file or directory`) 88 } 89 90 func (s *validateGadgetTestSuite) TestValidateBorkedMeta(c *C) { 91 var gadgetYamlContent = ` 92 volumes: 93 borked: 94 bootloader: bleh 95 structure: 96 - name: first-foo 97 type: DA,21686148-6449-6E6F-744E-656564454649 98 size: 1M 99 100 ` 101 makeSizedFile(c, filepath.Join(s.dir, "meta/gadget.yaml"), 0, []byte(gadgetYamlContent)) 102 103 err := gadget.Validate(s.dir, nil) 104 c.Assert(err, ErrorMatches, `invalid gadget metadata: bootloader must be one of .*`) 105 } 106 107 func (s *validateGadgetTestSuite) TestValidateFilesystemContent(c *C) { 108 var gadgetYamlContent = ` 109 volumes: 110 bad: 111 bootloader: grub 112 structure: 113 - name: bad-struct 114 type: DA,21686148-6449-6E6F-744E-656564454649 115 size: 1M 116 filesystem: ext4 117 content: 118 - source: foo/ 119 target: / 120 121 ` 122 makeSizedFile(c, filepath.Join(s.dir, "meta/gadget.yaml"), 0, []byte(gadgetYamlContent)) 123 124 err := gadget.Validate(s.dir, nil) 125 c.Assert(err, ErrorMatches, `invalid volume "bad": structure #0 \("bad-struct"\), content source:foo/: source path does not exist`) 126 127 // make it a file, which conflicts with foo/ as 'source' 128 fooPath := filepath.Join(s.dir, "foo") 129 makeSizedFile(c, fooPath, 1, nil) 130 err = gadget.Validate(s.dir, nil) 131 c.Assert(err, ErrorMatches, `invalid volume "bad": structure #0 \("bad-struct"\), content source:foo/: cannot specify trailing / for a source which is not a directory`) 132 133 // make it a directory 134 err = os.Remove(fooPath) 135 c.Assert(err, IsNil) 136 err = os.Mkdir(fooPath, 0755) 137 c.Assert(err, IsNil) 138 // validate should no longer complain 139 err = gadget.Validate(s.dir, nil) 140 c.Assert(err, IsNil) 141 } 142 143 func (s *validateGadgetTestSuite) TestValidateClassic(c *C) { 144 var gadgetYamlContent = ` 145 # on classic this can be empty 146 ` 147 makeSizedFile(c, filepath.Join(s.dir, "meta/gadget.yaml"), 0, []byte(gadgetYamlContent)) 148 149 err := gadget.Validate(s.dir, nil) 150 c.Assert(err, IsNil) 151 152 err = gadget.Validate(s.dir, &modelConstraints{classic: true}) 153 c.Assert(err, IsNil) 154 155 err = gadget.Validate(s.dir, &modelConstraints{classic: false}) 156 c.Assert(err, ErrorMatches, "invalid gadget metadata: bootloader not declared in any volume") 157 } 158 159 func (s *validateGadgetTestSuite) TestValidateSystemSeedRoleTwice(c *C) { 160 161 for _, role := range []string{"system-seed", "system-data", "system-boot"} { 162 gadgetYamlContent := fmt.Sprintf(` 163 volumes: 164 pc: 165 bootloader: grub 166 structure: 167 - name: foo 168 type: DA,21686148-6449-6E6F-744E-656564454649 169 size: 1M 170 role: %[1]s 171 - name: bar 172 type: DA,21686148-6449-6E6F-744E-656564454649 173 size: 1M 174 role: %[1]s 175 `, role) 176 makeSizedFile(c, filepath.Join(s.dir, "meta/gadget.yaml"), 0, []byte(gadgetYamlContent)) 177 err := gadget.Validate(s.dir, nil) 178 c.Assert(err, ErrorMatches, fmt.Sprintf(`invalid gadget metadata: invalid volume "pc": cannot have more than one partition with %s role`, role)) 179 } 180 }