github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/orderer/ledger/json/factory_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8                   http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package jsonledger
    18  
    19  import (
    20  	"testing"
    21  
    22  	"fmt"
    23  	"io/ioutil"
    24  	"os"
    25  	"path"
    26  
    27  	"github.com/hyperledger/fabric/common/configtx/tool/provisional"
    28  	logging "github.com/op/go-logging"
    29  	"github.com/stretchr/testify/assert"
    30  )
    31  
    32  func init() {
    33  	logging.SetLevel(logging.DEBUG, "")
    34  }
    35  
    36  // Some tests are skipped because `os.Chmod` does not take effect in the CI. The call
    37  // itself does not fail, but file mod is not changed, which cause tests to fail.
    38  // TODO(jay_guo): re-enable skipped tests once we sort out this problem.
    39  
    40  // This test checks that `New` factory should fail if parent directory is read-only
    41  func TestErrorMkdir(t *testing.T) {
    42  	name, err := ioutil.TempDir("", "hyperledger_fabric")
    43  	assert.Nil(t, err, "Error creating temp dir: %s", err)
    44  	defer os.RemoveAll(name)
    45  	ledgerPath := path.Join(name, "jsonledger")
    46  	assert.NoError(t, ioutil.WriteFile(ledgerPath, nil, 0700))
    47  
    48  	assert.Panics(t, func() { New(ledgerPath) }, "Should have failed to create factory")
    49  }
    50  
    51  // This test checks that `New` factory should fail if factory directory is not readable
    52  func TestErrorReadDir(t *testing.T) {
    53  	t.Skip("Temporarily skip this test due to the reason stated at the top of this file")
    54  
    55  	name, err := ioutil.TempDir("", "hyperledger_fabric")
    56  	assert.Nil(t, err, "Error creating temp dir: %s", err)
    57  	defer os.RemoveAll(name)
    58  	assert.Nil(t, os.Chmod(name, 0200), "Error chmod temp dir")
    59  	defer os.Chmod(name, 0700)
    60  
    61  	assert.Panics(t, func() { New(name) }, "Should have failed to create factory")
    62  }
    63  
    64  // This test checks that factory initialization should ignore dir with invalid name and files.
    65  // NOTE: unfortunately this test does not really test intended logic because errors caused by
    66  // constructing a chain from invalid dir or file are ignored anyway. Consider refactoring impl
    67  // to make it more testable.
    68  func TestIgnoreInvalidObjectInDir(t *testing.T) {
    69  	name, err := ioutil.TempDir("", "hyperledger_fabric")
    70  	assert.Nil(t, err, "Error creating temp dir: %s", err)
    71  	defer os.RemoveAll(name)
    72  	file, err := ioutil.TempFile(name, "chain_")
    73  	assert.Nil(t, err, "Errot creating temp file: %s", err)
    74  	defer file.Close()
    75  	_, err = ioutil.TempDir(name, "invalid_chain_")
    76  	assert.Nil(t, err, "Error creating temp dir: %s", err)
    77  
    78  	jlf := New(name)
    79  	assert.Empty(t, jlf.ChainIDs(), "Expected invalid objects to be ignored while restoring chains from directory")
    80  }
    81  
    82  // This test checks that factory initialization panics given invalid chain
    83  func TestInvalidChain(t *testing.T) {
    84  	name, err := ioutil.TempDir("", "hyperledger_fabric")
    85  	assert.Nil(t, err, "Error creating temp dir: %s", err)
    86  	defer os.RemoveAll(name)
    87  
    88  	chainDir, err := ioutil.TempDir(name, "chain_")
    89  	assert.Nil(t, err, "Error creating temp dir: %s", err)
    90  
    91  	t.Run("ChainDirNotReadable", func(t *testing.T) {
    92  		t.Skip("Temporarily skip this test due to the reason stated at the top of this file")
    93  		assert.Nil(t, os.Chmod(chainDir, 0200), "Error chmod chain dir")
    94  		defer os.Chmod(chainDir, 0700)
    95  		assert.Panics(t, func() { New(name) }, "Expected initialization panics if chain dir is not readable")
    96  		assert.Nil(t, os.Chmod(chainDir, 0700), "Error chmod chain dir")
    97  	})
    98  
    99  	// Skip Block 0 to trigger MissingBlock error
   100  	secondBlock := path.Join(chainDir, fmt.Sprintf(blockFileFormatString, 1))
   101  	assert.NoError(t, ioutil.WriteFile(secondBlock, nil, 0700))
   102  
   103  	t.Run("MissingBlock", func(t *testing.T) {
   104  		assert.Panics(t, func() { New(name) }, "Expected initialization panics if block is missing")
   105  	})
   106  
   107  	t.Run("SkipDir", func(t *testing.T) {
   108  		invalidBlock := path.Join(chainDir, fmt.Sprintf(blockFileFormatString, 0))
   109  		assert.NoError(t, os.Mkdir(invalidBlock, 0700))
   110  		assert.Panics(t, func() { New(name) }, "Expected initialization skips directory in chain dir")
   111  		assert.NoError(t, os.RemoveAll(invalidBlock))
   112  	})
   113  
   114  	firstBlock := path.Join(chainDir, fmt.Sprintf(blockFileFormatString, 0))
   115  	assert.NoError(t, ioutil.WriteFile(firstBlock, nil, 0700))
   116  
   117  	t.Run("BlockNotReadable", func(t *testing.T) {
   118  		t.Skip("Temporarily skip this test due to the reason stated at the top of this file")
   119  		assert.NoError(t, os.Chmod(secondBlock, 0200))
   120  		defer os.Chmod(secondBlock, 0700)
   121  		assert.Panics(t, func() { New(name) }, "Expected initialization panics if block is not readable")
   122  		assert.NoError(t, os.Chmod(secondBlock, 0700))
   123  	})
   124  
   125  	t.Run("MalformedBlock", func(t *testing.T) {
   126  		assert.Panics(t, func() { New(name) }, "Expected initialization panics if block is malformed")
   127  	})
   128  }
   129  
   130  // This test checks that file is ignored if the name is not valid
   131  func TestIgnoreInvalidBlockFileName(t *testing.T) {
   132  	name, err := ioutil.TempDir("", "hyperledger_fabric")
   133  	assert.Nil(t, err, "Error creating temp dir: %s", err)
   134  	defer os.RemoveAll(name)
   135  
   136  	chainDir, err := ioutil.TempDir(name, "chain_")
   137  	assert.Nil(t, err, "Error creating temp dir: %s", err)
   138  
   139  	invalidBlock := path.Join(chainDir, "invalid_block")
   140  	assert.NoError(t, ioutil.WriteFile(invalidBlock, nil, 0700))
   141  	jfl := New(name)
   142  	assert.Equal(t, 1, len(jfl.ChainIDs()), "Expected factory initialized with 1 chain")
   143  
   144  	chain, err := jfl.GetOrCreate(jfl.ChainIDs()[0])
   145  	assert.Nil(t, err, "Should have retrieved chain")
   146  	assert.Zero(t, chain.Height(), "Expected chain to be empty")
   147  }
   148  
   149  // This test checks that fs error causes creating chain to fail
   150  func TestErrorCreatingChain(t *testing.T) {
   151  	t.Skip("Temporarily skip this test due to the reason stated at the top of this file")
   152  
   153  	name, err := ioutil.TempDir("", "hyperledger_fabric")
   154  	assert.Nil(t, err, "Error creating temp dir: %s", err)
   155  	defer os.RemoveAll(name)
   156  
   157  	jlf := New(name)
   158  	assert.NoError(t, os.Chmod(name, 0400))
   159  	defer os.Chmod(name, 0700)
   160  	_, err = jlf.GetOrCreate(provisional.TestChainID)
   161  	assert.Error(t, err, "Should have failed to create chain due to fs error")
   162  }
   163  
   164  func TestClose(t *testing.T) {
   165  	name, err := ioutil.TempDir("", "hyperledger_fabric")
   166  	assert.Nil(t, err, "Error creating temp dir: %s", err)
   167  	defer os.RemoveAll(name)
   168  
   169  	jlf := New(name)
   170  	assert.NotPanics(t, func() { jlf.Close() }, "Noop should not pannic")
   171  }