Refactor testing into docker file
This means a decent scale refactor but ends with our testing being much simpler Key changes: * single Dockerfile for all services * tests moved into docker up so don't need to be run locally * configurations moved to environment
This commit is contained in:
parent
99da6c5d67
commit
14424c16ca
13 changed files with 171 additions and 107 deletions
|
@ -6,9 +6,11 @@ COPY . .
|
|||
RUN go mod download
|
||||
|
||||
# For /usr/share/dict/words
|
||||
RUN apt-get update && apt-get install -y wamerican
|
||||
RUN apt-get -q update && apt-get -qy install wamerican
|
||||
|
||||
# Build both executables
|
||||
RUN go build -o rove-server -ldflags="-X 'github.com/mdiluz/rove/pkg/version.Version=$(git describe --always --long --dirty --tags)'" cmd/rove-server/main.go
|
||||
RUN go build -o rove-accountant -ldflags="-X 'github.com/mdiluz/rove/pkg/version.Version=$(git describe --always --long --dirty --tags)'" cmd/rove-accountant/main.go
|
||||
|
||||
CMD [ "./rove-server" ]
|
||||
|
19
Makefile
19
Makefile
|
@ -12,22 +12,9 @@ gen:
|
|||
protoc --proto_path pkg/accounts --go_out=plugins=grpc:pkg/accounts/ --go_opt=paths=source_relative pkg/accounts/accounts.proto
|
||||
|
||||
test:
|
||||
go mod download
|
||||
go build ./...
|
||||
docker-compose up --build --exit-code-from=rove-tests --abort-on-container-exit
|
||||
|
||||
# Run the server and shut it down again to ensure our docker-compose works
|
||||
ROVE_ARGS="--quit 1" docker-compose up --build --exit-code-from=rove-server --abort-on-container-exit
|
||||
|
||||
# Run the server and shut it down again to ensure our docker-compose works
|
||||
docker-compose up -d
|
||||
|
||||
# Run tests with coverage and integration tags
|
||||
go test -v ./... --tags=integration -cover -coverprofile=/tmp/c.out -count 1
|
||||
|
||||
#
|
||||
docker-compose down
|
||||
|
||||
# Convert the coverage data to html
|
||||
go tool cover -html=/tmp/c.out -o /tmp/coverage.html
|
||||
# TODO: Collect and convert the coverage data to html
|
||||
# go tool cover -html=/tmp/c.out -o /tmp/coverage.html
|
||||
|
||||
.PHONY: install test
|
|
@ -1,11 +0,0 @@
|
|||
FROM golang:latest
|
||||
LABEL maintainer="Marc Di Luzio <marc.diluzio@gmail.com>"
|
||||
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN go mod download
|
||||
|
||||
RUN go build -o rove-accountant -ldflags="-X 'github.com/mdiluz/rove/pkg/version.Version=$(git describe --always --long --dirty --tags)'" cmd/rove-accountant/main.go
|
||||
|
||||
CMD [ "./rove-accountant" ]
|
||||
|
|
@ -2,7 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
|
@ -17,8 +16,8 @@ import (
|
|||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
var address = flag.String("address", "", "port to server the accountant on")
|
||||
var data = flag.String("data", os.TempDir(), "path to persistent data")
|
||||
var address = os.Getenv("HOST_ADDRESS")
|
||||
var data = os.Getenv("DATA_PATH")
|
||||
|
||||
// accountantServer is the internal object to manage the requests
|
||||
type accountantServer struct {
|
||||
|
@ -83,14 +82,12 @@ func (a *accountantServer) GetValue(_ context.Context, in *accounts.DataKey) (*a
|
|||
|
||||
// main
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
// Verify the input
|
||||
if len(*address) == 0 {
|
||||
log.Fatal("No address set with --address")
|
||||
if len(address) == 0 {
|
||||
log.Fatal("No address set with $HOST_ADDRESS")
|
||||
}
|
||||
|
||||
persistence.SetPath(*data)
|
||||
persistence.SetPath(data)
|
||||
|
||||
// Initialise and load the accountant
|
||||
accountant := &internal.Accountant{}
|
||||
|
@ -99,7 +96,7 @@ func main() {
|
|||
}
|
||||
|
||||
// Set up the RPC server and register
|
||||
lis, err := net.Listen("tcp", *address)
|
||||
lis, err := net.Listen("tcp", address)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to listen: %v", err)
|
||||
}
|
||||
|
@ -118,7 +115,7 @@ func main() {
|
|||
}()
|
||||
|
||||
// Serve the RPC server
|
||||
fmt.Printf("Serving accountant on %s\n", *address)
|
||||
fmt.Printf("Serving accountant on %s\n", address)
|
||||
if err := grpcServer.Serve(lis); err != nil {
|
||||
log.Fatalf("failed to server gRPC: %s", err)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
// +build integration
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
|
@ -11,30 +12,17 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// To be set by the main function
|
||||
var serv rove.Server
|
||||
const (
|
||||
defaultAddress = "localhost:80"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
s := NewServer()
|
||||
if err := s.Initialise(true); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
serv = rove.Server(s.Addr())
|
||||
|
||||
go s.Run()
|
||||
|
||||
fmt.Printf("Test server hosted on %s", serv)
|
||||
code := m.Run()
|
||||
|
||||
if err := s.StopAndClose(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
os.Exit(code)
|
||||
var serv = func() rove.Server {
|
||||
var address = os.Getenv("ROVE_SERVER_ADDRESS")
|
||||
if len(address) == 0 {
|
||||
address = defaultAddress
|
||||
}
|
||||
return rove.Server(address)
|
||||
}()
|
||||
|
||||
func TestServer_Status(t *testing.T) {
|
||||
status, err := serv.Status()
|
||||
|
|
|
@ -6,11 +6,13 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/mdiluz/rove/pkg/accounts"
|
||||
"github.com/mdiluz/rove/pkg/rove"
|
||||
"github.com/mdiluz/rove/pkg/version"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// Handler describes a function that handles any incoming request and can respond
|
||||
|
@ -87,8 +89,10 @@ func HandleRegister(s *Server, vars map[string]string, b io.ReadCloser, w io.Wri
|
|||
response.Error = "Cannot register empty name"
|
||||
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
reg := accounts.RegisterInfo{Name: data.Name}
|
||||
if acc, err := s.accountant.Register(context.Background(), ®); err != nil {
|
||||
if acc, err := s.accountant.Register(ctx, ®, grpc.WaitForReady(true)); err != nil {
|
||||
response.Error = err.Error()
|
||||
|
||||
} else if !acc.Success {
|
||||
|
@ -125,11 +129,13 @@ func HandleCommand(s *Server, vars map[string]string, b io.ReadCloser, w io.Writ
|
|||
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
key := accounts.DataKey{Account: id, Key: "rover"}
|
||||
if len(id) == 0 {
|
||||
response.Error = "No account ID provided"
|
||||
|
||||
} else if resp, err := s.accountant.GetValue(context.Background(), &key); err != nil {
|
||||
} else if resp, err := s.accountant.GetValue(ctx, &key); err != nil {
|
||||
response.Error = fmt.Sprintf("Provided account has no rover: %s", err)
|
||||
|
||||
} else if !resp.Success {
|
||||
|
@ -155,12 +161,14 @@ func HandleRadar(s *Server, vars map[string]string, b io.ReadCloser, w io.Writer
|
|||
Success: false,
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
id := vars["account"]
|
||||
key := accounts.DataKey{Account: id, Key: "rover"}
|
||||
if len(id) == 0 {
|
||||
response.Error = "No account ID provided"
|
||||
|
||||
} else if resp, err := s.accountant.GetValue(context.Background(), &key); err != nil {
|
||||
} else if resp, err := s.accountant.GetValue(ctx, &key); err != nil {
|
||||
response.Error = fmt.Sprintf("Provided account has no rover: %s", err)
|
||||
|
||||
} else if !resp.Success {
|
||||
|
@ -191,12 +199,14 @@ func HandleRover(s *Server, vars map[string]string, b io.ReadCloser, w io.Writer
|
|||
Success: false,
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
id := vars["account"]
|
||||
key := accounts.DataKey{Account: id, Key: "rover"}
|
||||
if len(id) == 0 {
|
||||
response.Error = "No account ID provided"
|
||||
|
||||
} else if resp, err := s.accountant.GetValue(context.Background(), &key); err != nil {
|
||||
} else if resp, err := s.accountant.GetValue(ctx, &key); err != nil {
|
||||
response.Error = fmt.Sprintf("Provided account has no rover: %s", err)
|
||||
|
||||
} else if !resp.Success {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// +build integration
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
|
@ -9,6 +11,7 @@ import (
|
|||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/mdiluz/rove/pkg/accounts"
|
||||
"github.com/mdiluz/rove/pkg/game"
|
||||
"github.com/mdiluz/rove/pkg/rove"
|
||||
|
@ -39,7 +42,7 @@ func TestHandleStatus(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestHandleRegister(t *testing.T) {
|
||||
data := rove.RegisterData{Name: "one"}
|
||||
data := rove.RegisterData{Name: uuid.New().String()}
|
||||
b, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -57,22 +60,24 @@ func TestHandleRegister(t *testing.T) {
|
|||
json.NewDecoder(response.Body).Decode(&status)
|
||||
|
||||
if status.Success != true {
|
||||
t.Errorf("got false for /register")
|
||||
t.Errorf("got false for /register: %s", status.Error)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleCommand(t *testing.T) {
|
||||
name := uuid.New().String()
|
||||
s := NewServer()
|
||||
s.Initialise(false) // Leave the world empty with no obstacles
|
||||
reg := accounts.RegisterInfo{Name: "test"}
|
||||
reg := accounts.RegisterInfo{Name: name}
|
||||
acc, err := s.accountant.Register(context.Background(), ®)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, acc.Success)
|
||||
assert.NotNil(t, acc)
|
||||
assert.True(t, acc.Success, acc.Error)
|
||||
|
||||
assert.NoError(t, err, "Error registering account")
|
||||
|
||||
// Spawn the rover rover for the account
|
||||
_, inst, err := s.SpawnRoverForAccount("test")
|
||||
_, inst, err := s.SpawnRoverForAccount(name)
|
||||
assert.NoError(t, s.world.WarpRover(inst, vector.Vector{}))
|
||||
|
||||
attribs, err := s.world.RoverAttributes(inst)
|
||||
|
@ -91,7 +96,7 @@ func TestHandleCommand(t *testing.T) {
|
|||
b, err := json.Marshal(data)
|
||||
assert.NoError(t, err, "Error marshalling data")
|
||||
|
||||
request, _ := http.NewRequest(http.MethodPost, path.Join("/", "test", "/command"), bytes.NewReader(b))
|
||||
request, _ := http.NewRequest(http.MethodPost, path.Join("/", name, "/command"), bytes.NewReader(b))
|
||||
response := httptest.NewRecorder()
|
||||
|
||||
s.router.ServeHTTP(response, request)
|
||||
|
@ -118,16 +123,17 @@ func TestHandleCommand(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestHandleRadar(t *testing.T) {
|
||||
name := uuid.New().String()
|
||||
s := NewServer()
|
||||
s.Initialise(false) // Spawn a clean world
|
||||
reg := accounts.RegisterInfo{Name: "test"}
|
||||
reg := accounts.RegisterInfo{Name: name}
|
||||
acc, err := s.accountant.Register(context.Background(), ®)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, acc.Success)
|
||||
assert.True(t, acc.Success, acc.Error)
|
||||
assert.NoError(t, err, "Error registering account")
|
||||
|
||||
// Spawn the rover rover for the account
|
||||
attrib, id, err := s.SpawnRoverForAccount("test")
|
||||
attrib, id, err := s.SpawnRoverForAccount(name)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Warp this rover to 0,0
|
||||
|
@ -143,7 +149,7 @@ func TestHandleRadar(t *testing.T) {
|
|||
assert.NoError(t, s.world.Atlas.SetTile(rockPos, game.TileRock))
|
||||
assert.NoError(t, s.world.Atlas.SetTile(emptyPos, game.TileEmpty))
|
||||
|
||||
request, _ := http.NewRequest(http.MethodGet, path.Join("/", "test", "/radar"), nil)
|
||||
request, _ := http.NewRequest(http.MethodGet, path.Join("/", name, "/radar"), nil)
|
||||
response := httptest.NewRecorder()
|
||||
|
||||
s.router.ServeHTTP(response, request)
|
||||
|
@ -175,18 +181,19 @@ func TestHandleRadar(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestHandleRover(t *testing.T) {
|
||||
name := uuid.New().String()
|
||||
s := NewServer()
|
||||
s.Initialise(true)
|
||||
reg := accounts.RegisterInfo{Name: "test"}
|
||||
reg := accounts.RegisterInfo{Name: name}
|
||||
acc, err := s.accountant.Register(context.Background(), ®)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, acc.Success)
|
||||
assert.True(t, acc.Success, acc.Error)
|
||||
|
||||
// Spawn one rover for the account
|
||||
attribs, _, err := s.SpawnRoverForAccount("test")
|
||||
attribs, _, err := s.SpawnRoverForAccount(name)
|
||||
assert.NoError(t, err)
|
||||
|
||||
request, _ := http.NewRequest(http.MethodGet, path.Join("/", "test", "/rover"), nil)
|
||||
request, _ := http.NewRequest(http.MethodGet, path.Join("/", name, "/rover"), nil)
|
||||
response := httptest.NewRecorder()
|
||||
|
||||
s.router.ServeHTTP(response, request)
|
||||
|
|
|
@ -3,11 +3,11 @@ package internal
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
@ -20,7 +20,7 @@ import (
|
|||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
var accountantAddress = flag.String("accountant", "", "address of the accountant to connect to")
|
||||
var accountantAddress = os.Getenv("ACCOUNTANT_ADDRESS")
|
||||
|
||||
const (
|
||||
// PersistentData will allow the server to load and save it's state
|
||||
|
@ -116,12 +116,12 @@ func (s *Server) Initialise(fillWorld bool) (err error) {
|
|||
s.sync.Add(1)
|
||||
|
||||
// Connect to the accountant
|
||||
fmt.Printf("Dialing accountant on %s\n", *accountantAddress)
|
||||
clientConn, err := grpc.Dial(*accountantAddress, grpc.WithInsecure())
|
||||
fmt.Printf("Dialing accountant on %s\n", accountantAddress)
|
||||
s.clientConn, err = grpc.Dial(accountantAddress, grpc.WithInsecure())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.accountant = accounts.NewAccountantClient(clientConn)
|
||||
s.accountant = accounts.NewAccountantClient(s.clientConn)
|
||||
|
||||
// Spawn a border on the default world
|
||||
if err := s.world.SpawnWorld(fillWorld); err != nil {
|
||||
|
@ -139,6 +139,7 @@ func (s *Server) Initialise(fillWorld bool) (err error) {
|
|||
}
|
||||
|
||||
// Start the listen
|
||||
fmt.Printf("Listening on %s\n", s.server.Addr)
|
||||
if s.listener, err = net.Listen("tcp", s.server.Addr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -3,8 +3,10 @@ package main
|
|||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
|
@ -15,9 +17,15 @@ import (
|
|||
|
||||
var ver = flag.Bool("version", false, "Display version number")
|
||||
var quit = flag.Int("quit", 0, "Quit after n seconds, useful for testing")
|
||||
var address = flag.String("address", "", "The address to host on, automatically selected if empty")
|
||||
var data = flag.String("data", "", "Directory to store persistant data, no storage if empty")
|
||||
var tick = flag.Int("tick", 5, "Number of minutes per server tick (0 for no tick)")
|
||||
|
||||
// Address to host the server on, automatically selected if empty
|
||||
var address = os.Getenv("HOST_ADDRESS")
|
||||
|
||||
// Path for persistent storage
|
||||
var data = os.Getenv("DATA_PATH")
|
||||
|
||||
// The tick rate of the server in seconds
|
||||
var tick = os.Getenv("TICK_RATE")
|
||||
|
||||
func InnerMain() {
|
||||
flag.Parse()
|
||||
|
@ -31,13 +39,23 @@ func InnerMain() {
|
|||
fmt.Printf("Initialising version %s...\n", version.Version)
|
||||
|
||||
// Set the persistence path
|
||||
persistence.SetPath(*data)
|
||||
persistence.SetPath(data)
|
||||
|
||||
// Convert the tick rate
|
||||
tickRate := 5
|
||||
if len(tick) > 0 {
|
||||
var err error
|
||||
tickRate, err = strconv.Atoi(tick)
|
||||
if err != nil {
|
||||
log.Fatalf("TICK_RATE not set to valid int: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create the server data
|
||||
s := internal.NewServer(
|
||||
internal.OptionAddress(*address),
|
||||
internal.OptionAddress(address),
|
||||
internal.OptionPersistentData(),
|
||||
internal.OptionTick(*tick))
|
||||
internal.OptionTick(tickRate))
|
||||
|
||||
// Initialise the server
|
||||
if err := s.Initialise(true); err != nil {
|
||||
|
@ -74,6 +92,5 @@ func InnerMain() {
|
|||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
InnerMain()
|
||||
}
|
||||
|
|
|
@ -12,9 +12,17 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var address = "localhost:80"
|
||||
const (
|
||||
defaultAddress = "localhost:80"
|
||||
)
|
||||
|
||||
func Test_InnerMain(t *testing.T) {
|
||||
|
||||
var address = os.Getenv("ROVE_SERVER_ADDRESS")
|
||||
if len(address) == 0 {
|
||||
address = defaultAddress
|
||||
}
|
||||
|
||||
// Set up the flags to act locally and use a temporary file
|
||||
flag.Set("data", path.Join(os.TempDir(), uuid.New().String()))
|
||||
|
||||
|
|
|
@ -4,24 +4,45 @@ volumes:
|
|||
persistent-data:
|
||||
|
||||
services:
|
||||
rove-server:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: cmd/rove-server/Dockerfile
|
||||
image: rove-server:latest
|
||||
ports:
|
||||
- "80:80"
|
||||
command: ./rove-server --address ":80" --data=/mnt/rove-server ${ROVE_ARGS} --accountant "rove-accountant:8081"
|
||||
volumes:
|
||||
- persistent-data:/mnt/rove-server:rw
|
||||
|
||||
rove-accountant:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: cmd/rove-accountant/Dockerfile
|
||||
image: rove-accountant:latest
|
||||
dockerfile: Dockerfile
|
||||
image: rove:latest
|
||||
ports:
|
||||
- "8081:8081"
|
||||
command: ./rove-accountant --address ":8081" --data=/mnt/rove-server
|
||||
environment:
|
||||
- HOST_ADDRESS=:8081
|
||||
- DATA_PATH=/mnt/rove-server
|
||||
volumes:
|
||||
- persistent-data:/mnt/rove-server:rw
|
||||
command: [ ./rove-accountant ]
|
||||
|
||||
rove-server:
|
||||
depends_on: [ rove-accountant ]
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: rove:latest
|
||||
ports:
|
||||
- "80:80"
|
||||
environment:
|
||||
- HOST_ADDRESS=:80
|
||||
- DATA_PATH=/mnt/rove-server
|
||||
- ACCOUNTANT_ADDRESS=rove-accountant:8081
|
||||
volumes:
|
||||
- persistent-data:/mnt/rove-server:rw
|
||||
|
||||
rove-tests:
|
||||
depends_on: [ rove-server ]
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: rove:latest
|
||||
environment:
|
||||
- ACCOUNTANT_ADDRESS=rove-accountant:8081
|
||||
- ROVE_SERVER_ADDRESS=rove-server:80
|
||||
command: [ "go", "test", "-v", "./...", "--tags=integration", "-cover", "-coverprofile=/tmp/c.out", "-count", "1" ]
|
||||
|
||||
|
||||
|
||||
|
|
1
go.mod
1
go.mod
|
@ -6,6 +6,7 @@ require (
|
|||
github.com/golang/protobuf v1.4.2
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gorilla/mux v1.7.4
|
||||
github.com/onsi/ginkgo v1.12.3 // indirect
|
||||
github.com/robfig/cron v1.2.0
|
||||
github.com/stretchr/testify v1.6.0
|
||||
github.com/tjarratt/babble v0.0.0-20191209142150-eecdf8c2339d
|
||||
|
|
36
go.sum
36
go.sum
|
@ -8,6 +8,9 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
|
@ -23,11 +26,22 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
|
|||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.12.3 h1:+RYp9QczoWz9zfUyLP/5SLXQVhfr6gZOoKGfQqHuLZQ=
|
||||
github.com/onsi/ginkgo v1.12.3/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
|
@ -45,22 +59,37 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx
|
|||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
@ -79,7 +108,14 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE
|
|||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue