Skip to content

Commit 797ba12

Browse files
committed
[FAB-9901] Add test config structure and tests
This adds the test config structure. Change-Id: Ibfe5d4655461cc4ab1d83017b759b63f5a38578c Signed-off-by: Latitia M Haskins <latitia.haskins@gmail.com> Signed-off-by: William Lahti <wtlahti@us.ibm.com>
1 parent f00890a commit 797ba12

16 files changed

+2104
-9
lines changed

Gopkg.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration/runner/testdata/configtx.yaml

+4-4
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ Organizations:
3737
ID: Org1MSP
3838
MSPDir: crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
3939
AnchorPeers:
40-
- Host: peer0.org1.example.com
41-
Port: 7051
40+
- Host: 127.0.0.1
41+
Port: 11051
4242
- &Org2
4343
Name: Org2
4444
ID: Org2MSP
4545
MSPDir: crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
4646
AnchorPeers:
47-
- Host: peer0.org2.example.com
48-
Port: 7051
47+
- Host: 127.0.0.1
48+
Port: 8051
4949
Orderer: &OrdererDefaults
5050
OrdererType: solo
5151
Addresses:

integration/runner/testdata/core.yaml

+5-4
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ logging:
1818
peer:
1919
id: jdoe
2020
networkId: dev
21-
listenAddress: 0.0.0.0:7051
22-
address: 0.0.0.0:7051
21+
listenAddress: 0.0.0.0:12051
22+
chaincodeListenAddress: 0.0.0.0:12052
23+
address: 0.0.0.0:12051
2324
addressAutoDetect: false
2425
gomaxprocs: -1
2526
keepalive:
@@ -31,7 +32,7 @@ peer:
3132
interval: 60s
3233
timeout: 20s
3334
gossip:
34-
bootstrap: 127.0.0.1:7051
35+
bootstrap: 127.0.0.1:12051
3536
useLeaderElection: true
3637
orgLeader: false
3738
endpoint:
@@ -68,7 +69,7 @@ peer:
6869
transientstoreMaxBlockRetention: 1000
6970
pushAckTimeout: 3s
7071
events:
71-
address: 0.0.0.0:7053
72+
address: 0.0.0.0:12053
7273
buffersize: 100
7374
timeout: 10ms
7475
timewindow: 15m

integration/world/components.go

+8
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ package world
99
import (
1010
"fmt"
1111
"os"
12+
"time"
1213

1314
docker "github.com/fsouza/go-dockerclient"
1415
"github.com/hyperledger/fabric/integration/runner"
1516
. "github.com/onsi/gomega"
1617
"github.com/onsi/gomega/gexec"
18+
"github.com/tedsuo/ifrit"
1719
)
1820

1921
type Components struct {
@@ -80,3 +82,9 @@ func (c *Components) Zookeeper(id int, network *docker.Network) *runner.Zookeepe
8082
NetworkName: network.Name,
8183
}
8284
}
85+
86+
func execute(r ifrit.Runner) {
87+
p := ifrit.Invoke(r)
88+
Eventually(p.Ready(), 2*time.Second).Should(BeClosed())
89+
Eventually(p.Wait(), 45*time.Second).Should(Receive(BeNil()))
90+
}

integration/world/config.go

