@@ -253,15 +253,17 @@ func TestGetMSPID(t *testing.T) {
253253
254254func TestChaincodeStubHandlers (t * testing.T ) {
255255 var tests = []struct {
256- name string
257- resType peer.ChaincodeMessage_Type
258- payload []byte
259- testFunc func (* ChaincodeStub , * Handler , * testing.T , []byte )
256+ name string
257+ resType peer.ChaincodeMessage_Type
258+ payload []byte
259+ usePeerWriteBatch bool
260+ testFunc func (* ChaincodeStub , * Handler , * testing.T , []byte )
260261 }{
261262 {
262- name : "Simple Response" ,
263- resType : peer .ChaincodeMessage_RESPONSE ,
264- payload : []byte ("myvalue" ),
263+ name : "Simple Response" ,
264+ resType : peer .ChaincodeMessage_RESPONSE ,
265+ payload : []byte ("myvalue" ),
266+ usePeerWriteBatch : true ,
265267 testFunc : func (s * ChaincodeStub , h * Handler , t * testing.T , payload []byte ) {
266268 resp , err := s .GetState ("key" )
267269 if err != nil {
@@ -313,13 +315,13 @@ func TestChaincodeStubHandlers(t *testing.T) {
313315 assert .NoError (t , err )
314316 err = s .PurgePrivateData ("" , "key" )
315317 assert .EqualError (t , err , "collection must not be an empty string" )
316-
317318 },
318319 },
319320 {
320- name : "Simple Response with WriteBatch" ,
321- resType : peer .ChaincodeMessage_RESPONSE ,
322- payload : []byte ("myvalue" ),
321+ name : "Simple Response with WriteBatch" ,
322+ resType : peer .ChaincodeMessage_RESPONSE ,
323+ payload : []byte ("myvalue" ),
324+ usePeerWriteBatch : true ,
323325 testFunc : func (s * ChaincodeStub , h * Handler , t * testing.T , payload []byte ) {
324326 s .StartWriteBatch ()
325327 err := s .PutState ("key" , payload )
@@ -364,6 +366,7 @@ func TestChaincodeStubHandlers(t *testing.T) {
364366 },
365367 },
366368 ),
369+ usePeerWriteBatch : true ,
367370 testFunc : func (s * ChaincodeStub , h * Handler , t * testing.T , payload []byte ) {
368371 resp , err := s .GetStateValidationParameter ("key" )
369372 if err != nil {
@@ -392,6 +395,7 @@ func TestChaincodeStubHandlers(t *testing.T) {
392395 ),
393396 },
394397 ),
398+ usePeerWriteBatch : true ,
395399 testFunc : func (s * ChaincodeStub , h * Handler , t * testing.T , payload []byte ) {
396400 resp := s .InvokeChaincode ("cc" , [][]byte {}, "channel" )
397401 assert .Equal (t , resp .Payload , []byte ("invokechaincode" ))
@@ -421,6 +425,7 @@ func TestChaincodeStubHandlers(t *testing.T) {
421425 HasMore : true ,
422426 },
423427 ),
428+ usePeerWriteBatch : true ,
424429 testFunc : func (s * ChaincodeStub , h * Handler , t * testing.T , payload []byte ) {
425430 expectedResult := & queryresult.KV {
426431 Key : "querykey" ,
@@ -557,6 +562,7 @@ func TestChaincodeStubHandlers(t *testing.T) {
557562 HasMore : false ,
558563 },
559564 ),
565+ usePeerWriteBatch : true ,
560566 testFunc : func (s * ChaincodeStub , h * Handler , t * testing.T , payload []byte ) {
561567 expectedResult := & queryresult.KeyModification {
562568 TxId : "txid" ,
@@ -575,9 +581,10 @@ func TestChaincodeStubHandlers(t *testing.T) {
575581 },
576582 },
577583 {
578- name : "Error Conditions" ,
579- resType : peer .ChaincodeMessage_ERROR ,
580- payload : []byte ("error" ),
584+ name : "Error Conditions" ,
585+ resType : peer .ChaincodeMessage_ERROR ,
586+ payload : []byte ("error" ),
587+ usePeerWriteBatch : true ,
581588 testFunc : func (s * ChaincodeStub , h * Handler , t * testing.T , payload []byte ) {
582589 _ , err := s .GetState ("key" )
583590 assert .EqualError (t , err , string (payload ))
@@ -619,6 +626,142 @@ func TestChaincodeStubHandlers(t *testing.T) {
619626 assert .NoError (t , err )
620627 },
621628 },
629+ {
630+ name : "WriteBatch - Old peer (usePeerWriteBatch false)" ,
631+ resType : peer .ChaincodeMessage_ERROR ,
632+ payload : []byte ("error" ),
633+ usePeerWriteBatch : false ,
634+ testFunc : func (s * ChaincodeStub , h * Handler , t * testing.T , payload []byte ) {
635+ s .StartWriteBatch ()
636+ err := s .PutState ("key" , payload )
637+ assert .ErrorContains (t , err , string (payload ))
638+ err = s .FinishWriteBatch ()
639+ assert .NoError (t , err )
640+ },
641+ },
642+ {
643+ name : "WriteBatch - different operations on the same key" ,
644+ resType : peer .ChaincodeMessage_RESPONSE ,
645+ payload : []byte ("myvalue" ),
646+ usePeerWriteBatch : true ,
647+ testFunc : func (s * ChaincodeStub , h * Handler , t * testing.T , payload []byte ) {
648+ s .StartWriteBatch ()
649+
650+ err := s .PutState ("key" , payload )
651+ assert .NoError (t , err )
652+ err = s .DelState ("key" )
653+ assert .NoError (t , err )
654+
655+ err = s .PutPrivateData ("col" , "key" , payload )
656+ assert .NoError (t , err )
657+ err = s .DelPrivateData ("col" , "key" )
658+ assert .NoError (t , err )
659+ err = s .PurgePrivateData ("col" , "key" )
660+ assert .NoError (t , err )
661+
662+ err = s .FinishWriteBatch ()
663+ assert .NoError (t , err )
664+
665+ chatStream , ok := s .handler .chatStream .(* mock.PeerChaincodeStream )
666+ assert .True (t , ok )
667+ assert .Equal (t , 1 , chatStream .SendCallCount ())
668+ peerChaincodeMsg := chatStream .SendArgsForCall (0 )
669+ assert .Equal (t , peer .ChaincodeMessage_WRITE_BATCH_STATE , peerChaincodeMsg .Type )
670+ batch := & peer.WriteBatchState {}
671+ err = proto .Unmarshal (peerChaincodeMsg .GetPayload (), batch )
672+ assert .NoError (t , err )
673+ assert .Equal (t , 2 , len (batch .GetRec ()))
674+ },
675+ },
676+ {
677+ name : "WriteBatch - State and StateValidationParameter keys are the same" ,
678+ resType : peer .ChaincodeMessage_RESPONSE ,
679+ payload : []byte ("myvalue" ),
680+ usePeerWriteBatch : true ,
681+ testFunc : func (s * ChaincodeStub , h * Handler , t * testing.T , payload []byte ) {
682+ s .StartWriteBatch ()
683+
684+ err := s .PutState ("key" , payload )
685+ assert .NoError (t , err )
686+ err = s .SetStateValidationParameter ("key" , payload )
687+ assert .NoError (t , err )
688+
689+ err = s .PutPrivateData ("col" , "key" , payload )
690+ assert .NoError (t , err )
691+ err = s .SetPrivateDataValidationParameter ("col" , "key" , payload )
692+ assert .NoError (t , err )
693+
694+ err = s .FinishWriteBatch ()
695+ assert .NoError (t , err )
696+
697+ chatStream , ok := s .handler .chatStream .(* mock.PeerChaincodeStream )
698+ assert .True (t , ok )
699+ assert .Equal (t , 1 , chatStream .SendCallCount ())
700+ peerChaincodeMsg := chatStream .SendArgsForCall (0 )
701+ assert .Equal (t , peer .ChaincodeMessage_WRITE_BATCH_STATE , peerChaincodeMsg .Type )
702+ batch := & peer.WriteBatchState {}
703+ err = proto .Unmarshal (peerChaincodeMsg .GetPayload (), batch )
704+ assert .NoError (t , err )
705+ assert .Equal (t , 4 , len (batch .GetRec ()))
706+ },
707+ },
708+ {
709+ name : "WriteBatch - key uniqueness check c+old - col+d" ,
710+ resType : peer .ChaincodeMessage_RESPONSE ,
711+ payload : []byte ("myvalue" ),
712+ usePeerWriteBatch : true ,
713+ testFunc : func (s * ChaincodeStub , h * Handler , t * testing.T , payload []byte ) {
714+ s .StartWriteBatch ()
715+
716+ err := s .PutPrivateData ("c" , "old" , payload )
717+ assert .NoError (t , err )
718+ err = s .PutPrivateData ("col" , "d" , payload )
719+ assert .NoError (t , err )
720+
721+ err = s .FinishWriteBatch ()
722+ assert .NoError (t , err )
723+
724+ chatStream , ok := s .handler .chatStream .(* mock.PeerChaincodeStream )
725+ assert .True (t , ok )
726+ assert .Equal (t , 1 , chatStream .SendCallCount ())
727+ peerChaincodeMsg := chatStream .SendArgsForCall (0 )
728+ assert .Equal (t , peer .ChaincodeMessage_WRITE_BATCH_STATE , peerChaincodeMsg .Type )
729+ batch := & peer.WriteBatchState {}
730+ err = proto .Unmarshal (peerChaincodeMsg .GetPayload (), batch )
731+ assert .NoError (t , err )
732+ assert .Equal (t , 2 , len (batch .GetRec ()))
733+ },
734+ },
735+ {
736+ name : "WriteBatch - starting a write batch twice" ,
737+ resType : peer .ChaincodeMessage_RESPONSE ,
738+ payload : []byte ("myvalue" ),
739+ usePeerWriteBatch : true ,
740+ testFunc : func (s * ChaincodeStub , h * Handler , t * testing.T , payload []byte ) {
741+ s .StartWriteBatch ()
742+
743+ err := s .PutState ("key" , payload )
744+ assert .NoError (t , err )
745+
746+ s .StartWriteBatch ()
747+
748+ err = s .PutState ("key1" , payload )
749+ assert .NoError (t , err )
750+
751+ err = s .FinishWriteBatch ()
752+ assert .NoError (t , err )
753+
754+ chatStream , ok := s .handler .chatStream .(* mock.PeerChaincodeStream )
755+ assert .True (t , ok )
756+ assert .Equal (t , 1 , chatStream .SendCallCount ())
757+ peerChaincodeMsg := chatStream .SendArgsForCall (0 )
758+ assert .Equal (t , peer .ChaincodeMessage_WRITE_BATCH_STATE , peerChaincodeMsg .Type )
759+ batch := & peer.WriteBatchState {}
760+ err = proto .Unmarshal (peerChaincodeMsg .GetPayload (), batch )
761+ assert .NoError (t , err )
762+ assert .Equal (t , 2 , len (batch .GetRec ()))
763+ },
764+ },
622765 }
623766
624767 for _ , test := range tests {
@@ -630,7 +773,7 @@ func TestChaincodeStubHandlers(t *testing.T) {
630773 cc : & mockChaincode {},
631774 responseChannels : map [string ]chan * peer.ChaincodeMessage {},
632775 state : ready ,
633- usePeerWriteBatch : true ,
776+ usePeerWriteBatch : test . usePeerWriteBatch ,
634777 maxSizeWriteBatch : 100 ,
635778 }
636779 stub := & ChaincodeStub {
0 commit comments