go_study/fabric-main/internal/configtxgen/genesisconfig/config_test.go

289 lines
8.6 KiB
Go

/*
Copyright IBM Corp. 2017 All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package genesisconfig
import (
"testing"
"github.com/hyperledger/fabric-protos-go/orderer/etcdraft"
"github.com/hyperledger/fabric/common/viperutil"
"github.com/hyperledger/fabric/core/config/configtest"
"github.com/stretchr/testify/require"
)
func TestLoadProfile(t *testing.T) {
configtest.SetDevFabricConfigPath(t)
pNames := []string{
SampleDevModeSoloProfile,
SampleSingleMSPChannelProfile,
SampleSingleMSPSoloProfile,
SampleDevModeEtcdRaftProfile,
SampleAppChannelEtcdRaftProfile,
}
for _, pName := range pNames {
t.Run(pName, func(t *testing.T) {
p := Load(pName)
require.NotNil(t, p, "profile should not be nil")
})
}
}
func TestLoadProfileWithPath(t *testing.T) {
devConfigDir := configtest.GetDevConfigDir()
pNames := []string{
SampleDevModeSoloProfile,
SampleSingleMSPChannelProfile,
SampleSingleMSPSoloProfile,
SampleDevModeEtcdRaftProfile,
SampleAppChannelEtcdRaftProfile,
}
for _, pName := range pNames {
t.Run(pName, func(t *testing.T) {
p := Load(pName, devConfigDir)
require.NotNil(t, p, "profile should not be nil")
})
}
}
func TestLoadTopLevel(t *testing.T) {
configtest.SetDevFabricConfigPath(t)
topLevel := LoadTopLevel()
require.NotNil(t, topLevel.Application, "application should not be nil")
require.NotNil(t, topLevel.Capabilities, "capabilities should not be nil")
require.NotNil(t, topLevel.Orderer, "orderer should not be nil")
require.NotNil(t, topLevel.Organizations, "organizations should not be nil")
require.NotNil(t, topLevel.Profiles, "profiles should not be nil")
}
func TestLoadTopLevelWithPath(t *testing.T) {
devConfigDir := configtest.GetDevConfigDir()
topLevel := LoadTopLevel(devConfigDir)
require.NotNil(t, topLevel.Application, "application should not be nil")
require.NotNil(t, topLevel.Capabilities, "capabilities should not be nil")
require.NotNil(t, topLevel.Orderer, "orderer should not be nil")
require.NotNil(t, topLevel.Organizations, "organizations should not be nil")
require.NotNil(t, topLevel.Profiles, "profiles should not be nil")
}
func TestConsensusSpecificInit(t *testing.T) {
configtest.SetDevFabricConfigPath(t)
devConfigDir := configtest.GetDevConfigDir()
t.Run("nil orderer type", func(t *testing.T) {
profile := &Profile{
Orderer: &Orderer{
OrdererType: "",
},
}
profile.completeInitialization(devConfigDir)
require.Equal(t, profile.Orderer.OrdererType, genesisDefaults.Orderer.OrdererType)
})
t.Run("unknown orderer type", func(t *testing.T) {
profile := &Profile{
Orderer: &Orderer{
OrdererType: "unknown",
},
}
require.Panics(t, func() {
profile.completeInitialization(devConfigDir)
})
})
t.Run("solo", func(t *testing.T) {
profile := &Profile{
Orderer: &Orderer{
OrdererType: "solo",
},
}
profile.completeInitialization(devConfigDir)
require.NotNil(t, profile.Orderer.BatchSize)
})
t.Run("raft", func(t *testing.T) {
makeProfile := func(consenters []*etcdraft.Consenter, options *etcdraft.Options) *Profile {
return &Profile{
Orderer: &Orderer{
OrdererType: "etcdraft",
EtcdRaft: &etcdraft.ConfigMetadata{
Consenters: consenters,
Options: options,
},
},
}
}
t.Run("EtcdRaft section not specified in profile", func(t *testing.T) {
profile := &Profile{
Orderer: &Orderer{
OrdererType: "etcdraft",
},
}
require.Panics(t, func() {
profile.completeInitialization(devConfigDir)
})
})
t.Run("nil consenter set", func(t *testing.T) { // should panic
profile := makeProfile(nil, nil)
require.Panics(t, func() {
profile.completeInitialization(devConfigDir)
})
})
t.Run("single consenter", func(t *testing.T) {
consenters := []*etcdraft.Consenter{
{
Host: "node-1.example.com",
Port: 7050,
ClientTlsCert: []byte("path/to/client/cert"),
ServerTlsCert: []byte("path/to/server/cert"),
},
}
t.Run("invalid consenters specification", func(t *testing.T) {
failingConsenterSpecifications := []*etcdraft.Consenter{
{ // missing Host
Port: 7050,
ClientTlsCert: []byte("path/to/client/cert"),
ServerTlsCert: []byte("path/to/server/cert"),
},
{ // missing Port
Host: "node-1.example.com",
ClientTlsCert: []byte("path/to/client/cert"),
ServerTlsCert: []byte("path/to/server/cert"),
},
{ // missing ClientTlsCert
Host: "node-1.example.com",
Port: 7050,
ServerTlsCert: []byte("path/to/server/cert"),
},
{ // missing ServerTlsCert
Host: "node-1.example.com",
Port: 7050,
ClientTlsCert: []byte("path/to/client/cert"),
},
}
for _, consenter := range failingConsenterSpecifications {
profile := makeProfile([]*etcdraft.Consenter{consenter}, nil)
require.Panics(t, func() {
profile.completeInitialization(devConfigDir)
})
}
})
t.Run("nil Options", func(t *testing.T) {
profile := makeProfile(consenters, nil)
profile.completeInitialization(devConfigDir)
// need not be tested in subsequent tests
require.NotNil(t, profile.Orderer.EtcdRaft, "EtcdRaft config settings should be set")
require.Equal(t, profile.Orderer.EtcdRaft.Consenters[0].ClientTlsCert, consenters[0].ClientTlsCert,
"Client TLS cert path should be correctly set")
// specific assertion for this test context
require.Equal(t, profile.Orderer.EtcdRaft.Options, genesisDefaults.Orderer.EtcdRaft.Options,
"Options should be set to the default value")
})
t.Run("heartbeat tick specified in Options", func(t *testing.T) {
heartbeatTick := uint32(2)
options := &etcdraft.Options{ // partially set so that we can check that the other members are set to defaults
HeartbeatTick: heartbeatTick,
}
profile := makeProfile(consenters, options)
profile.completeInitialization(devConfigDir)
// specific assertions for this test context
require.Equal(t, profile.Orderer.EtcdRaft.Options.HeartbeatTick, heartbeatTick,
"HeartbeatTick should be set to the specified value")
require.Equal(t, profile.Orderer.EtcdRaft.Options.ElectionTick, genesisDefaults.Orderer.EtcdRaft.Options.ElectionTick,
"ElectionTick should be set to the default value")
})
t.Run("election tick specified in Options", func(t *testing.T) {
electionTick := uint32(20)
options := &etcdraft.Options{ // partially set so that we can check that the other members are set to defaults
ElectionTick: electionTick,
}
profile := makeProfile(consenters, options)
profile.completeInitialization(devConfigDir)
// specific assertions for this test context
require.Equal(t, profile.Orderer.EtcdRaft.Options.ElectionTick, electionTick,
"ElectionTick should be set to the specified value")
require.Equal(t, profile.Orderer.EtcdRaft.Options.HeartbeatTick, genesisDefaults.Orderer.EtcdRaft.Options.HeartbeatTick,
"HeartbeatTick should be set to the default value")
})
t.Run("panic on invalid Heartbeat and Election tick", func(t *testing.T) {
options := &etcdraft.Options{
HeartbeatTick: 2,
ElectionTick: 1,
}
profile := makeProfile(consenters, options)
require.Panics(t, func() {
profile.completeInitialization(devConfigDir)
})
})
t.Run("panic on invalid TickInterval", func(t *testing.T) {
options := &etcdraft.Options{
TickInterval: "500",
}
profile := makeProfile(consenters, options)
require.Panics(t, func() {
profile.completeInitialization(devConfigDir)
})
})
})
})
}
func TestLoadConfigCache(t *testing.T) {
configtest.SetDevFabricConfigPath(t)
cfg := viperutil.New()
devConfigDir := configtest.GetDevConfigDir()
cfg.AddConfigPaths(devConfigDir)
cfg.SetConfigName("configtx")
err := cfg.ReadInConfig()
require.NoError(t, err)
configPath := cfg.ConfigFileUsed()
c := &configCache{
cache: make(map[string][]byte),
}
// Load the initial config, update the environment, and load again.
// With the caching behavior, the update should not be reflected.
initial, err := c.load(cfg, configPath)
require.NoError(t, err)
updated, err := c.load(cfg, configPath)
require.NoError(t, err)
require.Equal(t, initial, updated, "expected %#v to equal %#v", updated, initial)
// Change the configuration we got back and load again.
// The new value should not contain the updated to the initial
initial.Orderer.OrdererType = "bad-Orderer-Type"
updated, err = c.load(cfg, configPath)
require.NoError(t, err)
require.NotEqual(t, initial, updated, "expected %#v to not equal %#v", updated, initial)
}