github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/ais/tgtobj_internal_test.go (about) 1 // Package ais provides core functionality for the AIStore object storage. 2 /* 3 * Copyright (c) 2018-2024, NVIDIA CORPORATION. All rights reserved. 4 */ 5 package ais 6 7 import ( 8 "flag" 9 "io" 10 "net/http" 11 "os" 12 "path" 13 "testing" 14 "time" 15 16 "github.com/NVIDIA/aistore/api/apc" 17 "github.com/NVIDIA/aistore/cmn" 18 "github.com/NVIDIA/aistore/cmn/cos" 19 "github.com/NVIDIA/aistore/core" 20 "github.com/NVIDIA/aistore/core/meta" 21 "github.com/NVIDIA/aistore/core/mock" 22 "github.com/NVIDIA/aistore/fs" 23 "github.com/NVIDIA/aistore/tools/readers" 24 ) 25 26 const ( 27 testMountpath = "/tmp/ais-test-mpath" // mpath is created and deleted during the test 28 testBucket = "bck" 29 ) 30 31 var ( 32 t *target 33 34 // interface guard 35 _ http.ResponseWriter = (*discardRW)(nil) 36 ) 37 38 type ( 39 discardRW struct { 40 w io.Writer 41 } 42 ) 43 44 func newDiscardRW() *discardRW { 45 return &discardRW{ 46 w: io.Discard, 47 } 48 } 49 50 func (drw *discardRW) Write(p []byte) (int, error) { return drw.w.Write(p) } 51 func (*discardRW) Header() http.Header { return make(http.Header) } 52 func (*discardRW) WriteHeader(int) {} 53 54 func TestMain(m *testing.M) { 55 flag.Parse() 56 57 // file system 58 cos.CreateDir(testMountpath) 59 defer os.RemoveAll(testMountpath) 60 fs.TestNew(nil) 61 fs.CSM.Reg(fs.ObjectType, &fs.ObjectContentResolver{}, true) 62 fs.CSM.Reg(fs.WorkfileType, &fs.WorkfileContentResolver{}, true) 63 64 // target 65 config := cmn.GCO.Get() 66 config.Log.Level = "3" 67 co := newConfigOwner(config) 68 t = newTarget(co) 69 t.initSnode(config) 70 tid, _ := initTID(config) 71 t.si.Init(tid, apc.Target) 72 73 fs.Add(testMountpath, t.SID()) 74 75 t.htrun.init(config) 76 77 t.statsT = mock.NewStatsTracker() 78 core.Tinit(t, t.statsT, false) 79 80 bck := meta.NewBck(testBucket, apc.AIS, cmn.NsGlobal) 81 bmd := newBucketMD() 82 bmd.add(bck, &cmn.Bprops{ 83 Cksum: cmn.CksumConf{ 84 Type: cos.ChecksumNone, 85 }, 86 }) 87 t.owner.bmd.putPersist(bmd, nil) 88 fs.CreateBucket(bck.Bucket(), false /*nilbmd*/) 89 90 m.Run() 91 } 92 93 func BenchmarkObjPut(b *testing.B) { 94 benches := []struct { 95 fileSize int64 96 }{ 97 {cos.KiB}, 98 {512 * cos.KiB}, 99 {cos.MiB}, 100 {2 * cos.MiB}, 101 {4 * cos.MiB}, 102 {8 * cos.MiB}, 103 {16 * cos.MiB}, 104 } 105 for _, bench := range benches { 106 b.Run(cos.ToSizeIEC(bench.fileSize, 2), func(b *testing.B) { 107 lom := core.AllocLOM("objname") 108 defer core.FreeLOM(lom) 109 err := lom.InitBck(&cmn.Bck{Name: testBucket, Provider: apc.AIS, Ns: cmn.NsGlobal}) 110 if err != nil { 111 b.Fatal(err) 112 } 113 114 b.ResetTimer() 115 for range b.N { 116 b.StopTimer() 117 r, _ := readers.NewRand(bench.fileSize, cos.ChecksumNone) 118 poi := &putOI{ 119 atime: time.Now().UnixNano(), 120 t: t, 121 lom: lom, 122 r: r, 123 workFQN: path.Join(testMountpath, "objname.work"), 124 config: cmn.GCO.Get(), 125 } 126 os.Remove(lom.FQN) 127 b.StartTimer() 128 129 _, err := poi.putObject() 130 if err != nil { 131 b.Fatal(err) 132 } 133 } 134 b.StopTimer() 135 os.Remove(lom.FQN) 136 }) 137 } 138 } 139 140 func BenchmarkObjAppend(b *testing.B) { 141 benches := []struct { 142 fileSize int64 143 }{ 144 {fileSize: cos.KiB}, 145 {fileSize: 512 * cos.KiB}, 146 {fileSize: cos.MiB}, 147 {fileSize: 2 * cos.MiB}, 148 {fileSize: 4 * cos.MiB}, 149 {fileSize: 8 * cos.MiB}, 150 {fileSize: 16 * cos.MiB}, 151 } 152 153 buf := make([]byte, 16*cos.KiB) 154 for _, bench := range benches { 155 b.Run(cos.ToSizeIEC(bench.fileSize, 2), func(b *testing.B) { 156 lom := core.AllocLOM("objname") 157 defer core.FreeLOM(lom) 158 err := lom.InitBck(&cmn.Bck{Name: testBucket, Provider: apc.AIS, Ns: cmn.NsGlobal}) 159 if err != nil { 160 b.Fatal(err) 161 } 162 163 var hdl aoHdl 164 b.ResetTimer() 165 for range b.N { 166 b.StopTimer() 167 r, _ := readers.NewRand(bench.fileSize, cos.ChecksumNone) 168 aoi := &apndOI{ 169 started: time.Now().UnixNano(), 170 t: t, 171 lom: lom, 172 r: r, 173 op: apc.AppendOp, 174 hdl: hdl, 175 } 176 os.Remove(lom.FQN) 177 b.StartTimer() 178 179 newHandle, _, err := aoi.apnd(buf) 180 if err != nil { 181 b.Fatal(err) 182 } 183 err = aoi.parse(newHandle) 184 if err != nil { 185 b.Fatal(err) 186 } 187 } 188 b.StopTimer() 189 os.Remove(lom.FQN) 190 os.Remove(hdl.workFQN) 191 }) 192 } 193 } 194 195 func BenchmarkObjGetDiscard(b *testing.B) { 196 benches := []struct { 197 fileSize int64 198 chunked bool 199 }{ 200 {fileSize: cos.KiB, chunked: false}, 201 {fileSize: 512 * cos.KiB, chunked: false}, 202 {fileSize: cos.MiB, chunked: false}, 203 {fileSize: 2 * cos.MiB, chunked: false}, 204 {fileSize: 4 * cos.MiB, chunked: false}, 205 {fileSize: 16 * cos.MiB, chunked: false}, 206 207 {fileSize: cos.KiB, chunked: true}, 208 {fileSize: 512 * cos.KiB, chunked: true}, 209 {fileSize: cos.MiB, chunked: true}, 210 {fileSize: 2 * cos.MiB, chunked: true}, 211 {fileSize: 4 * cos.MiB, chunked: true}, 212 {fileSize: 16 * cos.MiB, chunked: true}, 213 } 214 215 for _, bench := range benches { 216 benchName := cos.ToSizeIEC(bench.fileSize, 2) 217 if bench.chunked { 218 benchName += "-chunked" 219 } 220 b.Run(benchName, func(b *testing.B) { 221 lom := core.AllocLOM("objname") 222 defer core.FreeLOM(lom) 223 err := lom.InitBck(&cmn.Bck{Name: testBucket, Provider: apc.AIS, Ns: cmn.NsGlobal}) 224 if err != nil { 225 b.Fatal(err) 226 } 227 228 r, _ := readers.NewRand(bench.fileSize, cos.ChecksumNone) 229 poi := &putOI{ 230 atime: time.Now().UnixNano(), 231 t: t, 232 lom: lom, 233 r: r, 234 workFQN: path.Join(testMountpath, "objname.work"), 235 config: cmn.GCO.Get(), 236 } 237 _, err = poi.putObject() 238 if err != nil { 239 b.Fatal(err) 240 } 241 242 if err := lom.Load(false, false); err != nil { 243 b.Fatal(err) 244 } 245 246 w := newDiscardRW() 247 goi := &getOI{ 248 atime: time.Now().UnixNano(), 249 t: t, 250 lom: lom, 251 w: w, 252 chunked: bench.chunked, 253 } 254 255 b.ResetTimer() 256 for range b.N { 257 _, err := goi.getObject() 258 if err != nil { 259 b.Fatal(err) 260 } 261 } 262 263 b.StopTimer() 264 os.Remove(lom.FQN) 265 }) 266 } 267 }