-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding parameter for mock server add mtls for mock server according to grpc/grpc-go#403 using mtls when create grpc connection Refactor using node as parameter Mock server test refactor with gexec fix #35 Signed-off-by: SamYuan1990 <yy19902439@126.com> Signed-off-by: Jay Guo <guojiannan1101@gmail.com>
- Loading branch information
1 parent
bad525a
commit 653fbc3
Showing
18 changed files
with
478 additions
and
213 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package e2e_test | ||
|
||
import ( | ||
"testing" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
func TestE2e(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "E2e Suite") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
package e2e | ||
|
||
import ( | ||
"crypto/tls" | ||
"crypto/x509" | ||
"io/ioutil" | ||
"net" | ||
"os" | ||
"os/exec" | ||
|
||
"github.com/guoger/stupid/e2e/mock" | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
. "github.com/onsi/gomega/gbytes" | ||
"github.com/onsi/gomega/gexec" | ||
"google.golang.org/grpc" | ||
"google.golang.org/grpc/credentials" | ||
) | ||
|
||
var _ = Describe("Mock test", func() { | ||
var ( | ||
mtlsCertFile, mtlsKeyFile *os.File | ||
tmpDir, stupidBin string | ||
stupidSession *gexec.Session | ||
) | ||
|
||
BeforeSuite(func() { | ||
tmpDir, err := ioutil.TempDir("", "stupid-e2e-") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
mtlsCertFile, err = ioutil.TempFile(tmpDir, "mtls-*.crt") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
mtlsKeyFile, err = ioutil.TempFile(tmpDir, "mtls-*.key") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
err = generateCertAndKeys(mtlsKeyFile, mtlsCertFile) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
mtlsCertFile.Close() | ||
mtlsKeyFile.Close() | ||
|
||
stupidBin, err = gexec.Build("../cmd/stupid") | ||
Expect(err).NotTo(HaveOccurred()) | ||
}) | ||
|
||
AfterEach(func() { | ||
stupidSession.Kill() | ||
}) | ||
|
||
AfterSuite(func() { | ||
os.RemoveAll(tmpDir) | ||
os.Remove(stupidBin) | ||
}) | ||
|
||
Context("E2E with mocked Fabric", func() { | ||
When("TLS is disabled", func() { | ||
It("should work properly", func() { | ||
lis, err := net.Listen("tcp", "127.0.0.1:0") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
grpcServer := grpc.NewServer() | ||
|
||
mock := &mock.Server{GrpcServer: grpcServer, Listener: lis} | ||
go mock.Start() | ||
defer mock.Stop() | ||
|
||
config, err := ioutil.TempFile("", "no-tls-config-*.yaml") | ||
configValue := values{ | ||
PrivSk: mtlsKeyFile.Name(), | ||
SignCert: mtlsCertFile.Name(), | ||
Mtls: false, | ||
Addr: lis.Addr().String(), | ||
} | ||
generateConfigFile(config.Name(), configValue) | ||
|
||
cmd := exec.Command(stupidBin, config.Name(), "500") | ||
stupidSession, err = gexec.Start(cmd, nil, nil) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Eventually(stupidSession.Out).Should(Say("Time.*Block.*Tx.*10.*")) | ||
}) | ||
}) | ||
|
||
When("client authentication is required", func() { | ||
It("should work properly", func() { | ||
peerCert, err := tls.LoadX509KeyPair(mtlsCertFile.Name(), | ||
mtlsKeyFile.Name()) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
caCert, err := ioutil.ReadFile(mtlsCertFile.Name()) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
caCertPool := x509.NewCertPool() | ||
caCertPool.AppendCertsFromPEM(caCert) | ||
ta := credentials.NewTLS(&tls.Config{ | ||
Certificates: []tls.Certificate{peerCert}, | ||
ClientCAs: caCertPool, | ||
ClientAuth: tls.RequireAndVerifyClientCert, | ||
}) | ||
grpcServer := grpc.NewServer(grpc.Creds(ta)) | ||
|
||
lis, err := net.Listen("tcp", "127.0.0.1:0") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
mock := &mock.Server{GrpcServer: grpcServer, Listener: lis} | ||
go mock.Start() | ||
defer mock.Stop() | ||
|
||
config, err := ioutil.TempFile("", "mtls-config-*.yaml") | ||
configValue := values{ | ||
PrivSk: mtlsKeyFile.Name(), | ||
SignCert: mtlsCertFile.Name(), | ||
Mtls: true, | ||
MtlsCrt: mtlsCertFile.Name(), | ||
MtlsKey: mtlsKeyFile.Name(), | ||
Addr: lis.Addr().String(), | ||
} | ||
|
||
generateConfigFile(config.Name(), configValue) | ||
|
||
cmd := exec.Command(stupidBin, config.Name(), "500") | ||
stupidSession, err = gexec.Start(cmd, nil, nil) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Eventually(stupidSession.Out).Should(Say("Time.*Block.*Tx.*10.*")) | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package mock | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
|
||
"github.com/hyperledger/fabric-protos-go/common" | ||
"github.com/hyperledger/fabric-protos-go/orderer" | ||
) | ||
|
||
type Orderer struct { | ||
cnt uint64 | ||
TxC chan struct{} | ||
} | ||
|
||
func (o *Orderer) Deliver(orderer.AtomicBroadcast_DeliverServer) error { | ||
panic("Not implemented") | ||
return nil | ||
} | ||
|
||
func (o *Orderer) Broadcast(srv orderer.AtomicBroadcast_BroadcastServer) error { | ||
for { | ||
_, err := srv.Recv() | ||
if err == io.EOF { | ||
return nil | ||
} | ||
|
||
if err != nil { | ||
fmt.Println(err) | ||
return err | ||
} | ||
|
||
o.TxC <- struct{}{} | ||
|
||
err = srv.Send(&orderer.BroadcastResponse{Status: common.Status_SUCCESS}) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package mock | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/hyperledger/fabric-protos-go/peer" | ||
) | ||
|
||
type Peer struct { | ||
BlkSize, txCnt uint64 | ||
TxC chan struct{} | ||
} | ||
|
||
func (p *Peer) ProcessProposal(context.Context, *peer.SignedProposal) (*peer.ProposalResponse, error) { | ||
return &peer.ProposalResponse{Response: &peer.Response{Status: 200}}, nil | ||
} | ||
|
||
func (p *Peer) Deliver(peer.Deliver_DeliverServer) error { | ||
panic("Not implemented") | ||
return nil | ||
} | ||
|
||
func (p *Peer) DeliverFiltered(srv peer.Deliver_DeliverFilteredServer) error { | ||
_, err := srv.Recv() | ||
if err != nil { | ||
panic("expect no recv error") | ||
} | ||
srv.Send(&peer.DeliverResponse{}) | ||
|
||
for range p.TxC { | ||
p.txCnt++ | ||
if p.txCnt%p.BlkSize == 0 { | ||
srv.Send(&peer.DeliverResponse{Type: &peer.DeliverResponse_FilteredBlock{ | ||
FilteredBlock: &peer.FilteredBlock{FilteredTransactions: make([]*peer.FilteredTransaction, p.BlkSize)}}}) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (p *Peer) DeliverWithPrivateData(peer.Deliver_DeliverWithPrivateDataServer) error { | ||
panic("Not implemented") | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package mock | ||
|
||
import ( | ||
"net" | ||
|
||
"github.com/hyperledger/fabric-protos-go/orderer" | ||
"github.com/hyperledger/fabric-protos-go/peer" | ||
"google.golang.org/grpc" | ||
) | ||
|
||
type Server struct { | ||
GrpcServer *grpc.Server | ||
Listener net.Listener | ||
} | ||
|
||
func (s *Server) Start() { | ||
blockC := make(chan struct{}, 1000) | ||
|
||
p := &Peer{ | ||
BlkSize: 10, | ||
TxC: blockC, | ||
} | ||
|
||
o := &Orderer{ | ||
TxC: blockC, | ||
} | ||
|
||
peer.RegisterEndorserServer(s.GrpcServer, p) | ||
peer.RegisterDeliverServer(s.GrpcServer, p) | ||
orderer.RegisterAtomicBroadcastServer(s.GrpcServer, o) | ||
|
||
err := s.GrpcServer.Serve(s.Listener) | ||
if err != nil { | ||
panic(err) | ||
} | ||
} | ||
|
||
func (s *Server) Stop() { | ||
s.GrpcServer.Stop() | ||
s.Listener.Close() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package e2e | ||
|
||
import ( | ||
"crypto/ecdsa" | ||
"crypto/elliptic" | ||
"crypto/rand" | ||
"crypto/x509" | ||
"encoding/pem" | ||
"math/big" | ||
"net" | ||
"os" | ||
"text/template" | ||
"time" | ||
) | ||
|
||
type values struct { | ||
PrivSk string | ||
SignCert string | ||
MtlsCrt string | ||
MtlsKey string | ||
Mtls bool | ||
Addr string | ||
} | ||
|
||
func generateCertAndKeys(key, cert *os.File) error { | ||
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) | ||
if err != nil { | ||
return err | ||
} | ||
privDer, err := x509.MarshalPKCS8PrivateKey(priv) | ||
if err != nil { | ||
return err | ||
} | ||
err = pem.Encode(key, &pem.Block{Type: "PRIVATE KEY", Bytes: privDer}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
template := &x509.Certificate{ | ||
SerialNumber: new(big.Int), | ||
NotAfter: time.Now().Add(time.Hour), | ||
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, | ||
} | ||
|
||
certDer, err := x509.CreateCertificate(rand.Reader, template, template, priv.Public(), priv) | ||
if err != nil { | ||
return err | ||
} | ||
err = pem.Encode(cert, &pem.Block{Type: "CERTIFICATE", Bytes: certDer}) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func generateConfigFile(fileName string, values values) { | ||
var Text = `# Definition of nodes | ||
node: &node | ||
addr: {{ .Addr }} | ||
{{ if .Mtls }} | ||
tls_ca_cert: {{.MtlsCrt}} | ||
tls_ca_key: {{.MtlsKey}} | ||
tls_ca_root: {{.MtlsCrt}} | ||
{{ end }} | ||
# Nodes to interact with | ||
endorsers: | ||
- *node | ||
committer: *node | ||
orderer: *node | ||
channel: test-channel | ||
chaincode: test-chaincode | ||
mspid: Org1MSP | ||
private_key: {{.PrivSk}} | ||
sign_cert: {{.SignCert}} | ||
num_of_conn: 10 | ||
client_per_conn: 10 | ||
` | ||
tmpl, err := template.New("test").Parse(Text) | ||
if err != nil { | ||
panic(err) | ||
} | ||
file, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY, 0755) | ||
if err != nil { | ||
panic(err) | ||
} | ||
defer file.Close() | ||
err = tmpl.Execute(file, values) | ||
if err != nil { | ||
panic(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.