Add helloworld tests with gRPC

This commit is contained in:
SALLEYRON Julien 2017-08-06 11:55:42 +02:00 committed by Ludovic Fernandez
parent 8071f31721
commit 990ee89650
8 changed files with 370 additions and 0 deletions

View file

@ -0,0 +1,29 @@
defaultEntryPoints = ["https"]
RootCAs = [ """{{ .CertContent }}""" ]
[entryPoints]
[entryPoints.https]
address = ":4443"
[entryPoints.https.tls]
[[entryPoints.https.tls.certificates]]
CertFile = """{{ .CertContent }}"""
KeyFile = """{{ .KeyContent }}"""
[web]
address = ":8080"
[file]
[backends]
[backends.backend1]
[backends.backend1.servers.server1]
url = "https://127.0.0.1:{{ .GRPCServerPort }}"
[frontends]
[frontends.frontend1]
backend = "backend1"
[frontends.frontend1.routes.test_1]
rule = "Host:127.0.0.1"

114
integration/grpc_test.go Normal file
View file

@ -0,0 +1,114 @@
package integration
import (
"crypto/tls"
"crypto/x509"
"io/ioutil"
"net"
"os"
"time"
"github.com/containous/traefik/integration/helloworld"
"github.com/containous/traefik/integration/try"
"github.com/go-check/check"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
var LocalhostCert []byte
var LocalhostKey []byte
// GRPCSuite
type GRPCSuite struct{ BaseSuite }
type myserver struct{}
func (suite *GRPCSuite) SetUpSuite(c *check.C) {
var err error
LocalhostCert, err = ioutil.ReadFile("./resources/tls/local.cert")
c.Assert(err, check.IsNil)
LocalhostKey, err = ioutil.ReadFile("./resources/tls/local.key")
c.Assert(err, check.IsNil)
}
func (s *myserver) SayHello(ctx context.Context, in *helloworld.HelloRequest) (*helloworld.HelloReply, error) {
return &helloworld.HelloReply{Message: "Hello " + in.Name}, nil
}
func startGRPCServer(lis net.Listener) error {
cert, err := tls.X509KeyPair(LocalhostCert, LocalhostKey)
if err != nil {
return err
}
creds := credentials.NewServerTLSFromCert(&cert)
serverOption := grpc.Creds(creds)
var s *grpc.Server = grpc.NewServer(serverOption)
defer s.Stop()
helloworld.RegisterGreeterServer(s, &myserver{})
return s.Serve(lis)
}
func callHelloClientGRPC() (string, error) {
roots := x509.NewCertPool()
roots.AppendCertsFromPEM(LocalhostCert)
credsClient := credentials.NewClientTLSFromCert(roots, "")
conn, err := grpc.Dial("127.0.0.1:4443", grpc.WithTransportCredentials(credsClient))
if err != nil {
return "", err
}
defer conn.Close()
client := helloworld.NewGreeterClient(conn)
name := "World"
r, err := client.SayHello(context.Background(), &helloworld.HelloRequest{Name: name})
if err != nil {
return "", err
}
return r.Message, nil
}
func (suite *GRPCSuite) TestGRPC(c *check.C) {
lis, err := net.Listen("tcp", ":0")
_, port, err := net.SplitHostPort(lis.Addr().String())
c.Assert(err, check.IsNil)
go func() {
err := startGRPCServer(lis)
c.Log(err)
c.Assert(err, check.IsNil)
}()
file := suite.adaptFile(c, "fixtures/grpc/config.toml", struct {
CertContent string
KeyContent string
GRPCServerPort string
}{
CertContent: string(LocalhostCert),
KeyContent: string(LocalhostKey),
GRPCServerPort: port,
})
defer os.Remove(file)
cmd, _ := suite.cmdTraefik(withConfigFile(file))
err = cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 1*time.Second, try.BodyContains("Host:127.0.0.1"))
c.Assert(err, check.IsNil)
var response string
err = try.Do(1*time.Second, func() error {
response, err = callHelloClientGRPC()
return err
})
c.Assert(err, check.IsNil)
c.Assert(response, check.Equals, "Hello World")
}

