Skip to content

Commit

Permalink
Merge pull request #5 from ncbi/release/1.1.0
Browse files Browse the repository at this point in the history
Release/1.1.0
  • Loading branch information
koiuo authored Jan 30, 2018
2 parents a4972e2 + a13e59a commit b76fc25
Show file tree
Hide file tree
Showing 10 changed files with 708 additions and 153 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Changelog

## 1.1.0 - 2018-01-30

### Added

- TLS support

`--tls` verify server with CA certificates installed on this system
`--tls-insecure` do NOT verify server (accept any certificate)
`--tls-cafile value` verify server with CA certificate stored in specified file
`--tls-capath value` verify server with CA certificates located under specified path
- Windows build

### Changed

- `--timeout` option now affects both dialing to server and RPC call (before that dialing had hard-coded 1s timeout)
- more descriptive messages are printed out in case of failure

## 1.0.0 - 2017-12-13

### Added
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ bin: deps ${BINARY}
release: release/gprobe-linux-amd64-${VERSION}.tar.gz
release: release/gprobe-linux-386-${VERSION}.tar.gz
release: release/gprobe-darwin-amd64-${VERSION}.tar.gz
release: release/gprobe-windows-amd64-${VERSION}.tar.gz

.PHONY: release-dir
release-dir:
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,16 @@ Get help
gprobe -h
```

## Building
## Building from source

Valid _go_ environment is required to build `gprobe` (`go` is in `PATH`, `GOPATH` is set, etc.).

Clone code into valid `GOPATH` location

```bash
git clone git@github.com:ncbi/gprobe.git $GOPATH/src/github.com/ncbi/gprobe
```

Build distributable tarballs for all OSes

```bash
Expand All @@ -56,7 +62,7 @@ This project follows git-flow branching model. All development is done off of th

To contribute:

