Skip to content

Commit dff291a

Browse files
committed
[FAB-9225] Add e2e test suite
This is the basic e2e test. Change-Id: If2523b27f0e838a97f75dac00c4004f67faa8f6f Signed-off-by: Latitia M Haskins <latitia.haskins@gmail.com> Signed-off-by: William Lahti <wtlahti@us.ibm.com>
1 parent 797ba12 commit dff291a

10 files changed

+1529
-1
lines changed

integration/e2e/e2e_suite_test.go

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
Copyright IBM Corp All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package e2e
8+
9+
import (
10+
"encoding/json"
11+
"io/ioutil"
12+
"os"
13+
14+
"github.com/hyperledger/fabric/integration/world"
15+
. "github.com/onsi/ginkgo"
16+
. "github.com/onsi/gomega"
17+
18+
"testing"
19+
)
20+
21+
func TestEndToEnd(t *testing.T) {
22+
RegisterFailHandler(Fail)
23+
RunSpecs(t, "EndToEnd Suite")
24+
}
25+
26+
var (
27+
components *world.Components
28+
testDir string
29+
)
30+
31+
var _ = SynchronizedBeforeSuite(func() []byte {
32+
components = &world.Components{}
33+
components.Build()
34+
35+
payload, err := json.Marshal(components)
36+
Expect(err).NotTo(HaveOccurred())
37+
38+
return payload
39+
}, func(payload []byte) {
40+
err := json.Unmarshal(payload, &components)
41+
Expect(err).NotTo(HaveOccurred())
42+
43+
testDir, err = ioutil.TempDir("", "e2e-suite")
44+
Expect(err).NotTo(HaveOccurred())
45+
})
46+
47+
var _ = SynchronizedAfterSuite(func() {
48+
os.RemoveAll(testDir)
49+
}, func() {
50+
components.Cleanup()
51+
})

integration/e2e/e2e_test.go

