storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/format-disk-cache_test.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2018 MinIO, Inc. 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 cmd 18 19 import ( 20 "context" 21 "os" 22 "testing" 23 ) 24 25 // TestDiskCacheFormat - tests initFormatCache, formatMetaGetFormatBackendCache, formatCacheGetVersion. 26 func TestDiskCacheFormat(t *testing.T) { 27 ctx := context.Background() 28 fsDirs, err := getRandomDisks(1) 29 if err != nil { 30 t.Fatal(err) 31 } 32 33 _, err = initFormatCache(ctx, fsDirs) 34 if err != nil { 35 t.Fatal(err) 36 } 37 // Do the basic sanity checks to check if initFormatCache() did its job. 38 cacheFormatPath := pathJoin(fsDirs[0], minioMetaBucket, formatConfigFile) 39 f, err := os.OpenFile(cacheFormatPath, os.O_RDWR|os.O_SYNC, 0) 40 if err != nil { 41 t.Fatal(err) 42 } 43 defer f.Close() 44 version, err := formatCacheGetVersion(f) 45 if err != nil { 46 t.Fatal(err) 47 } 48 if version != formatCacheVersionV2 { 49 t.Fatalf(`expected: %s, got: %s`, formatCacheVersionV2, version) 50 } 51 52 // Corrupt the format.json file and test the functions. 53 // formatMetaGetFormatBackendFS, formatFSGetVersion, initFormatFS should return errors. 54 if err = f.Truncate(0); err != nil { 55 t.Fatal(err) 56 } 57 if _, err = f.WriteString("b"); err != nil { 58 t.Fatal(err) 59 } 60 61 if _, _, err = loadAndValidateCacheFormat(context.Background(), fsDirs); err == nil { 62 t.Fatal("expected to fail") 63 } 64 65 // With unknown formatMetaV1.Version formatMetaGetFormatCache, initFormatCache should return error. 66 if err = f.Truncate(0); err != nil { 67 t.Fatal(err) 68 } 69 // Here we set formatMetaV1.Version to "2" 70 if _, err = f.WriteString(`{"version":"2","format":"cache","cache":{"version":"1"}}`); err != nil { 71 t.Fatal(err) 72 } 73 74 if _, _, err = loadAndValidateCacheFormat(context.Background(), fsDirs); err == nil { 75 t.Fatal("expected to fail") 76 } 77 } 78 79 // generates a valid format.json for Cache backend. 80 func genFormatCacheValid() []*formatCacheV2 { 81 disks := make([]string, 8) 82 formatConfigs := make([]*formatCacheV2, 8) 83 for index := range disks { 84 disks[index] = mustGetUUID() 85 } 86 for index := range disks { 87 format := &formatCacheV1{} 88 format.Version = formatMetaVersion1 89 format.Format = formatCache 90 format.Cache.Version = formatCacheVersionV2 91 format.Cache.This = disks[index] 92 format.Cache.Disks = disks 93 formatConfigs[index] = format 94 } 95 return formatConfigs 96 } 97 98 // generates a invalid format.json version for Cache backend. 99 func genFormatCacheInvalidVersion() []*formatCacheV2 { 100 disks := make([]string, 8) 101 formatConfigs := make([]*formatCacheV2, 8) 102 for index := range disks { 103 disks[index] = mustGetUUID() 104 } 105 for index := range disks { 106 format := &formatCacheV1{} 107 format.Version = formatMetaVersion1 108 format.Format = formatCache 109 format.Cache.Version = formatCacheVersionV1 110 format.Cache.This = disks[index] 111 format.Cache.Disks = disks 112 formatConfigs[index] = format 113 } 114 // Corrupt version numbers. 115 formatConfigs[0].Version = "2" 116 formatConfigs[3].Version = "-1" 117 return formatConfigs 118 } 119 120 // generates a invalid format.json version for Cache backend. 121 func genFormatCacheInvalidFormat() []*formatCacheV2 { 122 disks := make([]string, 8) 123 formatConfigs := make([]*formatCacheV2, 8) 124 for index := range disks { 125 disks[index] = mustGetUUID() 126 } 127 for index := range disks { 128 format := &formatCacheV2{} 129 format.Version = formatMetaVersion1 130 format.Format = formatCache 131 format.Cache.Version = formatCacheVersionV1 132 format.Cache.This = disks[index] 133 format.Cache.Disks = disks 134 formatConfigs[index] = format 135 } 136 // Corrupt format. 137 formatConfigs[0].Format = "cach" 138 formatConfigs[3].Format = "cach" 139 return formatConfigs 140 } 141 142 // generates a invalid format.json version for Cache backend. 143 func genFormatCacheInvalidCacheVersion() []*formatCacheV2 { 144 disks := make([]string, 8) 145 formatConfigs := make([]*formatCacheV2, 8) 146 for index := range disks { 147 disks[index] = mustGetUUID() 148 } 149 for index := range disks { 150 format := &formatCacheV2{} 151 format.Version = formatMetaVersion1 152 format.Format = formatCache 153 format.Cache.Version = formatCacheVersionV1 154 format.Cache.This = disks[index] 155 format.Cache.Disks = disks 156 formatConfigs[index] = format 157 } 158 // Corrupt version numbers. 159 formatConfigs[0].Cache.Version = "10" 160 formatConfigs[3].Cache.Version = "-1" 161 return formatConfigs 162 } 163 164 // generates a invalid format.json version for Cache backend. 165 func genFormatCacheInvalidDisksCount() []*formatCacheV2 { 166 disks := make([]string, 7) 167 formatConfigs := make([]*formatCacheV2, 8) 168 for index := range disks { 169 disks[index] = mustGetUUID() 170 } 171 for index := range disks { 172 format := &formatCacheV2{} 173 format.Version = formatMetaVersion1 174 format.Format = formatCache 175 format.Cache.Version = formatCacheVersionV2 176 format.Cache.This = disks[index] 177 format.Cache.Disks = disks 178 formatConfigs[index] = format 179 } 180 return formatConfigs 181 } 182 183 // generates a invalid format.json Disks for Cache backend. 184 func genFormatCacheInvalidDisks() []*formatCacheV2 { 185 disks := make([]string, 8) 186 formatConfigs := make([]*formatCacheV2, 8) 187 for index := range disks { 188 disks[index] = mustGetUUID() 189 } 190 for index := range disks { 191 format := &formatCacheV1{} 192 format.Version = formatMetaVersion1 193 format.Format = formatCache 194 format.Cache.Version = formatCacheVersionV2 195 format.Cache.This = disks[index] 196 format.Cache.Disks = disks 197 formatConfigs[index] = format 198 } 199 for index := range disks { 200 disks[index] = mustGetUUID() 201 } 202 // Corrupt Disks entries on disk 6 and disk 8. 203 formatConfigs[5].Cache.Disks = disks 204 formatConfigs[7].Cache.Disks = disks 205 return formatConfigs 206 } 207 208 // generates a invalid format.json This disk UUID for Cache backend. 209 func genFormatCacheInvalidThis() []*formatCacheV1 { 210 disks := make([]string, 8) 211 formatConfigs := make([]*formatCacheV1, 8) 212 for index := range disks { 213 disks[index] = mustGetUUID() 214 } 215 for index := range disks { 216 format := &formatCacheV1{} 217 format.Version = formatMetaVersion1 218 format.Format = formatCache 219 format.Cache.Version = formatCacheVersionV2 220 format.Cache.This = disks[index] 221 format.Cache.Disks = disks 222 formatConfigs[index] = format 223 } 224 // Make disk 5 and disk 8 have inconsistent disk uuid's. 225 formatConfigs[4].Cache.This = mustGetUUID() 226 formatConfigs[7].Cache.This = mustGetUUID() 227 return formatConfigs 228 } 229 230 // generates a invalid format.json Disk UUID in wrong order for Cache backend. 231 func genFormatCacheInvalidDisksOrder() []*formatCacheV2 { 232 disks := make([]string, 8) 233 formatConfigs := make([]*formatCacheV2, 8) 234 for index := range disks { 235 disks[index] = mustGetUUID() 236 } 237 for index := range disks { 238 format := &formatCacheV1{} 239 format.Version = formatMetaVersion1 240 format.Format = formatCache 241 format.Cache.Version = formatCacheVersionV2 242 format.Cache.This = disks[index] 243 format.Cache.Disks = disks 244 formatConfigs[index] = format 245 } 246 // Re order disks for failure case. 247 var disks1 = make([]string, 8) 248 copy(disks1, disks) 249 disks1[1], disks1[2] = disks[2], disks[1] 250 formatConfigs[2].Cache.Disks = disks1 251 return formatConfigs 252 } 253 254 // Wrapper for calling FormatCache tests - validates 255 // - valid format 256 // - unrecognized version number 257 // - unrecognized format tag 258 // - unrecognized cache version 259 // - wrong number of Disks entries 260 // - invalid This uuid 261 // - invalid Disks order 262 func TestFormatCache(t *testing.T) { 263 formatInputCases := [][]*formatCacheV1{ 264 genFormatCacheValid(), 265 genFormatCacheInvalidVersion(), 266 genFormatCacheInvalidFormat(), 267 genFormatCacheInvalidCacheVersion(), 268 genFormatCacheInvalidDisksCount(), 269 genFormatCacheInvalidDisks(), 270 genFormatCacheInvalidThis(), 271 genFormatCacheInvalidDisksOrder(), 272 } 273 testCases := []struct { 274 formatConfigs []*formatCacheV1 275 shouldPass bool 276 }{ 277 { 278 formatConfigs: formatInputCases[0], 279 shouldPass: true, 280 }, 281 { 282 formatConfigs: formatInputCases[1], 283 shouldPass: false, 284 }, 285 { 286 formatConfigs: formatInputCases[2], 287 shouldPass: false, 288 }, 289 { 290 formatConfigs: formatInputCases[3], 291 shouldPass: false, 292 }, 293 { 294 formatConfigs: formatInputCases[4], 295 shouldPass: false, 296 }, 297 { 298 formatConfigs: formatInputCases[5], 299 shouldPass: false, 300 }, 301 { 302 formatConfigs: formatInputCases[6], 303 shouldPass: false, 304 }, 305 { 306 formatConfigs: formatInputCases[7], 307 shouldPass: false, 308 }, 309 } 310 311 for i, testCase := range testCases { 312 err := validateCacheFormats(context.Background(), false, testCase.formatConfigs) 313 if err != nil && testCase.shouldPass { 314 t.Errorf("Test %d: Expected to pass but failed with %s", i+1, err) 315 } 316 if err == nil && !testCase.shouldPass { 317 t.Errorf("Test %d: Expected to fail but passed instead", i+1) 318 } 319 } 320 }