prysm-pulse/validator/client/service_test.go

107 lines
3.0 KiB
Go
Raw Normal View History

package client
import (
"context"
fix(grpcHeaders): accept values with "=" symbols (#8047) * fix(grpcHeaders): accept values with equal signs # What Before this commit, it was not possible to pass in base64-encoded content as a header value if it contained an equals sign. This commit changes the behavior slightly. Rather than ignore key/value pairs where the value happens to have an equals sign, we assume the first equals sign delimits the key from the value and pass in the rest of the value as-is. Also, instead of printing the header name along with its value, we print the name, so there is less risk of leaking information into logs that shouldn't be there. # Testing This has not been tested in the context of the full validator client. Instead, a small example was made to demonstrate the feasibility. The example is shown here: ```go package main import ( "log" "os" "strings" "github.com/davecgh/go-spew/spew" "github.com/urfave/cli/v2" ) type Config struct { GrpcHeadersFlag string } func main() { app := &cli.App{ Action: func(c *cli.Context) error { for _, hdr := range strings.Split(c.String("grpc-headers"), ",") { if hdr != "" { ss := strings.Split(hdr, "=") spew.Dump(ss[0]) spew.Dump(strings.Join(ss[1:], "=")) } } return nil }, Flags: []cli.Flag{ &cli.StringFlag{ Name: "grpc-headers", Usage: "A comma-separated list of key value pairs to pass as gRPC headers for all gRPC " + "calls. Example: --grpc-headers=key=value", }, }, } err := app.Run(os.Args) if err != nil { log.Fatal(err) } } ``` Example invocation: ```command ❯ go run main.go --grpc-headers=key=value,Authorization="Basic $(echo -n hello:world | base64)" (string) (len=3) "key" (string) (len=5) "value" (string) (len=13) "Authorization" (string) (len=22) "Basic aGVsbG86d29ybGQ=" ``` * Adds tests to new gRPC header parsing code * bazel run //:gazelle
2020-12-04 21:31:15 +00:00
"strings"
"testing"
"time"
"github.com/prysmaticlabs/prysm/runtime"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
logTest "github.com/sirupsen/logrus/hooks/test"
fix(grpcHeaders): accept values with "=" symbols (#8047) * fix(grpcHeaders): accept values with equal signs # What Before this commit, it was not possible to pass in base64-encoded content as a header value if it contained an equals sign. This commit changes the behavior slightly. Rather than ignore key/value pairs where the value happens to have an equals sign, we assume the first equals sign delimits the key from the value and pass in the rest of the value as-is. Also, instead of printing the header name along with its value, we print the name, so there is less risk of leaking information into logs that shouldn't be there. # Testing This has not been tested in the context of the full validator client. Instead, a small example was made to demonstrate the feasibility. The example is shown here: ```go package main import ( "log" "os" "strings" "github.com/davecgh/go-spew/spew" "github.com/urfave/cli/v2" ) type Config struct { GrpcHeadersFlag string } func main() { app := &cli.App{ Action: func(c *cli.Context) error { for _, hdr := range strings.Split(c.String("grpc-headers"), ",") { if hdr != "" { ss := strings.Split(hdr, "=") spew.Dump(ss[0]) spew.Dump(strings.Join(ss[1:], "=")) } } return nil }, Flags: []cli.Flag{ &cli.StringFlag{ Name: "grpc-headers", Usage: "A comma-separated list of key value pairs to pass as gRPC headers for all gRPC " + "calls. Example: --grpc-headers=key=value", }, }, } err := app.Run(os.Args) if err != nil { log.Fatal(err) } } ``` Example invocation: ```command ❯ go run main.go --grpc-headers=key=value,Authorization="Basic $(echo -n hello:world | base64)" (string) (len=3) "key" (string) (len=5) "value" (string) (len=13) "Authorization" (string) (len=22) "Basic aGVsbG86d29ybGQ=" ``` * Adds tests to new gRPC header parsing code * bazel run //:gazelle
2020-12-04 21:31:15 +00:00
"google.golang.org/grpc/metadata"
)
var _ runtime.Service = (*ValidatorService)(nil)
var _ GenesisFetcher = (*ValidatorService)(nil)
var _ SyncChecker = (*ValidatorService)(nil)
2019-04-20 11:24:40 +00:00
func TestStop_CancelsContext(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
vs := &ValidatorService{
ctx: ctx,
cancel: cancel,
}
assert.NoError(t, vs.Stop())
select {
case <-time.After(1 * time.Second):
t.Error("Context not canceled within 1s")
case <-vs.ctx.Done():
}
}
func TestLifecycle(t *testing.T) {
hook := logTest.NewGlobal()
upgrading linter from gometalinter to golangci-lint (#2100) * upgrading linter from gometalinter to golangci-lint * fixed golangci-lint linting * removed linting before_script command * removed disable-all command * Fixed golang config file * fixed golang config file v2 * removed gosec issue rule * formatting * fixed travis build to run golangci-lint * Add install golangci-lint command * fixing golangci-lint script * removed https:// * Added golangci-lint cmd script * added go get for local lint install * created a before_script * add install before script * Added get script * added go mod download * removed go mod downloads * changed * removed before script * Added before script go get lint * added exit zero to see what went wrong * removed golang run script * removed before script * change lint command * verbose output * removed verbose * change linter enable and disable configuration * Update .golangci.yml Removed gotype as a linter * Update .golangci.yml Added typecheck linter * Update .golangci.yml Added fixed lint version * Update .golangci.yml Added gotype * Update .golangci.yml Added typecheck * removed env:lint * Added env lint * fixing lint upgrade * Changing travis configuration * FIxed spelling errors * disabled typecheck * Enabled typecheck * remove binary * Deleting lib binary * adding more linters * fixed constants * fix spelling * fixed all lint issues * Revert "Changing travis configuration" This reverts commit 334afe9d05e96261b01f275aa3ada20e7f36aac4. * Merge branch 'master' of https://github.com/prysmaticlabs/prysm into update-linter * Changed from Infof to Info * Fixing commits * fixing commits with linter config * added install * Fixing * fix log statement
2019-04-26 06:24:01 +00:00
// Use canceled context so that the run function exits immediately..
ctx, cancel := context.WithCancel(context.Background())
cancel()
validatorService := &ValidatorService{
ctx: ctx,
cancel: cancel,
endpoint: "merkle tries",
withCert: "alice.crt",
}
validatorService.Start()
require.NoError(t, validatorService.Stop(), "Could not stop service")
require.LogsContain(t, hook, "Stopping service")
}
func TestLifecycle_Insecure(t *testing.T) {
hook := logTest.NewGlobal()
upgrading linter from gometalinter to golangci-lint (#2100) * upgrading linter from gometalinter to golangci-lint * fixed golangci-lint linting * removed linting before_script command * removed disable-all command * Fixed golang config file * fixed golang config file v2 * removed gosec issue rule * formatting * fixed travis build to run golangci-lint * Add install golangci-lint command * fixing golangci-lint script * removed https:// * Added golangci-lint cmd script * added go get for local lint install * created a before_script * add install before script * Added get script * added go mod download * removed go mod downloads * changed * removed before script * Added before script go get lint * added exit zero to see what went wrong * removed golang run script * removed before script * change lint command * verbose output * removed verbose * change linter enable and disable configuration * Update .golangci.yml Removed gotype as a linter * Update .golangci.yml Added typecheck linter * Update .golangci.yml Added fixed lint version * Update .golangci.yml Added gotype * Update .golangci.yml Added typecheck * removed env:lint * Added env lint * fixing lint upgrade * Changing travis configuration * FIxed spelling errors * disabled typecheck * Enabled typecheck * remove binary * Deleting lib binary * adding more linters * fixed constants * fix spelling * fixed all lint issues * Revert "Changing travis configuration" This reverts commit 334afe9d05e96261b01f275aa3ada20e7f36aac4. * Merge branch 'master' of https://github.com/prysmaticlabs/prysm into update-linter * Changed from Infof to Info * Fixing commits * fixing commits with linter config * added install * Fixing * fix log statement
2019-04-26 06:24:01 +00:00
// Use canceled context so that the run function exits immediately.
ctx, cancel := context.WithCancel(context.Background())
cancel()
validatorService := &ValidatorService{
ctx: ctx,
cancel: cancel,
endpoint: "merkle tries",
}
validatorService.Start()
require.LogsContain(t, hook, "You are using an insecure gRPC connection")
require.NoError(t, validatorService.Stop(), "Could not stop service")
require.LogsContain(t, hook, "Stopping service")
}
func TestStatus_NoConnectionError(t *testing.T) {
validatorService := &ValidatorService{}
assert.ErrorContains(t, "no connection", validatorService.Status())
}
fix(grpcHeaders): accept values with "=" symbols (#8047) * fix(grpcHeaders): accept values with equal signs # What Before this commit, it was not possible to pass in base64-encoded content as a header value if it contained an equals sign. This commit changes the behavior slightly. Rather than ignore key/value pairs where the value happens to have an equals sign, we assume the first equals sign delimits the key from the value and pass in the rest of the value as-is. Also, instead of printing the header name along with its value, we print the name, so there is less risk of leaking information into logs that shouldn't be there. # Testing This has not been tested in the context of the full validator client. Instead, a small example was made to demonstrate the feasibility. The example is shown here: ```go package main import ( "log" "os" "strings" "github.com/davecgh/go-spew/spew" "github.com/urfave/cli/v2" ) type Config struct { GrpcHeadersFlag string } func main() { app := &cli.App{ Action: func(c *cli.Context) error { for _, hdr := range strings.Split(c.String("grpc-headers"), ",") { if hdr != "" { ss := strings.Split(hdr, "=") spew.Dump(ss[0]) spew.Dump(strings.Join(ss[1:], "=")) } } return nil }, Flags: []cli.Flag{ &cli.StringFlag{ Name: "grpc-headers", Usage: "A comma-separated list of key value pairs to pass as gRPC headers for all gRPC " + "calls. Example: --grpc-headers=key=value", }, }, } err := app.Run(os.Args) if err != nil { log.Fatal(err) } } ``` Example invocation: ```command ❯ go run main.go --grpc-headers=key=value,Authorization="Basic $(echo -n hello:world | base64)" (string) (len=3) "key" (string) (len=5) "value" (string) (len=13) "Authorization" (string) (len=22) "Basic aGVsbG86d29ybGQ=" ``` * Adds tests to new gRPC header parsing code * bazel run //:gazelle
2020-12-04 21:31:15 +00:00
func TestStart_GrpcHeaders(t *testing.T) {
hook := logTest.NewGlobal()
// Use canceled context so that the run function exits immediately.
ctx, cancel := context.WithCancel(context.Background())
cancel()
for input, output := range map[string][]string{
"should-break": {},
"key=value": {"key", "value"},
"": {},
",": {},
"key=value,Authorization=Q=": {
fix(grpcHeaders): accept values with "=" symbols (#8047) * fix(grpcHeaders): accept values with equal signs # What Before this commit, it was not possible to pass in base64-encoded content as a header value if it contained an equals sign. This commit changes the behavior slightly. Rather than ignore key/value pairs where the value happens to have an equals sign, we assume the first equals sign delimits the key from the value and pass in the rest of the value as-is. Also, instead of printing the header name along with its value, we print the name, so there is less risk of leaking information into logs that shouldn't be there. # Testing This has not been tested in the context of the full validator client. Instead, a small example was made to demonstrate the feasibility. The example is shown here: ```go package main import ( "log" "os" "strings" "github.com/davecgh/go-spew/spew" "github.com/urfave/cli/v2" ) type Config struct { GrpcHeadersFlag string } func main() { app := &cli.App{ Action: func(c *cli.Context) error { for _, hdr := range strings.Split(c.String("grpc-headers"), ",") { if hdr != "" { ss := strings.Split(hdr, "=") spew.Dump(ss[0]) spew.Dump(strings.Join(ss[1:], "=")) } } return nil }, Flags: []cli.Flag{ &cli.StringFlag{ Name: "grpc-headers", Usage: "A comma-separated list of key value pairs to pass as gRPC headers for all gRPC " + "calls. Example: --grpc-headers=key=value", }, }, } err := app.Run(os.Args) if err != nil { log.Fatal(err) } } ``` Example invocation: ```command ❯ go run main.go --grpc-headers=key=value,Authorization="Basic $(echo -n hello:world | base64)" (string) (len=3) "key" (string) (len=5) "value" (string) (len=13) "Authorization" (string) (len=22) "Basic aGVsbG86d29ybGQ=" ``` * Adds tests to new gRPC header parsing code * bazel run //:gazelle
2020-12-04 21:31:15 +00:00
"key", "value", "Authorization", "Q=",
},
"Authorization=this is a valid value": {
fix(grpcHeaders): accept values with "=" symbols (#8047) * fix(grpcHeaders): accept values with equal signs # What Before this commit, it was not possible to pass in base64-encoded content as a header value if it contained an equals sign. This commit changes the behavior slightly. Rather than ignore key/value pairs where the value happens to have an equals sign, we assume the first equals sign delimits the key from the value and pass in the rest of the value as-is. Also, instead of printing the header name along with its value, we print the name, so there is less risk of leaking information into logs that shouldn't be there. # Testing This has not been tested in the context of the full validator client. Instead, a small example was made to demonstrate the feasibility. The example is shown here: ```go package main import ( "log" "os" "strings" "github.com/davecgh/go-spew/spew" "github.com/urfave/cli/v2" ) type Config struct { GrpcHeadersFlag string } func main() { app := &cli.App{ Action: func(c *cli.Context) error { for _, hdr := range strings.Split(c.String("grpc-headers"), ",") { if hdr != "" { ss := strings.Split(hdr, "=") spew.Dump(ss[0]) spew.Dump(strings.Join(ss[1:], "=")) } } return nil }, Flags: []cli.Flag{ &cli.StringFlag{ Name: "grpc-headers", Usage: "A comma-separated list of key value pairs to pass as gRPC headers for all gRPC " + "calls. Example: --grpc-headers=key=value", }, }, } err := app.Run(os.Args) if err != nil { log.Fatal(err) } } ``` Example invocation: ```command ❯ go run main.go --grpc-headers=key=value,Authorization="Basic $(echo -n hello:world | base64)" (string) (len=3) "key" (string) (len=5) "value" (string) (len=13) "Authorization" (string) (len=22) "Basic aGVsbG86d29ybGQ=" ``` * Adds tests to new gRPC header parsing code * bazel run //:gazelle
2020-12-04 21:31:15 +00:00
"Authorization", "this is a valid value",
},
} {
validatorService := &ValidatorService{
ctx: ctx,
cancel: cancel,
endpoint: "merkle tries",
grpcHeaders: strings.Split(input, ","),
}
validatorService.Start()
md, _ := metadata.FromOutgoingContext(validatorService.ctx)
if input == "should-break" {
require.LogsContain(t, hook, "Incorrect gRPC header flag format. Skipping should-break")
} else if len(output) == 0 {
require.DeepEqual(t, md, metadata.MD(nil))
} else {
require.DeepEqual(t, md, metadata.Pairs(output...))
}
}
}