coredns/plugin/proxy/grpc_test.go
Miek Gieben 643550eabe presubmit: check for uppercase (#1774)
Another thing we can test automatically, we sorta settled on using an
uppercase letter in in t.Log and t.Fatal calls.

Let's just check for this.
2018-05-07 23:47:25 +02:00

220 lines
6.4 KiB
Go

package proxy
import (
"context"
"fmt"
"testing"
"github.com/coredns/coredns/plugin/pkg/healthcheck"
"github.com/coredns/coredns/plugin/pkg/tls"
"github.com/coredns/coredns/plugin/test"
"github.com/coredns/coredns/request"
"github.com/miekg/dns"
"google.golang.org/grpc/grpclog"
)
func init() {
grpclog.SetLoggerV2(discardV2{})
}
func buildPool(size int) ([]*healthcheck.UpstreamHost, func(), error) {
ups := make([]*healthcheck.UpstreamHost, size)
srvs := []*dns.Server{}
errs := []error{}
for i := 0; i < size; i++ {
srv, addr, err := test.TCPServer("localhost:0")
if err != nil {
errs = append(errs, err)
continue
}
ups[i] = &healthcheck.UpstreamHost{Name: addr}
srvs = append(srvs, srv)
}
stopIt := func() {
for _, s := range srvs {
s.Shutdown()
}
}
if len(errs) > 0 {
go stopIt()
valErr := ""
for _, e := range errs {
valErr += fmt.Sprintf("%v\n", e)
}
return nil, nil, fmt.Errorf("Error at allocation of the pool : %v", valErr)
}
return ups, stopIt, nil
}
func TestGRPCStartupShutdown(t *testing.T) {
pool, closePool, err := buildPool(2)
if err != nil {
t.Fatalf("Error creating the pool of upstream for the test : %s", err)
}
defer closePool()
upstream := &staticUpstream{
from: ".",
HealthCheck: healthcheck.HealthCheck{
Hosts: pool,
},
}
g := newGrpcClient(nil, upstream)
upstream.ex = g
p := &Proxy{}
p.Upstreams = &[]Upstream{upstream}
err = g.OnStartup(p)
if err != nil {
t.Fatalf("Error starting grpc client exchanger: %s", err)
}
if len(g.clients) != len(pool) {
t.Fatalf("Expected %d grpc clients but found %d", len(pool), len(g.clients))
}
err = g.OnShutdown(p)
if err != nil {
t.Fatalf("Error stopping grpc client exchanger: %s", err)
}
if len(g.clients) != 0 {
t.Errorf("Shutdown didn't remove clients, found %d", len(g.clients))
}
if len(g.conns) != 0 {
t.Errorf("Shutdown didn't remove conns, found %d", len(g.conns))
}
}
func TestGRPCRunAQuery(t *testing.T) {
pool, closePool, err := buildPool(2)
if err != nil {
t.Fatalf("Error creating the pool of upstream for the test : %s", err)
}
defer closePool()
upstream := &staticUpstream{
from: ".",
HealthCheck: healthcheck.HealthCheck{
Hosts: pool,
},
}
g := newGrpcClient(nil, upstream)
upstream.ex = g
p := &Proxy{}
p.Upstreams = &[]Upstream{upstream}
err = g.OnStartup(p)
if err != nil {
t.Fatalf("Error starting grpc client exchanger: %s", err)
}
// verify the client is usable, or an error is properly raised
state := request.Request{W: &test.ResponseWriter{}, Req: new(dns.Msg)}
g.Exchange(context.TODO(), "localhost:10053", state)
// verify that you have proper error if the hostname is unknwn or not registered
_, err = g.Exchange(context.TODO(), "invalid:10055", state)
if err == nil {
t.Errorf("Expecting a proper error when querying gRPC client with invalid hostname : %s", err)
}
err = g.OnShutdown(p)
if err != nil {
t.Fatalf("Error stopping grpc client exchanger: %s", err)
}
}
func TestGRPCRunAQueryOnSecureLinkWithInvalidCert(t *testing.T) {
pool, closePool, err := buildPool(1)
if err != nil {
t.Fatalf("Error creating the pool of upstream for the test : %s", err)
}
defer closePool()
upstream := &staticUpstream{
from: ".",
HealthCheck: healthcheck.HealthCheck{
Hosts: pool,
},
}
filename, rmFunc, err := test.TempFile("", aCert)
if err != nil {
t.Errorf("Error saving file : %s", err)
return
}
defer rmFunc()
tls, _ := tls.NewTLSClientConfig(filename)
// ignore error as the certificate is known valid
g := newGrpcClient(tls, upstream)
upstream.ex = g
p := &Proxy{}
p.Upstreams = &[]Upstream{upstream}
// Although dial will not work, it is not expected to have an error
err = g.OnStartup(p)
if err != nil {
t.Fatalf("Error starting grpc client exchanger: %s", err)
}
// verify that you have proper error if the hostname is unknwn or not registered
state := request.Request{W: &test.ResponseWriter{}, Req: new(dns.Msg)}
_, err = g.Exchange(context.TODO(), pool[0].Name+"-whatever", state)
if err == nil {
t.Errorf("Error in Exchange process : %s ", err)
}
err = g.OnShutdown(p)
if err != nil {
t.Fatalf("Error stopping grpc client exchanger: %s", err)
}
}
// discard is a Logger that outputs nothing.
type discardV2 struct{}
func (d discardV2) Info(args ...interface{}) {}
func (d discardV2) Infoln(args ...interface{}) {}
func (d discardV2) Infof(format string, args ...interface{}) {}
func (d discardV2) Warning(args ...interface{}) {}
func (d discardV2) Warningln(args ...interface{}) {}
func (d discardV2) Warningf(format string, args ...interface{}) {}
func (d discardV2) Error(args ...interface{}) {}
func (d discardV2) Errorln(args ...interface{}) {}
func (d discardV2) Errorf(format string, args ...interface{}) {}
func (d discardV2) Fatal(args ...interface{}) {}
func (d discardV2) Fatalln(args ...interface{}) {}
func (d discardV2) Fatalf(format string, args ...interface{}) {}
func (d discardV2) V(l int) bool { return true }
const (
aCert = `-----BEGIN CERTIFICATE-----
MIIDlDCCAnygAwIBAgIJAPaRnBJUE/FVMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTcxMTI0MTM0OTQ3WhcNMTgxMTI0MTM0OTQ3WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAuTDeAoWS6tdZVcp/Vh3FlagbC+9Ohi5VjRXgkpcn9JopbcF5s2jpl1v+
cRpqkrmNNKLh8qOhmgdZQdh185VNe/iZ94H42qwKZ48vvnC5hLkk3MdgUT2ewgup
vZhy/Bb1bX+buCWkQa1u8SIilECMIPZHhBP4TuBUKJWK8bBEFAeUnxB5SCkX+un4
pctRlcfg8sX/ghADnp4e//YYDqex+1wQdFqM5zWhWDZAzc5Kdkyy9r+xXNfo4s1h
fI08f6F4skz1koxG2RXOzQ7OK4YxFwT2J6V72iyzUIlRGZTbYDvair/zm1kjTF1R
B1B+XLJF9oIB4BMZbekf033ZVaQ8YwIDAQABo4GGMIGDMDMGA1UdEQQsMCqHBH8A
AAGHBDR3AQGHBDR3AQCHBDR3KmSHBDR3KGSHBDR3KmWHBDR3KtIwHQYDVR0OBBYE
FFAEccLm7D/rN3fEe1fwzH7p0spAMB8GA1UdIwQYMBaAFFAEccLm7D/rN3fEe1fw
zH7p0spAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAF4zqaucNcK2
GwYfijwbbtgMqPEvbReUEXsC65riAPjksJQ9L2YxQ7K0RIugRizuD1DNQam+FSb0
cZEMEKzvMUIexbhZNFINWXY2X9yUS/oZd5pWP0WYIhn6qhmLvzl9XpxNPVzBXYWe
duMECCigU2x5tAGmFa6g/pXXOoZCBRzFXwXiuNhSyhJEEwODjLZ6vgbySuU2jso3
va4FKFDdVM16s1/RYOK5oM48XytCMB/JoYoSJHPfpt8LpVNAQEHMvPvHwuZBON/z
q8HFtDjT4pBpB8AfuzwtUZ/zJ5atwxa5+ahcqRnK2kX2RSINfyEy43FZjLlvjcGa
UIRTUJK1JKg=
-----END CERTIFICATE-----`
)