Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add helloworld tests with gRPC #1845

Merged
merged 7 commits into from Aug 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 29 additions & 0 deletions integration/fixtures/grpc/config.toml
@@ -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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline missing.

114 changes: 114 additions & 0 deletions integration/grpc_test.go
@@ -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()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to defer-stop here? Don't we need the server to continue running past the the return of this method?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s.Serve at the end of this method will block so it make sense

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah gotcha 👍


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")
}
164 changes: 164 additions & 0 deletions integration/helloworld/helloworld.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions integration/helloworld/helloworld.proto
@@ -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;
}
1 change: 1 addition & 0 deletions integration/integration_test.go
Expand Up @@ -39,6 +39,7 @@ func init() {
check.Suite(&DynamoDBSuite{})
check.Suite(&ErrorPagesSuite{})
check.Suite(&WebsocketSuite{})
check.Suite(&GRPCSuite{})
}

var traefikBinary = "../dist/traefik"
Expand Down
10 changes: 10 additions & 0 deletions integration/resources/tls/README.md
@@ -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
```
14 changes: 14 additions & 0 deletions integration/resources/tls/local.cert
@@ -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-----
15 changes: 15 additions & 0 deletions integration/resources/tls/local.key
@@ -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-----