github.com/0chain/gosdk@v1.17.11/zboxcore/fileref/hashnode_test.go (about) 1 package fileref 2 3 import ( 4 "strconv" 5 "strings" 6 "testing" 7 8 "github.com/0chain/gosdk/core/encryption" 9 "github.com/stretchr/testify/require" 10 ) 11 12 func TestHashnode_GetHashcode(t *testing.T) { 13 tests := []struct { 14 name string 15 exceptedRef blobberRef 16 actualHashnode Hashnode 17 }{ 18 { 19 name: "Empty root should be same", 20 exceptedRef: blobberRef{ 21 Type: DIRECTORY, 22 }, 23 actualHashnode: Hashnode{ 24 Type: DIRECTORY, 25 }, 26 }, 27 { 28 name: "Nested nodes should be same", 29 exceptedRef: blobberRef{ 30 AllocationID: "nested_nodes", 31 Type: DIRECTORY, 32 Name: "/", 33 Path: "/", 34 ValidationRoot: "content_hash", 35 FixedMerkleRoot: "merkle_root", 36 ActualFileHash: "actual_file_hash", 37 ChunkSize: 1024, 38 Size: 10240, 39 ActualFileSize: 10240, 40 Children: []*blobberRef{ 41 { 42 AllocationID: "nested_nodes", 43 Type: DIRECTORY, 44 Name: "sub1", 45 Path: "/sub1", 46 ValidationRoot: "content_hash", 47 FixedMerkleRoot: "merkle_root", 48 ActualFileHash: "actual_file_hash", 49 ChunkSize: 1024, 50 Size: 10240, 51 ActualFileSize: 10240, 52 childrenLoaded: true, 53 LookupHash: GetReferenceLookup("nested_nodes", "/sub1"), 54 Children: []*blobberRef{ 55 { 56 AllocationID: "nested_nodes", 57 Type: FILE, 58 Name: "file1", 59 Path: "/sub1/file1", 60 ValidationRoot: "content_hash", 61 FixedMerkleRoot: "merkle_root", 62 ActualFileHash: "actual_file_hash", 63 ChunkSize: 1024, 64 Size: 10240, 65 ActualFileSize: 10240, 66 LookupHash: GetReferenceLookup("nested_nodes", "/sub1/file1"), 67 }, 68 }, 69 }, 70 { 71 AllocationID: "nested_nodes", 72 Type: DIRECTORY, 73 Name: "emptydir", 74 Path: "/emptydir", 75 ValidationRoot: "content_hash", 76 FixedMerkleRoot: "merkle_root", 77 ActualFileHash: "actual_file_hash", 78 ChunkSize: 0, 79 Size: 0, 80 ActualFileSize: 0, 81 LookupHash: GetReferenceLookup("nested_nodes", "/emptydir"), 82 }, 83 }, 84 }, 85 actualHashnode: Hashnode{ 86 AllocationID: "nested_nodes", 87 Type: DIRECTORY, 88 Name: "/", 89 Path: "/", 90 ValidationRoot: "content_hash", 91 FixedMerkleRoot: "merkle_root", 92 ActualFileHash: "actual_file_hash", 93 ChunkSize: 1024, 94 Size: 10240, 95 ActualFileSize: 10240, 96 Children: []*Hashnode{ 97 { 98 AllocationID: "nested_nodes", 99 Type: DIRECTORY, 100 Name: "sub1", 101 Path: "/sub1", 102 ValidationRoot: "content_hash", 103 FixedMerkleRoot: "merkle_root", 104 ActualFileHash: "actual_file_hash", 105 ChunkSize: 1024, 106 Size: 10240, 107 ActualFileSize: 10240, 108 Children: []*Hashnode{ 109 { 110 AllocationID: "nested_nodes", 111 Type: FILE, 112 Name: "file1", 113 Path: "/sub1/file1", 114 ValidationRoot: "content_hash", 115 FixedMerkleRoot: "merkle_root", 116 ActualFileHash: "actual_file_hash", 117 ChunkSize: 1024, 118 Size: 10240, 119 ActualFileSize: 10240, 120 }, 121 }, 122 }, 123 { 124 AllocationID: "nested_nodes", 125 Type: DIRECTORY, 126 Name: "emptydir", 127 Path: "/emptydir", 128 ValidationRoot: "content_hash", 129 FixedMerkleRoot: "merkle_root", 130 ActualFileHash: "actual_file_hash", 131 ChunkSize: 0, 132 Size: 0, 133 ActualFileSize: 0, 134 }, 135 }, 136 }, 137 }, 138 } 139 140 for _, it := range tests { 141 t.Run(it.name, func(test *testing.T) { 142 require.Equal(test, it.exceptedRef.CalculateHash(), it.actualHashnode.GetHashCode()) 143 }) 144 } 145 } 146 147 // blobberRef copied from https://github.com/0chain/blobber/blob/staging/code/go/0chain.net/blobbercore/reference/ref.go for unit tests 148 type blobberRef struct { 149 ID int64 `gorm:"column:id;primary_key"` 150 Type string `gorm:"column:type" dirlist:"type" filelist:"type"` 151 AllocationID string `gorm:"column:allocation_id"` 152 LookupHash string `gorm:"column:lookup_hash" dirlist:"lookup_hash" filelist:"lookup_hash"` 153 Name string `gorm:"column:name" dirlist:"name" filelist:"name"` 154 Path string `gorm:"column:path" dirlist:"path" filelist:"path"` 155 Hash string `gorm:"column:hash" dirlist:"hash" filelist:"hash"` 156 157 ParentPath string `gorm:"column:parent_path"` 158 159 ValidationRoot string `gorm:"column:validation_root" filelist:"validation_root"` 160 Size int64 `gorm:"column:size" dirlist:"size" filelist:"size"` 161 FixedMerkleRoot string `gorm:"column:fixed_merkle_root" filelist:"fixed_merkle_root"` 162 ActualFileSize int64 `gorm:"column:actual_file_size" filelist:"actual_file_size"` 163 ActualFileHash string `gorm:"column:actual_file_hash" filelist:"actual_file_hash"` 164 165 Children []*blobberRef `gorm:"-"` 166 childrenLoaded bool 167 168 ChunkSize int64 `gorm:"column:chunk_size" dirlist:"chunk_size" filelist:"chunk_size"` 169 } 170 171 func (fr *blobberRef) GetFileHashData() string { 172 hashArray := make([]string, 0, 11) 173 hashArray = append(hashArray, 174 fr.AllocationID, 175 fr.Type, 176 fr.Name, 177 fr.Path, 178 strconv.FormatInt(fr.Size, 10), 179 fr.ValidationRoot, 180 fr.FixedMerkleRoot, 181 strconv.FormatInt(fr.ActualFileSize, 10), 182 fr.ActualFileHash, 183 strconv.FormatInt(fr.ChunkSize, 10), 184 ) 185 186 return strings.Join(hashArray, ":") 187 } 188 189 func (fr *blobberRef) CalculateFileHash() string { 190 fr.Hash = encryption.Hash(fr.GetFileHashData()) 191 fr.LookupHash = GetReferenceLookup(fr.AllocationID, fr.Path) 192 193 return fr.Hash 194 } 195 196 func (r *blobberRef) CalculateDirHash() string { 197 // empty directory, return hash directly 198 if len(r.Children) == 0 && !r.childrenLoaded { 199 return r.Hash 200 } 201 for _, childRef := range r.Children { 202 childRef.CalculateHash() 203 } 204 childHashes := make([]string, len(r.Children)) 205 206 var size int64 207 for index, childRef := range r.Children { 208 childHashes[index] = childRef.Hash 209 210 size += childRef.Size 211 } 212 213 r.Hash = encryption.Hash(strings.Join(childHashes, ":")) 214 215 r.Size = size 216 217 r.LookupHash = GetReferenceLookup(r.AllocationID, r.Path) 218 219 return r.Hash 220 } 221 222 func (r *blobberRef) CalculateHash() string { 223 if r.Type == DIRECTORY { 224 return r.CalculateDirHash() 225 } 226 return r.CalculateFileHash() 227 }