From 358abfb9f38274336f2cc2d16bd48a6c7d40a452 Mon Sep 17 00:00:00 2001 From: Sudesh Shetty Date: Wed, 5 Jul 2017 15:18:01 -0400 Subject: [PATCH] [FAB-5173] Orderer refactor and test coverage Change-Id: I01ce94407acd3ede7304afcedb00ae8f314857ef Signed-off-by: Sudesh Shetty --- .../mocks/mockbroadcastserver.go | 13 + pkg/fabric-client/mocks/mockconfig.go | 17 +- pkg/fabric-client/orderer/orderer_test.go | 231 ++++++++++++++++++ 3 files changed, 260 insertions(+), 1 deletion(-) diff --git a/pkg/fabric-client/mocks/mockbroadcastserver.go b/pkg/fabric-client/mocks/mockbroadcastserver.go index 9b7529f1f8..5fe13d0e8b 100644 --- a/pkg/fabric-client/mocks/mockbroadcastserver.go +++ b/pkg/fabric-client/mocks/mockbroadcastserver.go @@ -29,10 +29,17 @@ var broadcastResponseError = &po.BroadcastResponse{Status: common.Status_INTERNA type MockBroadcastServer struct { DeliverError error BroadcastInternalServerError bool + DeliverResponse *po.DeliverResponse + BroadcastError error } // Broadcast mock broadcast func (m *MockBroadcastServer) Broadcast(server po.AtomicBroadcast_BroadcastServer) error { + + if m.BroadcastError != nil { + return m.BroadcastError + } + if m.BroadcastInternalServerError { server.Send(broadcastResponseError) return nil @@ -47,6 +54,12 @@ func (m *MockBroadcastServer) Deliver(server po.AtomicBroadcast_DeliverServer) e return m.DeliverError } + if m.DeliverResponse != nil { + server.Recv() + server.SendMsg(m.DeliverResponse) + return nil + } + server.Recv() server.Send(TestBlock) diff --git a/pkg/fabric-client/mocks/mockconfig.go b/pkg/fabric-client/mocks/mockconfig.go index cc7b453e0c..373c672ede 100644 --- a/pkg/fabric-client/mocks/mockconfig.go +++ b/pkg/fabric-client/mocks/mockconfig.go @@ -11,12 +11,16 @@ import ( config "github.com/hyperledger/fabric-sdk-go/api/apiconfig" + "fmt" + bccspFactory "github.com/hyperledger/fabric/bccsp/factory" "github.com/spf13/viper" ) // MockConfig ... type MockConfig struct { + tlsEnabled bool + errorCase bool } // NewMockConfig ... @@ -24,6 +28,11 @@ func NewMockConfig() config.Config { return &MockConfig{} } +// NewMockConfigCustomized ... +func NewMockConfigCustomized(tlsEnabled bool, errorCase bool) config.Config { + return &MockConfig{tlsEnabled: tlsEnabled, errorCase: errorCase} +} + // CAConfig not implemented func (c *MockConfig) CAConfig(org string) (*config.CAConfig, error) { return nil, nil @@ -57,16 +66,22 @@ func (c *MockConfig) PeersConfig(org string) ([]config.PeerConfig, error) { // IsTLSEnabled ... func (c *MockConfig) IsTLSEnabled() bool { - return false + return c.tlsEnabled } // TLSCACertPool ... func (c *MockConfig) TLSCACertPool(tlsCertificate string) (*x509.CertPool, error) { + if c.errorCase { + return nil, fmt.Errorf("just to test error scenario") + } return nil, nil } // TLSCACertPoolFromRoots ... func (c *MockConfig) TLSCACertPoolFromRoots(ordererRootCAs [][]byte) (*x509.CertPool, error) { + if c.errorCase { + return nil, fmt.Errorf("just to test error scenario") + } return nil, nil } diff --git a/pkg/fabric-client/orderer/orderer_test.go b/pkg/fabric-client/orderer/orderer_test.go index e6b450ac4b..0c04723850 100644 --- a/pkg/fabric-client/orderer/orderer_test.go +++ b/pkg/fabric-client/orderer/orderer_test.go @@ -16,11 +16,35 @@ import ( client "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client" mocks "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/mocks" + "strings" + + "github.com/hyperledger/fabric/protos/common" ab "github.com/hyperledger/fabric/protos/orderer" "google.golang.org/grpc" ) var testOrdererURL = "0.0.0.0:4584" +var testOrdererURL2 = "0.0.0.0:4585" +var testOrdererURL3 = "0.0.0.0:4586" +var testOrdererURL4 = "0.0.0.0:4587" +var testOrdererURL5 = "0.0.0.0:4588" +var testOrdererURL6 = "0.0.0.0:4590" + +var validRootCA = `-----BEGIN CERTIFICATE----- +MIICYjCCAgmgAwIBAgIUB3CTDOU47sUC5K4kn/Caqnh114YwCgYIKoZIzj0EAwIw +fzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh +biBGcmFuY2lzY28xHzAdBgNVBAoTFkludGVybmV0IFdpZGdldHMsIEluYy4xDDAK +BgNVBAsTA1dXVzEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYxMDEyMTkzMTAw +WhcNMjExMDExMTkzMTAwWjB/MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZv +cm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEfMB0GA1UEChMWSW50ZXJuZXQg +V2lkZ2V0cywgSW5jLjEMMAoGA1UECxMDV1dXMRQwEgYDVQQDEwtleGFtcGxlLmNv +bTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKIH5b2JaSmqiQXHyqC+cmknICcF +i5AddVjsQizDV6uZ4v6s+PWiJyzfA/rTtMvYAPq/yeEHpBUB1j053mxnpMujYzBh +MA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQXZ0I9 +qp6CP8TFHZ9bw5nRtZxIEDAfBgNVHSMEGDAWgBQXZ0I9qp6CP8TFHZ9bw5nRtZxI +EDAKBggqhkjOPQQDAgNHADBEAiAHp5Rbp9Em1G/UmKn8WsCbqDfWecVbZPQj3RK4 +oG5kQQIgQAe4OOKYhJdh3f7URaKfGTf492/nmRmtK+ySKjpHSrU= +-----END CERTIFICATE-----` // // Orderer via chain setOrderer/getOrderer @@ -159,6 +183,19 @@ func TestSendDeliver(t *testing.T) { case <-time.After(time.Second * 5): t.Fatalf("Did not receive block or error from SendDeliver") } + + orderer, _ = NewOrderer(testOrdererURL+"invalid-test", "", "", mocks.NewMockConfig()) + // Test deliver happy path + blocks, errors = orderer.SendDeliver(&fab.SignedEnvelope{}) + select { + case block := <-blocks: + t.Fatalf("This usecase was not supposed to receive blocks : %#v", block) + case err := <-errors: + fmt.Printf("There is an error as expected : %s \n", err) + case <-time.After(time.Second * 5): + t.Fatalf("Did not receive error from SendDeliver") + } + } func startMockServer(t *testing.T) *mocks.MockBroadcastServer { @@ -175,3 +212,197 @@ func startMockServer(t *testing.T) *mocks.MockBroadcastServer { return broadcastServer } + +func startCustomizedMockServer(t *testing.T, serverURL string, grpcServer *grpc.Server, broadcastServer *mocks.MockBroadcastServer) *mocks.MockBroadcastServer { + + lis, err := net.Listen("tcp", serverURL) + ab.RegisterAtomicBroadcastServer(grpcServer, broadcastServer) + if err != nil { + fmt.Printf("Error starting test server %s", err) + t.FailNow() + } + fmt.Printf("Starting test customized server\n") + go grpcServer.Serve(lis) + + return broadcastServer +} + +func TestCreateNewOrdererWithRootCAs(t *testing.T) { + + rootCA := [][]byte{ + []byte(validRootCA), + } + + //Without TLS + ordr, err := CreateNewOrdererWithRootCAs("", rootCA, "", mocks.NewMockConfig()) + if ordr == nil || err != nil { + t.Fatalf("TestCreateNewOrdererWithRootCAs Failed, cause : [ %s ]", err) + } + + //With TLS + ordr, err = CreateNewOrdererWithRootCAs("", rootCA, "", mocks.NewMockConfigCustomized(true, false)) + if ordr == nil || err != nil { + t.Fatalf("TestCreateNewOrdererWithRootCAs Failed, cause : [ %s ]", err) + } + + //With TLS, With invalid rootCA + ordr, err = CreateNewOrdererWithRootCAs("", [][]byte{}, "", mocks.NewMockConfigCustomized(true, true)) + if ordr != nil || err == nil { + t.Fatal("TestCreateNewOrdererWithRootCAs Failed, was expecting error") + } + +} + +func TestNewOrdererWithTLS(t *testing.T) { + + //Positive Test case + orderer, err := NewOrderer("", "../../test/fixtures/tls/fabricca/ca/ca_root.pem", "", mocks.NewMockConfigCustomized(true, false)) + if orderer == nil || err != nil { + t.Fatalf("Testing NewOrderer with TLS failed, cause [%s]", err) + } + + //Negative Test case + orderer, err = NewOrderer("", "", "", mocks.NewMockConfigCustomized(true, true)) + if orderer != nil || err == nil { + t.Fatalf("Testing NewOrderer with TLS was supposed to failed") + } +} + +func TestSendBroadcast(t *testing.T) { + + //startMockServer(t) + + orderer, _ := NewOrderer(testOrdererURL, "", "", mocks.NewMockConfig()) + _, err := orderer.SendBroadcast(&fab.SignedEnvelope{}) + + if err != nil { + t.Fatalf("Test SendBroadcast was not supposed to fail") + } + + orderer, _ = NewOrderer(testOrdererURL+"Test", "", "", mocks.NewMockConfig()) + _, err = orderer.SendBroadcast(&fab.SignedEnvelope{}) + + if err == nil || !strings.HasPrefix(err.Error(), "Error Create NewAtomicBroadcastClient rpc error") { + t.Fatalf("Test SendBroadcast was supposed to fail with expected error, instead it fail with [%s] error", err) + } + +} + +func TestSendDeliverServerBadResponse(t *testing.T) { + + grpcServer := grpc.NewServer() + broadcastServer := mocks.MockBroadcastServer{ + DeliverResponse: &ab.DeliverResponse{ + Type: &ab.DeliverResponse_Status{ + Status: common.Status_BAD_REQUEST, + }, + }, + } + + startCustomizedMockServer(t, testOrdererURL2, grpcServer, &broadcastServer) + orderer, _ := NewOrderer(testOrdererURL2, "", "", mocks.NewMockConfig()) + + blocks, errors := orderer.SendDeliver(&fab.SignedEnvelope{}) + + select { + case block := <-blocks: + t.Fatalf("This usecase was not supposed to receive blocks : %#v", block) + case err := <-errors: + if err.Error() != "Got error status from ordering service: BAD_REQUEST" { + t.Fatalf("Ordering service error is not received as expected, %s", err) + } + case <-time.After(time.Second * 5): + t.Fatalf("Did not receive error from SendDeliver") + } +} + +func TestSendDeliverServerSuccessResponse(t *testing.T) { + + grpcServer := grpc.NewServer() + broadcastServer := mocks.MockBroadcastServer{ + DeliverResponse: &ab.DeliverResponse{ + Type: &ab.DeliverResponse_Status{ + Status: common.Status_SUCCESS, + }, + }, + } + + startCustomizedMockServer(t, testOrdererURL3, grpcServer, &broadcastServer) + orderer, _ := NewOrderer(testOrdererURL3, "", "", mocks.NewMockConfig()) + + blocks, errors := orderer.SendDeliver(&fab.SignedEnvelope{}) + + select { + case block := <-blocks: + if block != nil { + t.Fatalf("This usecase was not supposed to get valid block") + } + case err := <-errors: + t.Fatalf("This usecase was not supposed to get error : %s ", err.Error()) + case <-time.After(time.Second * 5): + t.Fatalf("Did not receive block from SendDeliver") + } +} + +func TestSendDeliverFailure(t *testing.T) { + + grpcServer := grpc.NewServer() + broadcastServer := mocks.MockBroadcastServer{ + DeliverResponse: &ab.DeliverResponse{}, + } + + startCustomizedMockServer(t, testOrdererURL6, grpcServer, &broadcastServer) + orderer, _ := NewOrderer(testOrdererURL6, "", "", mocks.NewMockConfig()) + + blocks, errors := orderer.SendDeliver(&fab.SignedEnvelope{}) + + select { + case block := <-blocks: + t.Fatalf("This usecase was not supposed to get valid block %v", block) + case err := <-errors: + if err == nil || !strings.HasPrefix(err.Error(), "Received unknown response from ordering service") { + t.Fatalf("Error response is not working as expected : '%s' ", err.Error()) + } + case <-time.After(time.Second * 5): + t.Fatal("Did not receive any response or error from SendDeliver") + } +} + +func TestSendBroadcastServerBadResponse(t *testing.T) { + + grpcServer := grpc.NewServer() + broadcastServer := mocks.MockBroadcastServer{ + BroadcastInternalServerError: true, + } + + startCustomizedMockServer(t, testOrdererURL4, grpcServer, &broadcastServer) + orderer, _ := NewOrderer(testOrdererURL4, "", "", mocks.NewMockConfig()) + + status, err := orderer.SendBroadcast(&fab.SignedEnvelope{}) + + if status.String() != "INTERNAL_SERVER_ERROR" { + t.Fatalf("Expected internal server error, but got %v", status) + } + if err == nil || err.Error() != "broadcast response is not success : INTERNAL_SERVER_ERROR" { + t.Fatalf("Expected internal server error, but got %s", err) + } + +} + +func TestSendBroadcastError(t *testing.T) { + + grpcServer := grpc.NewServer() + broadcastServer := mocks.MockBroadcastServer{ + BroadcastError: fmt.Errorf("just to test error scenario"), + } + + startCustomizedMockServer(t, testOrdererURL5, grpcServer, &broadcastServer) + orderer, _ := NewOrderer(testOrdererURL5, "", "", mocks.NewMockConfig()) + + status, err := orderer.SendBroadcast(&fab.SignedEnvelope{}) + + if err == nil || status != nil { + t.Fatalf("expected Send Broadcast to fail with error, but got %s", err) + } + +}