github.com/openebs/node-disk-manager@v1.9.1-0.20230225014141-4531f06ffa1e/pkg/udev/common_test.go (about) 1 /* 2 Copyright 2018 OpenEBS Authors. 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 udev 18 19 import ( 20 "path/filepath" 21 "testing" 22 23 "github.com/openebs/node-disk-manager/pkg/util" 24 "github.com/stretchr/testify/assert" 25 ) 26 27 /* 28 In this test case we create os disk's UdevDevice object. 29 get the syspath of that disk and compare with mock details 30 */ 31 func TestGetSyspath(t *testing.T) { 32 diskDetails, err := MockDiskDetails() 33 if err != nil { 34 t.Fatal(err) 35 } 36 newUdev, err := NewUdev() 37 if err != nil { 38 t.Fatal(err) 39 } 40 defer newUdev.UnrefUdev() 41 device, err := newUdev.NewDeviceFromSysPath(diskDetails.SysPath) 42 if err != nil { 43 t.Fatal(err) 44 } 45 defer device.UdevDeviceUnref() 46 tests := map[string]struct { 47 actualSyspath string 48 expectedSysPath string 49 }{ 50 "compare syspath of os disk": {actualSyspath: device.GetSyspath(), expectedSysPath: diskDetails.SysPath}, 51 } 52 for name, test := range tests { 53 t.Run(name, func(t *testing.T) { 54 assert.Equal(t, test.actualSyspath, test.expectedSysPath) 55 }) 56 } 57 } 58 59 /* 60 In this test case we create os disk's UdevDevice object. 61 and get the data what udevProbe can fill and compare it 62 with mock UdevDiskDetails struct 63 */ 64 func TestDiskInfoFromLibudev(t *testing.T) { 65 diskDetails, err := MockDiskDetails() 66 if err != nil { 67 t.Fatal(err) 68 } 69 newUdev, err := NewUdev() 70 if err != nil { 71 t.Fatal(err) 72 } 73 defer newUdev.UnrefUdev() 74 device, err := newUdev.NewDeviceFromSysPath(diskDetails.SysPath) 75 if err != nil { 76 t.Fatal(err) 77 } 78 defer device.UdevDeviceUnref() 79 expectedDiskDetails := UdevDiskDetails{ 80 Model: diskDetails.Model, 81 Serial: diskDetails.Serial, 82 Vendor: diskDetails.Vendor, 83 WWN: diskDetails.Wwn, 84 DiskType: diskDetails.DevType, 85 Path: diskDetails.DevNode, 86 ByIdDevLinks: diskDetails.ByIdDevLinks, 87 ByPathDevLinks: diskDetails.ByPathDevLinks, 88 SymLinks: diskDetails.SymLinks, 89 PartitionTableType: diskDetails.PartTableType, 90 IDType: diskDetails.IdType, 91 } 92 tests := map[string]struct { 93 actualDetails UdevDiskDetails 94 expectedDetails UdevDiskDetails 95 }{ 96 "check for details which udev probe can fill": {actualDetails: device.DiskInfoFromLibudev(), expectedDetails: expectedDiskDetails}, 97 } 98 for name, test := range tests { 99 t.Run(name, func(t *testing.T) { 100 assert.True(t, unorderedEqual(test.expectedDetails.ByIdDevLinks, test.actualDetails.ByIdDevLinks)) 101 assert.True(t, unorderedEqual(test.expectedDetails.ByPathDevLinks, test.actualDetails.ByPathDevLinks)) 102 // need to make this nil as devlinks already compared. 103 test.expectedDetails.ByIdDevLinks = nil 104 test.expectedDetails.ByPathDevLinks = nil 105 test.expectedDetails.SymLinks = nil 106 test.actualDetails.ByIdDevLinks = nil 107 test.actualDetails.ByPathDevLinks = nil 108 test.actualDetails.SymLinks = nil 109 assert.Equal(t, test.expectedDetails, test.actualDetails) 110 }) 111 } 112 } 113 114 /* 115 In this test case we create os disk's UdevDevice object. 116 as it is a disk it should return true 117 */ 118 func TestIsDisk(t *testing.T) { 119 diskDetails, err := MockDiskDetails() 120 if err != nil { 121 t.Fatal(err) 122 } 123 newUdev, err := NewUdev() 124 if err != nil { 125 t.Fatal(err) 126 } 127 defer newUdev.UnrefUdev() 128 device, err := newUdev.NewDeviceFromSysPath(diskDetails.SysPath) 129 if err != nil { 130 t.Fatal(err) 131 } 132 defer device.UdevDeviceUnref() 133 tests := map[string]struct { 134 actual bool 135 expected bool 136 }{ 137 "check if os disk is disk or not": {actual: device.IsDisk(), expected: true}, 138 } 139 for name, test := range tests { 140 t.Run(name, func(t *testing.T) { 141 assert.Equal(t, test.actual, test.expected) 142 }) 143 } 144 } 145 146 /* 147 In this test case we create os disk's UdevDevice object from that we 148 get uuid of os disk. Then we compare it with uuid generation logic. 149 */ 150 func TestGetUid(t *testing.T) { 151 diskDetails, err := MockDiskDetails() 152 if err != nil { 153 t.Fatal(err) 154 } 155 newUdev, err := NewUdev() 156 if err != nil { 157 t.Fatal(err) 158 } 159 defer newUdev.UnrefUdev() 160 device, err := newUdev.NewDeviceFromSysPath(diskDetails.SysPath) 161 if err != nil { 162 t.Fatal(err) 163 } 164 defer device.UdevDeviceUnref() 165 expectedUid := NDMBlockDevicePrefix + util.Hash(diskDetails.Wwn+diskDetails.Model+diskDetails.Serial+diskDetails.Vendor) 166 tests := map[string]struct { 167 actualUuid string 168 expectedUuid string 169 }{ 170 "check for os disk uuid": {actualUuid: device.GetUid(), expectedUuid: expectedUid}, 171 } 172 for name, test := range tests { 173 t.Run(name, func(t *testing.T) { 174 assert.Equal(t, test.actualUuid, test.expectedUuid) 175 }) 176 } 177 } 178 179 /* 180 Get devlinks and devnode (/dev/sda or /dev/sdb ... ) of os 181 disk, read file path of those devlinks and match with devnode. 182 Each devlink should be valid and file path of those links 183 equal with devnode of os disk. 184 */ 185 func TestGetDevLinks(t *testing.T) { 186 diskDetails, err := MockDiskDetails() 187 if err != nil { 188 t.Fatal(err) 189 } 190 newUdev, err := NewUdev() 191 if err != nil { 192 t.Fatal(err) 193 } 194 defer newUdev.UnrefUdev() 195 device, err := newUdev.NewDeviceFromSysPath(diskDetails.SysPath) 196 if err != nil { 197 t.Fatal(err) 198 } 199 defer device.UdevDeviceUnref() 200 osDiskPath := diskDetails.DevNode 201 var expectedError error 202 for name, links := range device.GetDevLinks() { 203 for _, link := range links { 204 t.Run(name, func(t *testing.T) { 205 path, err := filepath.EvalSymlinks(link) 206 assert.Equal(t, expectedError, err) 207 assert.Equal(t, osDiskPath, path) 208 }) 209 } 210 } 211 } 212 213 // unorderedEqual compares 2 arrays, if all elements in one array are present 214 // in the second array. 215 // eg: [1,2,3] and [3,1,2] are equal in unorderedEqual. 216 func unorderedEqual(first, second []string) bool { 217 if len(first) != len(second) { 218 return false 219 } 220 exists := make(map[string]bool) 221 for _, value := range first { 222 exists[value] = true 223 } 224 for _, value := range second { 225 if !exists[value] { 226 return false 227 } 228 } 229 return true 230 }