Skip to content

Commit bd84eb4

Browse files
committed
endorse_test improvements
Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
1 parent dae0c1f commit bd84eb4

File tree

1 file changed

+318
-14
lines changed

1 file changed

+318
-14
lines changed

token/services/ttx/endorse_test.go

Lines changed: 318 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ SPDX-License-Identifier: Apache-2.0
77
package ttx_test
88

99
import (
10+
"context"
11+
"math/rand"
12+
"strconv"
1013
"testing"
1114

1215
"github.com/hyperledger-labs/fabric-smart-client/pkg/utils/errors"
@@ -28,12 +31,78 @@ type TestEndorseViewContextInput struct {
2831
}
2932

3033
type TestEndorseViewContext struct {
31-
ctx *mock2.Context
32-
tx *ttx.Transaction
33-
options []ttx.TxOption
34-
storageProvider *mock2.StorageProvider
35-
storage *mock2.Storage
36-
session *mock2.Session
34+
ctx *mock2.Context
35+
tx *ttx.Transaction
36+
options []ttx.TxOption
37+
storageProvider *mock2.StorageProvider
38+
storage *mock2.Storage
39+
session *mock2.Session
40+
tokenSigner *mock.Signer
41+
networkIdentitySigner *mock2.NetworkIdentitySigner
42+
ch chan *view.Message
43+
tokenIP *mock.IdentityProvider
44+
networkIdentityProvider *mock2.NetworkIdentityProvider
45+
}
46+
47+
func newTransaction(t *testing.T) *ttx.Transaction {
48+
t.Helper()
49+
50+
session := &mock2.Session{}
51+
ch := make(chan *view.Message, 2)
52+
session.ReceiveReturns(ch)
53+
54+
seed := strconv.Itoa(rand.Int())
55+
56+
tms := &mock2.TokenManagementServiceWithExtensions{}
57+
tms.NetworkReturns("a_network" + seed)
58+
tms.ChannelReturns("a_channel" + seed)
59+
tmsID := token.TMSID{
60+
Network: "a_network" + seed,
61+
Channel: "a_channel" + seed,
62+
Namespace: "a_namespace" + seed,
63+
}
64+
tms.IDReturns(tmsID)
65+
tokenDes := &mock.Deserializer{}
66+
tokenIP := &mock.IdentityProvider{}
67+
tokenIP.IsMeReturns(true)
68+
tokenSigner := &mock.Signer{}
69+
tokenSigner.SignReturns([]byte("a_token_sigma"+seed), nil)
70+
tokenIP.GetSignerReturns(tokenSigner, nil)
71+
tms.SigServiceReturns(token.NewSignatureService(tokenDes, tokenIP))
72+
tokenAPITMS := tokenapi.NewMockedManagementService(t, tmsID)
73+
tms.SetTokenManagementServiceStub = func(arg1 *token.Request) error {
74+
arg1.SetTokenService(tokenAPITMS)
75+
return nil
76+
}
77+
tmsp := &mock2.TokenManagementServiceProvider{}
78+
tmsp.TokenManagementServiceReturns(tms, nil)
79+
network := &mock2.Network{}
80+
network.ComputeTxIDReturns("an_anchor" + seed)
81+
np := &mock2.NetworkProvider{}
82+
np.GetNetworkReturns(network, nil)
83+
84+
req := token.NewRequest(nil, token.RequestAnchor("an_anchor"+seed))
85+
req.Metadata.Issues = []*driver.IssueMetadata{
86+
{
87+
Issuer: driver.AuditableIdentity{
88+
Identity: []byte("an_issuer" + seed),
89+
},
90+
},
91+
}
92+
tms.NewRequestReturns(req, nil)
93+
94+
ctx := &mock2.Context{}
95+
ctx.SessionReturns(session)
96+
ctx.ContextReturns(t.Context())
97+
ctx.GetServiceReturnsOnCall(0, tmsp, nil)
98+
ctx.GetServiceReturnsOnCall(1, np, nil)
99+
ctx.GetServiceReturnsOnCall(2, &endpoint.Service{}, nil)
100+
ctx.GetServiceReturnsOnCall(3, np, nil)
101+
ctx.GetServiceReturnsOnCall(4, tmsp, nil)
102+
tx, err := ttx.NewTransaction(ctx, []byte("a_signer"))
103+
require.NoError(t, err)
104+
105+
return tx
37106
}
38107

39108
func newTestEndorseViewContext(t *testing.T, input *TestEndorseViewContextInput) *TestEndorseViewContext {
@@ -130,20 +199,34 @@ func newTestEndorseViewContext(t *testing.T, input *TestEndorseViewContextInput)
130199
Payload: signatureRequestRaw,
131200
}
132201
// then the transaction
133-
ch <- &view.Message{
134-
Payload: txRaw,
202+
if input.AnotherReceivedTx {
203+
tx2 := newTransaction(t)
204+
txRaw2, err := tx2.Bytes()
205+
require.NoError(t, err)
206+
ch <- &view.Message{
207+
Payload: txRaw2,
208+
}
209+
} else {
210+
ch <- &view.Message{
211+
Payload: txRaw,
212+
}
135213
}
136214

137215
ctx.RunViewStub = func(v view.View, option ...view.RunViewOption) (interface{}, error) {
138216
return v.Call(ctx)
139217
}
140218

141219
c := &TestEndorseViewContext{
142-
ctx: ctx,
143-
tx: tx,
144-
storage: storage,
145-
storageProvider: storageProvider,
146-
session: session,
220+
ctx: ctx,
221+
tx: tx,
222+
storage: storage,
223+
storageProvider: storageProvider,
224+
session: session,
225+
tokenSigner: tokenSigner,
226+
networkIdentitySigner: nis,
227+
ch: ch,
228+
tokenIP: tokenIP,
229+
networkIdentityProvider: networkIdentityProvider,
147230
}
148231
return c
149232
}
@@ -226,11 +309,232 @@ func TestEndorseView(t *testing.T) {
226309
},
227310
expectError: true,
228311
errorContains: "signature request's signer does not match the expected signer",
229-
expectErr: ttx.ErrSignerIdentityMismatch,
312+
verify: func(ctx *TestEndorseViewContext, _ any) {
313+
assert.Equal(t, 1, ctx.session.SendWithContextCallCount())
314+
},
315+
},
316+
{
317+
name: "failed unmarshalling signature request",
318+
prepare: func() *TestEndorseViewContext {
319+
c := newTestEndorseViewContext(t, nil)
320+
for len(c.ch) > 0 {
321+
<-c.ch
322+
}
323+
c.ch <- &view.Message{Payload: []byte("garbage")}
324+
return c
325+
},
326+
expectError: true,
327+
errorContains: "failed unmarshalling signature request",
328+
verify: func(ctx *TestEndorseViewContext, _ any) {
329+
assert.Equal(t, 0, ctx.session.SendWithContextCallCount())
330+
},
331+
},
332+
{
333+
name: "failed signing request",
334+
prepare: func() *TestEndorseViewContext {
335+
c := newTestEndorseViewContext(t, nil)
336+
c.tokenSigner.SignReturns(nil, errors.New("sign error"))
337+
return c
338+
},
339+
expectError: true,
340+
errorContains: "failed signing request",
341+
verify: func(ctx *TestEndorseViewContext, _ any) {
342+
assert.Equal(t, 0, ctx.session.SendWithContextCallCount())
343+
},
344+
},
345+
{
346+
name: "failed sending signature back",
347+
prepare: func() *TestEndorseViewContext {
348+
c := newTestEndorseViewContext(t, nil)
349+
c.session.SendWithContextReturns(errors.New("send error"))
350+
return c
351+
},
352+
expectError: true,
353+
errorContains: "failed sending signature back",
354+
verify: func(ctx *TestEndorseViewContext, _ any) {
355+
assert.Equal(t, 1, ctx.session.SendWithContextCallCount())
356+
},
357+
},
358+
{
359+
name: "failed receiving transaction",
360+
prepare: func() *TestEndorseViewContext {
361+
c := newTestEndorseViewContext(t, nil)
362+
sigReq := <-c.ch
363+
<-c.ch
364+
c.ch <- sigReq
365+
c.ch <- &view.Message{Payload: []byte("garbage transaction")}
366+
return c
367+
},
368+
expectError: true,
369+
errorContains: "failed receiving transaction",
370+
verify: func(ctx *TestEndorseViewContext, _ any) {
371+
assert.Equal(t, 1, ctx.session.SendWithContextCallCount())
372+
},
373+
},
374+
{
375+
name: "failed acknowledging transaction (signing)",
376+
prepare: func() *TestEndorseViewContext {
377+
c := newTestEndorseViewContext(t, nil)
378+
c.networkIdentitySigner.SignReturns(nil, errors.New("ack sign error"))
379+
return c
380+
},
381+
expectError: true,
382+
errorContains: "failed to sign ack response",
383+
verify: func(ctx *TestEndorseViewContext, _ any) {
384+
assert.Equal(t, 1, ctx.session.SendWithContextCallCount())
385+
},
386+
},
387+
{
388+
name: "failed acknowledging transaction (sending)",
389+
prepare: func() *TestEndorseViewContext {
390+
c := newTestEndorseViewContext(t, nil)
391+
count := 0
392+
c.session.SendWithContextStub = func(ctx context.Context, payload []byte) error {
393+
count++
394+
if count == 2 {
395+
return errors.New("ack send error")
396+
}
397+
return nil
398+
}
399+
return c
400+
},
401+
expectError: true,
402+
errorContains: "failed sending ack",
403+
verify: func(ctx *TestEndorseViewContext, _ any) {
404+
assert.Equal(t, 2, ctx.session.SendWithContextCallCount())
405+
},
406+
},
407+
{
408+
name: "failed getting storage provider",
409+
prepare: func() *TestEndorseViewContext {
410+
c := newTestEndorseViewContext(t, nil)
411+
c.ctx.GetServiceReturnsOnCall(4, nil, errors.New("storage provider error"))
412+
return c
413+
},
414+
expectError: true,
415+
errorContains: "failed to storage provider",
416+
verify: func(ctx *TestEndorseViewContext, _ any) {
417+
assert.Equal(t, 2, ctx.session.SendWithContextCallCount())
418+
},
419+
},
420+
{
421+
name: "failed getting identity provider",
422+
prepare: func() *TestEndorseViewContext {
423+
c := newTestEndorseViewContext(t, nil)
424+
c.ctx.GetServiceReturnsOnCall(3, nil, errors.New("identity provider error"))
425+
return c
426+
},
427+
expectError: true,
428+
errorContains: "failed getting identity provider",
429+
verify: func(ctx *TestEndorseViewContext, _ any) {
430+
assert.Equal(t, 1, ctx.session.SendWithContextCallCount())
431+
},
432+
},
433+
{
434+
name: "failed getting signer",
435+
prepare: func() *TestEndorseViewContext {
436+
c := newTestEndorseViewContext(t, nil)
437+
c.tokenIP.GetSignerReturns(nil, errors.New("signer error"))
438+
return c
439+
},
440+
expectError: true,
441+
errorContains: "cannot find signer for",
442+
verify: func(ctx *TestEndorseViewContext, _ any) {
443+
assert.Equal(t, 0, ctx.session.SendWithContextCallCount())
444+
},
445+
},
446+
{
447+
name: "success with FromSignatureRequest",
448+
prepare: func() *TestEndorseViewContext {
449+
c := newTestEndorseViewContext(t, nil)
450+
c.tx.FromSignatureRequest = &ttx.SignatureRequest{
451+
Signer: []byte("an_issuer"),
452+
}
453+
// Clear channel and put only transaction
454+
for len(c.ch) > 0 {
455+
<-c.ch
456+
}
457+
txRaw, _ := c.tx.Bytes()
458+
c.ch <- &view.Message{Payload: txRaw}
459+
return c
460+
},
461+
expectError: false,
462+
verify: func(ctx *TestEndorseViewContext, _ any) {
463+
assert.Equal(t, 2, ctx.session.SendWithContextCallCount())
464+
},
465+
},
466+
{
467+
name: "failed cache request",
468+
prepare: func() *TestEndorseViewContext {
469+
c := newTestEndorseViewContext(t, nil)
470+
c.storageProvider.CacheRequestReturns(errors.New("cache error"))
471+
return c
472+
},
473+
expectError: false,
474+
verify: func(ctx *TestEndorseViewContext, _ any) {
475+
assert.Equal(t, 2, ctx.session.SendWithContextCallCount())
476+
assert.Equal(t, 1, ctx.storageProvider.CacheRequestCallCount())
477+
},
478+
},
479+
{
480+
name: "failed getting signer for ack",
481+
prepare: func() *TestEndorseViewContext {
482+
c := newTestEndorseViewContext(t, nil)
483+
c.networkIdentityProvider.GetSignerReturns(nil, errors.New("ack signer error"))
484+
return c
485+
},
486+
expectError: true,
487+
errorContains: "failed to get signer for default identity",
488+
verify: func(ctx *TestEndorseViewContext, _ any) {
489+
assert.Equal(t, 1, ctx.session.SendWithContextCallCount())
490+
},
491+
},
492+
{
493+
name: "failed reading signature request (closed channel)",
494+
prepare: func() *TestEndorseViewContext {
495+
c := newTestEndorseViewContext(t, nil)
496+
close(c.ch)
497+
return c
498+
},
499+
expectError: true,
500+
errorContains: "failed reading signature request",
230501
verify: func(ctx *TestEndorseViewContext, _ any) {
231502
assert.Equal(t, 0, ctx.session.SendWithContextCallCount())
232503
},
233504
},
505+
{
506+
name: "multiple signers",
507+
prepare: func() *TestEndorseViewContext {
508+
c := newTestEndorseViewContext(t, nil)
509+
c.tx.TokenRequest.Metadata.Issues = append(c.tx.TokenRequest.Metadata.Issues, &driver.IssueMetadata{
510+
Issuer: driver.AuditableIdentity{
511+
Identity: []byte("another_issuer"),
512+
},
513+
})
514+
515+
req1 := <-c.ch
516+
tx := <-c.ch
517+
518+
c.ch = make(chan *view.Message, 3)
519+
c.session.ReceiveReturns(c.ch)
520+
521+
c.ch <- req1
522+
523+
sigReq := &ttx.SignatureRequest{
524+
Signer: []byte("another_issuer"),
525+
}
526+
sigReqRaw, _ := sigReq.Bytes()
527+
c.ch <- &view.Message{Payload: sigReqRaw}
528+
529+
c.ch <- tx
530+
531+
return c
532+
},
533+
expectError: false,
534+
verify: func(ctx *TestEndorseViewContext, _ any) {
535+
assert.Equal(t, 3, ctx.session.SendWithContextCallCount())
536+
},
537+
},
234538
}
235539

236540
for _, tc := range testCases {

0 commit comments

Comments
 (0)