+339
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
/*
2+
Copyright IBM Corp All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package e2e
8+
9+
import (
10+
"fmt"
11+
"io/ioutil"
12+
"os"
13+
"path/filepath"
14+
"strings"
15+
"syscall"
16+
"time"
17+
18+
docker "github.com/fsouza/go-dockerclient"
19+
"github.com/hyperledger/fabric/common/tools/configtxgen/localconfig"
20+
"github.com/hyperledger/fabric/integration/runner"
21+
"github.com/hyperledger/fabric/integration/world"
22+
. "github.com/onsi/ginkgo"
23+
. "github.com/onsi/gomega"
24+
"github.com/onsi/gomega/gbytes"
25+
26+
"github.com/tedsuo/ifrit"
27+
)
28+
29+
var _ = Describe("EndToEnd", func() {
30+
var (
31+
testdataDir string
32+
client *docker.Client
33+
network *docker.Network
34+
w world.World
35+
)
36+
37+
BeforeEach(func() {
38+
var err error
39+
40+
testdataDir, err = filepath.Abs("testdata")
41+
Expect(err).NotTo(HaveOccurred())
42+
client, err = docker.NewClientFromEnv()
43+
Expect(err).NotTo(HaveOccurred())
44+
45+
pOrg := []*localconfig.Organization{{
46+
Name: "Org1",
47+
ID: "Org1MSP",
48+
MSPDir: "crypto/peerOrganizations/org1.example.com/msp",
49+
AnchorPeers: []*localconfig.AnchorPeer{{
50+
Host: "0.0.0.0",
51+
Port: 7051,
52+
}},
53+
}, {
54+
Name: "Org2",
55+
ID: "Org2MSP",
56+
MSPDir: "crypto/peerOrganizations/org2.example.com/msp",
57+
AnchorPeers: []*localconfig.AnchorPeer{{
58+
Host: "0.0.0.0",
59+
Port: 8051,
60+
}},
61+
}}
62+
63+
ordererOrgs := world.OrdererConfig{
64+
OrganizationName: "OrdererOrg",
65+
Domain: "example.com",
66+
ProfileName: "TwoOrgsOrdererGenesis",
67+
OrdererNames: []string{"orderer"},
68+
BrokerCount: 0,
69+
}
70+
71+
peerOrgs := []world.PeerOrgConfig{{
72+
OrganizationName: pOrg[0].Name,
73+
ProfileName: "TwoOrgsChannel",
74+
Domain: "org1.example.com",
75+
EnableNodeOUs: false,
76+
UserCount: 1,
77+
PeerCount: 1,
78+
}, {
79+
OrganizationName: pOrg[1].Name,
80+
ProfileName: "TwoOrgsChannel",
81+
Domain: "org2.example.com",
82+
EnableNodeOUs: false,
83+
UserCount: 1,
84+
PeerCount: 1,
85+
}}
86+
87+
oOrg := []*localconfig.Organization{{
88+
Name: ordererOrgs.OrganizationName,
89+
ID: "OrdererMSP",
90+
MSPDir: filepath.Join("crypto", "ordererOrganizations", "example.com", "orderers", "orderer.example.com", "msp"),
91+
}}
92+
93+
deployment := world.Deployment{
94+
SystemChannel: "systestchannel",
95+
Channel: "testchannel",
96+
Chaincode: world.Chaincode{
97+
Name: "mycc",
98+
Version: "1.0",
99+
Path: filepath.Join("simple", "cmd"),
100+
GoPath: filepath.Join(testDir, "chaincode"),
101+
ExecPath: os.Getenv("PATH"),
102+
},
103+
InitArgs: `{"Args":["init","a","100","b","200"]}`,
104+
Peers: []string{"peer0.org1.example.com", "peer0.org2.example.com"},
105+
Policy: `OR ('Org1MSP.member','Org2MSP.member')`,
106+
Orderer: "127.0.0.1:7050",
107+
}
108+
109+
peerProfile := localconfig.Profile{
110+
Consortium: "SampleConsortium",
111+
Application: &localconfig.Application{
112+
Organizations: pOrg,
113+
Capabilities: map[string]bool{
114+
"V1_2": true,
115+
},
116+
},
117+
Capabilities: map[string]bool{
118+
"V1_1": true,
119+
},
120+
}
121+
122+
orderer := &localconfig.Orderer{
123+
BatchTimeout: 1 * time.Second,
124+
BatchSize: localconfig.BatchSize{
125+
MaxMessageCount: 1,
126+
AbsoluteMaxBytes: (uint32)(98 * 1024 * 1024),
127+
PreferredMaxBytes: (uint32)(512 * 1024),
128+
},
129+
Kafka: localconfig.Kafka{
130+
Brokers: []string{
131+
"127.0.0.1:9092",
132+
"127.0.0.1:8092",
133+
"127.0.0.1:7092",
134+
"127.0.0.1:6092",
135+
},
136+
},
137+
Organizations: oOrg,
138+
OrdererType: "solo",
139+
Addresses: []string{"0.0.0.0:7050"},
140+
Capabilities: map[string]bool{"V1_1": true},
141+
}
142+
143+
ordererProfile := localconfig.Profile{
144+
Application: &localconfig.Application{
145+
Organizations: oOrg,
146+
Capabilities: map[string]bool{"V1_2": true}},
147+
Orderer: orderer,
148+
Consortiums: map[string]*localconfig.Consortium{
149+
"SampleConsortium": &localconfig.Consortium{
150+
Organizations: append(oOrg, pOrg...),
151+
},
152+
},
153+
Capabilities: map[string]bool{"V1_1": true},
154+
}
155+
156+
profiles := map[string]localconfig.Profile{
157+
peerOrgs[0].ProfileName: peerProfile,
158+
ordererOrgs.ProfileName: ordererProfile,
159+
}
160+
161+
crypto := runner.Cryptogen{
162+
Config: filepath.Join(testDir, "crypto.yaml"),
163+
Output: filepath.Join(testDir, "crypto"),
164+
}
165+
166+
w = world.World{
167+
Rootpath: testDir,
168+
Components: components,
169+
Cryptogen: crypto,
170+
Deployment: deployment,
171+
OrdererOrgs: []world.OrdererConfig{ordererOrgs},
172+
PeerOrgs: peerOrgs,
173+
OrdererProfileName: ordererOrgs.ProfileName,
174+
ChannelProfileName: peerOrgs[0].ProfileName,
175+
Profiles: profiles,
176+
}
177+
})
178+
179+
AfterEach(func() {
180+
// Stop the docker constainers for zookeeper and kafka
181+
for _, cont := range w.LocalStoppers {
182+
cont.Stop()
183+
}
184+
185+
// Stop the running chaincode containers
186+
filters := map[string][]string{}
187+
filters["name"] = []string{fmt.Sprintf("%s-%s", w.Deployment.Chaincode.Name, w.Deployment.Chaincode.Version)}
188+
allContainers, _ := client.ListContainers(docker.ListContainersOptions{
189+
Filters: filters,
190+
})
191+
if len(allContainers) > 0 {
192+
for _, container := range allContainers {
193+
client.RemoveContainer(docker.RemoveContainerOptions{
194+
ID: container.ID,
195+
Force: true,
196+
})
197+
}
198+
}
199+
200+
// Remove chaincode image
201+
filters = map[string][]string{}
202+
filters["label"] = []string{fmt.Sprintf("org.hyperledger.fabric.chaincode.id.name=%s", w.Deployment.Chaincode.Name)}
203+
images, _ := client.ListImages(docker.ListImagesOptions{
204+
Filters: filters,
205+
})
206+
if len(images) > 0 {
207+
for _, image := range images {
208+
client.RemoveImage(image.ID)
209+
}
210+
}
211+
212+
// Stop the orderers and peers
213+
for _, localProc := range w.LocalProcess {
214+
localProc.Signal(syscall.SIGTERM)
215+
}
216+
217+
// Remove any started networks
218+
if network != nil {
219+
client.RemoveNetwork(network.Name)
220+
}
221+
})
222+
223+
It("executes a basic solo network with 2 orgs", func() {
224+
By("generating files to bootstrap the network")
225+
w.BootstrapNetwork()
226+
Expect(filepath.Join(testDir, "configtx.yaml")).To(BeARegularFile())
227+
Expect(filepath.Join(testDir, "crypto.yaml")).To(BeARegularFile())
228+
Expect(filepath.Join(testDir, "crypto", "peerOrganizations")).To(BeADirectory())
229+
Expect(filepath.Join(testDir, "crypto", "ordererOrganizations")).To(BeADirectory())
230+
Expect(filepath.Join(testDir, "systestchannel_block.pb")).To(BeARegularFile())
231+
Expect(filepath.Join(testDir, "testchannel_tx.pb")).To(BeARegularFile())
232+
Expect(filepath.Join(testDir, "Org1_anchors_update_tx.pb")).To(BeARegularFile())
233+
Expect(filepath.Join(testDir, "Org2_anchors_update_tx.pb")).To(BeARegularFile())
234+
235+
By("setting up directories for the network")
236+
copyFile(filepath.Join("testdata", "orderer.yaml"), filepath.Join(testDir, "orderer.yaml"))
237+
copyPeerConfigs(w.PeerOrgs, w.Rootpath)
238+
239+
By("building the network")
240+
w.BuildNetwork()
241+
242+
By("setting up the channel")
243+
copyDir(filepath.Join("testdata", "chaincode"), filepath.Join(testDir, "chaincode"))
244+
err := w.SetupChannel()
245+
Expect(err).NotTo(HaveOccurred())
246+
247+
By("verifying the chaincode is installed")
248+
adminPeer := components.Peer()
249+
adminPeer.ConfigDir = filepath.Join(testDir, "org1.example.com_0")
250+
adminPeer.MSPConfigPath = filepath.Join(testDir, "crypto", "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
251+
adminRunner := adminPeer.ChaincodeListInstalled()
252+
execute(adminRunner)
253+
Eventually(adminRunner.Buffer()).Should(gbytes.Say("Path: simple/cmd"))
254+
255+
By("waiting for the chaincode to complete instantiation")
256+
listInstantiated := func() bool {
257+
p := components.Peer()
258+
p.ConfigDir = filepath.Join(testDir, "org1.example.com_0")
259+
p.MSPConfigPath = filepath.Join(testDir, "crypto", "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
260+
adminRunner := p.ChaincodeListInstantiated(w.Deployment.Channel)
261+
err := execute(adminRunner)
262+
if err != nil {
263+
return false
264+
}
265+
return strings.Contains(string(adminRunner.Buffer().Contents()), "Path: simple/cmd")
266+
}
267+
Eventually(listInstantiated, 30*time.Second, 500*time.Millisecond).Should(BeTrue())
268+
269+
By("querying the chaincode")
270+
adminPeer = components.Peer()
271+
adminPeer.LogLevel = "debug"
272+
adminPeer.ConfigDir = filepath.Join(testDir, "org1.example.com_0")
273+
adminPeer.MSPConfigPath = filepath.Join(testDir, "crypto", "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
274+
adminRunner = adminPeer.QueryChaincode(w.Deployment.Chaincode.Name, w.Deployment.Channel, `{"Args":["query","a"]}`)
275+
execute(adminRunner)
276+
Eventually(adminRunner.Buffer()).Should(gbytes.Say("100"))
277+
278+
By("invoking the chaincode")
279+
adminRunner = adminPeer.InvokeChaincode(w.Deployment.Chaincode.Name, w.Deployment.Channel, `{"Args":["invoke","a","b","10"]}`, w.Deployment.Orderer)
280+
execute(adminRunner)
281+
Eventually(adminRunner.Err()).Should(gbytes.Say("Chaincode invoke successful. result: status:200"))
282+
283+
By("querying the chaincode again")
284+
adminRunner = adminPeer.QueryChaincode(w.Deployment.Chaincode.Name, w.Deployment.Channel, `{"Args":["query","a"]}`)
285+
execute(adminRunner)
286+
Eventually(adminRunner.Buffer()).Should(gbytes.Say("90"))
287+
288+
By("updating the channel")
289+
adminPeer = components.Peer()
290+
adminPeer.ConfigDir = filepath.Join(testDir, "org1.example.com_0")
291+
adminPeer.MSPConfigPath = filepath.Join(testDir, "crypto", "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
292+
adminRunner = adminPeer.UpdateChannel(filepath.Join(testDir, "Org1_anchors_update_tx.pb"), w.Deployment.Channel, w.Deployment.Orderer)
293+
execute(adminRunner)
294+
Eventually(adminRunner.Err()).Should(gbytes.Say("Successfully submitted channel update"))
295+
})
296+
})
297+
298+
func copyFile(src, dest string) {
299+
data, err := ioutil.ReadFile(src)
300+
Expect(err).NotTo(HaveOccurred())
301+
err = ioutil.WriteFile(dest, data, 0775)
302+
Expect(err).NotTo(HaveOccurred())
303+
}
304+
305+
func copyDir(src, dest string) {
306+
os.MkdirAll(dest, 0755)
307+
objects, err := ioutil.ReadDir(src)
308+
for _, obj := range objects {
309+
srcfileptr := src + "/" + obj.Name()
310+
destfileptr := dest + "/" + obj.Name()
311+
if obj.IsDir() {
312+
copyDir(srcfileptr, destfileptr)
313+
} else {
314+
copyFile(srcfileptr, destfileptr)
315+
}
316+
}
317+
Expect(err).NotTo(HaveOccurred())
318+
}
319+
320+
func execute(r ifrit.Runner) (err error) {
321+
p := ifrit.Invoke(r)
322+
Eventually(p.Ready()).Should(BeClosed())
323+
Eventually(p.Wait(), 10*time.Second).Should(Receive(&err))
324+
return err
325+
}
326+
327+
func copyPeerConfigs(peerOrgs []world.PeerOrgConfig, rootPath string) {
328+
for _, peerOrg := range peerOrgs {
329+
for peer := 0; peer < peerOrg.PeerCount; peer++ {
330+
peerDir := fmt.Sprintf("%s_%d", peerOrg.Domain, peer)
331+
if _, err := os.Stat(filepath.Join(rootPath, peerDir)); os.IsNotExist(err) {
332+
err := os.Mkdir(filepath.Join(rootPath, peerDir), 0755)
333+
Expect(err).NotTo(HaveOccurred())
334+
}
335+
copyFile(filepath.Join("testdata", fmt.Sprintf("%s-core.yaml", peerDir)),
336+
filepath.Join(rootPath, peerDir, "core.yaml"))
337+
}
338+
}
339+
}

0 commit comments

Comments
 (0)