From 7be7cbb8132e8e446cce60d6feabc0c825df6759 Mon Sep 17 00:00:00 2001 From: SamYuan1990 Date: Thu, 19 Nov 2020 22:36:56 +0800 Subject: [PATCH] add a workable test suite as preformance brench of endorsement fix for #102 Signed-off-by: SamYuan1990 --- azure-pipelines.yml | 12 +++++--- pkg/infra/benchmark_test.go | 61 +++++++++++++++++++++++++++++++++++++ pkg/infra/proposer_test.go | 31 +++++++++++++++++++ 3 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 pkg/infra/benchmark_test.go diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1f93894d..a1ed1a25 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -27,19 +27,23 @@ jobs: inputs: version: '1.14' - task: Go@0 + displayName: install inputs: command: 'get' arguments: '-d ./...' workingDirectory: '$(System.DefaultWorkingDirectory)' - task: Go@0 + displayName: build inputs: - command: 'test' - arguments: '-v ./... -cover' + command: 'build' + arguments: './...' workingDirectory: '$(System.DefaultWorkingDirectory)' - task: Go@0 + displayName: test inputs: - command: 'build' - arguments: './...' + command: 'test' + # for any benchmark testing should run locally to avoid impacts from random vm on azp pipeline. + arguments: '-v ./... --bench=. -cover' workingDirectory: '$(System.DefaultWorkingDirectory)' - job: dockerbuild diff --git a/pkg/infra/benchmark_test.go b/pkg/infra/benchmark_test.go new file mode 100644 index 00000000..097375c8 --- /dev/null +++ b/pkg/infra/benchmark_test.go @@ -0,0 +1,61 @@ +package infra + +import ( + "net" + "testing" + + "github.com/guoger/tape/e2e/mock" + "github.com/hyperledger/fabric-protos-go/peer" + log "github.com/sirupsen/logrus" + "google.golang.org/grpc" +) + +func StartMockPeer() (*mock.Server, string) { + lis, _ := net.Listen("tcp", "127.0.0.1:0") + grpcServer := grpc.NewServer() + mockPeer := &mock.Server{GrpcServer: grpcServer, Listener: lis} + go mockPeer.Start() + return mockPeer, lis.Addr().String() +} + +func StartProposer(signed, processed chan *Elements, done chan struct{}, logger *log.Logger, threshold int, addr string) { + peer := Node{ + Addr: addr, + } + Proposer, _ := CreateProposer(peer, logger) + go Proposer.Start(signed, processed, done, threshold) +} + +func benchmarkNPeer(concurrent int, b *testing.B) { + processed := make(chan *Elements, 10) + done := make(chan struct{}) + defer close(done) + signeds := make([]chan *Elements, concurrent) + for i := 0; i < concurrent; i++ { + signeds[i] = make(chan *Elements, 10) + mockpeer, mockpeeraddr := StartMockPeer() + StartProposer(signeds[i], processed, done, nil, concurrent, mockpeeraddr) + defer mockpeer.Stop() + } + + b.ResetTimer() + go func() { + for i := 0; i < b.N; i++ { + data := &Elements{SignedProp: &peer.SignedProposal{}} + for _, s := range signeds { + s <- data + } + } + }() + var n int + for n < b.N { + <-processed + n++ + } + b.StopTimer() +} + +func BenchmarkPeerEndorsement1(b *testing.B) { benchmarkNPeer(1, b) } +func BenchmarkPeerEndorsement2(b *testing.B) { benchmarkNPeer(2, b) } +func BenchmarkPeerEndorsement4(b *testing.B) { benchmarkNPeer(4, b) } +func BenchmarkPeerEndorsement8(b *testing.B) { benchmarkNPeer(8, b) } diff --git a/pkg/infra/proposer_test.go b/pkg/infra/proposer_test.go index 0011f668..10bebf45 100644 --- a/pkg/infra/proposer_test.go +++ b/pkg/infra/proposer_test.go @@ -2,6 +2,7 @@ package infra_test import ( "github.com/guoger/tape/pkg/infra" + "github.com/hyperledger/fabric-protos-go/peer" "github.com/hyperledger/fabric-sdk-go/pkg/fab/mocks" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -12,6 +13,8 @@ var _ = Describe("Proposer", func() { var addr string var logger = log.New() + var processed chan *infra.Elements + var done chan struct{} BeforeEach(func() { srv := &mocks.MockEndorserServer{} @@ -55,4 +58,32 @@ var _ = Describe("Proposer", func() { Expect(err).Should(MatchError(ContainSubstring("error connecting to invalid_addr"))) }) }) + + Context("Tape should do less for prepare and summary endorsement process", func() { + // 0.002 here for mac testing on azp + // For ginkgo, + // You may only call Measure from within a Describe, Context or When + // So here only tested with concurrent as 8 peers + Measure("it should do endorsement efficiently for 2 peers", func(b Benchmarker) { + peerNum := 2 + processed = make(chan *infra.Elements, 10) + done = make(chan struct{}) + defer close(done) + signeds := make([]chan *infra.Elements, peerNum) + for i := 0; i < peerNum; i++ { + signeds[i] = make(chan *infra.Elements, 10) + mockpeer, mockpeeraddr := infra.StartMockPeer() + infra.StartProposer(signeds[i], processed, done, nil, peerNum, mockpeeraddr) + defer mockpeer.Stop() + } + runtime := b.Time("runtime", func() { + data := &infra.Elements{SignedProp: &peer.SignedProposal{}} + for _, s := range signeds { + s <- data + } + <-processed + }) + Expect(runtime.Seconds()).Should(BeNumerically("<", 0.002), "endorsement() shouldn't take too long.") + }, 10) + }) })