github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/orderer/common/bootstrap/file/bootstrap_test.go (about)

     1  // Copyright hechain. All Rights Reserved.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package file_test
     5  
     6  import (
     7  	"io/ioutil"
     8  	"os"
     9  	"path"
    10  	"testing"
    11  
    12  	"github.com/golang/protobuf/proto"
    13  	bootfile "github.com/hechain20/hechain/orderer/common/bootstrap/file"
    14  	cb "github.com/hyperledger/fabric-protos-go/common"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  const (
    19  	file     = "abc.genesis"
    20  	fileBak  = file + ".bak"
    21  	fileFake = file + ".fake"
    22  )
    23  
    24  func TestGenesisBlock(t *testing.T) {
    25  	testDir, err := ioutil.TempDir("", "unittest")
    26  	require.NoErrorf(t, err, "generate temporary test dir")
    27  	defer os.RemoveAll(testDir)
    28  
    29  	testFile := path.Join(testDir, file)
    30  
    31  	testFileFake := path.Join(testDir, fileFake)
    32  
    33  	t.Run("Bad - No file", func(t *testing.T) {
    34  		require.Panics(t, func() {
    35  			helper := bootfile.New(testFileFake)
    36  			_ = helper.GenesisBlock()
    37  		}, "No file")
    38  	})
    39  
    40  	t.Run("Bad - Malformed Block", func(t *testing.T) {
    41  		err := ioutil.WriteFile(testFile, []byte("abc"), 0o644)
    42  		require.NoErrorf(t, err, "generate temporary test file: %s", file)
    43  
    44  		require.Panics(t, func() {
    45  			helper := bootfile.New(testFile)
    46  			_ = helper.GenesisBlock()
    47  		}, "Malformed Block")
    48  	})
    49  
    50  	t.Run("Correct flow", func(t *testing.T) {
    51  		// The original block and file
    52  		expectedNumber := uint64(0)
    53  		expectedBytes := []byte("abc")
    54  		expectedHash := []byte(nil)
    55  
    56  		header := &cb.BlockHeader{
    57  			Number:       expectedNumber,
    58  			PreviousHash: expectedHash,
    59  			DataHash:     expectedBytes,
    60  		}
    61  		data := &cb.BlockData{
    62  			Data: [][]byte{expectedBytes},
    63  		}
    64  		expectedDataLen := len(data.Data)
    65  		metadata := &cb.BlockMetadata{
    66  			Metadata: [][]byte{expectedBytes},
    67  		}
    68  		expectedMetaLen := len(metadata.Metadata)
    69  		block := &cb.Block{
    70  			Header:   header,
    71  			Data:     data,
    72  			Metadata: metadata,
    73  		}
    74  		marshalledBlock, _ := proto.Marshal(block)
    75  		err := ioutil.WriteFile(testFile, marshalledBlock, 0o644)
    76  		require.NoErrorf(t, err, "generate temporary test file: %s", file)
    77  		defer os.Remove(testFile)
    78  
    79  		helper := bootfile.New(testFile)
    80  		outBlock := helper.GenesisBlock()
    81  
    82  		outHeader := outBlock.Header
    83  		require.Equal(t, expectedNumber, outHeader.Number, "block header Number not read correctly")
    84  		require.Equal(t, expectedHash, outHeader.PreviousHash, "block header PreviousHash not read correctly")
    85  		require.Equal(t, expectedBytes, outHeader.DataHash, "block header DataHash not read correctly")
    86  
    87  		outData := outBlock.Data
    88  		require.Equal(t, expectedDataLen, len(outData.Data), "block len(data) not read correctly")
    89  		require.Equal(t, expectedBytes, outData.Data[0], "block data not read correctly")
    90  
    91  		outMeta := outBlock.Metadata
    92  		require.Equal(t, expectedMetaLen, len(outMeta.Metadata), "block len(Metadata) not read correctly")
    93  		require.Equal(t, expectedBytes, outMeta.Metadata[0], "block Metadata not read correctly")
    94  	})
    95  }
    96  
    97  func TestReplaceGenesisBlockFile(t *testing.T) {
    98  	// The original block and file
    99  	expectedNumber := uint64(0)
   100  	expectedBytes := []byte("abc")
   101  	expectedHash := []byte(nil)
   102  	header := &cb.BlockHeader{
   103  		Number:       expectedNumber,
   104  		PreviousHash: expectedHash,
   105  		DataHash:     expectedBytes,
   106  	}
   107  	data := &cb.BlockData{
   108  		Data: [][]byte{expectedBytes},
   109  	}
   110  	metadata := &cb.BlockMetadata{
   111  		Metadata: [][]byte{expectedBytes},
   112  	}
   113  	block := &cb.Block{
   114  		Header:   header,
   115  		Data:     data,
   116  		Metadata: metadata,
   117  	}
   118  	marshalledBlock, _ := proto.Marshal(block)
   119  
   120  	testDir, err := ioutil.TempDir("", "unittest")
   121  	require.NoErrorf(t, err, "generate temporary test dir")
   122  	defer os.RemoveAll(testDir)
   123  
   124  	testFile := path.Join(testDir, file)
   125  	err = ioutil.WriteFile(testFile, marshalledBlock, 0o644)
   126  	require.NoErrorf(t, err, "generate temporary test file: %s", file)
   127  
   128  	testFileBak := path.Join(testDir, fileBak)
   129  	testFileFake := path.Join(testDir, fileFake)
   130  
   131  	// The new block
   132  	expectedNumber2 := uint64(1)
   133  	expectedBytes2 := []byte("def")
   134  	expectedHash2 := []byte(nil)
   135  
   136  	header2 := &cb.BlockHeader{
   137  		Number:       expectedNumber2,
   138  		PreviousHash: expectedHash2,
   139  		DataHash:     expectedBytes2,
   140  	}
   141  	data2 := &cb.BlockData{
   142  		Data: [][]byte{expectedBytes2},
   143  	}
   144  	expectedDataLen2 := len(data2.Data)
   145  	metadata2 := &cb.BlockMetadata{
   146  		Metadata: [][]byte{expectedBytes2},
   147  	}
   148  	expectedMetaLen2 := len(metadata2.Metadata)
   149  	block2 := &cb.Block{
   150  		Header:   header2,
   151  		Data:     data2,
   152  		Metadata: metadata2,
   153  	}
   154  
   155  	t.Run("Good", func(t *testing.T) {
   156  		replacer := bootfile.NewReplacer(testFile)
   157  		errWr := replacer.CheckReadWrite()
   158  		require.NoErrorf(t, errWr, "Failed to verify writable: %s", testFile)
   159  
   160  		errRep := replacer.ReplaceGenesisBlockFile(block2)
   161  		defer os.Remove(testFileBak)
   162  		require.NoErrorf(t, errRep, "Failed to replace: %s", testFile)
   163  
   164  		helper := bootfile.New(testFile)
   165  		outBlock := helper.GenesisBlock()
   166  
   167  		outHeader := outBlock.Header
   168  		require.Equal(t, expectedNumber2, outHeader.Number, "block header Number not read correctly.")
   169  		require.Equal(t, []uint8([]byte(nil)), outHeader.PreviousHash, "block header PreviousHash not read correctly.")
   170  		require.Equal(t, expectedBytes2, outHeader.DataHash, "block header DataHash not read correctly.")
   171  
   172  		outData := outBlock.Data
   173  		require.Equal(t, expectedDataLen2, len(outData.Data), "block len(data) not read correctly.")
   174  		require.Equal(t, expectedBytes2, outData.Data[0], "block data not read correctly.")
   175  
   176  		outMeta := outBlock.Metadata
   177  		require.Equal(t, expectedMetaLen2, len(outMeta.Metadata), "block len(Metadata) not read correctly.")
   178  		require.Equal(t, expectedBytes2, outMeta.Metadata[0], "block Metadata not read correctly.")
   179  	})
   180  
   181  	t.Run("Bad - No original", func(t *testing.T) {
   182  		replacer := bootfile.NewReplacer(testFileFake)
   183  		errWr := replacer.CheckReadWrite()
   184  		require.Error(t, errWr, "no such file")
   185  		require.Contains(t, errWr.Error(), "no such file or directory")
   186  
   187  		errRep := replacer.ReplaceGenesisBlockFile(block2)
   188  		require.Error(t, errRep, "no such file")
   189  		require.Contains(t, errRep.Error(), "no such file or directory")
   190  	})
   191  
   192  	t.Run("Bad - Not a regular file", func(t *testing.T) {
   193  		replacer := bootfile.NewReplacer(testDir)
   194  		errWr := replacer.CheckReadWrite()
   195  		require.Error(t, errWr, "not a regular file")
   196  		require.Contains(t, errWr.Error(), "not a regular file")
   197  
   198  		errRep := replacer.ReplaceGenesisBlockFile(block2)
   199  		require.Error(t, errRep, "not a regular file")
   200  		require.Contains(t, errRep.Error(), "not a regular file")
   201  	})
   202  
   203  	t.Run("Bad - backup not writable", func(t *testing.T) {
   204  		replacer := bootfile.NewReplacer(testFile)
   205  
   206  		_, err := os.Create(testFileBak)
   207  		defer os.Remove(testFileBak)
   208  		require.NoErrorf(t, err, "Failed to create backup")
   209  		err = os.Chmod(testFileBak, 0o400)
   210  		require.NoErrorf(t, err, "Failed to change permission on backup")
   211  
   212  		err = replacer.ReplaceGenesisBlockFile(block2)
   213  		require.Errorf(t, err, "Fail to replace, backup")
   214  		require.Contains(t, err.Error(), "permission denied")
   215  		require.Contains(t, err.Error(), "could not copy genesis block file")
   216  
   217  		err = os.Chmod(testFileBak, 0o600)
   218  		require.NoErrorf(t, err, "Failed to restore permission on backup")
   219  	})
   220  
   221  	t.Run("Bad - source not writable", func(t *testing.T) {
   222  		replacer := bootfile.NewReplacer(testFile)
   223  
   224  		errC := os.Chmod(testFile, 0o400)
   225  		require.NoErrorf(t, errC, "Failed to change permission on origin")
   226  
   227  		errWr := replacer.CheckReadWrite()
   228  		require.Error(t, errWr, "not writable")
   229  		require.Contains(t, errWr.Error(), "permission denied")
   230  		require.Contains(t, errWr.Error(), "cannot be opened for read-write, check permissions")
   231  
   232  		errRep := replacer.ReplaceGenesisBlockFile(block2)
   233  		require.Errorf(t, errRep, "Fail to replace, unwritable origin")
   234  		require.Contains(t, errRep.Error(), "permission denied")
   235  		require.Contains(t, errRep.Error(), "could not write new genesis block into file")
   236  		require.Contains(t, errRep.Error(), "use backup if necessary")
   237  
   238  		err = os.Chmod(testFile, 0o600)
   239  		require.NoErrorf(t, err, "Failed to restore permission, origin")
   240  	})
   241  
   242  	t.Run("Bad - source not readable", func(t *testing.T) {
   243  		replacer := bootfile.NewReplacer(testFile)
   244  
   245  		errC := os.Chmod(testFile, 0o200)
   246  		require.NoErrorf(t, errC, "Failed to change permission on origin")
   247  
   248  		errWr := replacer.CheckReadWrite()
   249  		require.Error(t, errWr, "not writable")
   250  		require.Contains(t, errWr.Error(), "permission denied")
   251  		require.Contains(t, errWr.Error(), "cannot be opened for read-write, check permissions")
   252  
   253  		errRep := replacer.ReplaceGenesisBlockFile(block2)
   254  		require.Errorf(t, errRep, "Fail to replace, unwritable origin")
   255  		require.Contains(t, errRep.Error(), "permission denied")
   256  		require.Contains(t, errRep.Error(), "could not copy genesis block file")
   257  
   258  		err = os.Chmod(testFile, 0o600)
   259  		require.NoErrorf(t, err, "Failed to restore permission, origin")
   260  	})
   261  }