github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/cmd/erasure-server-pool-decom_test.go (about) 1 // Copyright (c) 2015-2022 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 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 Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package cmd 19 20 import ( 21 "context" 22 "testing" 23 ) 24 25 func prepareErasurePools() (ObjectLayer, []string, error) { 26 nDisks := 32 27 fsDirs, err := getRandomDisks(nDisks) 28 if err != nil { 29 return nil, nil, err 30 } 31 32 pools := mustGetPoolEndpoints(0, fsDirs[:16]...) 33 pools = append(pools, mustGetPoolEndpoints(1, fsDirs[16:]...)...) 34 35 // Everything is fine, should return nil 36 objLayer, err := newErasureServerPools(context.Background(), pools) 37 if err != nil { 38 return nil, nil, err 39 } 40 return objLayer, fsDirs, nil 41 } 42 43 func TestPoolMetaValidate(t *testing.T) { 44 objLayer1, fsDirs, err := prepareErasurePools() 45 if err != nil { 46 t.Fatal(err) 47 } 48 defer removeRoots(fsDirs) 49 50 meta := objLayer1.(*erasureServerPools).poolMeta 51 pools := objLayer1.(*erasureServerPools).serverPools 52 53 objLayer2, fsDirs, err := prepareErasurePools() 54 if err != nil { 55 t.Fatalf("Initialization of object layer failed for Erasure setup: %s", err) 56 } 57 defer removeRoots(fsDirs) 58 59 newPools := objLayer2.(*erasureServerPools).serverPools 60 reducedPools := pools[1:] 61 orderChangePools := []*erasureSets{ 62 pools[1], 63 pools[0], 64 } 65 66 var nmeta1 poolMeta 67 nmeta1.Version = poolMetaVersion 68 nmeta1.Pools = append(nmeta1.Pools, meta.Pools...) 69 for i, pool := range nmeta1.Pools { 70 if i == 0 { 71 nmeta1.Pools[i] = PoolStatus{ 72 CmdLine: pool.CmdLine, 73 ID: i, 74 LastUpdate: UTCNow(), 75 Decommission: &PoolDecommissionInfo{ 76 Complete: true, 77 }, 78 } 79 } 80 } 81 82 var nmeta2 poolMeta 83 nmeta2.Version = poolMetaVersion 84 nmeta2.Pools = append(nmeta2.Pools, meta.Pools...) 85 for i, pool := range nmeta2.Pools { 86 if i == 0 { 87 nmeta2.Pools[i] = PoolStatus{ 88 CmdLine: pool.CmdLine, 89 ID: i, 90 LastUpdate: UTCNow(), 91 Decommission: &PoolDecommissionInfo{ 92 Complete: false, 93 }, 94 } 95 } 96 } 97 98 testCases := []struct { 99 meta poolMeta 100 pools []*erasureSets 101 expectedUpdate bool 102 expectedErr bool 103 name string 104 }{ 105 { 106 meta: meta, 107 pools: pools, 108 name: "Correct", 109 expectedErr: false, 110 expectedUpdate: false, 111 }, 112 { 113 meta: meta, 114 pools: newPools, 115 name: "Correct-Update", 116 expectedErr: false, 117 expectedUpdate: true, 118 }, 119 { 120 meta: meta, 121 pools: reducedPools, 122 name: "Correct-Update", 123 expectedErr: false, 124 expectedUpdate: true, 125 }, 126 { 127 meta: meta, 128 pools: orderChangePools, 129 name: "Invalid-Orderchange", 130 expectedErr: false, 131 expectedUpdate: true, 132 }, 133 { 134 meta: nmeta1, 135 pools: pools, 136 name: "Invalid-Completed-Pool-Not-Removed", 137 expectedErr: true, 138 expectedUpdate: false, 139 }, 140 { 141 meta: nmeta2, 142 pools: pools, 143 name: "Correct-Decom-Pending", 144 expectedErr: false, 145 expectedUpdate: false, 146 }, 147 { 148 meta: nmeta2, 149 pools: reducedPools, 150 name: "Invalid-Decom-Pending-Pool-Removal", 151 expectedErr: false, 152 expectedUpdate: true, 153 }, 154 { 155 meta: nmeta1, 156 pools: reducedPools, 157 name: "Correct-Decom-Pool-Removed", 158 expectedErr: false, 159 expectedUpdate: true, 160 }, 161 { 162 meta: poolMeta{}, // no-pool info available fresh setup. 163 pools: pools, 164 name: "Correct-Fresh-Setup", 165 expectedErr: false, 166 expectedUpdate: true, 167 }, 168 { 169 meta: nmeta2, 170 pools: orderChangePools, 171 name: "Invalid-Orderchange-Decom", 172 expectedErr: false, 173 expectedUpdate: true, 174 }, 175 } 176 177 t.Parallel() 178 for _, testCase := range testCases { 179 testCase := testCase 180 t.Run(testCase.name, func(t *testing.T) { 181 update, err := testCase.meta.validate(testCase.pools) 182 if testCase.expectedErr { 183 t.Log(err) 184 } 185 if err != nil && !testCase.expectedErr { 186 t.Errorf("Expected success, but found %s", err) 187 } 188 if err == nil && testCase.expectedErr { 189 t.Error("Expected error, but got `nil`") 190 } 191 if update != testCase.expectedUpdate { 192 t.Errorf("Expected %t, got %t", testCase.expectedUpdate, update) 193 } 194 }) 195 } 196 }