1
// Copyright 2023 The CubeFS Authors.
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
7
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12
// implied. See the License for the specific language governing
13
// permissions and limitations under the License.
28
raftstoremock "github.com/cubefs/cubefs/metanode/mocktest/raftstore"
29
"github.com/cubefs/cubefs/proto"
30
"github.com/cubefs/cubefs/util"
31
"github.com/cubefs/cubefs/util/config"
32
"github.com/cubefs/cubefs/util/log"
33
"github.com/golang/mock/gomock"
34
"github.com/stretchr/testify/assert"
38
partitionId uint64 = 10
39
manager = &metadataManager{partitions: make(map[uint64]MetaPartition), volUpdating: new(sync.Map)}
43
// PartitionId uint64 `json:"partition_id"`
44
// VolName string `json:"vol_name"`
45
// PartitionType int `json:"partition_type"`
46
var metaConf = &MetaPartitionConfig{
48
VolName: VolNameForTest,
49
PartitionType: proto.VolumeTypeHot,
53
ConfigKeyLogDir = "logDir"
54
ConfigKeyLogLevel = "logLevel"
55
DirModeType uint32 = 2147484141
60
"logDir": "/tmp/cubefs/Logs",
62
"walDir":"/tmp/cubefs/raft",
63
"clusterName":"cubefs"
67
func tLogf(format string, args ...interface{}) {
68
tlog.Log(fmt.Sprintf(format, args...))
71
func newPartition(conf *MetaPartitionConfig, manager *metadataManager) (mp *metaPartition) {
74
dentryTree: NewBtree(),
75
inodeTree: NewBtree(),
76
extendTree: NewBtree(),
77
multipartTree: NewBtree(),
78
stopC: make(chan bool),
79
storeChan: make(chan *storeMsg, 100),
80
freeList: newFreeList(),
81
extDelCh: make(chan []proto.ExtentKey, defaultDelExtentsCnt),
82
extReset: make(chan struct{}),
88
mp.config.End = 100000
89
mp.uidManager = NewUidMgr(conf.VolName, mp.config.PartitionId)
90
mp.mqMgr = NewQuotaManager(conf.VolName, mp.config.PartitionId)
95
cfg := config.LoadConfigString(cfgJSON)
97
logDir := cfg.GetString(ConfigKeyLogDir)
100
if _, err := log.InitLog(logDir, "metanode", log.DebugLevel, nil, log.DefaultLogLeftSpaceLimit); err != nil {
101
fmt.Println("Fatal: failed to start the cubefs daemon - ", err)
104
log.LogDebugf("action start")
108
func initMp(t *testing.T) {
110
mp = newPartition(metaConf, manager)
111
mp.multiVersionList = &proto.VolVersionInfoList{}
112
ino := testCreateInode(nil, DirModeType)
113
t.Logf("cursor %v create ino[%v]", mp.config.Cursor, ino)
114
mp.config.Cursor = 1000
117
func buildExtentKey(seq uint64, foffset uint64, extid uint64, exteoffset uint64, size uint32) proto.ExtentKey {
118
return proto.ExtentKey{
120
PartitionId: partitionId,
122
ExtentOffset: exteoffset, // offset in extent like tiny extent offset large than 0,normal is 0
123
Size: size, // extent real size?
124
SnapInfo: &proto.ExtSnapInfo{
130
func buildExtents(verSeq uint64, startFileOff uint64, extid uint64) (exts []proto.ExtentKey) {
136
ext1 := buildExtentKey(verSeq, startFileOff+i*1000, extid, extOff+i*1000, 1000)
137
exts = append(exts, ext1)
143
func isExtEqual(ek1 proto.ExtentKey, ek2 proto.ExtentKey) bool {
144
return ek1.ExtentId == ek2.ExtentId &&
145
ek1.FileOffset == ek2.FileOffset &&
146
ek1.Size == ek2.Size &&
147
ek1.ExtentOffset == ek2.ExtentOffset &&
148
ek1.PartitionId == ek2.PartitionId
151
func isDentryEqual(den1 *proto.Dentry, den2 *Dentry) bool {
152
return den1.Inode == den2.Inode &&
153
den1.Name == den2.Name &&
154
den1.Type == den2.Type
157
func checkOffSetInSequnce(t *testing.T, eks []proto.ExtentKey) bool {
163
lastFileOff uint64 = eks[0].FileOffset
164
lastSize uint32 = eks[0].Size
167
for idx, ext := range eks[1:] {
168
// t.Logf("idx:%v ext:%v, lastFileOff %v, lastSize %v", idx, ext, lastFileOff, lastSize)
169
if ext.FileOffset != lastFileOff+uint64(lastSize) {
170
t.Errorf("checkOffSetInSequnce not equal idx %v %v:(%v+%v) eks{%v}", idx, ext.FileOffset, lastFileOff, lastSize, eks)
173
lastFileOff = ext.FileOffset
179
func testGetExtList(t *testing.T, ino *Inode, verRead uint64) (resp *proto.GetExtentsResponse) {
180
reqExtList := &proto.GetExtentsRequest{
181
VolName: metaConf.VolName,
182
PartitionID: partitionId,
186
reqExtList.VerSeq = verRead
187
assert.True(t, nil == mp.ExtentsList(reqExtList, packet))
188
resp = &proto.GetExtentsResponse{}
190
assert.True(t, nil == packet.UnmarshalData(resp))
191
t.Logf("testGetExtList.resp %v", resp)
192
assert.True(t, packet.ResultCode == proto.OpOk)
193
assert.True(t, checkOffSetInSequnce(t, resp.Extents))
197
func testCheckExtList(t *testing.T, ino *Inode, seqArr []uint64) bool {
198
reqExtList := &proto.GetExtentsRequest{
199
VolName: metaConf.VolName,
200
PartitionID: partitionId,
204
for idx, verRead := range seqArr {
205
t.Logf("check extlist index %v ver [%v]", idx, verRead)
206
reqExtList.VerSeq = verRead
207
getExtRsp := testGetExtList(t, ino, verRead)
208
t.Logf("check extlist rsp %v size %v,%v", getExtRsp, getExtRsp.Size, ino.Size)
209
assert.True(t, getExtRsp.Size == uint64(1000*(idx+1)))
210
if getExtRsp.Size != uint64(1000*(idx+1)) {
217
func testCreateInode(t *testing.T, mode uint32) *Inode {
218
inoID, _ := mp.nextInodeID()
220
t.Logf("inode id:%v", inoID)
223
ino := NewInode(inoID, mode)
224
ino.setVer(mp.verSeq)
226
t.Logf("testCreateInode ino[%v]", ino)
229
mp.fsmCreateInode(ino)
233
func testCreateDentry(t *testing.T, parentId uint64, inodeId uint64, name string, mod uint32) *Dentry {
239
multiSnap: NewDentrySnap(mp.verSeq),
242
t.Logf("createDentry dentry %v", dentry)
243
ret := mp.fsmCreateDentry(dentry, false)
244
assert.True(t, proto.OpOk == ret)
245
if ret != proto.OpOk {
251
func TestEkMarshal(t *testing.T) {
252
log.LogDebugf("TestEkMarshal")
254
// inodeID uint64, ekRef *sync.Map, ek *proto.ExtentKey
255
ino := testCreateInode(t, FileModeType)
256
ino.multiSnap = NewMultiSnap(mp.verSeq)
257
ino.multiSnap.ekRefMap = new(sync.Map)
258
ek := &proto.ExtentKey{
261
SnapInfo: &proto.ExtSnapInfo{
265
id := storeEkSplit(0, 0, ino.multiSnap.ekRefMap, ek)
266
dpID, extID := proto.ParseFromId(id)
267
assert.True(t, dpID == ek.PartitionId)
268
assert.True(t, extID == ek.ExtentId)
270
ok, _ := ino.DecSplitEk(mp.config.PartitionId, ek)
271
assert.True(t, ok == true)
272
log.LogDebugf("TestEkMarshal close")
276
verInfo := &proto.VolVersionInfo{
278
Status: proto.VersionNormal,
280
mp.multiVersionList.VerList = append(mp.multiVersionList.VerList, verInfo)
283
func testGetSplitSize(t *testing.T, ino *Inode) (cnt int32) {
284
if nil == mp.inodeTree.Get(ino) {
287
ino.multiSnap.ekRefMap.Range(func(key, value interface{}) bool {
288
dpID, extID := proto.ParseFromId(key.(uint64))
289
log.LogDebugf("id:[%v],key %v (dpId-%v|extId-%v) refCnt %v", cnt, key, dpID, extID, value.(uint32))
296
func testGetEkRefCnt(t *testing.T, ino *Inode, ek *proto.ExtentKey) (cnt uint32) {
297
id := ek.GenerateId()
302
if nil == mp.inodeTree.Get(ino) {
303
t.Logf("testGetEkRefCnt inode[%v] ek [%v] not found", ino, ek)
306
if val, ok = ino.multiSnap.ekRefMap.Load(id); !ok {
307
t.Logf("inode[%v] not ek [%v]", ino.Inode, ek)
310
t.Logf("testGetEkRefCnt ek [%v] get refCnt %v", ek, val.(uint32))
314
func testDelDiscardEK(t *testing.T, fileIno *Inode) (cnt uint32) {
315
delCnt := len(mp.extDelCh)
316
t.Logf("enter testDelDiscardEK extDelCh size %v", delCnt)
317
if len(mp.extDelCh) == 0 {
318
t.Logf("testDelDiscardEK discard ek cnt %v", cnt)
321
for i := 0; i < delCnt; i++ {
323
for _, ek := range eks {
324
t.Logf("the delete ek is %v", ek)
327
t.Logf("pop [%v]", i)
329
t.Logf("testDelDiscardEK discard ek cnt %v", cnt)
334
func TestSplitKeyDeletion(t *testing.T) {
335
log.LogDebugf("action[TestSplitKeyDeletion] start!!!!!!!!!!!")
338
mp.config.Cursor = 1100
340
fileIno := testCreateInode(t, FileModeType)
342
fileName := "fileTest"
343
dirDen := testCreateDentry(t, 1, fileIno.Inode, fileName, FileModeType)
344
assert.True(t, dirDen != nil)
346
initExt := buildExtentKey(0, 0, 1024, 0, 1000)
347
fileIno.Extents.eks = append(fileIno.Extents.eks, initExt)
349
splitSeq := testCreateVer()
350
splitKey := buildExtentKey(splitSeq, 500, 1024, 128100, 100)
351
extents := &SortedExtents{}
352
extents.eks = append(extents.eks, splitKey)
355
Inode: fileIno.Inode,
357
multiSnap: &InodeMultiSnap{
361
mp.verSeq = iTmp.getVer()
362
mp.fsmAppendExtentsWithCheck(iTmp, true)
363
assert.True(t, testGetSplitSize(t, fileIno) == 1)
364
assert.True(t, testGetEkRefCnt(t, fileIno, &initExt) == 4)
366
testCleanSnapshot(t, 0)
367
delCnt := testDelDiscardEK(t, fileIno)
368
assert.True(t, 1 == delCnt)
370
assert.True(t, testGetSplitSize(t, fileIno) == 1)
371
assert.True(t, testGetEkRefCnt(t, fileIno, &initExt) == 3)
373
log.LogDebugf("try to deletion current")
374
testDeleteDirTree(t, 1, 0)
376
fileIno.GetAllExtsOfflineInode(mp.config.PartitionId)
378
splitCnt := uint32(testGetSplitSize(t, fileIno))
379
assert.True(t, 0 == splitCnt)
381
assert.True(t, testGetSplitSize(t, fileIno) == 0)
382
assert.True(t, testGetEkRefCnt(t, fileIno, &initExt) == 0)
385
func testGetlastVer() (verSeq uint64) {
386
vlen := len(mp.multiVersionList.VerList)
387
return mp.multiVersionList.VerList[vlen-1].Ver
390
var tm = time.Now().Unix()
392
func testCreateVer() (verSeq uint64) {
393
mp.multiVersionList.RWLock.Lock()
394
defer mp.multiVersionList.RWLock.Unlock()
397
verInfo := &proto.VolVersionInfo{
399
Status: proto.VersionNormal,
401
mp.multiVersionList.VerList = append(mp.multiVersionList.VerList, verInfo)
402
mp.verSeq = verInfo.Ver
406
func testReadDirAll(t *testing.T, verSeq uint64, parentId uint64) (resp *ReadDirLimitResp) {
407
// testPrintAllDentry(t)
408
t.Logf("[testReadDirAll] with seq [%v] parentId %v", verSeq, parentId)
409
req := &ReadDirLimitReq{
410
PartitionID: partitionId,
411
VolName: mp.GetVolName(),
413
Limit: math.MaxUint64,
416
return mp.readDirLimit(req)
419
func testVerListRemoveVer(t *testing.T, verSeq uint64) bool {
420
testPrintAllSysVerList(t)
421
for i, ver := range mp.multiVersionList.VerList {
422
if ver.Ver == verSeq {
423
// mp.multiVersionList = append(mp.multiVersionList[:i], mp.multiVersionList[i+1:]...)
424
if i == len(mp.multiVersionList.VerList)-1 {
425
mp.multiVersionList.VerList = mp.multiVersionList.VerList[:i]
428
mp.multiVersionList.VerList = append(mp.multiVersionList.VerList[:i], mp.multiVersionList.VerList[i+1:]...)
436
ct = uint64(time.Now().Unix())
437
seqAllArr = []uint64{0, ct, ct + 2111, ct + 10333, ct + 53456, ct + 60000, ct + 72344, ct + 234424, ct + 334424}
440
func TestAppendList(t *testing.T) {
442
for _, verSeq := range seqAllArr {
443
verInfo := &proto.VolVersionInfo{
445
Status: proto.VersionNormal,
447
mp.multiVersionList.VerList = append(mp.multiVersionList.VerList, verInfo)
450
ino := testCreateInode(t, 0)
451
t.Logf("enter TestAppendList")
453
seqArr := seqAllArr[1:index]
454
t.Logf("layer len %v, arr size %v, seqarr(%v)", ino.getLayerLen(), len(seqArr), seqArr)
455
for idx, seq := range seqArr {
456
exts := buildExtents(seq, uint64(idx*1000), uint64(idx))
457
t.Logf("buildExtents exts[%v]", exts)
460
Extents: &SortedExtents{
463
ObjExtents: NewSortedObjExtents(),
464
multiSnap: &InodeMultiSnap{
470
if status := mp.fsmAppendExtentsWithCheck(iTmp, false); status != proto.OpOk {
471
t.Errorf("status [%v]", status)
474
t.Logf("layer len %v, arr size %v, seqarr(%v)", ino.getLayerLen(), len(seqArr), seqArr)
475
assert.True(t, ino.getLayerLen() == len(seqArr))
476
assert.True(t, ino.getVer() == mp.verSeq)
478
for i := 0; i < len(seqArr)-1; i++ {
479
assert.True(t, ino.getLayerVer(i) == seqArr[len(seqArr)-i-2])
480
t.Logf("layer %v len %v content %v,seq [%v], %v", i, len(ino.multiSnap.multiVersions[i].Extents.eks), ino.multiSnap.multiVersions[i].Extents.eks,
481
ino.getLayerVer(i), seqArr[len(seqArr)-i-2])
482
assert.True(t, len(ino.multiSnap.multiVersions[i].Extents.eks) == 0)
485
//------------- split at begin -----------------------------------------
486
t.Logf("start split at begin")
487
splitSeq := seqAllArr[index]
488
splitKey := buildExtentKey(splitSeq, 0, 0, 128000, 10)
489
extents := &SortedExtents{}
490
extents.eks = append(extents.eks, splitKey)
495
multiSnap: &InodeMultiSnap{
499
mp.verSeq = iTmp.getVer()
500
mp.fsmAppendExtentsWithCheck(iTmp, true)
501
t.Logf("in split at begin")
502
assert.True(t, ino.multiSnap.multiVersions[0].Extents.eks[0].GetSeq() == ino.getLayerVer(3))
503
assert.True(t, ino.multiSnap.multiVersions[0].Extents.eks[0].FileOffset == 0)
504
assert.True(t, ino.multiSnap.multiVersions[0].Extents.eks[0].ExtentId == 0)
505
assert.True(t, ino.multiSnap.multiVersions[0].Extents.eks[0].ExtentOffset == 0)
506
assert.True(t, ino.multiSnap.multiVersions[0].Extents.eks[0].Size == splitKey.Size)
508
t.Logf("in split at begin")
510
assert.True(t, isExtEqual(ino.Extents.eks[0], splitKey))
511
assert.True(t, checkOffSetInSequnce(t, ino.Extents.eks))
513
t.Logf("top layer len %v, layer 1 len %v arr size %v", len(ino.Extents.eks), len(ino.multiSnap.multiVersions[0].Extents.eks), len(seqArr))
514
assert.True(t, len(ino.multiSnap.multiVersions[0].Extents.eks) == 1)
515
assert.True(t, len(ino.Extents.eks) == len(seqArr)+1)
517
testCheckExtList(t, ino, seqArr)
519
//-------- split at middle -----------------------------------------------
520
t.Logf("start split at middle")
522
lastTopEksLen := len(ino.Extents.eks)
523
t.Logf("split at middle lastTopEksLen %v", lastTopEksLen)
526
splitSeq = seqAllArr[index]
527
splitKey = buildExtentKey(splitSeq, 500, 0, 128100, 100)
528
extents = &SortedExtents{}
529
extents.eks = append(extents.eks, splitKey)
534
multiSnap: &InodeMultiSnap{
538
t.Logf("split at middle multiSnap.multiVersions %v", ino.getLayerLen())
539
mp.verSeq = iTmp.getVer()
540
mp.fsmAppendExtentsWithCheck(iTmp, true)
541
t.Logf("split at middle multiSnap.multiVersions %v", ino.getLayerLen())
543
getExtRsp := testGetExtList(t, ino, ino.getLayerVer(0))
544
t.Logf("split at middle getExtRsp len %v seq(%v), toplayer len:%v seq(%v)",
545
len(getExtRsp.Extents), ino.getLayerVer(0), len(ino.Extents.eks), ino.getVer())
547
assert.True(t, len(getExtRsp.Extents) == lastTopEksLen+2)
548
assert.True(t, len(ino.Extents.eks) == lastTopEksLen+2)
549
assert.True(t, checkOffSetInSequnce(t, ino.Extents.eks))
551
t.Logf("ino exts{%v}", ino.Extents.eks)
553
//-------- split at end -----------------------------------------------
554
t.Logf("start split at end")
556
lastTopEksLen = len(ino.Extents.eks)
558
splitSeq = seqAllArr[index]
559
splitKey = buildExtentKey(splitSeq, 3900, 3, 129000, 100)
560
extents = &SortedExtents{}
561
extents.eks = append(extents.eks, splitKey)
566
multiSnap: &InodeMultiSnap{
570
t.Logf("split key:%v", splitKey)
571
getExtRsp = testGetExtList(t, ino, ino.getLayerVer(0))
572
t.Logf("split at middle multiSnap.multiVersions %v, extent %v, level 1 %v", ino.getLayerLen(), getExtRsp.Extents, ino.multiSnap.multiVersions[0].Extents.eks)
573
mp.verSeq = iTmp.getVer()
574
mp.fsmAppendExtentsWithCheck(iTmp, true)
575
t.Logf("split at middle multiSnap.multiVersions %v", ino.getLayerLen())
576
getExtRsp = testGetExtList(t, ino, ino.getLayerVer(0))
577
t.Logf("split at middle multiSnap.multiVersions %v, extent %v, level 1 %v", ino.getLayerLen(), getExtRsp.Extents, ino.multiSnap.multiVersions[0].Extents.eks)
579
t.Logf("split at middle getExtRsp len %v seq(%v), toplayer len:%v seq(%v)",
580
len(getExtRsp.Extents), ino.getLayerVer(0), len(ino.Extents.eks), ino.getVer())
582
assert.True(t, len(getExtRsp.Extents) == lastTopEksLen+1)
583
assert.True(t, len(ino.Extents.eks) == lastTopEksLen+1)
584
assert.True(t, isExtEqual(ino.Extents.eks[lastTopEksLen], splitKey))
585
// assert.True(t, false)
587
//-------- split at the splited one -----------------------------------------------
588
t.Logf("start split at end")
590
lastTopEksLen = len(ino.Extents.eks)
592
splitSeq = seqAllArr[index]
593
splitKey = buildExtentKey(splitSeq, 3950, 3, 129000, 20)
594
extents = &SortedExtents{}
595
extents.eks = append(extents.eks, splitKey)
600
multiSnap: &InodeMultiSnap{
604
t.Logf("split key:%v", splitKey)
605
mp.verSeq = iTmp.getVer()
606
mp.fsmAppendExtentsWithCheck(iTmp, true)
608
getExtRsp = testGetExtList(t, ino, ino.getLayerVer(0))
610
assert.True(t, len(ino.Extents.eks) == lastTopEksLen+2)
611
assert.True(t, checkOffSetInSequnce(t, ino.Extents.eks))
614
//func MockSubmitTrue(mp *metaPartition, inode uint64, offset int, data []byte,
615
// flags int) (write int, err error) {
616
// return len(data), nil
619
func testPrintAllSysVerList(t *testing.T) {
620
for idx, info := range mp.multiVersionList.VerList {
621
t.Logf("testPrintAllSysVerList idx %v, info %v", idx, info)
625
func testPrintAllDentry(t *testing.T) uint64 {
627
mp.dentryTree.Ascend(func(i BtreeItem) bool {
629
t.Logf("testPrintAllDentry name %v top layer dentry:%v", den.Name, den)
630
if den.getSnapListLen() > 0 {
631
for id, info := range den.multiSnap.dentryList {
632
t.Logf("testPrintAllDentry name %v layer %v, denseq [%v] den %v", den.Name, id, info.getVerSeq(), info)
641
func testPrintAllInodeInfo(t *testing.T) {
642
mp.inodeTree.Ascend(func(item BtreeItem) bool {
644
t.Logf("action[PrintAllVersionInfo] toplayer inode[%v] verSeq [%v] hist len [%v]", i, i.getVer(), i.getLayerLen())
645
if i.getLayerLen() == 0 {
648
for id, info := range i.multiSnap.multiVersions {
649
t.Logf("action[PrintAllVersionInfo] layer [%v] verSeq [%v] inode[%v]", id, info.getVer(), info)
655
func testPrintInodeInfo(t *testing.T, ino *Inode) {
656
i := mp.inodeTree.Get(ino).(*Inode)
657
t.Logf("action[PrintAllVersionInfo] toplayer inode[%v] verSeq [%v] hist len [%v]", i, i.getVer(), i.getLayerLen())
658
if i.getLayerLen() == 0 {
661
for id, info := range i.multiSnap.multiVersions {
662
t.Logf("action[PrintAllVersionInfo] layer [%v] verSeq [%v] inode[%v]", id, info.getVer(), info)
666
func testDelDirSnapshotVersion(t *testing.T, verSeq uint64, dirIno *Inode, dirDentry *Dentry) {
668
assert.True(t, testVerListRemoveVer(t, verSeq))
671
rspReadDir := testReadDirAll(t, verSeq, dirIno.Inode)
672
// testPrintAllDentry(t)
674
rDirIno := dirIno.Copy().(*Inode)
675
rDirIno.setVerNoCheck(verSeq)
677
rspDelIno := mp.fsmUnlinkInode(rDirIno, 0)
679
t.Logf("rspDelinfo ret %v content %v", rspDelIno.Status, rspDelIno)
680
assert.True(t, rspDelIno.Status == proto.OpOk)
681
if rspDelIno.Status != proto.OpOk {
684
rDirDentry := dirDentry.Copy().(*Dentry)
685
rDirDentry.setVerSeq(verSeq)
686
rspDelDen := mp.fsmDeleteDentry(rDirDentry, false)
687
assert.True(t, rspDelDen.Status == proto.OpOk)
689
for idx, info := range rspReadDir.Children {
690
t.Logf("testDelDirSnapshotVersion: delseq [%v] to del idx %v infof %v", verSeq, idx, info)
694
multiSnap: &InodeMultiSnap{
698
testPrintInodeInfo(t, rino)
699
log.LogDebugf("testDelDirSnapshotVersion get rino[%v] start", rino)
700
t.Logf("testDelDirSnapshotVersion get rino[%v] start", rino)
701
ino := mp.getInode(rino, false)
702
log.LogDebugf("testDelDirSnapshotVersion get rino[%v] end", ino)
703
t.Logf("testDelDirSnapshotVersion get rino[%v] end", rino)
704
assert.True(t, ino.Status == proto.OpOk)
705
if ino.Status != proto.OpOk {
709
rspDelIno = mp.fsmUnlinkInode(rino, 0)
711
assert.True(t, rspDelIno.Status == proto.OpOk || rspDelIno.Status == proto.OpNotExistErr)
712
if rspDelIno.Status != proto.OpOk && rspDelIno.Status != proto.OpNotExistErr {
713
t.Logf("testDelDirSnapshotVersion: rspDelino[%v] return st %v", rspDelIno, proto.ParseErrorCode(int32(rspDelIno.Status)))
717
ParentId: rDirIno.Inode,
720
multiSnap: NewDentrySnap(verSeq),
723
log.LogDebugf("test.testDelDirSnapshotVersion: dentry param %v ", dentry)
724
// testPrintAllDentry(t)
725
iden, st := mp.getDentry(dentry)
726
if st != proto.OpOk {
727
t.Logf("testDelDirSnapshotVersion: dentry %v return st %v", dentry, proto.ParseErrorCode(int32(st)))
729
log.LogDebugf("test.testDelDirSnapshotVersion: get dentry %v ", iden)
730
assert.True(t, st == proto.OpOk)
732
rDen := iden.Copy().(*Dentry)
733
rDen.multiSnap = NewDentrySnap(verSeq)
734
rspDelDen = mp.fsmDeleteDentry(rDen, false)
735
assert.True(t, rspDelDen.Status == proto.OpOk)
739
func TestDentry(t *testing.T) {
742
var denArry []*Dentry
743
// err := gohook.HookMethod(mp, "submit", MockSubmitTrue, nil)
744
mp.config.Cursor = 1100
745
//--------------------build dir and it's child on different version ------------------
746
seq0 := testCreateVer()
747
dirIno := testCreateInode(t, DirModeType)
748
assert.True(t, dirIno != nil)
749
dirDen := testCreateDentry(t, 1, dirIno.Inode, "testDir", DirModeType)
750
assert.True(t, dirDen != nil)
752
fIno := testCreateInode(t, FileModeType)
753
assert.True(t, fIno != nil)
754
fDen := testCreateDentry(t, dirIno.Inode, fIno.Inode, "testfile", FileModeType)
755
denArry = append(denArry, fDen)
757
//--------------------------------------
758
seq1 := testCreateVer()
759
fIno1 := testCreateInode(t, FileModeType)
760
fDen1 := testCreateDentry(t, dirIno.Inode, fIno1.Inode, "testfile2", FileModeType)
761
denArry = append(denArry, fDen1)
763
//--------------------------------------
764
seq2 := testCreateVer()
765
fIno2 := testCreateInode(t, FileModeType)
766
fDen2 := testCreateDentry(t, dirIno.Inode, fIno2.Inode, "testfile3", FileModeType)
767
denArry = append(denArry, fDen2)
769
//--------------------------------------
770
seq3 := testCreateVer()
771
//--------------------read dir and it's child on different version ------------------
773
t.Logf("TestDentry seq [%v],%v,uncommit %v,dir:%v, dentry {%v],inode[%v,%v,%v]", seq1, seq2, seq3, dirDen, denArry, fIno, fIno1, fIno2)
774
//-----------read curr version --
775
rspReadDir := testReadDirAll(t, 0, 1)
776
t.Logf("len child %v, len arry %v", len(rspReadDir.Children), len(denArry))
777
assert.True(t, len(rspReadDir.Children) == 1)
778
assert.True(t, isDentryEqual(&rspReadDir.Children[0], dirDen))
780
rspReadDir = testReadDirAll(t, 0, dirIno.Inode)
781
assert.True(t, len(rspReadDir.Children) == len(denArry))
783
for idx, info := range rspReadDir.Children {
784
t.Logf("getinfo:%v, expect:%v", info, denArry[idx])
785
assert.True(t, isDentryEqual(&info, denArry[idx]))
788
//-----------read 0 version --
789
rspReadDir = testReadDirAll(t, math.MaxUint64, dirIno.Inode)
790
assert.True(t, len(rspReadDir.Children) == 0)
792
//-----------read layer 1 version -- seq2 is the last layer, seq1 is the second layer
793
rspReadDir = testReadDirAll(t, seq1, dirIno.Inode)
794
assert.True(t, len(rspReadDir.Children) == 2)
795
for idx, info := range rspReadDir.Children {
796
t.Logf("getinfo:%v, expect:%v", info, denArry[idx])
797
assert.True(t, isDentryEqual(&info, denArry[idx]))
799
//-----------read layer 2 version --
800
rspReadDir = testReadDirAll(t, seq0, dirIno.Inode)
801
assert.True(t, len(rspReadDir.Children) == 1)
802
assert.True(t, isDentryEqual(&rspReadDir.Children[0], fDen))
804
testPrintAllDentry(t)
805
//--------------------del snapshot and read dir and it's child on different version(cann't be work on interfrace) ------------------
806
t.Logf("try testDelDirSnapshotVersion %v", seq0)
807
log.LogDebugf("try testDelDirSnapshotVersion %v", seq0)
809
testDelDirSnapshotVersion(t, seq0, dirIno, dirDen)
810
rspReadDir = testReadDirAll(t, seq0, dirIno.Inode)
811
assert.True(t, len(rspReadDir.Children) == 0)
813
testPrintAllDentry(t)
814
//---------------------------------------------
815
t.Logf("try testDelDirSnapshotVersion 0 top layer")
816
log.LogDebugf("try testDelDirSnapshotVersion 0")
817
testDelDirSnapshotVersion(t, 0, dirIno, dirDen)
818
rspReadDir = testReadDirAll(t, 0, dirIno.Inode)
819
t.Logf("after testDelDirSnapshotVersion read seq [%v] can see file %v %v", 0, len(rspReadDir.Children), rspReadDir.Children)
820
assert.True(t, len(rspReadDir.Children) == 0)
821
rspReadDir = testReadDirAll(t, seq1, dirIno.Inode)
822
t.Logf("after testDelDirSnapshotVersion read seq [%v] can see file %v %v", seq1, len(rspReadDir.Children), rspReadDir.Children)
823
assert.True(t, len(rspReadDir.Children) == 2)
825
//---------------------------------------------
826
t.Logf("try testDelDirSnapshotVersion %v", seq1)
827
log.LogDebugf("try testDelDirSnapshotVersion %v", seq1)
828
testDelDirSnapshotVersion(t, seq1, dirIno, dirDen)
830
rspReadDir = testReadDirAll(t, seq1, dirIno.Inode)
831
t.Logf("after testDelDirSnapshotVersion %v can see file %v %v", seq1, len(rspReadDir.Children), rspReadDir.Children)
832
assert.True(t, len(rspReadDir.Children) == 0)
833
testPrintAllSysVerList(t)
835
//---------------------------------------------
836
t.Logf("try testDelDirSnapshotVersion %v", seq2)
837
log.LogDebugf("try testDelDirSnapshotVersion %v", seq2)
838
testDelDirSnapshotVersion(t, seq2, dirIno, dirDen)
840
rspReadDir = testReadDirAll(t, seq2, dirIno.Inode)
841
t.Logf("after testDelDirSnapshotVersion %v can see file %v %v", seq1, len(rspReadDir.Children), rspReadDir.Children)
842
assert.True(t, len(rspReadDir.Children) == 0)
844
t.Logf("testPrintAllSysVerList")
845
testPrintAllSysVerList(t)
846
t.Logf("testPrintAllInodeInfo")
847
testPrintAllInodeInfo(t)
850
func testPrintDirTree(t *testing.T, parentId uint64, path string, verSeq uint64) (dirCnt int, fCnt int) {
852
verSeq = math.MaxUint64
854
rspReadDir := testReadDirAll(t, verSeq, parentId)
855
for _, child := range rspReadDir.Children {
856
pathInner := fmt.Sprintf("%v/%v", path, child.Name)
857
if proto.IsDir(child.Type) {
859
dc, fc := testPrintDirTree(t, child.Inode, pathInner, verSeq)
862
t.Logf("dir:%v", pathInner)
865
t.Logf("file:%v", pathInner)
871
func testAppendExt(t *testing.T, seq uint64, idx int, inode uint64) {
872
exts := buildExtents(seq, uint64(idx*1000), uint64(idx))
873
t.Logf("buildExtents exts[%v]", exts)
876
Extents: &SortedExtents{
879
ObjExtents: NewSortedObjExtents(),
880
multiSnap: &InodeMultiSnap{
885
if status := mp.fsmAppendExtentsWithCheck(iTmp, false); status != proto.OpOk {
886
t.Errorf("status [%v]", status)
890
func TestTruncateAndDel(t *testing.T) {
891
log.LogDebugf("TestTruncate start")
893
mp.config.Cursor = 1100
894
//--------------------build dir and it's child on different version ------------------
896
fileIno := testCreateInode(t, FileModeType)
897
assert.True(t, fileIno != nil)
898
dirDen := testCreateDentry(t, 1, fileIno.Inode, "testDir", FileModeType)
899
assert.True(t, dirDen != nil)
900
log.LogDebugf("TestTruncate start")
901
testAppendExt(t, 0, 0, fileIno.Inode)
902
log.LogDebugf("TestTruncate start")
903
seq1 := testCreateVer() // seq1 is NOT commited
905
seq2 := testCreateVer() // seq1 is commited,seq2 not commited
907
t.Logf("TestTruncate. create new snapshot seq [%v],%v,file verlist [%v]", seq1, seq2, fileIno.getLayerLen())
908
log.LogDebugf("TestTruncate start")
910
Inode: fileIno.Inode,
912
ModifyTime: time.Now().Unix(),
914
mp.fsmExtentsTruncate(ino)
915
log.LogDebugf("TestTruncate start")
916
t.Logf("TestTruncate. create new snapshot seq [%v],%v,file verlist size %v [%v]", seq1, seq2, len(fileIno.multiSnap.multiVersions), fileIno.multiSnap.multiVersions)
918
assert.True(t, 2 == len(fileIno.multiSnap.multiVersions))
919
rsp := testGetExtList(t, fileIno, 0)
920
assert.True(t, rsp.Size == 500)
922
rsp = testGetExtList(t, fileIno, seq2)
923
assert.True(t, rsp.Size == 500)
925
rsp = testGetExtList(t, fileIno, seq1)
926
assert.True(t, rsp.Size == 1000)
928
rsp = testGetExtList(t, fileIno, math.MaxUint64)
929
assert.True(t, rsp.Size == 1000)
931
// -------------------------------------------------------
932
log.LogDebugf("TestTruncate start")
933
testCreateVer() // seq2 IS commited, seq3 not
934
mp.fsmUnlinkInode(ino, 0)
936
log.LogDebugf("TestTruncate start")
937
assert.True(t, 3 == len(fileIno.multiSnap.multiVersions))
938
rsp = testGetExtList(t, fileIno, 0)
939
assert.True(t, len(rsp.Extents) == 0)
941
rsp = testGetExtList(t, fileIno, seq2)
942
assert.True(t, rsp.Size == 500)
944
rsp = testGetExtList(t, fileIno, seq1)
945
assert.True(t, rsp.Size == 1000)
947
rsp = testGetExtList(t, fileIno, math.MaxUint64)
948
assert.True(t, rsp.Size == 1000)
951
func testDeleteFile(t *testing.T, verSeq uint64, parentId uint64, child *proto.Dentry) {
952
t.Logf("testDeleteFile seq [%v]", verSeq)
953
fsmDentry := &Dentry{
958
multiSnap: NewDentrySnap(verSeq),
960
t.Logf("testDeleteFile seq [%v] %v dentry %v", verSeq, fsmDentry.getSeqFiled(), fsmDentry)
961
assert.True(t, nil != mp.fsmDeleteDentry(fsmDentry, false))
966
multiSnap: &InodeMultiSnap{
971
rspDelIno := mp.fsmUnlinkInode(rino, 0)
973
assert.True(t, rspDelIno.Status == proto.OpOk || rspDelIno.Status == proto.OpNotExistErr)
974
if rspDelIno.Status != proto.OpOk && rspDelIno.Status != proto.OpNotExistErr {
975
t.Logf("testDelDirSnapshotVersion: rspDelino[%v] return st %v", rspDelIno, proto.ParseErrorCode(int32(rspDelIno.Status)))
980
func testDeleteDirTree(t *testing.T, parentId uint64, verSeq uint64) {
981
t.Logf("testDeleteDirTree parentId %v seq [%v]", parentId, verSeq)
982
rspReadDir := testReadDirAll(t, verSeq, parentId)
983
for _, child := range rspReadDir.Children {
984
if proto.IsDir(child.Type) {
985
testDeleteDirTree(t, child.Inode, verSeq)
987
t.Logf("action[testDeleteDirTree] delete children %v", child)
988
log.LogDebugf("action[testDeleteDirTree] seq [%v] delete children %v", verSeq, child)
989
testDeleteFile(t, verSeq, parentId, &child)
994
func testCleanSnapshot(t *testing.T, verSeq uint64) {
995
t.Logf("action[testCleanSnapshot] verseq [%v]", verSeq)
996
log.LogDebugf("action[testCleanSnapshot] verseq [%v]", verSeq)
997
assert.True(t, testVerListRemoveVer(t, verSeq))
999
verSeq = math.MaxUint64
1001
testDeleteDirTree(t, 1, verSeq)
1006
func testSnapshotDeletion(t *testing.T, topFirst bool) {
1007
log.LogDebugf("action[TestSnapshotDeletion] start!!!!!!!!!!!")
1010
// err := gohook.HookMethod(mp, "submit", MockSubmitTrue, nil)
1011
mp.config.Cursor = 1100
1012
//--------------------build dir and it's child on different version ------------------
1025
for layIdx := 0; layIdx < dirLayCnt; layIdx++ {
1026
t.Logf("build tree:layer %v,last dir name %v inodeid %v", layIdx, dirName, dirInoId)
1027
dirIno := testCreateInode(t, DirModeType)
1028
assert.True(t, dirIno != nil)
1029
dirName = fmt.Sprintf("dir_layer_%v_1", layIdx+1)
1030
dirDen := testCreateDentry(t, dirInoId, dirIno.Inode, dirName, DirModeType)
1031
assert.True(t, dirDen != nil)
1035
dirIno1 := testCreateInode(t, DirModeType)
1036
assert.True(t, dirIno1 != nil)
1037
dirName1 := fmt.Sprintf("dir_layer_%v_2", layIdx+1)
1038
dirDen1 := testCreateDentry(t, dirInoId, dirIno1.Inode, dirName1, DirModeType)
1039
assert.True(t, dirDen1 != nil)
1042
renameDen = dirDen.Copy().(*Dentry)
1045
renameDstIno = dirIno1.Inode
1047
for fileIdx := 0; fileIdx < (layIdx+1)*2; fileIdx++ {
1048
fileIno := testCreateInode(t, FileModeType)
1049
assert.True(t, dirIno != nil)
1051
fileName := fmt.Sprintf("layer_%v_file_%v", layIdx+1, fileIdx+1)
1052
dirDen = testCreateDentry(t, dirIno.Inode, fileIno.Inode, fileName, FileModeType)
1053
assert.True(t, dirDen != nil)
1055
dirInoId = dirIno.Inode
1056
ver := testGetlastVer()
1057
verArr = append(verArr, ver)
1059
dCnt, fCnt := testPrintDirTree(t, 1, "root", ver)
1060
if layIdx+1 < dirLayCnt {
1061
log.LogDebugf("testCreateVer")
1065
log.LogDebugf("PrintALl verseq [%v] get dirCnt %v, fCnt %v mp verlist size %v", ver, dCnt, fCnt, len(mp.multiVersionList.VerList))
1068
t.Logf("---------------------------------------------------------------------")
1069
t.Logf("--------testPrintDirTree by ver -------------------------------------")
1070
t.Logf("---------------------------------------------------------------------")
1071
for idx, ver := range verArr {
1072
dCnt, fCnt := testPrintDirTree(t, 1, "root", ver)
1073
t.Logf("---------------------------------------------------------------------")
1074
t.Logf("PrintALl verseq [%v] get dirCnt %v, fCnt %v", ver, dCnt, fCnt)
1075
assert.True(t, dCnt == dirCnt+2)
1076
assert.True(t, fCnt == fileCnt+(idx+1)*2)
1080
t.Logf("------------rename dir ----------------------")
1081
if renameDen != nil {
1082
t.Logf("try to move dir %v", renameDen)
1083
assert.True(t, nil != mp.fsmDeleteDentry(renameDen, false))
1084
renameDen.Name = fmt.Sprintf("rename_from_%v", renameDen.Name)
1085
renameDen.ParentId = renameDstIno
1087
t.Logf("try to move to dir %v", renameDen)
1088
assert.True(t, mp.fsmCreateDentry(renameDen, false) == proto.OpOk)
1089
testPrintDirTree(t, 1, "root", 0)
1091
delSnapshotList := func() {
1092
t.Logf("---------------------------------------------------------------------")
1093
t.Logf("--------testCleanSnapshot by ver-------------------------------------")
1094
t.Logf("---------------------------------------------------------------------")
1095
for idx, ver := range verArr {
1096
t.Logf("---------------------------------------------------------------------")
1097
t.Logf("index %v ver [%v] try to deletion", idx, ver)
1098
log.LogDebugf("index %v ver [%v] try to deletion", idx, ver)
1099
t.Logf("---------------------------------------------------------------------")
1100
testCleanSnapshot(t, ver)
1101
t.Logf("---------------------------------------------------------------------")
1102
t.Logf("index %v ver [%v] after deletion mp inode freeList len %v", idx, ver, mp.freeList.Len())
1103
log.LogDebugf("index %v ver [%v] after deletion mp inode freeList len %v", idx, ver, mp.freeList.Len())
1104
t.Logf("---------------------------------------------------------------------")
1105
if idx == len(verArr)-2 {
1110
delCurrent := func() {
1111
t.Logf("---------------------------------------------------------------------")
1112
t.Logf("--------testDeleteAll current -------------------------------------")
1113
t.Logf("---------------------------------------------------------------------")
1114
log.LogDebugf("try to deletion current")
1115
testDeleteDirTree(t, 1, 0)
1116
log.LogDebugf("try to deletion current finish")
1127
t.Logf("---------------------------------------------------------------------")
1128
t.Logf("after deletion current layerr mp inode freeList len %v fileCnt %v dircnt %v", mp.freeList.Len(), fileCnt, dirCnt)
1129
assert.True(t, mp.freeList.Len() == fileCnt)
1130
// base on 3.2.0 the dir will push to freelist, not count in in later release version
1131
// assert.True(t, mp.freeList.Len() == fileCnt+dirCnt)
1132
assert.True(t, 0 == testPrintAllDentry(t))
1133
t.Logf("---------------------------------------------------------------------")
1135
t.Logf("---------------------------------------------------------------------")
1136
t.Logf("--------testPrintAllInodeInfo should have no inode -------------------------------------")
1137
t.Logf("---------------------------------------------------------------------")
1138
testPrintAllInodeInfo(t)
1139
t.Logf("---------------------------------------------")
1140
// assert.True(t, false)
1144
func TestSnapshotDeletion(t *testing.T) {
1145
testSnapshotDeletion(t, true)
1146
testSnapshotDeletion(t, false)
1149
func TestDentryVerMarshal(t *testing.T) {
1156
multiSnap: NewDentrySnap(mp.GetVerSeq()),
1158
val, err := den1.Marshal()
1165
t.Logf("seq, %v %v,parent %v", den1.getVerSeq(), den2.getVerSeq(), den2.ParentId)
1166
assert.True(t, den1.getVerSeq() == den2.getVerSeq())
1167
assert.True(t, reflect.DeepEqual(den1, den2))
1170
func TestInodeVerMarshal(t *testing.T) {
1172
var topSeq uint64 = 10
1173
var sndSeq uint64 = 2
1175
ino1 := NewInode(10, 5)
1177
ino1_1 := NewInode(10, 5)
1178
ino1_1.setVer(sndSeq)
1180
ino1.multiSnap.multiVersions = append(ino1.multiSnap.multiVersions, ino1_1)
1181
v1, _ := ino1.Marshal()
1183
ino2 := NewInode(0, 0)
1186
assert.True(t, ino2.getVer() == topSeq)
1187
assert.True(t, ino2.getLayerLen() == ino1.getLayerLen())
1188
assert.True(t, ino2.getLayerVer(0) == sndSeq)
1189
assert.True(t, reflect.DeepEqual(ino1, ino2))
1192
func TestSplitKey(t *testing.T) {
1193
dp := &DataPartition{
1195
Hosts: []string{"192.168.0.1", "192.168.0.2", "192.168.0.3"},
1197
ext := &proto.ExtentKey{
1200
Size: util.PageSize,
1201
SnapInfo: &proto.ExtSnapInfo{
1205
_, invalid := NewPacketToDeleteExtent(dp, ext)
1206
assert.True(t, invalid == true)
1208
ext.ExtentOffset = 0
1209
_, invalid = NewPacketToDeleteExtent(dp, ext)
1210
assert.True(t, invalid == false)
1212
ext.ExtentOffset = 10
1213
ext.Size = 2 * util.PageSize
1214
_, invalid = NewPacketToDeleteExtent(dp, ext)
1215
assert.True(t, invalid == false)
1218
func NewMetaPartitionForTest() *metaPartition {
1219
mpC := &MetaPartitionConfig{
1220
PartitionId: PartitionIdForTest,
1221
VolName: VolNameForTest,
1223
partition := NewMetaPartition(mpC, nil).(*metaPartition)
1224
partition.uniqChecker.keepTime = 1
1225
partition.uniqChecker.keepOps = 0
1226
partition.mqMgr = NewQuotaManager(VolNameForTest, 1)
1231
func mockPartitionRaftForTest(ctrl *gomock.Controller) *metaPartition {
1232
partition := NewMetaPartitionForTest()
1233
raft := raftstoremock.NewMockPartition(ctrl)
1235
raft.EXPECT().Submit(gomock.Any()).DoAndReturn(func(cmd []byte) (resp interface{}, err error) {
1237
return partition.Apply(cmd, idx)
1240
raft.EXPECT().IsRaftLeader().DoAndReturn(func(cmd []byte) (resp interface{}, err error) {
1244
raft.EXPECT().LeaderTerm().Return(uint64(1), uint64(1)).AnyTimes()
1245
partition.raftPartition = raft
1249
func TestCheckVerList(t *testing.T) {
1251
mp.multiVersionList.VerList = append(mp.multiVersionList.VerList,
1252
[]*proto.VolVersionInfo{
1253
{Ver: 20, Status: proto.VersionNormal},
1254
{Ver: 30, Status: proto.VersionNormal},
1255
{Ver: 40, Status: proto.VersionNormal},
1258
masterList := &proto.VolVersionInfoList{
1259
VerList: []*proto.VolVersionInfo{
1260
{Ver: 0, Status: proto.VersionNormal},
1261
{Ver: 20, Status: proto.VersionNormal},
1262
{Ver: 30, Status: proto.VersionNormal},
1263
{Ver: 40, Status: proto.VersionNormal},
1264
{Ver: 50, Status: proto.VersionNormal},
1268
mp.checkVerList(masterList, false)
1269
verData = <-mp.verUpdateChan
1270
mp.submit(opFSMVersionOp, verData)
1271
assert.True(t, mp.verSeq == 50)
1272
assert.True(t, mp.multiVersionList.VerList[len(mp.multiVersionList.VerList)-1].Ver == 50)
1274
masterList = &proto.VolVersionInfoList{
1275
VerList: []*proto.VolVersionInfo{
1276
{Ver: 20, Status: proto.VersionNormal},
1277
{Ver: 40, Status: proto.VersionNormal},
1281
needUpdate, _ := mp.checkVerList(masterList, false)
1282
assert.True(t, needUpdate == false)
1284
assert.True(t, mp.verSeq == 50)
1285
assert.True(t, len(mp.multiVersionList.VerList) == 5)
1289
func checkStoreMode(t *testing.T, ExtentType uint8) (err error) {
1290
if proto.IsTinyExtentType(ExtentType) || proto.IsNormalExtentType(ExtentType) {
1293
t.Logf("action[checkStoreMode] extent type %v", ExtentType)
1294
return fmt.Errorf("error")
1297
func TestCheckMod(t *testing.T) {
1299
err := checkStoreMode(t, tp)
1300
assert.True(t, err == nil)
1303
func managerVersionPrepare(req *proto.MultiVersionOpRequest) (err error) {
1304
if err, _ = manager.prepareCreateVersion(req); err != nil {
1307
return manager.commitCreateVersion(req.VolumeID, req.VerSeq, req.Op, true)
1310
func newMpWithMock(t *testing.T) {
1311
mockCtrl := gomock.NewController(t)
1312
defer mockCtrl.Finish()
1313
mp = mockPartitionRaftForTest(mockCtrl)
1315
mp.verUpdateChan = make(chan []byte, 100)
1316
mp.config = metaConf
1317
mp.config.Cursor = 0
1318
mp.config.End = 100000
1319
mp.uidManager = NewUidMgr(metaConf.VolName, metaConf.PartitionId)
1320
mp.mqMgr = NewQuotaManager(metaConf.VolName, metaConf.PartitionId)
1321
mp.multiVersionList.VerList = append(mp.multiVersionList.VerList, &proto.VolVersionInfo{
1324
mp.multiVersionList.TemporaryVerMap = make(map[uint64]*proto.VolVersionInfo)
1327
func TestOpCommitVersion(t *testing.T) {
1328
mockCtrl := gomock.NewController(t)
1329
defer mockCtrl.Finish()
1330
for i := 1; i < 5; i++ {
1331
mp = mockPartitionRaftForTest(mockCtrl)
1332
mp.config.PartitionId = uint64(i)
1333
mp.manager = manager
1334
mp.manager.partitions[mp.config.PartitionId] = mp
1335
mp.config.NodeId = 1
1338
err := managerVersionPrepare(&proto.MultiVersionOpRequest{VolumeID: VolNameForTest, Op: proto.CreateVersionPrepare, VerSeq: 10000})
1339
assert.True(t, err == nil)
1340
for _, m := range manager.partitions {
1341
mList := m.GetVerList()
1342
assert.True(t, len(mList) == 1)
1343
assert.True(t, mList[0].Ver == 10000)
1344
assert.True(t, mList[0].Status == proto.VersionPrepare)
1346
err = manager.commitCreateVersion(VolNameForTest, 10000, proto.CreateVersionPrepare, true)
1347
assert.True(t, err == nil)
1348
for _, m := range manager.partitions {
1349
mList := m.GetVerList()
1350
assert.True(t, len(mList) == 1)
1351
assert.True(t, mList[0].Ver == 10000)
1352
assert.True(t, mList[0].Status == proto.VersionPrepare)
1354
err = managerVersionPrepare(&proto.MultiVersionOpRequest{VolumeID: VolNameForTest, Op: proto.CreateVersionPrepare, VerSeq: 5000})
1355
assert.True(t, err == nil)
1356
for _, m := range manager.partitions {
1357
mList := m.GetVerList()
1358
assert.True(t, len(mList) == 1)
1359
assert.True(t, mList[0].Ver == 10000)
1360
assert.True(t, mList[0].Status == proto.VersionPrepare)
1362
err = managerVersionPrepare(&proto.MultiVersionOpRequest{VolumeID: VolNameForTest, Op: proto.CreateVersionPrepare, VerSeq: 20000})
1363
assert.True(t, err == nil)
1364
for _, m := range manager.partitions {
1365
mList := m.GetVerList()
1366
assert.True(t, len(mList) == 2)
1367
assert.True(t, mList[0].Ver == 10000)
1368
assert.True(t, mList[0].Status == proto.VersionPrepare)
1369
assert.True(t, mList[1].Ver == 20000)
1370
assert.True(t, mList[1].Status == proto.VersionPrepare)
1372
err = manager.commitCreateVersion(VolNameForTest, 20000, proto.CreateVersionCommit, true)
1373
assert.True(t, err == nil)
1374
for _, m := range manager.partitions {
1375
mList := m.GetVerList()
1376
assert.True(t, len(mList) == 2)
1377
assert.True(t, mList[0].Ver == 10000)
1378
assert.True(t, mList[0].Status == proto.VersionPrepare)
1379
assert.True(t, mList[1].Ver == 20000)
1380
assert.True(t, mList[1].Status == proto.VersionNormal)
1384
func TestExtendSerialization(t *testing.T) {
1385
dataMap := map[string][]byte{
1386
"key1": []byte("value1"),
1387
"key2": []byte("value2"),
1395
checkFunc := func() {
1396
bytes, err := mv.Bytes()
1398
t.Errorf("Failed to serialize Extend: %v", err)
1401
newExtend, err := NewExtendFromBytes(bytes)
1403
t.Errorf("Failed to deserialize Extend: %v", err)
1406
if !reflect.DeepEqual(mv, newExtend) {
1407
t.Errorf("Deserialized Extend does not match the original object")
1413
mv.multiVers = []*Extend{
1416
dataMap: map[string][]byte{"key3": []byte("value3")},
1421
dataMap: map[string][]byte{"key4": []byte("value4")},
1428
func TestXAttrOperation(t *testing.T) {
1431
mp.SetXAttr(&proto.SetXAttrRequest{Key: "test", Value: "value"}, &Packet{})
1432
mp.SetXAttr(&proto.SetXAttrRequest{Key: "test1", Value: "value1"}, &Packet{})
1436
// operation on top of snapshot version
1437
err := mp.SetXAttr(&proto.SetXAttrRequest{Key: "test1", Value: "value2"}, &Packet{})
1438
assert.True(t, err == nil)
1439
packRsp := &Packet{}
1440
mp.GetXAttr(&proto.GetXAttrRequest{Key: "test1", VerSeq: 0}, packRsp)
1441
assert.True(t, packRsp.ResultCode == proto.OpOk)
1442
resp := new(proto.GetXAttrResponse)
1443
err = packRsp.UnmarshalData(resp)
1444
assert.True(t, err == nil)
1445
assert.True(t, resp.Value == "value2")
1447
// remove test1 but it should exist in snapshot
1448
err = mp.RemoveXAttr(&proto.RemoveXAttrRequest{Key: "test1"}, &Packet{})
1449
assert.True(t, err == nil)
1451
mp.GetXAttr(&proto.GetXAttrRequest{Key: "test1", VerSeq: 0}, packRsp)
1452
assert.True(t, packRsp.ResultCode == proto.OpOk)
1453
err = packRsp.UnmarshalData(resp)
1454
assert.True(t, err == nil)
1455
assert.True(t, resp.Value == "")
1457
// get snapshot xattr the 0 version
1459
mp.GetXAttr(&proto.GetXAttrRequest{Key: "test1", VerSeq: math.MaxUint64}, packRsp)
1460
assert.True(t, packRsp.ResultCode == proto.OpOk)
1462
resp = new(proto.GetXAttrResponse)
1463
err = packRsp.UnmarshalData(resp)
1464
assert.True(t, err == nil)
1465
assert.True(t, resp.Value == "value1")
1468
func TestUpdateDenty(t *testing.T) {
1470
testCreateInode(nil, DirModeType)
1471
err := mp.CreateDentry(&CreateDentryReq{Name: "testfile", ParentID: 1, Inode: 1000}, &Packet{}, localAddrForAudit)
1472
assert.True(t, err == nil)
1474
mp.UpdateDentry(&UpdateDentryReq{Name: "testfile", ParentID: 1, Inode: 2000}, &Packet{}, localAddrForAudit)
1475
den := &Dentry{Name: "testfile", ParentId: 1}
1476
den.setVerSeq(math.MaxUint64)
1477
denRsp, status := mp.getDentry(den)
1478
assert.True(t, status == proto.OpOk)
1479
assert.True(t, denRsp.Inode == 1000)
1482
func TestCheckEkEqual(t *testing.T) {
1483
ek1 := &proto.ExtentKey{FileOffset: 10, SnapInfo: &proto.ExtSnapInfo{VerSeq: 10, IsSplit: true}}
1484
ek2 := &proto.ExtentKey{FileOffset: 10, SnapInfo: &proto.ExtSnapInfo{VerSeq: 10, IsSplit: true}}
1485
assert.True(t, ek1.Equals(ek2))
1488
func TestDelPartitionVersion(t *testing.T) {
1489
manager = &metadataManager{partitions: make(map[uint64]MetaPartition), volUpdating: new(sync.Map)}
1491
mp.config.PartitionId = metaConf.PartitionId
1492
mp.manager = manager
1493
mp.manager.partitions[mp.config.PartitionId] = mp
1494
mp.config.NodeId = 1
1496
err := managerVersionPrepare(&proto.MultiVersionOpRequest{VolumeID: VolNameForTest, Op: proto.CreateVersionPrepare, VerSeq: 10})
1497
assert.True(t, err == nil)
1499
ino := testCreateInode(t, FileModeType)
1500
assert.True(t, ino.getVer() == 10)
1501
mp.SetXAttr(&proto.SetXAttrRequest{Inode: ino.Inode, Key: "key1", Value: "0000"}, &Packet{})
1502
mp.CreateDentry(&CreateDentryReq{Inode: ino.Inode, Name: "dentryName"}, &Packet{}, "/dentryName")
1504
err = managerVersionPrepare(&proto.MultiVersionOpRequest{VolumeID: VolNameForTest, Op: proto.CreateVersionPrepare, VerSeq: 25})
1505
mp.SetXAttr(&proto.SetXAttrRequest{Inode: ino.Inode, Key: "key1", Value: "1111"}, &Packet{})
1507
assert.True(t, err == nil)
1509
extend := mp.extendTree.Get(NewExtend(ino.Inode)).(*Extend)
1510
assert.True(t, len(extend.multiVers) == 1)
1512
masterList := &proto.VolVersionInfoList{
1513
VerList: []*proto.VolVersionInfo{
1514
{Ver: 20, Status: proto.VersionNormal},
1515
{Ver: 30, Status: proto.VersionNormal},
1516
{Ver: 40, Status: proto.VersionNormal},
1517
{Ver: 50, Status: proto.VersionNormal},
1520
mp.checkByMasterVerlist(mp.multiVersionList, masterList)
1521
mp.checkVerList(masterList, true)
1522
assert.True(t, len(mp.multiVersionList.TemporaryVerMap) == 2)
1524
mp.SetXAttr(&proto.SetXAttrRequest{Inode: ino.Inode, Key: "key1", Value: "2222"}, &Packet{})
1526
go mp.multiVersionTTLWork(time.Millisecond * 10)
1530
if len(mp.multiVersionList.TemporaryVerMap) != 0 {
1531
time.Sleep(time.Millisecond * 100)
1537
inoNew := mp.getInode(&Inode{Inode: ino.Inode}, false).Msg
1538
assert.True(t, inoNew.getVer() == 25)
1539
extend = mp.extendTree.Get(NewExtend(ino.Inode)).(*Extend)
1540
t.Logf("extent verseq [%v], multivers %v", extend.verSeq, extend.multiVers)
1541
assert.True(t, extend.verSeq == 50)
1542
assert.True(t, len(extend.multiVers) == 1)
1543
assert.True(t, extend.multiVers[0].verSeq == 25)
1545
assert.True(t, string(extend.multiVers[0].dataMap["key1"]) == "1111")
1547
err = extend.checkSequence()
1548
t.Logf("extent checkSequence err %v", err)
1549
assert.True(t, err == nil)
1550
assert.True(t, len(mp.multiVersionList.TemporaryVerMap) == 0)
1553
func TestMpMultiVerStore(t *testing.T) {
1556
crc, _ := mp.storeMultiVersion(filePath, &storeMsg{
1557
multiVerList: []*proto.VolVersionInfo{{Ver: 20, Status: proto.VersionNormal}, {Ver: 30, Status: proto.VersionNormal}},
1559
err := mp.loadMultiVer(filePath, crc)
1560
assert.True(t, err == nil)
1563
func TestGetAllVerList(t *testing.T) {
1565
mp.multiVersionList = &proto.VolVersionInfoList{
1566
VerList: []*proto.VolVersionInfo{
1567
{Ver: 20, Status: proto.VersionNormal},
1568
{Ver: 30, Status: proto.VersionNormal},
1569
{Ver: 40, Status: proto.VersionNormal},
1570
{Ver: 50, Status: proto.VersionNormal},
1573
tmp := mp.multiVersionList.VerList
1574
mp.multiVersionList.VerList = append(mp.multiVersionList.VerList[:1], mp.multiVersionList.VerList[2:]...)
1575
tmp = append(tmp, &proto.VolVersionInfo{Ver: 30, Status: proto.VersionNormal})
1577
sort.SliceStable(tmp, func(i, j int) bool {
1578
if tmp[i].Ver < tmp[j].Ver {
1584
t.Logf("tmp[%v]", tmp)
1585
t.Logf("mp.multiVersionList %v", mp.multiVersionList)
1587
mp.multiVersionList.TemporaryVerMap = make(map[uint64]*proto.VolVersionInfo)
1588
mp.multiVersionList.TemporaryVerMap[25] = &proto.VolVersionInfo{Ver: 25, Status: proto.VersionNormal}
1589
mp.multiVersionList.TemporaryVerMap[45] = &proto.VolVersionInfo{Ver: 45, Status: proto.VersionNormal}
1590
newList := mp.GetAllVerList()
1591
oldList := mp.multiVersionList.VerList
1592
t.Logf("newList %v oldList %v", newList, oldList)
1593
assert.True(t, true)
1596
func TestVerlistSnapshot(t *testing.T) {
1597
verList := []*proto.VolVersionInfo{
1598
{Ver: 20, Status: proto.VersionNormal},
1600
var verListBuf1 []byte
1602
if verListBuf1, err = json.Marshal(verList); err != nil {
1605
t.Logf("mp.TestVerlistSnapshot %v", verListBuf1)
1606
var verList12 []*proto.VolVersionInfo
1607
if err = json.Unmarshal(verListBuf1, &verList12); err != nil {
1608
t.Logf("mp.TestVerlistSnapshot err %v", err)
1610
t.Logf("mp.TestVerlistSnapshot %v", verList12)
1611
assert.True(t, true)