github.com/s7techlab/cckit@v0.10.5/testing/tx.go (about)

     1  package testing
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/golang/protobuf/ptypes/timestamp"
     7  	"github.com/hyperledger/fabric-chaincode-go/shim"
     8  	"github.com/hyperledger/fabric-protos-go/peer"
     9  	"go.uber.org/zap"
    10  
    11  	"github.com/s7techlab/cckit/response"
    12  	"github.com/s7techlab/cckit/router"
    13  	"github.com/s7techlab/cckit/testing/expect"
    14  )
    15  
    16  type (
    17  	TxHandler struct {
    18  		MockStub *MockStub
    19  		m        sync.Mutex
    20  		Logger   *zap.Logger
    21  		Context  router.Context
    22  	}
    23  
    24  	TxResult struct {
    25  		Result interface{}
    26  		Err    error
    27  		Event  *peer.ChaincodeEvent
    28  	}
    29  )
    30  
    31  func NewTxHandler(name string) (*TxHandler, router.Context) {
    32  	var (
    33  		mockStub = NewMockStub(name, nil)
    34  		logger   = router.NewLogger(name)
    35  		ctx      = router.NewContext(mockStub, logger)
    36  	)
    37  	return &TxHandler{
    38  		MockStub: mockStub,
    39  		Logger:   logger,
    40  		Context:  ctx,
    41  	}, ctx
    42  }
    43  
    44  func (p *TxHandler) From(creator ...interface{}) *TxHandler {
    45  	p.MockStub.From(creator...)
    46  	return p
    47  }
    48  
    49  func (p *TxHandler) Init(txHdl func(ctx router.Context) (interface{}, error)) *TxResult {
    50  	return p.Invoke(txHdl)
    51  }
    52  
    53  // Invoke emulates chaincode invocation and returns transaction result
    54  func (p *TxHandler) Invoke(invoke func(ctx router.Context) (interface{}, error)) *TxResult {
    55  	uuid := p.MockStub.generateTxUID()
    56  
    57  	p.MockStub.MockTransactionStart(uuid)
    58  	res, err := invoke(p.Context)
    59  	p.MockStub.TxResult = response.Create(res, err)
    60  	p.MockStub.MockTransactionEnd(uuid)
    61  
    62  	txRes := &TxResult{
    63  		Result: res,
    64  		Err:    err,
    65  		Event:  p.MockStub.ChaincodeEvent,
    66  	}
    67  
    68  	return txRes
    69  }
    70  
    71  // Tx emulates chaincode invocation
    72  func (p *TxHandler) Tx(tx func()) {
    73  	p.m.Lock()
    74  	defer p.m.Unlock()
    75  
    76  	uuid := p.MockStub.generateTxUID()
    77  	p.MockStub.MockTransactionStart(uuid)
    78  
    79  	// expect that invoke will be with shim.OK status, need for dump state changes
    80  	// if during tx func got error - func setTxResult must be called
    81  	p.MockStub.TxResult = peer.Response{
    82  		Status:  shim.OK,
    83  		Message: "",
    84  		Payload: nil,
    85  	}
    86  	tx()
    87  	p.MockStub.MockTransactionEnd(uuid)
    88  }
    89  
    90  // SetTxResult can be used for set txResult error during Tx
    91  func (p *TxHandler) SetTxResult(err error) {
    92  	if p.MockStub.TxID == `` {
    93  		panic(`can be called only during Tx() evaluation`)
    94  	}
    95  	if err != nil {
    96  		p.MockStub.TxResult.Status = shim.ERROR
    97  		p.MockStub.TxResult.Message = err.Error()
    98  	}
    99  }
   100  
   101  // TxFunc returns tx closure, can be used directly as ginkgo func
   102  func (p *TxHandler) TxFunc(tx func()) func() {
   103  	return func() {
   104  		p.Tx(tx)
   105  	}
   106  }
   107  
   108  // Expect returns assertion helper
   109  func (p *TxHandler) Expect(res interface{}, err error) *expect.TxRes {
   110  	return &expect.TxRes{
   111  		Result: res,
   112  		Err:    err,
   113  		Event:  p.MockStub.ChaincodeEvent,
   114  	}
   115  }
   116  
   117  // TxTimestamp returns last tx timestamp
   118  func (p *TxHandler) TxTimestamp() *timestamp.Timestamp {
   119  	return p.MockStub.TxTimestamp
   120  }
   121  
   122  // TxEvent returns last tx event
   123  func (p *TxHandler) TxEvent() *peer.ChaincodeEvent {
   124  	return p.MockStub.ChaincodeEvent
   125  }
   126  
   127  func (r *TxResult) Expect() *expect.TxRes {
   128  	return &expect.TxRes{
   129  		Result: r.Result,
   130  		Err:    r.Err,
   131  		Event:  r.Event,
   132  	}
   133  }