From d9763a720f209131bafb3df035ba55196bb8605f Mon Sep 17 00:00:00 2001 From: bpopovschi Date: Thu, 7 Feb 2019 21:24:02 +0200 Subject: [PATCH 1/5] Merge cmd/gen-test-vectors and integration/client_tests.go --- core/integration/alltests.go | 2 +- core/integration/client_tests.go | 178 ++++++++++++++++++++++++++++++ {impl => core}/integration/env.go | 5 +- core/testdata/gen.go | 2 +- impl/integration/main_test.go | 14 ++- 5 files changed, 194 insertions(+), 7 deletions(-) rename {impl => core}/integration/env.go (98%) diff --git a/core/integration/alltests.go b/core/integration/alltests.go index 8fd5fe0ee..a33f4b37f 100644 --- a/core/integration/alltests.go +++ b/core/integration/alltests.go @@ -29,7 +29,7 @@ import ( ) // Env holds a complete testing environment for end-to-end tests. -type Env struct { +type EnvClient struct { Client *client.Client Cli pb.KeyTransparencyClient Sequencer spb.KeyTransparencySequencerClient diff --git a/core/integration/client_tests.go b/core/integration/client_tests.go index 6a4ff201f..e2ba095f6 100644 --- a/core/integration/client_tests.go +++ b/core/integration/client_tests.go @@ -17,16 +17,25 @@ package integration import ( "bytes" "context" + "encoding/json" "fmt" + "io/ioutil" + "os" "reflect" "sort" "testing" "time" + "github.com/google/keytransparency/core/testdata" + "github.com/google/keytransparency/impl/authentication" + "github.com/google/trillian/types" + "github.com/google/keytransparency/core/client" "github.com/google/keytransparency/core/sequencer" "github.com/google/keytransparency/core/testutil" + "github.com/golang/protobuf/jsonpb" + "github.com/google/martian/log" "github.com/google/tink/go/tink" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -492,3 +501,172 @@ func (m uint64Slice) Less(i, j int) bool { return m[i] < m[j] } func cp(tag int) []byte { return []byte(fmt.Sprintf("bar%v", tag)) } + +// GenerateTestVectors verifies set/get semantics. +// TODO(gbelvin): Migrate into core/integration/client_tests to avoid code rot. +func GenerateTestVectors(ctx context.Context, env *Env) error { + go func() { + ticker := time.NewTicker(100 * time.Millisecond) + defer ticker.Stop() + sequencer.PeriodicallyRun(ctx, ticker.C, func(ctx context.Context) { + req := &spb.RunBatchRequest{ + DirectoryId: env.Directory.DirectoryId, + MinBatch: 1, + MaxBatch: 100, + } + if _, err := env.Sequencer.RunBatch(ctx, req); err != nil { + log.Errorf("RunBatch(): %v", err) + } + }) + }() + testdataDir := "." + // Create lists of signers. + signers1 := testutil.SignKeysetsFromPEMs(testPrivKey1) + + // Create lists of authorized keys + authorizedKeys1 := testutil.VerifyKeysetFromPEMs(testPubKey1).Keyset() + + // Collect a list of valid GetUserResponses + getUserResps := make([]testdata.GetUserResponseVector, 0) + + // Start with an empty trusted log root + slr := &types.LogRootV1{} + + for _, tc := range []struct { + desc string + wantProfile []byte + setProfile []byte + ctx context.Context + userID string + signers []tink.Signer + authorizedKeys *tinkpb.Keyset + }{ + { + desc: "empty_alice", + wantProfile: nil, + setProfile: []byte("alice-key1"), + ctx: authentication.WithOutgoingFakeAuth(ctx, "alice"), + userID: "alice", + signers: signers1, + authorizedKeys: authorizedKeys1, + }, + { + desc: "bob0_set", + wantProfile: nil, + setProfile: []byte("bob-key1"), + ctx: authentication.WithOutgoingFakeAuth(ctx, "bob"), + userID: "bob", + signers: signers1, + authorizedKeys: authorizedKeys1, + }, + { + desc: "set_carol", + wantProfile: nil, + setProfile: []byte("carol-key1"), + ctx: authentication.WithOutgoingFakeAuth(ctx, "carol"), + userID: "carol", + signers: signers1, + authorizedKeys: authorizedKeys1, + }, + { + desc: "bob1_get", + wantProfile: []byte("bob-key1"), + setProfile: nil, + ctx: context.Background(), + userID: "bob", + signers: signers1, + authorizedKeys: authorizedKeys1, + }, + { + desc: "bob1_set", + wantProfile: []byte("bob-key1"), + setProfile: []byte("bob-key2"), + ctx: authentication.WithOutgoingFakeAuth(ctx, "bob"), + userID: "bob", + signers: signers1, + authorizedKeys: authorizedKeys1, + }, + } { + // Check profile. + e, err := env.Cli.GetUser(ctx, &pb.GetUserRequest{ + DirectoryId: env.Directory.DirectoryId, + UserId: tc.userID, + LastVerifiedTreeSize: int64(slr.TreeSize), + }) + if err != nil { + return fmt.Errorf("gen-test-vectors: GetUser(): %v", err) + } + newslr, smr, err := env.Client.VerifyRevision(e.Revision, *slr) + if err != nil { + return fmt.Errorf("gen-test-vectors: VerifyRevision(): %v", err) + } + if err := env.Client.VerifyMapLeaf(env.Directory.DirectoryId, tc.userID, e.Leaf, smr); err != nil { + return fmt.Errorf("gen-test-vectors: VerifyMapLeaf(): %v", err) + } + + if got, want := e.GetLeaf().GetCommitted().GetData(), tc.wantProfile; !bytes.Equal(got, want) { + return fmt.Errorf("gen-test-vectors: VerifiedGetUser(%v): %s, want %s", tc.userID, got, want) + } + + // Update the trusted root on the first revision, then let it fall behind + // every few revisions to make consistency proofs more interesting. + trust := newslr.TreeSize%5 == 1 + if trust { + slr = newslr + } + getUserResps = append(getUserResps, testdata.GetUserResponseVector{ + Desc: tc.desc, + UserID: tc.userID, + Resp: e, + TrustNewLog: trust, + }) + + // Update profile. + if tc.setProfile != nil { + u := &tpb.User{ + UserId: tc.userID, + PublicKeyData: tc.setProfile, + AuthorizedKeys: tc.authorizedKeys, + } + cctx, cancel := context.WithTimeout(tc.ctx, env.Timeout) + defer cancel() + _, err := env.Client.Update(cctx, u, tc.signers) + if err != nil { + return fmt.Errorf("gen-test-vectors: Update(%v): %v", tc.userID, err) + } + } + } + + if err := SaveTestVectors(testdataDir, env, getUserResps); err != nil { + return fmt.Errorf("gen-test-vectors: SaveTestVectors(): %v", err) + } + return nil +} + +// SaveTestVectors generates test vectors for interoprability testing. +func SaveTestVectors(dir string, env *Env, resps []testdata.GetUserResponseVector) error { + marshaler := &jsonpb.Marshaler{ + Indent: "\t", + } + // Output all key material needed to verify the test vectors. + directoryFile := dir + "/directory.json" + f, err := os.Create(directoryFile) + if err != nil { + return err + } + defer f.Close() + if err := marshaler.Marshal(f, env.Directory); err != nil { + return fmt.Errorf("gen-test-vectors: jsonpb.Marshal(): %v", err) + } + + // Save list of responses + respFile := dir + "/getentryresponse.json" + out, err := json.MarshalIndent(resps, "", "\t") + if err != nil { + return fmt.Errorf("gen-test-vectors: json.Marshal(): %v", err) + } + if err := ioutil.WriteFile(respFile, out, 0666); err != nil { + return fmt.Errorf("gen-test-vectors: WriteFile(%v): %v", respFile, err) + } + return nil +} diff --git a/impl/integration/env.go b/core/integration/env.go similarity index 98% rename from impl/integration/env.go rename to core/integration/env.go index e56475dc6..325f0209a 100644 --- a/impl/integration/env.go +++ b/core/integration/env.go @@ -31,7 +31,6 @@ import ( "github.com/google/keytransparency/core/adminserver" "github.com/google/keytransparency/core/client" - "github.com/google/keytransparency/core/integration" "github.com/google/keytransparency/core/keyserver" "github.com/google/keytransparency/core/mutator/entry" "github.com/google/keytransparency/core/sequencer" @@ -88,7 +87,7 @@ func Listen() (net.Listener, *grpc.ClientConn, error) { // Env holds a complete testing environment for end-to-end tests. type Env struct { - *integration.Env + *EnvClient mapEnv *ttest.MapEnv logEnv *ttest.LogEnv admin *adminserver.Server @@ -204,7 +203,7 @@ func NewEnv(ctx context.Context) (*Env, error) { // Integration tests manually create revisions immediately, so retry fairly quickly. client.RetryDelay = 10 * time.Millisecond return &Env{ - Env: &integration.Env{ + EnvClient: &EnvClient{ Client: client, Cli: pb.NewKeyTransparencyClient(cc), Sequencer: spb.NewKeyTransparencySequencerClient(cc), diff --git a/core/testdata/gen.go b/core/testdata/gen.go index 7998e5e4d..eac447326 100644 --- a/core/testdata/gen.go +++ b/core/testdata/gen.go @@ -14,4 +14,4 @@ package testdata -//go:generate go run ../../cmd/gen-test-vectors/main.go --testdata=. +//go:generate go test ../../impl/integration --generate diff --git a/impl/integration/main_test.go b/impl/integration/main_test.go index cd2dec90b..a9f6fdcd6 100644 --- a/impl/integration/main_test.go +++ b/impl/integration/main_test.go @@ -16,22 +16,32 @@ package integration import ( "context" + "flag" "testing" "github.com/google/keytransparency/core/integration" "github.com/google/trillian/storage/testdb" ) +var ( + generate = flag.Bool("generate", false, "Defines if test vectors should be generated") +) + // TestIntegration runs all KeyTransparency integration tests. func TestIntegration(t *testing.T) { // We can only run the integration tests if there is a MySQL instance available. testdb.SkipIfNoMySQL(t) + flag.Parse() for _, test := range integration.AllTests { t.Run(test.Name, func(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - env, err := NewEnv(ctx) + env, err := integration.NewEnv(ctx) + + if *generate { + integration.GenerateTestVectors(ctx, env) + } if err != nil { t.Fatalf("Could not create Env: %v", err) } @@ -43,7 +53,7 @@ func TestIntegration(t *testing.T) { // canceling the master context. ctx, cancel := context.WithCancel(ctx) defer cancel() - test.Fn(ctx, env.Env, t) + test.Fn(ctx, env, t) }() }) } From 4b8315d42091db52d8490421c606890e42759b70 Mon Sep 17 00:00:00 2001 From: bpopovschi Date: Thu, 7 Feb 2019 21:44:03 +0200 Subject: [PATCH 2/5] error return check --- impl/integration/main_test.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/impl/integration/main_test.go b/impl/integration/main_test.go index a9f6fdcd6..06fb9c5f4 100644 --- a/impl/integration/main_test.go +++ b/impl/integration/main_test.go @@ -38,13 +38,15 @@ func TestIntegration(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() env, err := integration.NewEnv(ctx) - - if *generate { - integration.GenerateTestVectors(ctx, env) - } if err != nil { t.Fatalf("Could not create Env: %v", err) } + if *generate { + err = integration.GenerateTestVectors(ctx, env) + if err != nil { + t.Fatalf("Could not generate Test vectors: %v", err) + } + } defer env.Close() func() { // Cancel the test function context (and thus From c7735303a7ef56fc64ec348b444108e6e932b1cf Mon Sep 17 00:00:00 2001 From: bpopovschi Date: Fri, 8 Feb 2019 17:48:48 +0200 Subject: [PATCH 3/5] move env back to impl, brake cycle dependency --- core/integration/alltests.go | 2 +- core/integration/client_tests.go | 16 +++++++--------- {core => impl}/integration/env.go | 5 +++-- impl/integration/main_test.go | 30 +++++++++++++++++++++--------- 4 files changed, 32 insertions(+), 21 deletions(-) rename {core => impl}/integration/env.go (98%) diff --git a/core/integration/alltests.go b/core/integration/alltests.go index a33f4b37f..8fd5fe0ee 100644 --- a/core/integration/alltests.go +++ b/core/integration/alltests.go @@ -29,7 +29,7 @@ import ( ) // Env holds a complete testing environment for end-to-end tests. -type EnvClient struct { +type Env struct { Client *client.Client Cli pb.KeyTransparencyClient Sequencer spb.KeyTransparencySequencerClient diff --git a/core/integration/client_tests.go b/core/integration/client_tests.go index e2ba095f6..9dd5a3f3d 100644 --- a/core/integration/client_tests.go +++ b/core/integration/client_tests.go @@ -27,7 +27,6 @@ import ( "time" "github.com/google/keytransparency/core/testdata" - "github.com/google/keytransparency/impl/authentication" "github.com/google/trillian/types" "github.com/google/keytransparency/core/client" @@ -503,7 +502,6 @@ func cp(tag int) []byte { } // GenerateTestVectors verifies set/get semantics. -// TODO(gbelvin): Migrate into core/integration/client_tests to avoid code rot. func GenerateTestVectors(ctx context.Context, env *Env) error { go func() { ticker := time.NewTicker(100 * time.Millisecond) @@ -536,7 +534,7 @@ func GenerateTestVectors(ctx context.Context, env *Env) error { desc string wantProfile []byte setProfile []byte - ctx context.Context + opts []grpc.CallOption userID string signers []tink.Signer authorizedKeys *tinkpb.Keyset @@ -545,7 +543,7 @@ func GenerateTestVectors(ctx context.Context, env *Env) error { desc: "empty_alice", wantProfile: nil, setProfile: []byte("alice-key1"), - ctx: authentication.WithOutgoingFakeAuth(ctx, "alice"), + opts: env.CallOpts("alice"), userID: "alice", signers: signers1, authorizedKeys: authorizedKeys1, @@ -554,7 +552,7 @@ func GenerateTestVectors(ctx context.Context, env *Env) error { desc: "bob0_set", wantProfile: nil, setProfile: []byte("bob-key1"), - ctx: authentication.WithOutgoingFakeAuth(ctx, "bob"), + opts: env.CallOpts("bob"), userID: "bob", signers: signers1, authorizedKeys: authorizedKeys1, @@ -563,7 +561,7 @@ func GenerateTestVectors(ctx context.Context, env *Env) error { desc: "set_carol", wantProfile: nil, setProfile: []byte("carol-key1"), - ctx: authentication.WithOutgoingFakeAuth(ctx, "carol"), + opts: env.CallOpts("carol"), userID: "carol", signers: signers1, authorizedKeys: authorizedKeys1, @@ -572,7 +570,7 @@ func GenerateTestVectors(ctx context.Context, env *Env) error { desc: "bob1_get", wantProfile: []byte("bob-key1"), setProfile: nil, - ctx: context.Background(), + opts: env.CallOpts("bob"), userID: "bob", signers: signers1, authorizedKeys: authorizedKeys1, @@ -581,7 +579,7 @@ func GenerateTestVectors(ctx context.Context, env *Env) error { desc: "bob1_set", wantProfile: []byte("bob-key1"), setProfile: []byte("bob-key2"), - ctx: authentication.WithOutgoingFakeAuth(ctx, "bob"), + opts: env.CallOpts("bob"), userID: "bob", signers: signers1, authorizedKeys: authorizedKeys1, @@ -628,7 +626,7 @@ func GenerateTestVectors(ctx context.Context, env *Env) error { PublicKeyData: tc.setProfile, AuthorizedKeys: tc.authorizedKeys, } - cctx, cancel := context.WithTimeout(tc.ctx, env.Timeout) + cctx, cancel := context.WithTimeout(ctx, env.Timeout) defer cancel() _, err := env.Client.Update(cctx, u, tc.signers) if err != nil { diff --git a/core/integration/env.go b/impl/integration/env.go similarity index 98% rename from core/integration/env.go rename to impl/integration/env.go index 325f0209a..e56475dc6 100644 --- a/core/integration/env.go +++ b/impl/integration/env.go @@ -31,6 +31,7 @@ import ( "github.com/google/keytransparency/core/adminserver" "github.com/google/keytransparency/core/client" + "github.com/google/keytransparency/core/integration" "github.com/google/keytransparency/core/keyserver" "github.com/google/keytransparency/core/mutator/entry" "github.com/google/keytransparency/core/sequencer" @@ -87,7 +88,7 @@ func Listen() (net.Listener, *grpc.ClientConn, error) { // Env holds a complete testing environment for end-to-end tests. type Env struct { - *EnvClient + *integration.Env mapEnv *ttest.MapEnv logEnv *ttest.LogEnv admin *adminserver.Server @@ -203,7 +204,7 @@ func NewEnv(ctx context.Context) (*Env, error) { // Integration tests manually create revisions immediately, so retry fairly quickly. client.RetryDelay = 10 * time.Millisecond return &Env{ - EnvClient: &EnvClient{ + Env: &integration.Env{ Client: client, Cli: pb.NewKeyTransparencyClient(cc), Sequencer: spb.NewKeyTransparencySequencerClient(cc), diff --git a/impl/integration/main_test.go b/impl/integration/main_test.go index 06fb9c5f4..e5e2cf534 100644 --- a/impl/integration/main_test.go +++ b/impl/integration/main_test.go @@ -17,6 +17,7 @@ package integration import ( "context" "flag" + "fmt" "testing" "github.com/google/keytransparency/core/integration" @@ -32,21 +33,21 @@ func TestIntegration(t *testing.T) { // We can only run the integration tests if there is a MySQL instance available. testdb.SkipIfNoMySQL(t) flag.Parse() - + if *generate { + err := runGenerateTestVectors() + if err != nil { + t.Fatalf("Could not generate Test vectors: %v", err) + } + } for _, test := range integration.AllTests { t.Run(test.Name, func(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - env, err := integration.NewEnv(ctx) + env, err := NewEnv(ctx) if err != nil { t.Fatalf("Could not create Env: %v", err) } - if *generate { - err = integration.GenerateTestVectors(ctx, env) - if err != nil { - t.Fatalf("Could not generate Test vectors: %v", err) - } - } + defer env.Close() func() { // Cancel the test function context (and thus @@ -55,8 +56,19 @@ func TestIntegration(t *testing.T) { // canceling the master context. ctx, cancel := context.WithCancel(ctx) defer cancel() - test.Fn(ctx, env, t) + test.Fn(ctx, env.Env, t) }() }) } } + +func runGenerateTestVectors() error { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + env, err := NewEnv(ctx) + if err != nil { + return fmt.Errorf("Could not create Env: %v", err) + } + defer env.Close() + return integration.GenerateTestVectors(ctx, env.Env) +} From 8600e5c21ce8f9a78d904be8c896013c2aa310ee Mon Sep 17 00:00:00 2001 From: bpopovschi Date: Fri, 8 Feb 2019 17:52:41 +0200 Subject: [PATCH 4/5] replace log with glog --- cmd/gen-test-vectors/main.go | 244 ------------------------------- core/integration/client_tests.go | 9 +- 2 files changed, 4 insertions(+), 249 deletions(-) delete mode 100644 cmd/gen-test-vectors/main.go diff --git a/cmd/gen-test-vectors/main.go b/cmd/gen-test-vectors/main.go deleted file mode 100644 index be39c1a6b..000000000 --- a/cmd/gen-test-vectors/main.go +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright 2018 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "bytes" - "context" - "encoding/json" - "flag" - "fmt" - "io/ioutil" - "os" - "time" - - "github.com/golang/glog" - "github.com/golang/protobuf/jsonpb" - "github.com/google/keytransparency/core/sequencer" - "github.com/google/keytransparency/core/testdata" - "github.com/google/keytransparency/core/testutil" - "github.com/google/keytransparency/impl/authentication" - "github.com/google/keytransparency/impl/integration" - "github.com/google/tink/go/tink" - "github.com/google/trillian/types" - - tpb "github.com/google/keytransparency/core/api/type/type_go_proto" - pb "github.com/google/keytransparency/core/api/v1/keytransparency_go_proto" - spb "github.com/google/keytransparency/core/sequencer/sequencer_go_proto" - tinkpb "github.com/google/tink/proto/tink_go_proto" -) - -var ( - testdataDir = flag.String("testdata", "core/testdata", "The directory in which to place the generated test data") -) - -const ( - // openssl ecparam -name prime256v1 -genkey -out p256-key.pem - testPrivKey1 = `-----BEGIN EC PRIVATE KEY----- -MHcCAQEEIBoLpoKGPbrFbEzF/ZktBSuGP+Llmx2wVKSkbdAdQ+3JoAoGCCqGSM49 -AwEHoUQDQgAE+xVOdphkfpEtl7OF8oCyvWw31dV4hnGbXDPbdFlL1nmayhnqyEfR -dXNlpBT2U9hXcSxliKI1rHrAJFDx3ncttA== ------END EC PRIVATE KEY-----` - // openssl ec -in p256-key.pem -pubout -out p256-pubkey.pem - testPubKey1 = `-----BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+xVOdphkfpEtl7OF8oCyvWw31dV4 -hnGbXDPbdFlL1nmayhnqyEfRdXNlpBT2U9hXcSxliKI1rHrAJFDx3ncttA== ------END PUBLIC KEY-----` -) - -func main() { - flag.Parse() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - env, err := integration.NewEnv(ctx) - if err != nil { - glog.Fatalf("Could not create Env: %v", err) - } - defer env.Close() - cctx, cancel2 := context.WithCancel(ctx) - if err := GenerateTestVectors(cctx, env); err != nil { - glog.Fatalf("GenerateTestVectors(): %v", err) - } - cancel2() -} - -// GenerateTestVectors verifies set/get semantics. -// TODO(gbelvin): Migrate into core/integration/client_tests to avoid code rot. -func GenerateTestVectors(ctx context.Context, env *integration.Env) error { - go func() { - ticker := time.NewTicker(100 * time.Millisecond) - defer ticker.Stop() - sequencer.PeriodicallyRun(ctx, ticker.C, func(ctx context.Context) { - req := &spb.RunBatchRequest{ - DirectoryId: env.Directory.DirectoryId, - MinBatch: 1, - MaxBatch: 100, - } - if _, err := env.Sequencer.RunBatch(ctx, req); err != nil { - glog.Errorf("RunBatch(): %v", err) - } - }) - }() - // Create lists of signers. - signers1 := testutil.SignKeysetsFromPEMs(testPrivKey1) - - // Create lists of authorized keys - authorizedKeys1 := testutil.VerifyKeysetFromPEMs(testPubKey1).Keyset() - - // Collect a list of valid GetUserResponses - getUserResps := make([]testdata.GetUserResponseVector, 0) - - // Start with an empty trusted log root - slr := &types.LogRootV1{} - - for _, tc := range []struct { - desc string - wantProfile []byte - setProfile []byte - ctx context.Context - userID string - signers []tink.Signer - authorizedKeys *tinkpb.Keyset - }{ - { - desc: "empty_alice", - wantProfile: nil, - setProfile: []byte("alice-key1"), - ctx: authentication.WithOutgoingFakeAuth(ctx, "alice"), - userID: "alice", - signers: signers1, - authorizedKeys: authorizedKeys1, - }, - { - desc: "bob0_set", - wantProfile: nil, - setProfile: []byte("bob-key1"), - ctx: authentication.WithOutgoingFakeAuth(ctx, "bob"), - userID: "bob", - signers: signers1, - authorizedKeys: authorizedKeys1, - }, - { - desc: "set_carol", - wantProfile: nil, - setProfile: []byte("carol-key1"), - ctx: authentication.WithOutgoingFakeAuth(ctx, "carol"), - userID: "carol", - signers: signers1, - authorizedKeys: authorizedKeys1, - }, - { - desc: "bob1_get", - wantProfile: []byte("bob-key1"), - setProfile: nil, - ctx: context.Background(), - userID: "bob", - signers: signers1, - authorizedKeys: authorizedKeys1, - }, - { - desc: "bob1_set", - wantProfile: []byte("bob-key1"), - setProfile: []byte("bob-key2"), - ctx: authentication.WithOutgoingFakeAuth(ctx, "bob"), - userID: "bob", - signers: signers1, - authorizedKeys: authorizedKeys1, - }, - } { - // Check profile. - e, err := env.Cli.GetUser(ctx, &pb.GetUserRequest{ - DirectoryId: env.Directory.DirectoryId, - UserId: tc.userID, - LastVerifiedTreeSize: int64(slr.TreeSize), - }) - if err != nil { - return fmt.Errorf("gen-test-vectors: GetUser(): %v", err) - } - newslr, smr, err := env.Client.VerifyRevision(e.Revision, *slr) - if err != nil { - return fmt.Errorf("gen-test-vectors: VerifyRevision(): %v", err) - } - if err := env.Client.VerifyMapLeaf(env.Directory.DirectoryId, tc.userID, e.Leaf, smr); err != nil { - return fmt.Errorf("gen-test-vectors: VerifyMapLeaf(): %v", err) - } - - if got, want := e.GetLeaf().GetCommitted().GetData(), tc.wantProfile; !bytes.Equal(got, want) { - return fmt.Errorf("gen-test-vectors: VerifiedGetUser(%v): %s, want %s", tc.userID, got, want) - } - - // Update the trusted root on the first revision, then let it fall behind - // every few revisions to make consistency proofs more interesting. - trust := newslr.TreeSize%5 == 1 - if trust { - slr = newslr - } - getUserResps = append(getUserResps, testdata.GetUserResponseVector{ - Desc: tc.desc, - UserID: tc.userID, - Resp: e, - TrustNewLog: trust, - }) - - // Update profile. - if tc.setProfile != nil { - u := &tpb.User{ - UserId: tc.userID, - PublicKeyData: tc.setProfile, - AuthorizedKeys: tc.authorizedKeys, - } - cctx, cancel := context.WithTimeout(tc.ctx, env.Timeout) - defer cancel() - _, err := env.Client.Update(cctx, u, tc.signers) - if err != nil { - return fmt.Errorf("gen-test-vectors: Update(%v): %v", tc.userID, err) - } - } - } - - if err := SaveTestVectors(*testdataDir, env, getUserResps); err != nil { - return fmt.Errorf("gen-test-vectors: SaveTestVectors(): %v", err) - } - return nil -} - -// SaveTestVectors generates test vectors for interoprability testing. -func SaveTestVectors(dir string, env *integration.Env, resps []testdata.GetUserResponseVector) error { - marshaler := &jsonpb.Marshaler{ - Indent: "\t", - } - // Output all key material needed to verify the test vectors. - directoryFile := dir + "/directory.json" - f, err := os.Create(directoryFile) - if err != nil { - return err - } - defer f.Close() - if err := marshaler.Marshal(f, env.Directory); err != nil { - return fmt.Errorf("gen-test-vectors: jsonpb.Marshal(): %v", err) - } - - // Save list of responses - respFile := dir + "/getentryresponse.json" - out, err := json.MarshalIndent(resps, "", "\t") - if err != nil { - return fmt.Errorf("gen-test-vectors: json.Marshal(): %v", err) - } - if err := ioutil.WriteFile(respFile, out, 0666); err != nil { - return fmt.Errorf("gen-test-vectors: WriteFile(%v): %v", respFile, err) - } - return nil -} diff --git a/core/integration/client_tests.go b/core/integration/client_tests.go index 9dd5a3f3d..13f53f69a 100644 --- a/core/integration/client_tests.go +++ b/core/integration/client_tests.go @@ -26,15 +26,14 @@ import ( "testing" "time" - "github.com/google/keytransparency/core/testdata" - "github.com/google/trillian/types" - + "github.com/golang/glog" "github.com/google/keytransparency/core/client" "github.com/google/keytransparency/core/sequencer" + "github.com/google/keytransparency/core/testdata" "github.com/google/keytransparency/core/testutil" + "github.com/google/trillian/types" "github.com/golang/protobuf/jsonpb" - "github.com/google/martian/log" "github.com/google/tink/go/tink" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -513,7 +512,7 @@ func GenerateTestVectors(ctx context.Context, env *Env) error { MaxBatch: 100, } if _, err := env.Sequencer.RunBatch(ctx, req); err != nil { - log.Errorf("RunBatch(): %v", err) + glog.Errorf("RunBatch(): %v", err) } }) }() From 88592223450ac4ff1ccbb2d8ed0e2d84850e7521 Mon Sep 17 00:00:00 2001 From: Gary Belvin Date: Tue, 12 Feb 2019 17:43:00 +0000 Subject: [PATCH 5/5] Use separate test for GenerateVectors --- impl/integration/main_test.go | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/impl/integration/main_test.go b/impl/integration/main_test.go index e5e2cf534..ce3cd558d 100644 --- a/impl/integration/main_test.go +++ b/impl/integration/main_test.go @@ -17,7 +17,6 @@ package integration import ( "context" "flag" - "fmt" "testing" "github.com/google/keytransparency/core/integration" @@ -32,13 +31,6 @@ var ( func TestIntegration(t *testing.T) { // We can only run the integration tests if there is a MySQL instance available. testdb.SkipIfNoMySQL(t) - flag.Parse() - if *generate { - err := runGenerateTestVectors() - if err != nil { - t.Fatalf("Could not generate Test vectors: %v", err) - } - } for _, test := range integration.AllTests { t.Run(test.Name, func(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) @@ -62,13 +54,19 @@ func TestIntegration(t *testing.T) { } } -func runGenerateTestVectors() error { +func TestGenerateVectors(t *testing.T) { + flag.Parse() + if !*generate { + t.Skip("Test vector generation not requested") + } ctx, cancel := context.WithCancel(context.Background()) defer cancel() env, err := NewEnv(ctx) if err != nil { - return fmt.Errorf("Could not create Env: %v", err) + t.Fatalf("could not create Env: %v", err) } defer env.Close() - return integration.GenerateTestVectors(ctx, env.Env) + if err := integration.GenerateTestVectors(ctx, env.Env); err != nil { + t.Errorf("GenerateTestVectors(): %v", err) + } }