github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/common/configvalues/channel/orderer/sharedconfig_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 orderer
    18  
    19  import (
    20  	"os"
    21  	"os/exec"
    22  	"reflect"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/stretchr/testify/assert"
    27  
    28  	cb "github.com/hyperledger/fabric/protos/common"
    29  	ab "github.com/hyperledger/fabric/protos/orderer"
    30  
    31  	logging "github.com/op/go-logging"
    32  )
    33  
    34  func init() {
    35  	logging.SetLevel(logging.DEBUG, "")
    36  }
    37  
    38  func invalidMessage() *cb.ConfigValue {
    39  	return &cb.ConfigValue{
    40  		Value: []byte("Garbage Data"),
    41  	}
    42  }
    43  
    44  func groupToKeyValue(configGroup *cb.ConfigGroup) (string, *cb.ConfigValue) {
    45  	for key, value := range configGroup.Groups[GroupKey].Values {
    46  		return key, value
    47  	}
    48  	panic("No value encoded")
    49  }
    50  
    51  func doesFuncCrash(crasher func(), test string) bool {
    52  	// Adapted from https://talks.golang.org/2014/testing.slide#23 to test os.Exit() functionality
    53  	if os.Getenv("BE_CRASHER") == "1" {
    54  		crasher()
    55  		return false
    56  	}
    57  	cmd := exec.Command(os.Args[0], "-test.run="+test)
    58  	cmd.Env = append(os.Environ(), "BE_CRASHER=1")
    59  	err := cmd.Run()
    60  	if e, ok := err.(*exec.ExitError); ok && !e.Success() {
    61  		return true
    62  	}
    63  	return false
    64  }
    65  
    66  func TestDoubleBegin(t *testing.T) {
    67  	crashes := doesFuncCrash(func() {
    68  		m := NewManagerImpl(nil)
    69  		m.BeginValueProposals(nil)
    70  		m.BeginValueProposals(nil)
    71  	}, "TestDoubleBegin")
    72  
    73  	if !crashes {
    74  		t.Fatalf("Should have crashed on multiple begin configs")
    75  	}
    76  }
    77  
    78  func TestCommitWithoutBegin(t *testing.T) {
    79  	crashes := doesFuncCrash(func() {
    80  		m := NewManagerImpl(nil)
    81  		m.CommitProposals()
    82  	}, "TestCommitWithoutBegin")
    83  
    84  	if !crashes {
    85  		t.Fatalf("Should have crashed on multiple begin configs")
    86  	}
    87  }
    88  
    89  func TestRollback(t *testing.T) {
    90  	m := NewManagerImpl(nil)
    91  	m.pendingConfig = &ordererConfig{}
    92  	m.RollbackProposals()
    93  	if m.pendingConfig != nil {
    94  		t.Fatalf("Should have cleared pending config on rollback")
    95  	}
    96  }
    97  
    98  func TestConsensusType(t *testing.T) {
    99  	endType := "foo"
   100  	invalidMessage := invalidMessage()
   101  	validMessage := TemplateConsensusType(endType)
   102  	otherValidMessage := TemplateConsensusType("bar")
   103  
   104  	m := NewManagerImpl(nil)
   105  	m.BeginValueProposals(nil)
   106  
   107  	err := m.ProposeValue(groupToKeyValue(validMessage))
   108  	if err != nil {
   109  		t.Fatalf("Error applying valid config: %s", err)
   110  	}
   111  
   112  	m.CommitProposals()
   113  	m.BeginValueProposals(nil)
   114  
   115  	err = m.ProposeValue(ConsensusTypeKey, invalidMessage)
   116  	if err == nil {
   117  		t.Fatalf("Should have failed on invalid message")
   118  	}
   119  
   120  	err = m.ProposeValue(groupToKeyValue(validMessage))
   121  	if err != nil {
   122  		t.Fatalf("Error re-applying valid config: %s", err)
   123  	}
   124  
   125  	err = m.ProposeValue(groupToKeyValue(otherValidMessage))
   126  	if err == nil {
   127  		t.Fatalf("Should not have applied config with different consensus type after it was initially set")
   128  	}
   129  
   130  	m.CommitProposals()
   131  
   132  	if nowType := m.ConsensusType(); nowType != endType {
   133  		t.Fatalf("Consensus type should have ended as %s but was %s", endType, nowType)
   134  	}
   135  }
   136  
   137  func TestBatchSize(t *testing.T) {
   138  
   139  	validMaxMessageCount := uint32(10)
   140  	validAbsoluteMaxBytes := uint32(1000)
   141  	validPreferredMaxBytes := uint32(500)
   142  
   143  	t.Run("ValidConfig", func(t *testing.T) {
   144  		m := NewManagerImpl(nil)
   145  		m.BeginValueProposals(nil)
   146  		err := m.ProposeValue(
   147  			groupToKeyValue(TemplateBatchSize(&ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validPreferredMaxBytes})),
   148  		)
   149  		assert.Nil(t, err, "Error applying valid config: %s", err)
   150  		m.CommitProposals()
   151  		if m.BatchSize().MaxMessageCount != validMaxMessageCount {
   152  			t.Fatalf("Got batch size max message count of %d. Expected: %d", m.BatchSize().MaxMessageCount, validMaxMessageCount)
   153  		}
   154  		if m.BatchSize().AbsoluteMaxBytes != validAbsoluteMaxBytes {
   155  			t.Fatalf("Got batch size absolute max bytes of %d. Expected: %d", m.BatchSize().AbsoluteMaxBytes, validAbsoluteMaxBytes)
   156  		}
   157  		if m.BatchSize().PreferredMaxBytes != validPreferredMaxBytes {
   158  			t.Fatalf("Got batch size preferred max bytes of %d. Expected: %d", m.BatchSize().PreferredMaxBytes, validPreferredMaxBytes)
   159  		}
   160  	})
   161  
   162  	t.Run("UnserializableConfig", func(t *testing.T) {
   163  		m := NewManagerImpl(nil)
   164  		m.BeginValueProposals(nil)
   165  		err := m.ProposeValue(BatchSizeKey, invalidMessage())
   166  		assert.NotNil(t, err, "Should have failed on invalid message")
   167  		m.CommitProposals()
   168  	})
   169  
   170  	t.Run("ZeroMaxMessageCount", func(t *testing.T) {
   171  		m := NewManagerImpl(nil)
   172  		m.BeginValueProposals(nil)
   173  		err := m.ProposeValue(groupToKeyValue(TemplateBatchSize(&ab.BatchSize{MaxMessageCount: 0, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validPreferredMaxBytes})))
   174  		assert.NotNil(t, err, "Should have rejected batch size max message count of 0")
   175  		m.CommitProposals()
   176  	})
   177  
   178  	t.Run("ZeroAbsoluteMaxBytes", func(t *testing.T) {
   179  		m := NewManagerImpl(nil)
   180  		m.BeginValueProposals(nil)
   181  		err := m.ProposeValue(groupToKeyValue(TemplateBatchSize(&ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: 0, PreferredMaxBytes: validPreferredMaxBytes})))
   182  		assert.NotNil(t, err, "Should have rejected batch size absolute max message bytes of 0")
   183  		m.CommitProposals()
   184  	})
   185  
   186  	t.Run("TooLargePreferredMaxBytes", func(t *testing.T) {
   187  		m := NewManagerImpl(nil)
   188  		m.BeginValueProposals(nil)
   189  		err := m.ProposeValue(groupToKeyValue(TemplateBatchSize(&ab.BatchSize{MaxMessageCount: validMaxMessageCount, AbsoluteMaxBytes: validAbsoluteMaxBytes, PreferredMaxBytes: validAbsoluteMaxBytes + 1})))
   190  		assert.NotNil(t, err, "Should have rejected batch size preferred max message bytes greater than absolute max message bytes")
   191  		m.CommitProposals()
   192  	})
   193  }
   194  
   195  func TestBatchTimeout(t *testing.T) {
   196  	endBatchTimeout, _ := time.ParseDuration("1s")
   197  	invalidMessage := invalidMessage()
   198  	negativeBatchTimeout := TemplateBatchTimeout("-1s")
   199  	zeroBatchTimeout := TemplateBatchTimeout("0s")
   200  	validMessage := TemplateBatchTimeout(endBatchTimeout.String())
   201  
   202  	m := NewManagerImpl(nil)
   203  	m.BeginValueProposals(nil)
   204  
   205  	err := m.ProposeValue(groupToKeyValue(validMessage))
   206  	if err != nil {
   207  		t.Fatalf("Error applying valid config: %s", err)
   208  	}
   209  
   210  	err = m.ProposeValue(BatchTimeoutKey, invalidMessage)
   211  	if err == nil {
   212  		t.Fatalf("Should have failed on invalid message")
   213  	}
   214  
   215  	err = m.ProposeValue(groupToKeyValue(negativeBatchTimeout))
   216  	if err == nil {
   217  		t.Fatalf("Should have rejected negative batch timeout: %s", err)
   218  	}
   219  
   220  	err = m.ProposeValue(groupToKeyValue(zeroBatchTimeout))
   221  	if err == nil {
   222  		t.Fatalf("Should have rejected batch timeout of 0")
   223  	}
   224  
   225  	m.CommitProposals()
   226  
   227  	if nowBatchTimeout := m.BatchTimeout(); nowBatchTimeout != endBatchTimeout {
   228  		t.Fatalf("Got batch timeout of %s when expecting batch size of %s", nowBatchTimeout.String(), endBatchTimeout.String())
   229  	}
   230  }
   231  
   232  func TestKafkaBrokers(t *testing.T) {
   233  	endList := []string{"127.0.0.1:9092", "foo.bar:9092"}
   234  
   235  	invalidMessage := invalidMessage()
   236  	zeroBrokers := TemplateKafkaBrokers([]string{})
   237  	badList := []string{"127.0.0.1", "foo.bar", "127.0.0.1:-1", "localhost:65536", "foo.bar.:9092", ".127.0.0.1:9092", "-foo.bar:9092"}
   238  	badMessages := []*cb.ConfigGroup{}
   239  	for _, badAddress := range badList {
   240  		badMessages = append(badMessages, TemplateKafkaBrokers([]string{badAddress}))
   241  	}
   242  
   243  	validMessage := TemplateKafkaBrokers(endList)
   244  
   245  	m := NewManagerImpl(nil)
   246  	m.BeginValueProposals(nil)
   247  
   248  	err := m.ProposeValue(groupToKeyValue(validMessage))
   249  	if err != nil {
   250  		t.Fatalf("Error applying valid config: %s", err)
   251  	}
   252  
   253  	err = m.ProposeValue(KafkaBrokersKey, invalidMessage)
   254  	if err == nil {
   255  		t.Fatalf("Should have failed on invalid message")
   256  	}
   257  
   258  	err = m.ProposeValue(groupToKeyValue(zeroBrokers))
   259  	if err == nil {
   260  		t.Fatalf("Should have rejected empty brokers list")
   261  	}
   262  
   263  	for i := range badMessages {
   264  		err = m.ProposeValue(groupToKeyValue(badMessages[i]))
   265  		if err == nil {
   266  			t.Fatalf("Should have rejected broker address which is obviously malformed")
   267  		}
   268  	}
   269  
   270  	m.CommitProposals()
   271  
   272  	nowList := m.KafkaBrokers()
   273  	switch {
   274  	case len(nowList) != len(endList), nowList[0] != endList[0]:
   275  		t.Fatalf("Got brokers list %s when expecting brokers list %s", nowList, endList)
   276  	default:
   277  		return
   278  	}
   279  }
   280  
   281  func testPolicyNames(m *ManagerImpl, key string, initializer func(val []string) *cb.ConfigGroup, retriever func() []string, t *testing.T) {
   282  	endPolicy := []string{"foo", "bar"}
   283  	invalidMessage := invalidMessage()
   284  	validMessage := initializer(endPolicy)
   285  
   286  	m.BeginValueProposals(nil)
   287  
   288  	err := m.ProposeValue(groupToKeyValue(validMessage))
   289  	if err != nil {
   290  		t.Fatalf("Error applying valid config: %s", err)
   291  	}
   292  
   293  	m.CommitProposals()
   294  	m.BeginValueProposals(nil)
   295  
   296  	err = m.ProposeValue(key, invalidMessage)
   297  	if err == nil {
   298  		t.Fatalf("Should have failed on invalid message")
   299  	}
   300  
   301  	err = m.ProposeValue(groupToKeyValue(validMessage))
   302  	if err != nil {
   303  		t.Fatalf("Error re-applying valid config: %s", err)
   304  	}
   305  
   306  	m.CommitProposals()
   307  
   308  	if nowPolicy := retriever(); !reflect.DeepEqual(nowPolicy, endPolicy) {
   309  		t.Fatalf("%s should have ended as %s but was %s", key, endPolicy, nowPolicy)
   310  	}
   311  }
   312  
   313  func TestIngressPolicyNames(t *testing.T) {
   314  	m := NewManagerImpl(nil)
   315  	testPolicyNames(m, IngressPolicyNamesKey, TemplateIngressPolicyNames, m.IngressPolicyNames, t)
   316  }
   317  
   318  func TestEgressPolicyNames(t *testing.T) {
   319  	m := NewManagerImpl(nil)
   320  	testPolicyNames(m, EgressPolicyNamesKey, TemplateEgressPolicyNames, m.EgressPolicyNames, t)
   321  }
   322  
   323  func TestChainCreationPolicyNames(t *testing.T) {
   324  	m := NewManagerImpl(nil)
   325  	testPolicyNames(m, ChainCreationPolicyNamesKey, TemplateChainCreationPolicyNames, m.ChainCreationPolicyNames, t)
   326  }
   327  
   328  func TestEmptyChainCreationPolicyNames(t *testing.T) {
   329  	m := NewManagerImpl(nil)
   330  
   331  	m.BeginValueProposals(nil)
   332  
   333  	err := m.ProposeValue(groupToKeyValue(TemplateChainCreationPolicyNames(nil)))
   334  	if err != nil {
   335  		t.Fatalf("Error applying valid config: %s", err)
   336  	}
   337  
   338  	m.CommitProposals()
   339  
   340  	if m.ChainCreationPolicyNames() == nil {
   341  		t.Fatalf("Should have gotten back empty slice, not nil")
   342  	}
   343  }