+266
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
/*
2+
Copyright IBM Corp All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
package world
7+
8+
import (
9+
"bytes"
10+
"fmt"
11+
"io"
12+
"io/ioutil"
13+
"path/filepath"
14+
"strings"
15+
"time"
16+
17+
"github.com/alecthomas/template"
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/onsi/gomega"
22+
"github.com/onsi/gomega/gbytes"
23+
"github.com/tedsuo/ifrit"
24+
yaml "gopkg.in/yaml.v2"
25+
)
26+
27+
type Profile struct {
28+
Profiles map[string]localconfig.Profile `yaml:"Profiles"`
29+
}
30+
31+
type OrdererConfig struct {
32+
OrganizationName string
33+
ProfileName string
34+
Domain string
35+
OrdererNames []string
36+
BrokerCount int // 0 is solo
37+
ZookeeperCount int
38+
KafkaMinInsyncReplicas int
39+
KafkaDefaultReplicationFactor int
40+
}
41+
42+
type PeerOrgConfig struct {
43+
OrganizationName string
44+
ProfileName string
45+
Domain string
46+
EnableNodeOUs bool
47+
UserCount int
48+
PeerCount int
49+
}
50+
51+
type Stopper interface {
52+
Stop() error
53+
}
54+
55+
type World struct {
56+
Rootpath string
57+
Components *Components
58+
Network *docker.Network
59+
OrdererProfileName string
60+
ChannelProfileName string
61+
OrdererOrgs []OrdererConfig
62+
PeerOrgs []PeerOrgConfig
63+
Profiles map[string]localconfig.Profile
64+
Cryptogen runner.Cryptogen
65+
Deployment Deployment
66+
67+
LocalStoppers []Stopper
68+
LocalProcess []ifrit.Process
69+
}
70+
71+
type Chaincode struct {
72+
Name string
73+
Path string
74+
Version string
75+
GoPath string
76+
ExecPath string
77+
}
78+
79+
type Deployment struct {
80+
Chaincode Chaincode
81+
SystemChannel string
82+
Channel string
83+
InitArgs string
84+
Policy string
85+
Orderer string
86+
Peers []string
87+
}
88+
89+
func (w *World) Construct() {
90+
var ordererCrypto = `
91+
OrdererOrgs:{{range .OrdererOrgs}}
92+
- Name: {{.OrganizationName}}
93+
Domain: {{.Domain}}
94+
CA:
95+
Country: US
96+
Province: California
97+
Locality: San Francisco
98+
Specs:{{range .OrdererNames}}
99+
- Hostname: {{.}}{{end}}
100+
{{end}}`
101+
102+
var peerCrypto = `
103+
PeerOrgs:{{range .PeerOrgs}}
104+
- Name: {{.OrganizationName}}
105+
Domain: {{.Domain}}
106+
EnableNodeOUs: {{.EnableNodeOUs}}
107+
CA:
108+
Country: US
109+
Province: California
110+
Locality: San Francisco
111+
Template:
112+
Count: {{.PeerCount}}
113+
Users:
114+
Count: {{.UserCount}}
115+
{{end}}`
116+
117+
// Generates the crypto config
118+
buf := &bytes.Buffer{}
119+
w.buildTemplate(buf, ordererCrypto)
120+
w.buildTemplate(buf, peerCrypto)
121+
err := ioutil.WriteFile(filepath.Join(w.Rootpath, "crypto.yaml"), buf.Bytes(), 0644)
122+
Expect(err).NotTo(HaveOccurred())
123+
124+
// Generates the configtx config
125+
type profiles struct {
126+
Profiles map[string]localconfig.Profile `yaml:"Profiles"`
127+
}
128+
profileData, err := yaml.Marshal(&profiles{w.Profiles})
129+
Expect(err).NotTo(HaveOccurred())
130+
err = ioutil.WriteFile(filepath.Join(w.Rootpath, "configtx.yaml"), profileData, 0644)
131+
Expect(err).NotTo(HaveOccurred())
132+
}
133+
134+
func (w *World) buildTemplate(writer io.Writer, orgTemplate string) {
135+
tmpl, err := template.New("org").Parse(orgTemplate)
136+
Expect(err).NotTo(HaveOccurred())
137+
err = tmpl.Execute(writer, w)
138+
Expect(err).NotTo(HaveOccurred())
139+
}
140+
141+
func (w *World) BootstrapNetwork() {
142+
w.Construct()
143+
144+
w.Cryptogen.Path = w.Components.Paths["cryptogen"]
145+
r := w.Cryptogen.Generate()
146+
execute(r)
147+
148+
configtxgen := runner.Configtxgen{
149+
Path: w.Components.Paths["configtxgen"],
150+
ChannelID: w.Deployment.SystemChannel,
151+
Profile: w.OrdererProfileName,
152+
ConfigDir: w.Rootpath,
153+
Output: filepath.Join(w.Rootpath, fmt.Sprintf("%s_block.pb", w.Deployment.SystemChannel)),
154+
}
155+
r = configtxgen.OutputBlock()
156+
execute(r)
157+
158+
configtxgen = runner.Configtxgen{
159+
Path: w.Components.Paths["configtxgen"],
160+
ChannelID: w.Deployment.Channel,
161+
Profile: w.ChannelProfileName,
162+
ConfigDir: w.Rootpath,
163+
Output: filepath.Join(w.Rootpath, fmt.Sprintf("%s_tx.pb", w.Deployment.Channel)),
164+
}
165+
r = configtxgen.OutputCreateChannelTx()
166+
execute(r)
167+
168+
for _, peer := range w.PeerOrgs {
169+
configtxgen = runner.Configtxgen{
170+
Path: w.Components.Paths["configtxgen"],
171+
ChannelID: w.Deployment.Channel,
172+
AsOrg: peer.OrganizationName,
173+
Profile: w.ChannelProfileName,
174+
ConfigDir: w.Rootpath,
175+
Output: filepath.Join(w.Rootpath, fmt.Sprintf("%s_anchors_update_tx.pb", peer.OrganizationName)),
176+
}
177+
r = configtxgen.OutputAnchorPeersUpdate()
178+
execute(r)
179+
}
180+
}
181+
182+
func (w *World) BuildNetwork() {
183+
w.ordererNetwork()
184+
w.peerNetwork()
185+
}
186+
187+
func (w *World) ordererNetwork() {
188+
var o *runner.Orderer
189+
190+
o = w.Components.Orderer()
191+
o.ConfigDir = w.Rootpath
192+
o.LedgerLocation = filepath.Join(w.Rootpath, "ledger")
193+
o.LogLevel = "debug"
194+
ordererRunner := o.New()
195+
ordererProcess := ifrit.Invoke(ordererRunner)
196+
Eventually(ordererProcess.Ready()).Should(BeClosed())
197+
Consistently(ordererProcess.Wait()).ShouldNot(Receive())
198+
w.LocalProcess = append(w.LocalProcess, ordererProcess)
199+
}
200+
201+
func (w *World) peerNetwork() {
202+
var p *runner.Peer
203+
204+
for _, peerOrg := range w.PeerOrgs {
205+
for peer := 0; peer < peerOrg.PeerCount; peer++ {
206+
p = w.Components.Peer()
207+
p.ConfigDir = filepath.Join(w.Rootpath, fmt.Sprintf("%s_%d", peerOrg.Domain, peer))
208+
peerProcess := ifrit.Invoke(p.NodeStart())
209+
Eventually(peerProcess.Ready()).Should(BeClosed())
210+
Consistently(peerProcess.Wait()).ShouldNot(Receive())
211+
w.LocalProcess = append(w.LocalProcess, peerProcess)
212+
}
213+
}
214+
}
215+
216+
func (w *World) SetupChannel() error {
217+
var p *runner.Peer
218+
219+
p = w.Components.Peer()
220+
p.ConfigDir = filepath.Join(w.Rootpath, "org1.example.com_0")
221+
p.LogLevel = "debug"
222+
p.MSPConfigPath = filepath.Join(w.Rootpath, "crypto", "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
223+
adminRunner := p.CreateChannel(w.Deployment.Channel, filepath.Join(w.Rootpath, fmt.Sprintf("%s_tx.pb", w.Deployment.Channel)), w.Deployment.Orderer)
224+
execute(adminRunner)
225+
226+
for _, peerOrg := range w.PeerOrgs {
227+
for peer := 0; peer < peerOrg.PeerCount; peer++ {
228+
p = w.Components.Peer()
229+
peerDir := fmt.Sprintf("%s_%d", peerOrg.Domain, peer)
230+
p.LogLevel = "debug"
231+
p.ConfigDir = filepath.Join(w.Rootpath, peerDir)
232+
p.MSPConfigPath = filepath.Join(w.Rootpath, "crypto", "peerOrganizations", peerOrg.Domain, "users", fmt.Sprintf("Admin@%s", peerOrg.Domain), "msp")
233+
adminRunner = p.FetchChannel(w.Deployment.Channel, filepath.Join(w.Rootpath, peerDir, fmt.Sprintf("%s_block.pb", w.Deployment.Channel)), "0", w.Deployment.Orderer)
234+
execute(adminRunner)
235+
Expect(adminRunner.Err()).To(gbytes.Say("Received block: 0"))
236+
237+
adminRunner = p.JoinChannel(filepath.Join(w.Rootpath, peerDir, fmt.Sprintf("%s_block.pb", w.Deployment.Channel)))
238+
execute(adminRunner)
239+
Expect(adminRunner.Err()).To(gbytes.Say("Successfully submitted proposal to join channel"))
240+
241+
p.ExecPath = w.Deployment.Chaincode.ExecPath
242+
p.GoPath = w.Deployment.Chaincode.GoPath
243+
adminRunner = p.InstallChaincode(w.Deployment.Chaincode.Name, w.Deployment.Chaincode.Version, w.Deployment.Chaincode.Path)
244+
execute(adminRunner)
245+
Expect(adminRunner.Err()).To(gbytes.Say(`\QInstalled remotely response:<status:200 payload:"OK" >\E`))
246+
}
247+
}
248+
249+
p = w.Components.Peer()
250+
p.ConfigDir = filepath.Join(w.Rootpath, "org1.example.com_0")
251+
p.MSPConfigPath = filepath.Join(w.Rootpath, "crypto", "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
252+
adminRunner = p.InstantiateChaincode(w.Deployment.Chaincode.Name, w.Deployment.Chaincode.Version, w.Deployment.Orderer, w.Deployment.Channel, w.Deployment.InitArgs, w.Deployment.Policy)
253+
execute(adminRunner)
254+
255+
listInstantiated := func() bool {
256+
p = w.Components.Peer()
257+
p.ConfigDir = filepath.Join(w.Rootpath, "org1.example.com_0")
258+
p.MSPConfigPath = filepath.Join(w.Rootpath, "crypto", "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
259+
adminRunner = p.ChaincodeListInstantiated(w.Deployment.Channel)
260+
execute(adminRunner)
261+
return strings.Contains(string(adminRunner.Buffer().Contents()), fmt.Sprintf("Path: %s", w.Deployment.Chaincode.Path))
262+
}
263+
Eventually(listInstantiated, 30*time.Second, 500*time.Millisecond).Should(BeTrue())
264+
265+
return nil
266+
}

0 commit comments

Comments
 (0)