1. Create a feature branch from the latest `develop`, commit your work there
1. Fork or create a feature branch from the latest `develop`, commit your work there
```bash
git checkout develop
git pull
Expand Down
52 changes: 52 additions & 0 deletions acctest/key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDP1dCRnLuw2Jo2
1GoCOdunHC3uBjUUTI0CGog+9RP2gsNgGdNHM77Htg6Qjrs51PngkYpC5GFpfkbx
6CaFYpsPOWyJcdUnDnieDhMTHMu7PwHKWf1hgSJxoiNbQKjNH+sJTW+au3pshuoX
JMl0uibis+pyRtfD3MK5wanASlmEC2ldyiEXW8JZgARY94/R7/c7AIMsH1YJq4PR
CJ8pQmaV7xSrlT+/r+bB9JtBNTFkehaC/D1hf7IihcCwlanHgGiVJdPpprX+CASM
8EVrXNmm55Xq+edSc4yHeb2l8AH8OXrsDfNNwuVv1f70PTmae7WgKdXfLR1avDUf
oDxCPoAoVgncl5e6Wm0zGFVzuJtHl+tgyzFqwduXjnm7MGY/0IODFaS37DKxxaFC
Ff5y1TuaIeOZZBzt1+2RDFw5vOajB/SL76VgM06qi+TW9hCES4jAS6H56KUP0Rpl
MxRCe7mRU+2w8+RuOhJKtjT8YPPWCP3NfvfS/iCsk9OIOuJQycdonXs7pfruvftA
/Y1j8gRhrExauIeIYGIaq4KRolKQDaAUQd2EFg95UVVpTpEZL9bYM/YBDccH+W8B
hgo6N2n0eUEFqiclWFtvAN1vAAMTe1/CjYh41HkqIlxA51rJ+7tekRd8xr2BrKKc
9Vu1POmTGdrjr30OET8+6jzdL5MwewIDAQABAoICAQCUMKeDe9bUVM04tSJVLf3x
XIVfR2vHaoHMczCce1DdnwVB24grJ7krWyNtbWgP50y4E+4ang7bEl/xko8M4m8f
XtmF8vWB4K6eO/jb0tdtTpKvPpUNVe9CSNKe+S6i+9QxkNY35N94zIXTNLa0FRsu
4AwVqW+lRx5NJsorwperMBvT9RC9P/8Go+H1sacJkOmeV1IwPrOxN2tIu7YIzECr
PYpmgYev3PNTbl7ZEt2CAA9XHBWEFHHmbaoj/sLM7kEjv5Im8minlf3wpE1LLSw/
9raNkdyfjKYx3tsbm1M/DZkZASVvV70Sjeo5KgKNpRGu/sVxWRCqJrJWN4Ff1oK3
dXi1zdoC56mNsqDLaHftFBy6T85UlNJhvXrNxr9JI8SaflCBgLrV1yT+5SkYjc4t
xqAAl18TFk3eZL7Wf4rK6Z9c1NlUW/H44OHgd3sUQMdmbaKhT9eyxlohdMTl7ly/
l2fczZGoaX4dwNvrw6MQGFC/J4e7x2FARTm6UAbVeJ9hqwx3qY02MgCVO8ZhCdPk
aJ7rxFUIdhYHY84sGN27zxjx4ja7b/NdEB8glVXewPpWuZbngLMgWvlLGsLdQfoS
DZmXT4B6AwA/6DW2tMKMYAv+yud5VmeiXQ9vRkuwT4lHLY9CcoFbl63PIkeeKDHe
+9r7mkbUtmOgiw8qRcDJeQKCAQEA/sU7oKemdKl9HXnheNh+ql3C9/t1OaHkHlKv
g964r2rjIpYhiNS59kmXizA1KEJAmk2BZfV7gSuarbGU8v4WAcQQUEJ/c0aqf02K
7XfH/dIEf2C3IngTYybN08Eq8uQNyrNsXcIYCEjY9vDedouP0J5kZN+e66Aqxj8/
dp3nvIt8XL/0eGwq5xa6tJwhX3EzGim34Hv4Ifb0TGeko52fah1oCAfqmYRMJlH6
zJhBhCH7IszlqItx3t6+KEg4dUIx1Yi4nh7XI9zQg+fzssh9kDeBsbpCRnUPat9m
FgCLsZRaQYTW50xt3DTEYS8sGzjfmrhXXHEDek/oZwvZAr1k3wKCAQEA0NaX+hmP
vQvqBhBVYfSH/KAU9JCyF5yWoMJlJOOyb4ryUU1Fs3cAS8vMCUkRcZK/Q7icpm4r
k+3/2BPZeOzWhSOGJTvJ1oSsS9cmuq4MSJDmDXP4G0FS7uAKOj1HUjXwd7dWrHvE
IlW9PrvVNXOLedzA8k45ZCQRBawsLoaBJg64EZsLc87PEECxGiSBiN4aabr191xc
J5IqF51P6D2mUdhnf6GZvBmBTtzs9ocmGEV5Efv/VO/CcgL5kQOOR7jpB0lIIHwF
2WjLLalEQ1r6iBQSYswXdcTQT5MYX+DxXFv//qePFuaM1O4c3G4ODhJrGHsez1EN
g4uFnKmBoBmr5QKCAQAY3S7gkvwPzqrDQa3bmWVjQxtQEF50bXRR8Ufn2sizdf8M
1RIYxIoRm0UK9H17nFups365cKfJB3RlFzuuK1YCfhwJeTPvECp7mhnA6zu9bc26
kLnOx2E9AAB+dg+2/MLL0Y7154do55MlJoTPlPdIKO0rWxerb0o9ZtbOwMJpCEPu
2V0Gk6fsPa+jCMnJAsc1+nRTmEWzKuLUwhizTyLLvGr2va8LpHm6E64iYYmjV52m
29BeDp3iXmK4k7PO3dL3QAykgeYFPfuro+uIu0Bl3sTtj3wAXFRQ3dScuRjpD81v
L4O5tx/RqeSwh2YKkhZghzUfdHgea8YGqIVZWxqJAoIBAQDGyn8AYzSgD6dE/mdI
RyzrHLbV1qawMy5u+Jyu8M/5vZnMKnIe0zhE7knazOL96WKHZEQ5aMWymurfFIX+
xfOt6JLY/oCy4rffuX30VZj7unJCfBHAX/5BxKH3rj0l1JKCYtLufSHGTTdHcCUU
LFioN6qy/CNFX8+URsAHyaFGSNyOZbgRFNul7O6oo/dqAYHDA2T/gbt3L3tB300h
FQ4s+oIKzBk7JEwidcpbIWrxz6/fnrD+ePvu60YE9A2L2Eh51xgBVA19VnORk36X
XxL8VZ7qzLvILwDbvnmFSup1sF2OWpGqiuukBMUUTu6yFnY7Z3d8gPsMLNOSvQfX
DpjBAoIBAAGrx9X6JFCz0rE3fSyZVr9+tYVcz0kt+B9a3bN08/szO7c6xBbGeaRS
5wrTVomMeiQWd5q7xttAB+XhqqnJqoPt+tDJj5CA239lNHFCOv+ayk0f5Luequ2B
hI8ylsa17oPKrPj+wR1WHfMQg6F+hFay29Kz9usQJY0ciXb1pE31Qm28ldnAiWX0
hO98do3+E5mS/XcTuerXTRQoctFaXeYVx5tV6XHYth0kULAdEX5/z6ZvGXFS7K/3
V608CusCn3MsRYjFoRTHOL2LswhM4yGbJBcMg+tVCpS6K4nwBCbf/+ro/1oKrm8f
LiCYg6qO9tI/KXTUZjr6VMtlZ13CAEY=
-----END PRIVATE KEY-----
206 changes: 161 additions & 45 deletions acctest/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,108 +22,226 @@ package acctest

import (
"bytes"
"flag"
"fmt"
"github.com/stretchr/testify/assert"
"google.golang.org/grpc"
"google.golang.org/grpc/health"
hv1 "google.golang.org/grpc/health/grpc_health_v1"
"io"
"log"
"net"
"os"
"os/exec"
"syscall"
"testing"
"flag"

hv1 "google.golang.org/grpc/health/grpc_health_v1"
)

var (
port int
listenAddr string
bin string
port int
caFile string
caPath string
key string
bin string
stubSrvAddr string
)

func startServer() net.Listener {
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
if err != nil {
log.Fatalf("failed to listen: %v", err)
}

grpcServer := grpc.NewServer()
server := health.NewServer()
hv1.RegisterHealthServer(grpcServer, server)

server.SetServingStatus("foo", hv1.HealthCheckResponse_SERVING)
server.SetServingStatus("bar", hv1.HealthCheckResponse_NOT_SERVING)
go grpcServer.Serve(listener)
return listener
}

func init() {
flag.IntVar(&port, "stub-port", 54321, "port for the stub server")
flag.StringVar(&bin, "gprobe", "", "path to the gprobe binary")
flag.StringVar(&caFile, "stub-cafile", "x509/certificate.pem", "path to the x509 certificate file")
flag.StringVar(&caPath, "stub-capath", "x509/", "path to the x509 certificates dir")
flag.StringVar(&key, "stub-key", "key.pem", "path to the stub server private key")
flag.StringVar(&bin, "gprobe", "../gprobe", "path to the gprobe binary")
}

func TestMain(m *testing.M) {
flag.Parse()
listenAddr = fmt.Sprintf("%s:%d", "localhost", port)

lis := startServer()
result := 0
defer func() {
lis.Close()
os.Exit(result)
}()

result = m.Run()
stubSrvAddr = fmt.Sprintf("%s:%d", "localhost", port)
os.Exit(m.Run())
}

func TestShouldReturnServingForRunningServer(t *testing.T) {
stdout, stderr, exitcode := runBin(t, listenAddr)
// given
srv, _, err := StartInsecureServer(port)
if err != nil {
log.Fatalf("can't start stub server: %v", err)
}
defer srv.GracefulStop()

// when
stdout, stderr, exitcode := runBin(t, stubSrvAddr)

assert.Equal(t, 0, exitcode)
assert.Equal(t, "SERVING\n", stdout)
assert.Empty(t, stderr)
}

func TestShouldFailIfServerIsNotListening(t *testing.T) {
stdout, stderr, exitcode := runBin(t, "nosuchhost:1234")
// given no server

// when
stdout, stderr, exitcode := runBin(t, stubSrvAddr)

// then
assert.Equal(t, 127, exitcode)
assert.Empty(t, stdout)
assert.Contains(t, stderr, "application isn't listening")
}

func TestShouldFailIfServerDoesNotImplementHealthCheckProtocol(t *testing.T) {
// given
srv, err := StartEmptyServer(port)
if err != nil {
log.Fatalf("can't start stub server: %v", err)
}
defer srv.GracefulStop()

// when
stdout, stderr, exitcode := runBin(t, stubSrvAddr)

// then
assert.Equal(t, 127, exitcode)
assert.Empty(t, stdout)
assert.Contains(t, stderr, "error", "should print status to STDOUT")
assert.Equal(t, stderr, "rpc error: server doesn't implement gRPC health-checking protocol\n")
}

func TestShouldReturnServingForHealthyService(t *testing.T) {
stdout, stderr, exitcode := runBin(t, listenAddr, "foo")
// given
srv, svc, err := StartInsecureServer(port)
if err != nil {
log.Fatalf("can't start stub server: %v", err)
}
defer srv.GracefulStop()
svc.SetServingStatus("foo", hv1.HealthCheckResponse_SERVING)

// when
stdout, stderr, exitcode := runBin(t, stubSrvAddr, "foo")

// then
assert.Equal(t, 0, exitcode)
assert.Equal(t, "SERVING\n", stdout)
assert.Empty(t, stderr)
}

func TestShouldReturnNotServingForUnhealthyService(t *testing.T) {
stdout, stderr, exitcode := runBin(t, listenAddr, "bar")
// given
srv, svc, err := StartInsecureServer(port)
if err != nil {
log.Fatalf("can't start stub server: %v", err)
}
defer srv.GracefulStop()
svc.SetServingStatus("foo", hv1.HealthCheckResponse_NOT_SERVING)

// when
stdout, stderr, exitcode := runBin(t, stubSrvAddr, "foo")

// then
assert.Equal(t, 2, exitcode)
assert.Equal(t, "NOT_SERVING\n", stdout)
assert.Contains(t, stderr, "health-check failed")
}

func TestShouldNotFailForUnhealthyServiceIfNoFailIsSet(t *testing.T) {
stdout, stderr, exitcode := runBin(t, "--no-fail", listenAddr, "bar")
// given
srv, svc, err := StartInsecureServer(port)
if err != nil {
log.Fatalf("can't start stub server: %v", err)
}
defer srv.GracefulStop()
svc.SetServingStatus("foo", hv1.HealthCheckResponse_NOT_SERVING)

// when
stdout, stderr, exitcode := runBin(t, "--no-fail", stubSrvAddr, "foo")

// then
assert.Equal(t, 0, exitcode)
assert.Equal(t, "NOT_SERVING\n", stdout)
assert.Empty(t, stderr)
}

func TestShouldFailIfServiceHealthCheckIsNotRegistered(t *testing.T) {
stdout, stderr, exitcode := runBin(t, listenAddr, "non_registered_service")
// given
srv, _, err := StartInsecureServer(port)
if err != nil {
log.Fatalf("can't start stub server: %v", err)
}
defer srv.GracefulStop()

// when
stdout, stderr, exitcode := runBin(t, stubSrvAddr, "my.service.Foo")

// then
assert.Equal(t, 127, exitcode)
assert.Empty(t, stdout)
assert.Contains(t, stderr, "NotFound")
assert.Equal(t, stderr, "rpc error: unknown service my.service.Foo\n")
}

// TLS tests

func TestShouldFailOnTlsVerificationWithSelfSignedCert(t *testing.T) {
// given
srv, _, err := StartServer(port, caFile, key)
if err != nil {
log.Fatalf("can't start stub server: %v", err)
}
defer srv.GracefulStop()

// when
stdout, stderr, exitcode := runBin(t, "--tls", stubSrvAddr)

// then
assert.Equal(t, 127, exitcode)
assert.Empty(t, stdout)
assert.Contains(t, stderr, "TLS handshake failed")
}

func TestShouldBeAbleToSkipTlsVerification(t *testing.T) {
// given
srv, _, err := StartServer(port, caFile, key)
if err != nil {
log.Fatalf("can't start stub server: %v", err)
}
defer srv.GracefulStop()

// when
stdout, stderr, exitcode := runBin(t, "--tls-insecure", stubSrvAddr)

// then
assert.Equal(t, 0, exitcode)
assert.Equal(t, "SERVING\n", stdout)
assert.Empty(t, stderr)
}

func TestShouldBeAbleToSetCustomCAFile(t *testing.T) {
// given
srv, _, err := StartServer(port, caFile, key)
if err != nil {
log.Fatalf("can't start stub server: %v", err)
}
defer srv.GracefulStop()

// when
stdout, stderr, exitcode := runBin(t, "--tls-cafile", caFile, stubSrvAddr)

// then
assert.Equal(t, 0, exitcode)
assert.Equal(t, "SERVING\n", stdout)
assert.Empty(t, stderr)
}

func TestShouldBeAbleToSetCustomCAPath(t *testing.T) {
// given
srv, _, err := StartServer(port, caFile, key)
if err != nil {
log.Fatalf("can't start stub server: %v", err)
}
defer srv.GracefulStop()

// when
stdout, stderr, exitcode := runBin(t, "--tls-capath", caPath, stubSrvAddr)

// then
assert.Equal(t, 0, exitcode)
assert.Equal(t, "SERVING\n", stdout)
assert.Empty(t, stderr)
}

func runBin(t *testing.T, args ...string) (stdout string, stderr string, exitcode int) {
Expand Down Expand Up @@ -166,5 +284,3 @@ func waitForExitCode(t *testing.T, cmd *exec.Cmd) (exitcode int) {
}
return
}


Loading

0 comments on commit b76fc25

Please sign in to comment.