github.com/lzy4123/fabric@v2.1.1+incompatible/internal/configtxgen/genesisconfig/config_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package genesisconfig
     8  
     9  import (
    10  	"os"
    11  	"testing"
    12  
    13  	"github.com/hyperledger/fabric-protos-go/orderer/etcdraft"
    14  	"github.com/hyperledger/fabric/core/config/configtest"
    15  	"github.com/spf13/viper"
    16  	"github.com/stretchr/testify/assert"
    17  )
    18  
    19  func TestLoadProfile(t *testing.T) {
    20  	cleanup := configtest.SetDevFabricConfigPath(t)
    21  	defer cleanup()
    22  
    23  	pNames := []string{
    24  		SampleDevModeKafkaProfile,
    25  		SampleDevModeSoloProfile,
    26  		SampleSingleMSPChannelProfile,
    27  		SampleSingleMSPKafkaProfile,
    28  		SampleSingleMSPSoloProfile,
    29  	}
    30  	for _, pName := range pNames {
    31  		t.Run(pName, func(t *testing.T) {
    32  			p := Load(pName)
    33  			assert.NotNil(t, p, "profile should not be nil")
    34  		})
    35  	}
    36  }
    37  
    38  func TestLoadProfileWithPath(t *testing.T) {
    39  	devConfigDir := configtest.GetDevConfigDir()
    40  
    41  	pNames := []string{
    42  		SampleDevModeKafkaProfile,
    43  		SampleDevModeSoloProfile,
    44  		SampleSingleMSPChannelProfile,
    45  		SampleSingleMSPKafkaProfile,
    46  		SampleSingleMSPSoloProfile,
    47  	}
    48  	for _, pName := range pNames {
    49  		t.Run(pName, func(t *testing.T) {
    50  			p := Load(pName, devConfigDir)
    51  			assert.NotNil(t, p, "profile should not be nil")
    52  		})
    53  	}
    54  }
    55  
    56  func TestLoadTopLevel(t *testing.T) {
    57  	cleanup := configtest.SetDevFabricConfigPath(t)
    58  	defer cleanup()
    59  
    60  	topLevel := LoadTopLevel()
    61  	assert.NotNil(t, topLevel.Application, "application should not be nil")
    62  	assert.NotNil(t, topLevel.Capabilities, "capabilities should not be nil")
    63  	assert.NotNil(t, topLevel.Orderer, "orderer should not be nil")
    64  	assert.NotNil(t, topLevel.Organizations, "organizations should not be nil")
    65  	assert.NotNil(t, topLevel.Profiles, "profiles should not be nil")
    66  }
    67  
    68  func TestLoadTopLevelWithPath(t *testing.T) {
    69  	devConfigDir := configtest.GetDevConfigDir()
    70  
    71  	topLevel := LoadTopLevel(devConfigDir)
    72  	assert.NotNil(t, topLevel.Application, "application should not be nil")
    73  	assert.NotNil(t, topLevel.Capabilities, "capabilities should not be nil")
    74  	assert.NotNil(t, topLevel.Orderer, "orderer should not be nil")
    75  	assert.NotNil(t, topLevel.Organizations, "organizations should not be nil")
    76  	assert.NotNil(t, topLevel.Profiles, "profiles should not be nil")
    77  }
    78  
    79  func TestConsensusSpecificInit(t *testing.T) {
    80  	cleanup := configtest.SetDevFabricConfigPath(t)
    81  	defer cleanup()
    82  
    83  	devConfigDir := configtest.GetDevConfigDir()
    84  
    85  	t.Run("nil orderer type", func(t *testing.T) {
    86  		profile := &Profile{
    87  			Orderer: &Orderer{
    88  				OrdererType: "",
    89  			},
    90  		}
    91  		profile.completeInitialization(devConfigDir)
    92  
    93  		assert.Equal(t, profile.Orderer.OrdererType, genesisDefaults.Orderer.OrdererType)
    94  	})
    95  
    96  	t.Run("unknown orderer type", func(t *testing.T) {
    97  		profile := &Profile{
    98  			Orderer: &Orderer{
    99  				OrdererType: "unknown",
   100  			},
   101  		}
   102  
   103  		assert.Panics(t, func() {
   104  			profile.completeInitialization(devConfigDir)
   105  		})
   106  	})
   107  
   108  	t.Run("solo", func(t *testing.T) {
   109  		profile := &Profile{
   110  			Orderer: &Orderer{
   111  				OrdererType: "solo",
   112  			},
   113  		}
   114  		profile.completeInitialization(devConfigDir)
   115  		assert.Nil(t, profile.Orderer.Kafka.Brokers, "Kafka config settings should not be set")
   116  	})
   117  
   118  	t.Run("kafka", func(t *testing.T) {
   119  		profile := &Profile{
   120  			Orderer: &Orderer{
   121  				OrdererType: "kafka",
   122  			},
   123  		}
   124  		profile.completeInitialization(devConfigDir)
   125  		assert.NotNil(t, profile.Orderer.Kafka.Brokers, "Kafka config settings should be set")
   126  	})
   127  
   128  	t.Run("raft", func(t *testing.T) {
   129  		makeProfile := func(consenters []*etcdraft.Consenter, options *etcdraft.Options) *Profile {
   130  			return &Profile{
   131  				Orderer: &Orderer{
   132  					OrdererType: "etcdraft",
   133  					EtcdRaft: &etcdraft.ConfigMetadata{
   134  						Consenters: consenters,
   135  						Options:    options,
   136  					},
   137  				},
   138  			}
   139  		}
   140  		t.Run("EtcdRaft section not specified in profile", func(t *testing.T) {
   141  			profile := &Profile{
   142  				Orderer: &Orderer{
   143  					OrdererType: "etcdraft",
   144  				},
   145  			}
   146  
   147  			assert.Panics(t, func() {
   148  				profile.completeInitialization(devConfigDir)
   149  			})
   150  		})
   151  
   152  		t.Run("nil consenter set", func(t *testing.T) { // should panic
   153  			profile := makeProfile(nil, nil)
   154  
   155  			assert.Panics(t, func() {
   156  				profile.completeInitialization(devConfigDir)
   157  			})
   158  		})
   159  
   160  		t.Run("single consenter", func(t *testing.T) {
   161  			consenters := []*etcdraft.Consenter{
   162  				{
   163  					Host:          "node-1.example.com",
   164  					Port:          7050,
   165  					ClientTlsCert: []byte("path/to/client/cert"),
   166  					ServerTlsCert: []byte("path/to/server/cert"),
   167  				},
   168  			}
   169  
   170  			t.Run("invalid consenters specification", func(t *testing.T) {
   171  				failingConsenterSpecifications := []*etcdraft.Consenter{
   172  					{ // missing Host
   173  						Port:          7050,
   174  						ClientTlsCert: []byte("path/to/client/cert"),
   175  						ServerTlsCert: []byte("path/to/server/cert"),
   176  					},
   177  					{ // missing Port
   178  						Host:          "node-1.example.com",
   179  						ClientTlsCert: []byte("path/to/client/cert"),
   180  						ServerTlsCert: []byte("path/to/server/cert"),
   181  					},
   182  					{ // missing ClientTlsCert
   183  						Host:          "node-1.example.com",
   184  						Port:          7050,
   185  						ServerTlsCert: []byte("path/to/server/cert"),
   186  					},
   187  					{ // missing ServerTlsCert
   188  						Host:          "node-1.example.com",
   189  						Port:          7050,
   190  						ClientTlsCert: []byte("path/to/client/cert"),
   191  					},
   192  				}
   193  
   194  				for _, consenter := range failingConsenterSpecifications {
   195  					profile := makeProfile([]*etcdraft.Consenter{consenter}, nil)
   196  
   197  					assert.Panics(t, func() {
   198  						profile.completeInitialization(devConfigDir)
   199  					})
   200  				}
   201  			})
   202  
   203  			t.Run("nil Options", func(t *testing.T) {
   204  				profile := makeProfile(consenters, nil)
   205  				profile.completeInitialization(devConfigDir)
   206  
   207  				// need not be tested in subsequent tests
   208  				assert.NotNil(t, profile.Orderer.EtcdRaft, "EtcdRaft config settings should be set")
   209  				assert.Equal(t, profile.Orderer.EtcdRaft.Consenters[0].ClientTlsCert, consenters[0].ClientTlsCert,
   210  					"Client TLS cert path should be correctly set")
   211  
   212  				// specific assertion for this test context
   213  				assert.Equal(t, profile.Orderer.EtcdRaft.Options, genesisDefaults.Orderer.EtcdRaft.Options,
   214  					"Options should be set to the default value")
   215  			})
   216  
   217  			t.Run("heartbeat tick specified in Options", func(t *testing.T) {
   218  				heartbeatTick := uint32(2)
   219  				options := &etcdraft.Options{ // partially set so that we can check that the other members are set to defaults
   220  					HeartbeatTick: heartbeatTick,
   221  				}
   222  				profile := makeProfile(consenters, options)
   223  				profile.completeInitialization(devConfigDir)
   224  
   225  				// specific assertions for this test context
   226  				assert.Equal(t, profile.Orderer.EtcdRaft.Options.HeartbeatTick, heartbeatTick,
   227  					"HeartbeatTick should be set to the specified value")
   228  				assert.Equal(t, profile.Orderer.EtcdRaft.Options.ElectionTick, genesisDefaults.Orderer.EtcdRaft.Options.ElectionTick,
   229  					"ElectionTick should be set to the default value")
   230  			})
   231  
   232  			t.Run("election tick specified in Options", func(t *testing.T) {
   233  				electionTick := uint32(20)
   234  				options := &etcdraft.Options{ // partially set so that we can check that the other members are set to defaults
   235  					ElectionTick: electionTick,
   236  				}
   237  				profile := makeProfile(consenters, options)
   238  				profile.completeInitialization(devConfigDir)
   239  
   240  				// specific assertions for this test context
   241  				assert.Equal(t, profile.Orderer.EtcdRaft.Options.ElectionTick, electionTick,
   242  					"ElectionTick should be set to the specified value")
   243  				assert.Equal(t, profile.Orderer.EtcdRaft.Options.HeartbeatTick, genesisDefaults.Orderer.EtcdRaft.Options.HeartbeatTick,
   244  					"HeartbeatTick should be set to the default value")
   245  			})
   246  
   247  			t.Run("panic on invalid Heartbeat and Election tick", func(t *testing.T) {
   248  				options := &etcdraft.Options{
   249  					HeartbeatTick: 2,
   250  					ElectionTick:  1,
   251  				}
   252  				profile := makeProfile(consenters, options)
   253  
   254  				assert.Panics(t, func() {
   255  					profile.completeInitialization(devConfigDir)
   256  				})
   257  			})
   258  
   259  			t.Run("panic on invalid TickInterval", func(t *testing.T) {
   260  				options := &etcdraft.Options{
   261  					TickInterval: "500",
   262  				}
   263  				profile := makeProfile(consenters, options)
   264  
   265  				assert.Panics(t, func() {
   266  					profile.completeInitialization(devConfigDir)
   267  				})
   268  			})
   269  		})
   270  	})
   271  }
   272  
   273  func TestLoadConfigCache(t *testing.T) {
   274  	cleanup := configtest.SetDevFabricConfigPath(t)
   275  	defer cleanup()
   276  
   277  	v := viper.New()
   278  	devConfigDir := configtest.GetDevConfigDir()
   279  	v.AddConfigPath(devConfigDir)
   280  	v.SetConfigName("configtx")
   281  	err := v.ReadInConfig()
   282  	assert.NoError(t, err)
   283  
   284  	configPath := v.ConfigFileUsed()
   285  	c := &configCache{
   286  		cache: make(map[string][]byte),
   287  	}
   288  
   289  	// Load the initial config, update the environment, and load again.
   290  	// With the caching behavior, the update should not be reflected.
   291  	initial, err := c.load(v, configPath)
   292  	assert.NoError(t, err)
   293  	os.Setenv("ORDERER_KAFKA_RETRY_SHORTINTERVAL", "120s")
   294  	updated, err := c.load(v, configPath)
   295  	assert.Equal(t, initial, updated, "expected %#v to equal %#v", updated, initial)
   296  
   297  	// Change the configuration we got back and load again.
   298  	// The  new value should not contain the updated to the initial
   299  	initial.Orderer.OrdererType = "bad-Orderer-Type"
   300  	updated, err = c.load(v, configPath)
   301  	assert.NoError(t, err)
   302  	assert.NotEqual(t, initial, updated, "expected %#v to not equal %#v", updated, initial)
   303  }