diff options
| -rw-r--r-- | sth.go | 34 | ||||
| -rw-r--r-- | sth_test.go | 114 | 
2 files changed, 74 insertions, 74 deletions
| @@ -58,6 +58,23 @@ func NewActiveSthSource(cli trillian.TrillianLogClient, lp *LogParameters) (*Act  	return &s, nil  } +func (s *ActiveSthSource) Run(ctx context.Context) { +	schedule.Every(ctx, s.logParameters.Interval, func(ctx context.Context) { +		// get the next stable sth +		ictx, _ := context.WithTimeout(ctx, s.logParameters.Deadline) +		sth, err := s.Latest(ictx) +		if err != nil { +			glog.Warningf("cannot rotate without new sth: Latest: %v", err) +			return +		} +		// rotate +		s.mutex.Lock() +		defer s.mutex.Unlock() +		s.rotate(sth) +		// TODO: persist cosigned STH? +	}) +} +  func (s *ActiveSthSource) Latest(ctx context.Context) (*StItem, error) {  	trsp, err := s.client.GetLatestSignedLogRoot(ctx, &trillian.GetLatestSignedLogRootRequest{  		LogId: s.logParameters.TreeId, @@ -105,23 +122,6 @@ func (s *ActiveSthSource) AddCosignature(_ context.Context, costh *StItem) error  	return nil  } -func (s *ActiveSthSource) Run(ctx context.Context) { -	schedule.Every(ctx, s.logParameters.Interval, func(ctx context.Context) { -		// get the next stable sth -		ictx, _ := context.WithTimeout(ctx, s.logParameters.Deadline) -		sth, err := s.Latest(ictx) -		if err != nil { -			glog.Warningf("cannot rotate without new sth: Latest: %v", err) -			return -		} -		// rotate -		s.mutex.Lock() -		defer s.mutex.Unlock() -		s.rotate(sth) -		// TODO: persist cosigned STH? -	}) -} -  // rotate rotates the log's cosigned and stable STH.  The caller must aquire the  // source's read-write lock if there are concurrent reads and/or writes.  func (s *ActiveSthSource) rotate(fixedSth *StItem) { diff --git a/sth_test.go b/sth_test.go index c174672..b77e96c 100644 --- a/sth_test.go +++ b/sth_test.go @@ -14,6 +14,63 @@ import (  	"github.com/system-transparency/stfe/namespace/testdata"  ) +func TestNewActiveSthSource(t *testing.T) { +	for _, table := range []struct { +		description string +		signer      crypto.Signer +		trsp        *trillian.GetLatestSignedLogRootResponse +		terr        error +		wantErr     bool +		wantCosi    *StItem // current cosigned sth +		wantStable  *StItem // next stable sth that signatures are collected for +	}{ +		{ +			description: "invalid trillian response", +			signer:      cttestdata.NewSignerWithFixedSig(nil, testSignature), +			terr:        fmt.Errorf("internal server error"), +			wantErr:     true, +		}, +		{ +			description: "valid", +			signer:      cttestdata.NewSignerWithFixedSig(nil, testSignature), +			trsp:        makeLatestSignedLogRootResponse(t, testTimestamp, testTreeSize, testNodeHash), +			wantCosi:    NewCosignedTreeHeadV1(NewSignedTreeHeadV1(NewTreeHeadV1(makeTrillianLogRoot(t, testTimestamp, testTreeSize, testNodeHash)), testLogId, testSignature).SignedTreeHeadV1, nil), +			wantStable:  NewCosignedTreeHeadV1(NewSignedTreeHeadV1(NewTreeHeadV1(makeTrillianLogRoot(t, testTimestamp, testTreeSize, testNodeHash)), testLogId, testSignature).SignedTreeHeadV1, nil), +		}, +	} { +		func() { // run deferred functions at the end of each iteration +			th := newTestHandler(t, table.signer, nil) +			defer th.mockCtrl.Finish() +			th.client.EXPECT().GetLatestSignedLogRoot(gomock.Any(), gomock.Any()).Return(table.trsp, table.terr) +			source, err := NewActiveSthSource(th.client, th.instance.LogParameters) +			if got, want := err != nil, table.wantErr; got != want { +				t.Errorf("got error %v but wanted %v in test %q: %v", got, want, table.description, err) +			} +			if err != nil { +				return +			} + +			if got, want := source.currSth, table.wantCosi; !reflect.DeepEqual(got, want) { +				t.Errorf("got cosigned sth %v but wanted %v in test %q", got, want, table.description) +			} +			if got, want := source.nextSth, table.wantStable; !reflect.DeepEqual(got, want) { +				t.Errorf("got stable sth %v but wanted %v in test %q", got, want, table.description) +			} +			cosignatureFrom := make(map[string]bool) +			for _, wit := range table.wantStable.CosignedTreeHeadV1.SignatureV1 { +				cosignatureFrom[wit.Namespace.String()] = true +			} +			if got, want := source.cosignatureFrom, cosignatureFrom; !reflect.DeepEqual(got, want) { +				if got == nil { +					t.Errorf("got uninitialized witness map %v but wanted %v in test %q", nil, want, table.description) +				} else { +					t.Errorf("got witness map %v but wanted %v in test %q", got, want, table.description) +				} +			} +		}() +	} +} +  func TestLatest(t *testing.T) {  	for _, table := range []struct {  		description string @@ -452,60 +509,3 @@ func TestRotate(t *testing.T) {  		}  	}  } - -func TestNewActiveSthSource(t *testing.T) { -	for _, table := range []struct { -		description string -		signer      crypto.Signer -		trsp        *trillian.GetLatestSignedLogRootResponse -		terr        error -		wantErr     bool -		wantCosi    *StItem // current cosigned sth -		wantStable  *StItem // next stable sth that signatures are collected for -	}{ -		{ -			description: "invalid trillian response", -			signer:      cttestdata.NewSignerWithFixedSig(nil, testSignature), -			terr:        fmt.Errorf("internal server error"), -			wantErr:     true, -		}, -		{ -			description: "valid", -			signer:      cttestdata.NewSignerWithFixedSig(nil, testSignature), -			trsp:        makeLatestSignedLogRootResponse(t, testTimestamp, testTreeSize, testNodeHash), -			wantCosi:    NewCosignedTreeHeadV1(NewSignedTreeHeadV1(NewTreeHeadV1(makeTrillianLogRoot(t, testTimestamp, testTreeSize, testNodeHash)), testLogId, testSignature).SignedTreeHeadV1, nil), -			wantStable:  NewCosignedTreeHeadV1(NewSignedTreeHeadV1(NewTreeHeadV1(makeTrillianLogRoot(t, testTimestamp, testTreeSize, testNodeHash)), testLogId, testSignature).SignedTreeHeadV1, nil), -		}, -	} { -		func() { // run deferred functions at the end of each iteration -			th := newTestHandler(t, table.signer, nil) -			defer th.mockCtrl.Finish() -			th.client.EXPECT().GetLatestSignedLogRoot(gomock.Any(), gomock.Any()).Return(table.trsp, table.terr) -			source, err := NewActiveSthSource(th.client, th.instance.LogParameters) -			if got, want := err != nil, table.wantErr; got != want { -				t.Errorf("got error %v but wanted %v in test %q: %v", got, want, table.description, err) -			} -			if err != nil { -				return -			} - -			if got, want := source.currSth, table.wantCosi; !reflect.DeepEqual(got, want) { -				t.Errorf("got cosigned sth %v but wanted %v in test %q", got, want, table.description) -			} -			if got, want := source.nextSth, table.wantStable; !reflect.DeepEqual(got, want) { -				t.Errorf("got stable sth %v but wanted %v in test %q", got, want, table.description) -			} -			cosignatureFrom := make(map[string]bool) -			for _, wit := range table.wantStable.CosignedTreeHeadV1.SignatureV1 { -				cosignatureFrom[wit.Namespace.String()] = true -			} -			if got, want := source.cosignatureFrom, cosignatureFrom; !reflect.DeepEqual(got, want) { -				if got == nil { -					t.Errorf("got uninitialized witness map %v but wanted %v in test %q", nil, want, table.description) -				} else { -					t.Errorf("got witness map %v but wanted %v in test %q", got, want, table.description) -				} -			} -		}() -	} -} | 
