From ef594841f71606f3e209d675db66e8ca4f793bbf Mon Sep 17 00:00:00 2001 From: Angelo De Caro Date: Thu, 9 Jan 2025 10:18:43 +0100 Subject: [PATCH 1/2] check the error is returned correctly Signed-off-by: Angelo De Caro --- integration/fsc/pingpong/factory.go | 14 ++++++++++++-- integration/fsc/pingpong/initiator.go | 14 ++++++++++++-- integration/fsc/pingpong/pingpong_test.go | 20 ++++++++++++++++++++ integration/fsc/pingpong/responder.go | 19 +++++++++++++++---- 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/integration/fsc/pingpong/factory.go b/integration/fsc/pingpong/factory.go index 2cbd1f68f..859e44a2a 100644 --- a/integration/fsc/pingpong/factory.go +++ b/integration/fsc/pingpong/factory.go @@ -6,12 +6,22 @@ SPDX-License-Identifier: Apache-2.0 package pingpong -import "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" +import ( + "encoding/json" + + "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" +) // InitiatorViewFactory is the factory of Initiator views type InitiatorViewFactory struct{} // NewView returns a new instance of the Initiator view func (i *InitiatorViewFactory) NewView(in []byte) (view.View, error) { - return &Initiator{}, nil + m := Message{} + if len(in) != 0 { + if err := json.Unmarshal(in, &m); err != nil { + return nil, err + } + } + return &Initiator{Message: m}, nil } diff --git a/integration/fsc/pingpong/initiator.go b/integration/fsc/pingpong/initiator.go index a71a2884e..c80e2a40a 100644 --- a/integration/fsc/pingpong/initiator.go +++ b/integration/fsc/pingpong/initiator.go @@ -15,7 +15,13 @@ import ( "github.com/pkg/errors" ) -type Initiator struct{} +type Message struct { + Payload []byte +} + +type Initiator struct { + Message +} func (p *Initiator) Call(context view.Context) (interface{}, error) { // Retrieve responder identity @@ -25,7 +31,11 @@ func (p *Initiator) Call(context view.Context) (interface{}, error) { session, err := context.GetSession(context.Initiator(), responder) assert.NoError(err) // Send a ping - err = session.Send([]byte("ping")) + if len(p.Payload) == 0 { + p.Payload = []byte("ping") + } + + err = session.Send(p.Payload) assert.NoError(err) // Wait for the pong ch := session.Receive() select { diff --git a/integration/fsc/pingpong/pingpong_test.go b/integration/fsc/pingpong/pingpong_test.go index dd125a720..080b8228b 100644 --- a/integration/fsc/pingpong/pingpong_test.go +++ b/integration/fsc/pingpong/pingpong_test.go @@ -189,6 +189,17 @@ var _ = Describe("EndToEnd", func() { AfterEach(s.TearDown) It("generate artifacts & successful mock pingpong", s.TestGenerateAndMockPingPong) }) + + Describe("Network-based PongWithErr With Websockets", func() { + s := NewTestSuite(fsc.WebSocket, true, integration.NoReplication) + BeforeEach(s.Setup) + AfterEach(s.TearDown) + It("successed", func() { + s.TestGenerateAndPongErr("pongWithSendError", "initiator") + s.TestGenerateAndPongErr("pongWithError", "initiator") + s.TestGenerateAndPongErr("pongWithPanic", "initiator") + }) + }) }) func newNode(conf string) api.FabricSmartClientNode { @@ -313,6 +324,15 @@ func (s *TestSuite) TestGenerateAndMockPingPong() { Expect(common.JSONUnmarshalString(res)).To(BeEquivalentTo("OK")) } +func (s *TestSuite) TestGenerateAndPongErr(payload string, clients ...string) { + // Initiate a view and check the output + for _, clientName := range clients { + _, err := s.II.Client(clientName).CallView("init", common.JSONMarshall(&pingpong.Message{Payload: []byte(payload)})) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring(fmt.Sprintf("expected ping, got %s", payload))) + } +} + func newWebClient(confDir string) *web.Client { c, err := client.NewWebClientConfigFromFSC(confDir) Expect(err).NotTo(HaveOccurred()) diff --git a/integration/fsc/pingpong/responder.go b/integration/fsc/pingpong/responder.go index 878045a15..3e7d67171 100644 --- a/integration/fsc/pingpong/responder.go +++ b/integration/fsc/pingpong/responder.go @@ -34,10 +34,21 @@ func (p *Responder) Call(context view.Context) (interface{}, error) { m := string(payload) switch { case m != "ping": - // reply with an error - err := session.SendError([]byte(fmt.Sprintf("expected ping, got %s", m))) - assert.NoError(err) - return nil, errors.Errorf("expected ping, got %s", m) + // reply with an error, + // alternatively, you can just return with an error or panic. + // The executor of the view will take care of sending the error back + switch m { + case "pongWithSendError": + err := session.SendError([]byte(fmt.Sprintf("expected ping, got %s", m))) + assert.NoError(err) + return nil, nil + case "pongWithError": + return nil, errors.Errorf("expected ping, got %s", m) + case "pongWithPanic": + panic(fmt.Sprintf("expected ping, got %s", m)) + default: + panic(fmt.Sprintf("unexpected message: %s", m)) + } default: // reply with pong err := session.Send([]byte("pong")) From a8f9a5863ef685788026061e957d0c451e9a2091 Mon Sep 17 00:00:00 2001 From: Angelo De Caro Date: Thu, 9 Jan 2025 10:38:05 +0100 Subject: [PATCH 2/2] change default behaviour Signed-off-by: Angelo De Caro --- integration/fsc/pingpong/responder.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/integration/fsc/pingpong/responder.go b/integration/fsc/pingpong/responder.go index 3e7d67171..1dba8de12 100644 --- a/integration/fsc/pingpong/responder.go +++ b/integration/fsc/pingpong/responder.go @@ -47,7 +47,9 @@ func (p *Responder) Call(context view.Context) (interface{}, error) { case "pongWithPanic": panic(fmt.Sprintf("expected ping, got %s", m)) default: - panic(fmt.Sprintf("unexpected message: %s", m)) + err := session.SendError([]byte(fmt.Sprintf("expected ping, got %s", m))) + assert.NoError(err) + return nil, errors.Errorf("expected ping, got %s", m) } default: // reply with pong