289 lines
8.6 KiB
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)
|
|
}
|