Skip to content

Commit e9a546c

Browse files
test: Add tests for notification service
- add Simple integration test - add unit test - implement removeFinalityListener Signed-off-by: Said Altury <[email protected]>
1 parent 153324c commit e9a546c

File tree

17 files changed

+1815
-118
lines changed

17 files changed

+1815
-118
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ INTEGRATION_TARGETS += fabric-twonets
150150

151151
## fabricx section
152152
INTEGRATION_TARGETS += fabricx-iou
153+
INTEGRATION_TARGETS += fabricx-simple
153154

154155
.PHONE: list-integration-tests
155156
list-integration-tests: ## List all integration tests

go.mod

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ require (
3434
github.com/miekg/pkcs11 v1.1.1
3535
github.com/miracl/conflate v1.3.4
3636
github.com/multiformats/go-multiaddr v0.13.0
37-
github.com/onsi/ginkgo/v2 v2.23.4
38-
github.com/onsi/gomega v1.37.0
37+
github.com/onsi/ginkgo/v2 v2.25.1
38+
github.com/onsi/gomega v1.38.2
3939
github.com/prometheus/client_golang v1.20.5
4040
github.com/spf13/cobra v1.8.1
4141
github.com/spf13/viper v1.20.1
@@ -63,8 +63,6 @@ require (
6363
modernc.org/sqlite v1.32.0
6464
)
6565

66-
require golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 // indirect
67-
6866
require (
6967
cel.dev/expr v0.24.0 // indirect
7068
cloud.google.com/go v0.116.0 // indirect
@@ -82,6 +80,7 @@ require (
8280
github.com/IBM/idemix/bccsp/schemes/aries v0.0.0-20241220065751-dc7206770307 // indirect
8381
github.com/IBM/idemix/bccsp/schemes/weak-bb v0.0.0-20241220065751-dc7206770307 // indirect
8482
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
83+
github.com/Masterminds/semver/v3 v3.4.0 // indirect
8584
github.com/Microsoft/go-winio v0.6.2 // indirect
8685
github.com/VictoriaMetrics/fastcache v1.12.2 // indirect
8786
github.com/alecthomas/kingpin/v2 v2.4.0 // indirect
@@ -289,12 +288,14 @@ require (
289288
go.uber.org/fx v1.23.0 // indirect
290289
go.uber.org/mock v0.5.0 // indirect
291290
go.uber.org/multierr v1.11.0 // indirect
291+
go.yaml.in/yaml/v3 v3.0.4 // indirect
292292
golang.org/x/arch v0.11.0 // indirect
293293
golang.org/x/crypto v0.45.0 // indirect
294294
golang.org/x/mod v0.29.0 // indirect
295295
golang.org/x/net v0.47.0 // indirect
296296
golang.org/x/oauth2 v0.30.0 // indirect
297297
golang.org/x/sys v0.38.0 // indirect
298+
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 // indirect
298299
golang.org/x/time v0.8.0 // indirect
299300
golang.org/x/tools v0.38.0 // indirect
300301
gonum.org/v1/gonum v0.16.0 // indirect

go.sum

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,8 @@ github.com/IBM/mathlib v0.0.3-0.20250709075152-a138079496c3/go.mod h1:O230ebw6/2
655655
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
656656
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
657657
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
658+
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
659+
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
658660
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
659661
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
660662
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
@@ -1335,8 +1337,8 @@ github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxm
13351337
github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo=
13361338
github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts=
13371339
github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM=
1338-
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
1339-
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
1340+
github.com/onsi/ginkgo/v2 v2.25.1 h1:Fwp6crTREKM+oA6Cz4MsO8RhKQzs2/gOIVOUscMAfZY=
1341+
github.com/onsi/ginkgo/v2 v2.25.1/go.mod h1:ppTWQ1dh9KM/F1XgpeRqelR+zHVwV81DGRSDnFxK7Sk=
13401342
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
13411343
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
13421344
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
@@ -1351,8 +1353,8 @@ github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfad
13511353
github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw=
13521354
github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ=
13531355
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
1354-
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
1355-
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
1356+
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
1357+
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
13561358
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
13571359
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
13581360
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
@@ -1674,6 +1676,8 @@ go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
16741676
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
16751677
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
16761678
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
1679+
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
1680+
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
16771681
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
16781682
golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4=
16791683
golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=

integration/fabricx/simple/sdk.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package simple
8+
9+
import (
10+
"errors"
11+
12+
common "github.com/hyperledger-labs/fabric-smart-client/platform/common/sdk/dig"
13+
digutils "github.com/hyperledger-labs/fabric-smart-client/platform/common/utils/dig"
14+
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/services/state"
15+
fabricx "github.com/hyperledger-labs/fabric-smart-client/platform/fabricx/sdk/dig"
16+
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services"
17+
)
18+
19+
type SDK struct {
20+
common.SDK
21+
}
22+
23+
func NewSDK(registry services.Registry) *SDK {
24+
return NewFrom(fabricx.NewSDK(registry))
25+
}
26+
27+
func NewFrom(sdk common.SDK) *SDK {
28+
return &SDK{SDK: sdk}
29+
}
30+
31+
func (p *SDK) Install() error {
32+
if err := p.SDK.Install(); err != nil {
33+
return err
34+
}
35+
36+
return errors.Join(
37+
digutils.Register[state.VaultService](p.Container()),
38+
)
39+
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package simple_test
8+
9+
import (
10+
"testing"
11+
12+
"github.com/hyperledger-labs/fabric-smart-client/integration"
13+
"github.com/hyperledger-labs/fabric-smart-client/integration/fabricx/simple"
14+
"github.com/hyperledger-labs/fabric-smart-client/integration/fabricx/simple/views"
15+
nwocommon "github.com/hyperledger-labs/fabric-smart-client/integration/nwo/common"
16+
nwofabricx "github.com/hyperledger-labs/fabric-smart-client/integration/nwo/fabricx"
17+
nwofsc "github.com/hyperledger-labs/fabric-smart-client/integration/nwo/fsc"
18+
"github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
19+
. "github.com/onsi/ginkgo/v2"
20+
. "github.com/onsi/gomega"
21+
)
22+
23+
const testDataPath = "./out/testdata"
24+
25+
func TestEndToEnd(t *testing.T) {
26+
RegisterFailHandler(Fail)
27+
RunSpecs(t, "simple suite")
28+
}
29+
30+
type TestSuite struct {
31+
*integration.TestSuite
32+
}
33+
34+
var _ = Describe("EndToEnd", func() {
35+
for _, c := range []nwofsc.P2PCommunicationType{nwofsc.WebSocket} {
36+
Describe("simple Life Cycle", Label(c), func() {
37+
s := NewTestSuite(c)
38+
BeforeEach(s.Setup)
39+
AfterEach(s.TearDown)
40+
It("succeeded", func() {
41+
RunTest(s.II)
42+
})
43+
})
44+
}
45+
})
46+
47+
var testObjects = []views.SomeObject{
48+
{
49+
Owner: "Boss",
50+
Value: 100,
51+
},
52+
{
53+
Owner: "Bob",
54+
Value: 200,
55+
},
56+
{
57+
Owner: "RedHotChilli",
58+
Value: 900,
59+
},
60+
{
61+
Owner: "DogsEatCarrots",
62+
Value: 600,
63+
},
64+
}
65+
66+
// This object has a negative value, it should return an error from the test.
67+
var negativeTestObjects = []views.SomeObject{
68+
{
69+
Owner: "TigerEatsGrass",
70+
Value: -100,
71+
},
72+
}
73+
74+
func RunTest(n *integration.Infrastructure) {
75+
// create some objects
76+
for _, obj := range testObjects {
77+
res, err := n.Client(simple.CreatorNode).CallView("create", nwocommon.JSONMarshall(views.CreateParams{
78+
Owner: obj.Owner,
79+
Value: obj.Value,
80+
Namespace: simple.Namespace,
81+
Approvers: []view.Identity{n.Identity(simple.ApproverNode)},
82+
}))
83+
Expect(err).NotTo(HaveOccurred())
84+
_ = res
85+
}
86+
87+
// try to create one of our objects again, this should fail and return with an error
88+
someExistingObject := testObjects[0]
89+
_, err := n.Client(simple.CreatorNode).CallView("create", nwocommon.JSONMarshall(views.CreateParams{
90+
Owner: someExistingObject.Owner,
91+
Value: someExistingObject.Value,
92+
Namespace: simple.Namespace,
93+
Approvers: []view.Identity{n.Identity(simple.ApproverNode)},
94+
}))
95+
Expect(err).To(HaveOccurred())
96+
97+
// try to create an object with a negative value, this should fail and return with an error
98+
someAbsurdObject := negativeTestObjects[0]
99+
_, err = n.Client(simple.CreatorNode).CallView("create", nwocommon.JSONMarshall(views.CreateParams{
100+
Owner: someAbsurdObject.Owner,
101+
Value: someAbsurdObject.Value,
102+
Namespace: simple.Namespace,
103+
Approvers: []view.Identity{n.Identity(simple.ApproverNode)},
104+
}))
105+
Expect(err).To(HaveOccurred())
106+
107+
// lets see that we can query all our objects
108+
lookupIDs := make([]string, len(testObjects))
109+
for i, obj := range testObjects {
110+
linearID, errx := obj.GetLinearID()
111+
Expect(errx).ToNot(HaveOccurred())
112+
lookupIDs[i] = linearID
113+
}
114+
115+
res, err := n.Client(simple.CreatorNode).CallView("query", nwocommon.JSONMarshall(views.QueryParams{
116+
SomeIDs: lookupIDs,
117+
Namespace: simple.Namespace,
118+
}))
119+
Expect(err).ToNot(HaveOccurred())
120+
121+
raw, ok := res.([]byte)
122+
Expect(ok).To(BeTrue())
123+
var objs []views.SomeObject
124+
nwocommon.JSONUnmarshal(raw, &objs)
125+
Expect(objs).To(ConsistOf(testObjects))
126+
127+
// do some lookup which do not exist
128+
_, err = n.Client(simple.CreatorNode).CallView("query", nwocommon.JSONMarshall(views.QueryParams{
129+
SomeIDs: []string{"doo", "boo", "bong", "ding"},
130+
Namespace: simple.Namespace,
131+
}))
132+
Expect(err).ToNot(HaveOccurred())
133+
}
134+
135+
func NewTestSuite(commType nwofsc.P2PCommunicationType) *TestSuite {
136+
return &TestSuite{integration.NewTestSuite(func() (*integration.Infrastructure, error) {
137+
ii, err := integration.New(integration.IOUPort.StartPortForNode(), testDataPath, simple.Topology(&simple.SDK{}, commType)...)
138+
if err != nil {
139+
return nil, err
140+
}
141+
142+
ii.RegisterPlatformFactory(nwofabricx.NewPlatformFactory())
143+
144+
ii.DeleteOnStart = true
145+
ii.DeleteOnStop = false
146+
147+
ii.Generate()
148+
149+
return ii, nil
150+
})}
151+
}

integration/fabricx/simple/topo.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package simple
8+
9+
import (
10+
simpleviews "github.com/hyperledger-labs/fabric-smart-client/integration/fabricx/simple/views"
11+
"github.com/hyperledger-labs/fabric-smart-client/integration/nwo/api"
12+
"github.com/hyperledger-labs/fabric-smart-client/integration/nwo/fabric"
13+
nwofabricx "github.com/hyperledger-labs/fabric-smart-client/integration/nwo/fabricx"
14+
"github.com/hyperledger-labs/fabric-smart-client/integration/nwo/fabricx/extensions/scv2"
15+
"github.com/hyperledger-labs/fabric-smart-client/integration/nwo/fsc"
16+
"github.com/hyperledger-labs/fabric-smart-client/pkg/node"
17+
)
18+
19+
const (
20+
ApproverNode = "approver"
21+
CreatorNode = "creator"
22+
Namespace = "simple"
23+
)
24+
25+
func Topology(sdk node.SDK, commType fsc.P2PCommunicationType) []api.Topology {
26+
fabricTopology := nwofabricx.NewDefaultTopology()
27+
fabricTopology.AddOrganizationsByName("Org1")
28+
fabricTopology.AddNamespaceWithUnanimity(Namespace, "Org1")
29+
30+
fscTopology := fsc.NewTopology()
31+
fscTopology.P2PCommunicationType = commType
32+
fscTopology.SetLogging("grpc=error:fabricx=debug:info", "")
33+
34+
fscTopology.AddNodeByName(ApproverNode).
35+
AddOptions(fabric.WithOrganization("Org1")).
36+
AddOptions(scv2.WithApproverRole()).
37+
// simple approval
38+
RegisterResponder(&simpleviews.ApproveView{}, &simpleviews.CreateView{})
39+
40+
fscTopology.AddNodeByName(CreatorNode).
41+
AddOptions(fabric.WithOrganization("Org1")).
42+
// simple logic
43+
RegisterViewFactory("create", &simpleviews.CreateViewFactory{}).
44+
RegisterViewFactory("query", &simpleviews.QueryViewFactory{})
45+
46+
fscTopology.AddSDK(sdk)
47+
48+
return []api.Topology{
49+
fabricTopology,
50+
fscTopology,
51+
}
52+
}

0 commit comments

Comments
 (0)