storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/erasure-sets_test.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2017 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 "path/filepath" 23 "testing" 24 25 "github.com/google/uuid" 26 ) 27 28 var testUUID = uuid.MustParse("f5c58c61-7175-4018-ab5e-a94fe9c2de4e") 29 30 func BenchmarkCrcHash(b *testing.B) { 31 cases := []struct { 32 key int 33 }{ 34 {16}, 35 {64}, 36 {128}, 37 {256}, 38 {512}, 39 {1024}, 40 } 41 for _, testCase := range cases { 42 testCase := testCase 43 key := randString(testCase.key) 44 b.Run("", func(b *testing.B) { 45 b.SetBytes(1024) 46 b.ReportAllocs() 47 b.ResetTimer() 48 for i := 0; i < b.N; i++ { 49 crcHashMod(key, 16) 50 } 51 }) 52 } 53 } 54 55 func BenchmarkSipHash(b *testing.B) { 56 cases := []struct { 57 key int 58 }{ 59 {16}, 60 {64}, 61 {128}, 62 {256}, 63 {512}, 64 {1024}, 65 } 66 for _, testCase := range cases { 67 testCase := testCase 68 key := randString(testCase.key) 69 b.Run("", func(b *testing.B) { 70 b.SetBytes(1024) 71 b.ReportAllocs() 72 b.ResetTimer() 73 for i := 0; i < b.N; i++ { 74 sipHashMod(key, 16, testUUID) 75 } 76 }) 77 } 78 } 79 80 // TestSipHashMod - test sip hash. 81 func TestSipHashMod(t *testing.T) { 82 testCases := []struct { 83 objectName string 84 sipHash int 85 }{ 86 // cases which should pass the test. 87 // passing in valid object name. 88 {"object", 37}, 89 {"The Shining Script <v1>.pdf", 38}, 90 {"Cost Benefit Analysis (2009-2010).pptx", 59}, 91 {"117Gn8rfHL2ACARPAhaFd0AGzic9pUbIA/5OCn5A", 35}, 92 {"SHØRT", 49}, 93 {"There are far too many object names, and far too few bucket names!", 8}, 94 {"a/b/c/", 159}, 95 {"/a/b/c", 96}, 96 {string([]byte{0xff, 0xfe, 0xfd}), 147}, 97 } 98 99 // Tests hashing order to be consistent. 100 for i, testCase := range testCases { 101 if sipHashElement := hashKey("SIPMOD", testCase.objectName, 200, testUUID); sipHashElement != testCase.sipHash { 102 t.Errorf("Test case %d: Expected \"%v\" but failed \"%v\"", i+1, testCase.sipHash, sipHashElement) 103 } 104 } 105 106 if sipHashElement := hashKey("SIPMOD", "This will fail", -1, testUUID); sipHashElement != -1 { 107 t.Errorf("Test: Expected \"-1\" but got \"%v\"", sipHashElement) 108 } 109 110 if sipHashElement := hashKey("SIPMOD", "This will fail", 0, testUUID); sipHashElement != -1 { 111 t.Errorf("Test: Expected \"-1\" but got \"%v\"", sipHashElement) 112 } 113 114 if sipHashElement := hashKey("UNKNOWN", "This will fail", 0, testUUID); sipHashElement != -1 { 115 t.Errorf("Test: Expected \"-1\" but got \"%v\"", sipHashElement) 116 } 117 } 118 119 // TestCrcHashMod - test crc hash. 120 func TestCrcHashMod(t *testing.T) { 121 testCases := []struct { 122 objectName string 123 crcHash int 124 }{ 125 // cases which should pass the test. 126 // passing in valid object name. 127 {"object", 28}, 128 {"The Shining Script <v1>.pdf", 142}, 129 {"Cost Benefit Analysis (2009-2010).pptx", 133}, 130 {"117Gn8rfHL2ACARPAhaFd0AGzic9pUbIA/5OCn5A", 185}, 131 {"SHØRT", 97}, 132 {"There are far too many object names, and far too few bucket names!", 101}, 133 {"a/b/c/", 193}, 134 {"/a/b/c", 116}, 135 {string([]byte{0xff, 0xfe, 0xfd}), 61}, 136 } 137 138 // Tests hashing order to be consistent. 139 for i, testCase := range testCases { 140 if crcHashElement := hashKey("CRCMOD", testCase.objectName, 200, testUUID); crcHashElement != testCase.crcHash { 141 t.Errorf("Test case %d: Expected \"%v\" but failed \"%v\"", i+1, testCase.crcHash, crcHashElement) 142 } 143 } 144 145 if crcHashElement := hashKey("CRCMOD", "This will fail", -1, testUUID); crcHashElement != -1 { 146 t.Errorf("Test: Expected \"-1\" but got \"%v\"", crcHashElement) 147 } 148 149 if crcHashElement := hashKey("CRCMOD", "This will fail", 0, testUUID); crcHashElement != -1 { 150 t.Errorf("Test: Expected \"-1\" but got \"%v\"", crcHashElement) 151 } 152 153 if crcHashElement := hashKey("UNKNOWN", "This will fail", 0, testUUID); crcHashElement != -1 { 154 t.Errorf("Test: Expected \"-1\" but got \"%v\"", crcHashElement) 155 } 156 } 157 158 // TestNewErasure - tests initialization of all input disks 159 // and constructs a valid `Erasure` object 160 func TestNewErasureSets(t *testing.T) { 161 ctx, cancel := context.WithCancel(context.Background()) 162 defer cancel() 163 164 var nDisks = 16 // Maximum disks. 165 var erasureDisks []string 166 for i := 0; i < nDisks; i++ { 167 // Do not attempt to create this path, the test validates 168 // so that newErasureSets initializes non existing paths 169 // and successfully returns initialized object layer. 170 disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix()) 171 erasureDisks = append(erasureDisks, disk) 172 defer os.RemoveAll(disk) 173 } 174 175 endpoints := mustGetNewEndpoints(erasureDisks...) 176 _, _, err := waitForFormatErasure(true, endpoints, 1, 0, 16, "", "") 177 if err != errInvalidArgument { 178 t.Fatalf("Expecting error, got %s", err) 179 } 180 181 _, _, err = waitForFormatErasure(true, nil, 1, 1, 16, "", "") 182 if err != errInvalidArgument { 183 t.Fatalf("Expecting error, got %s", err) 184 } 185 186 // Initializes all erasure disks 187 storageDisks, format, err := waitForFormatErasure(true, endpoints, 1, 1, 16, "", "") 188 if err != nil { 189 t.Fatalf("Unable to format disks for erasure, %s", err) 190 } 191 192 if _, err := newErasureSets(ctx, endpoints, storageDisks, format, ecDrivesNoConfig(16), 0); err != nil { 193 t.Fatalf("Unable to initialize erasure") 194 } 195 } 196 197 // TestHashedLayer - tests the hashed layer which will be returned 198 // consistently for a given object name. 199 func TestHashedLayer(t *testing.T) { 200 // Test distribution with 16 sets. 201 var objs [16]*erasureObjects 202 for i := range objs { 203 objs[i] = &erasureObjects{} 204 } 205 206 sets := &erasureSets{sets: objs[:], distributionAlgo: "CRCMOD"} 207 208 testCases := []struct { 209 objectName string 210 expectedObj *erasureObjects 211 }{ 212 // cases which should pass the test. 213 // passing in valid object name. 214 {"object", objs[12]}, 215 {"The Shining Script <v1>.pdf", objs[14]}, 216 {"Cost Benefit Analysis (2009-2010).pptx", objs[13]}, 217 {"117Gn8rfHL2ACARPAhaFd0AGzic9pUbIA/5OCn5A", objs[1]}, 218 {"SHØRT", objs[9]}, 219 {"There are far too many object names, and far too few bucket names!", objs[13]}, 220 {"a/b/c/", objs[1]}, 221 {"/a/b/c", objs[4]}, 222 {string([]byte{0xff, 0xfe, 0xfd}), objs[13]}, 223 } 224 225 // Tests hashing order to be consistent. 226 for i, testCase := range testCases { 227 gotObj := sets.getHashedSet(testCase.objectName) 228 if gotObj != testCase.expectedObj { 229 t.Errorf("Test case %d: Expected \"%#v\" but failed \"%#v\"", i+1, testCase.expectedObj, gotObj) 230 } 231 } 232 }