github.com/anjalikarhana/fabric@v2.1.1+incompatible/orderer/common/bootstrap/file/bootstrap_test.go (about)

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