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  }