View file

@ -0,0 +1,164 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: helloworld.proto
/*
Package helloworld is a generated protocol buffer package.
It is generated from these files:
helloworld.proto
It has these top-level messages:
HelloRequest
HelloReply
*/
package helloworld
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// The request message containing the user's name.
type HelloRequest struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
}
func (m *HelloRequest) Reset() { *m = HelloRequest{} }
func (m *HelloRequest) String() string { return proto.CompactTextString(m) }
func (*HelloRequest) ProtoMessage() {}
func (*HelloRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *HelloRequest) GetName() string {
if m != nil {
return m.Name
}
return ""
}
// The response message containing the greetings
type HelloReply struct {
Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"`
}
func (m *HelloReply) Reset() { *m = HelloReply{} }
func (m *HelloReply) String() string { return proto.CompactTextString(m) }
func (*HelloReply) ProtoMessage() {}
func (*HelloReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *HelloReply) GetMessage() string {
if m != nil {
return m.Message
}
return ""
}
func init() {
proto.RegisterType((*HelloRequest)(nil), "helloworld.HelloRequest")
proto.RegisterType((*HelloReply)(nil), "helloworld.HelloReply")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for Greeter service
type GreeterClient interface {
// Sends a greeting
SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
}
type greeterClient struct {
cc *grpc.ClientConn
}
func NewGreeterClient(cc *grpc.ClientConn) GreeterClient {
return &greeterClient{cc}
}
func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) {
out := new(HelloReply)
err := grpc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Greeter service
type GreeterServer interface {
// Sends a greeting
SayHello(context.Context, *HelloRequest) (*HelloReply, error)
}
func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) {
s.RegisterService(&_Greeter_serviceDesc, srv)
}
func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(HelloRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GreeterServer).SayHello(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/helloworld.Greeter/SayHello",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Greeter_serviceDesc = grpc.ServiceDesc{
ServiceName: "helloworld.Greeter",
HandlerType: (*GreeterServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "SayHello",
Handler: _Greeter_SayHello_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "helloworld.proto",
}
func init() { proto.RegisterFile("helloworld.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 175 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xc8, 0x48, 0xcd, 0xc9,
0xc9, 0x2f, 0xcf, 0x2f, 0xca, 0x49, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x42, 0x88,
0x28, 0x29, 0x71, 0xf1, 0x78, 0x80, 0x78, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25, 0x42, 0x42,
0x5c, 0x2c, 0x79, 0x89, 0xb9, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x60, 0xb6, 0x92,
0x1a, 0x17, 0x17, 0x54, 0x4d, 0x41, 0x4e, 0xa5, 0x90, 0x04, 0x17, 0x7b, 0x6e, 0x6a, 0x71, 0x71,
0x62, 0x3a, 0x4c, 0x11, 0x8c, 0x6b, 0xe4, 0xc9, 0xc5, 0xee, 0x5e, 0x94, 0x9a, 0x5a, 0x92, 0x5a,
0x24, 0x64, 0xc7, 0xc5, 0x11, 0x9c, 0x58, 0x09, 0xd6, 0x25, 0x24, 0xa1, 0x87, 0xe4, 0x02, 0x64,
0xcb, 0xa4, 0xc4, 0xb0, 0xc8, 0x14, 0xe4, 0x54, 0x2a, 0x31, 0x38, 0x19, 0x70, 0x49, 0x67, 0xe6,
0xeb, 0xa5, 0x17, 0x15, 0x24, 0xeb, 0xa5, 0x56, 0x24, 0xe6, 0x16, 0xe4, 0xa4, 0x16, 0x23, 0xa9,
0x75, 0xe2, 0x07, 0x2b, 0x0e, 0x07, 0xb1, 0x03, 0x40, 0x5e, 0x0a, 0x60, 0x4c, 0x62, 0x03, 0xfb,
0xcd, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xb7, 0xcd, 0xf2, 0xef, 0x00, 0x00, 0x00,
}

View file

@ -0,0 +1,23 @@
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
package helloworld;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}

View file

@ -39,6 +39,7 @@ func init() {
check.Suite(&DynamoDBSuite{})
check.Suite(&ErrorPagesSuite{})
check.Suite(&WebsocketSuite{})
check.Suite(&GRPCSuite{})
}
var traefikBinary = "../dist/traefik"

View file

@ -0,0 +1,10 @@
# TLS certificate description
## local.crt / local.key
Generate with
```bash
go run $GOROOT/src/crypto/tls/generate_cert.go --rsa-bits 1024 --host 127.0.0.1,::1,localhost --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
mv cert.pem local.cert
mv key.pem local.key
```

View file

@ -0,0 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICEjCCAXugAwIBAgIRAKdsOQKo42YbSWoXHFxiMBwwDQYJKoZIhvcNAQELBQAw
EjEQMA4GA1UEChMHQWNtZSBDbzAgFw03MDAxMDEwMDAwMDBaGA8yMDg0MDEyOTE2
MDAwMFowEjEQMA4GA1UEChMHQWNtZSBDbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEA1YHPs3TZnMcIOManaIsv1qZ2I9FhbxOwP88tBH751IcYSwF5Qm40MOUq
sWvCMEFa+Bv5ke8E0ybX/za7eWz/hNg+FvTLbi+7c2fSkv+79w9554pzD22fb/mQ
LuYz/r/RpQguJSRh9cgpdRFY/zgzMWCqRGCC+MOin9D25pCAUJ8CAwEAAaNmMGQw
DgYDVR0PAQH/BAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQF
MAMBAf8wLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/AAABhxAAAAAAAAAAAAAAAAAA
AAABMA0GCSqGSIb3DQEBCwUAA4GBAEw7efpVsoNmJFc3tQAjHw3GW/N7co9iP/nY
g8gBYtbqQQapFCQ7/dPCNm+fZWjx05S9i/4c/c6sl2dR5lJLPtjG/2AY/LPNq7/N
/BU4KPVF+yi21SoK6GG09hnfbeT5xcvQxa+LNFiTNMHwzolgNhxxabxYPaOQZvyD
wZ6WZa5z
-----END CERTIFICATE-----

View file

@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDVgc+zdNmcxwg4xqdoiy/WpnYj0WFvE7A/zy0EfvnUhxhLAXlC
bjQw5Sqxa8IwQVr4G/mR7wTTJtf/Nrt5bP+E2D4W9MtuL7tzZ9KS/7v3D3nninMP
bZ9v+ZAu5jP+v9GlCC4lJGH1yCl1EVj/ODMxYKpEYIL4w6Kf0PbmkIBQnwIDAQAB
AoGAPkAO8t/K4u8U8pjZDp4mYItAPsk5g01WQgSBt6Hd7Z1F8/iGBlxjUy49+GTW
xYMIpvZhGa961KWqrHqkxo6FIQmhiuMRfk8JGH0c9ibe7rGP05EsJOWz/X2k//4A
xfl6P5POMNAbyS18dONQSzMYdMgYkuoiGH/A0tXMFRrRNgECQQDWOMXJiNJEHG0J
2ro+S2Mp0KTBMiVWh+Ee/yTgNIkpDXy45mCBx52vBm7/9sIDkol/XWGn/6cYD6bd
eRJIdkNBAkEA/yVbZYHvI4YO6XGdAUBFph+E5yklcXyWEQjKiFGdAEg+M1YRgZVX
0C3DdV34x3gW9wot3xWVtHPNSy3w6cv73wJAWaQoH81BL381oYoFpUumkzjbuHxj
Y3I4od/ibm+NdcBPEJBWkfgV48etay62wQfwwXsyAjrYkRj7mnGvVOMoAQJBAKFm
Dz/SBuVw2yP/E7OD5cslaxwTYjU8+20BI6VCA0/3Yyl0S5SuVSNCn78x17rOk7Bo
RwY0kEPbcUUaZahvuf8CQAQtu9hkyRo8jaEr+XLT3uhyBpon34nrbcSwK11lf7S6
ZQ60JoL3T0iridIinjDx/yL1A7anOfpSIiilNMFTfPQ=
-----END RSA PRIVATE KEY-----