github.com/mirantis/virtlet@v1.5.2-0.20191204181327-1659b8a48e9b/pkg/blockdev/blockdev_test.go (about) 1 /* 2 Copyright 2018 Mirantis 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package blockdev 18 19 import ( 20 "crypto/sha256" 21 "os" 22 "path/filepath" 23 "reflect" 24 "testing" 25 26 fake "github.com/Mirantis/virtlet/pkg/blockdev/fake" 27 "github.com/Mirantis/virtlet/pkg/utils" 28 fakeutils "github.com/Mirantis/virtlet/pkg/utils/fake" 29 testutils "github.com/Mirantis/virtlet/pkg/utils/testing" 30 ) 31 32 func TestDevHeader(t *testing.T) { 33 for _, tc := range []struct { 34 name string 35 content []string 36 dmPath string 37 fileSize uint64 38 imageWrittenAgain bool 39 errors [2]string 40 }{ 41 { 42 name: "image unchanged", 43 content: []string{"image1", "image1"}, 44 fileSize: 8704, // just added a sector 45 }, 46 { 47 name: "image change", 48 content: []string{"image1", "image2"}, 49 fileSize: 16384, 50 imageWrittenAgain: true, 51 }, 52 { 53 name: "first image too big", 54 content: []string{"image1"}, 55 fileSize: 4096, 56 errors: [2]string{ 57 "too small", 58 "", 59 }, 60 }, 61 { 62 name: "second image too big", 63 content: []string{"image1", "image2"}, 64 fileSize: 8704, 65 errors: [2]string{ 66 "", 67 "too small", 68 }, 69 }, 70 } { 71 t.Run(tc.name, func(t *testing.T) { 72 fake.WithFakeRootDev(t, tc.fileSize, func(devPath, devDir string) { 73 for n, content := range tc.content { 74 if content == "" { 75 continue 76 } 77 cmd := fakeutils.NewCommander(nil, nil) 78 79 ldh := NewLogicalDeviceHandler(cmd, "", "") 80 headerExpectedToMatch := n > 0 && tc.content[n-1] == content 81 imageHash := sha256.Sum256([]byte(content)) 82 headerMatches, err := ldh.EnsureDevHeaderMatches(devPath, imageHash) 83 if err != nil { 84 t.Fatalf("EnsureDevHeaderMatches: %v", err) 85 } 86 87 switch { 88 case headerMatches == headerExpectedToMatch: 89 // ok 90 case headerMatches: 91 t.Errorf("[%d] the header is expected to match but didn't", n) 92 case !headerMatches: 93 t.Errorf("[%d] the header is not expected to match but did", n) 94 } 95 } 96 }) 97 }) 98 } 99 } 100 101 func TestCreateRemoveVirtualBlockDevice(t *testing.T) { 102 fake.WithFakeRootDev(t, 0, func(devPath, devDir string) { 103 rec := testutils.NewToplevelRecorder() 104 cmd := fakeutils.NewCommander(rec, []fakeutils.CmdSpec{ 105 { 106 Match: "blockdev --getsz", 107 Stdout: "4", 108 }, 109 { 110 Match: "dmsetup create", 111 }, 112 { 113 Match: "dmsetup remove", 114 }, 115 }) 116 cmd.ReplaceTempPath("__dev__", "/dev") 117 symlinkPath := filepath.Join(devDir, "rootdevlink") 118 if err := os.Symlink(devPath, symlinkPath); err != nil { 119 t.Fatalf("Symlink(): %v", err) 120 } 121 122 ldh := NewLogicalDeviceHandler(cmd, "", "") 123 if err := ldh.Map(symlinkPath, "virtlet-dm-foobar", 1024); err != nil { 124 t.Fatalf("Map(): %v", err) 125 } 126 if err := ldh.Unmap("virtlet-dm-foobar"); err != nil { 127 t.Fatalf("Unmap(): %v", err) 128 } 129 130 expectedRecs := []*testutils.Record{ 131 { 132 Name: "CMD", 133 Value: map[string]string{ 134 "cmd": "blockdev --getsz /dev/rootdevlink", 135 "stdout": "4", 136 }, 137 }, 138 { 139 Name: "CMD", 140 Value: map[string]string{ 141 "cmd": "dmsetup create virtlet-dm-foobar", 142 "stdin": "0 3 linear /dev/rootdev 1\n", 143 }, 144 }, 145 { 146 Name: "CMD", 147 Value: map[string]string{ 148 "cmd": "dmsetup remove virtlet-dm-foobar", 149 }, 150 }, 151 } 152 if !reflect.DeepEqual(expectedRecs, rec.Content()) { 153 t.Errorf("bad commands recorded:\n%s\ninstead of\n%s", utils.ToJSON(rec.Content()), utils.ToJSON(expectedRecs)) 154 } 155 }) 156 } 157 158 func TestIsVirtletBlockDevice(t *testing.T) { 159 fake.WithFakeRootDevsAndSysfs(t, func(devPaths []string, table, devDir, sysfsDir string) { 160 cmd := fakeutils.NewCommander(nil, []fakeutils.CmdSpec{ 161 { 162 Match: "^dmsetup table$", 163 Stdout: table, 164 }, 165 }) 166 ldh := NewLogicalDeviceHandler(cmd, devDir, sysfsDir) 167 for _, devPath := range devPaths { 168 if _, err := ldh.EnsureDevHeaderMatches(devPath, sha256.Sum256([]byte("foobar"))); err != nil { 169 t.Fatalf("EnsureDevHeaderMatches(): %v", err) 170 } 171 } 172 173 devs, err := ldh.ListVirtletLogicalDevices() 174 if err != nil { 175 t.Fatalf("ListVirtletLogicalDevices(): %v", err) 176 } 177 178 expectedDevs := []string{ 179 "virtlet-dm-5edfe2ad-9852-439b-bbfb-3fe8b7c72906", 180 "virtlet-dm-9a322047-1f0d-4395-8e43-6e1b310ce6f3", 181 } 182 if !reflect.DeepEqual(devs, expectedDevs) { 183 t.Errorf("bad Virtlet block device list: %s instead of %s", utils.ToJSONUnindented(devs), utils.ToJSONUnindented(expectedDevs)) 184 } 185 }) 186 }