Commit cee7e9b1 authored by Latitia M Haskins's avatar Latitia M Haskins Committed by Gari Singh
Browse files

[FAB-10255] Consolidate the chaincode for tests



Instead of each test setup having it's own copy
of chaincode we should have a single chaincodei directory containing
chaincode that can be accessed.

Change-Id: I93916f9875f9d8d302d7a42f2488536050614bfb
Signed-off-by: default avatarLatitia M. Haskins <latitia.haskins@gmail.com>
parent 36eca57b
......@@ -10,9 +10,8 @@ import (
"fmt"
"os"
"simple"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/integration/chaincode/simple"
)
func main() {
......
......@@ -11,7 +11,6 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"syscall"
"time"
......@@ -93,8 +92,7 @@ var _ = Describe("EndToEnd", func() {
Chaincode: world.Chaincode{
Name: "mycc",
Version: "1.0",
Path: filepath.Join("simple", "cmd"),
GoPath: filepath.Join(testDir, "chaincode"),
Path: "github.com/hyperledger/fabric/integration/chaincode/simple/cmd",
ExecPath: os.Getenv("PATH"),
},
InitArgs: `{"Args":["init","a","100","b","200"]}`,
......@@ -237,38 +235,15 @@ var _ = Describe("EndToEnd", func() {
w.BuildNetwork()
By("setting up the channel")
copyDir(filepath.Join("testdata", "chaincode"), filepath.Join(testDir, "chaincode"))
err := w.SetupChannel()
Expect(err).NotTo(HaveOccurred())
By("verifying the chaincode is installed")
adminPeer := components.Peer()
adminPeer.ConfigDir = filepath.Join(testDir, "org1.example.com_0")
adminPeer.MSPConfigPath = filepath.Join(testDir, "crypto", "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
adminRunner := adminPeer.ChaincodeListInstalled()
execute(adminRunner)
Eventually(adminRunner.Buffer()).Should(gbytes.Say("Path: simple/cmd"))
By("waiting for the chaincode to complete instantiation")
listInstantiated := func() bool {
p := components.Peer()
p.ConfigDir = filepath.Join(testDir, "org1.example.com_0")
p.MSPConfigPath = filepath.Join(testDir, "crypto", "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
adminRunner := p.ChaincodeListInstantiated(w.Deployment.Channel)
err := execute(adminRunner)
if err != nil {
return false
}
return strings.Contains(string(adminRunner.Buffer().Contents()), "Path: simple/cmd")
}
Eventually(listInstantiated, 30*time.Second, 500*time.Millisecond).Should(BeTrue())
By("querying the chaincode")
adminPeer = components.Peer()
adminPeer := components.Peer()
adminPeer.LogLevel = "debug"
adminPeer.ConfigDir = filepath.Join(testDir, "org1.example.com_0")
adminPeer.MSPConfigPath = filepath.Join(testDir, "crypto", "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
adminRunner = adminPeer.QueryChaincode(w.Deployment.Chaincode.Name, w.Deployment.Channel, `{"Args":["query","a"]}`)
adminRunner := adminPeer.QueryChaincode(w.Deployment.Chaincode.Name, w.Deployment.Channel, `{"Args":["query","a"]}`)
execute(adminRunner)
Eventually(adminRunner.Buffer()).Should(gbytes.Say("100"))
......
......@@ -12,7 +12,6 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"
"syscall"
"time"
......@@ -93,8 +92,7 @@ var _ = Describe("EndToEnd", func() {
Chaincode: world.Chaincode{
Name: "mycc",
Version: "1.0",
Path: filepath.Join("simple", "cmd"),
GoPath: filepath.Join(testDir, "chaincode"),
Path: "github.com/hyperledger/fabric/integration/chaincode/simple/cmd",
ExecPath: os.Getenv("PATH"),
},
InitArgs: `{"Args":["init","a","100","b","200"]}`,
......@@ -237,7 +235,6 @@ var _ = Describe("EndToEnd", func() {
w.BuildNetwork()
By("setting up the channel")
copyDir(filepath.Join("testdata", "chaincode"), filepath.Join(testDir, "chaincode"))
err := w.SetupChannel()
Expect(err).NotTo(HaveOccurred())
......@@ -252,34 +249,12 @@ var _ = Describe("EndToEnd", func() {
activations = CountValidationPluginActivations()
Expect(activations).To(Equal(peerCount))
By("verifying the chaincode is installed")
adminPeer := components.Peer()
adminPeer.ConfigDir = filepath.Join(testDir, "org1.example.com_0")
adminPeer.MSPConfigPath = filepath.Join(testDir, "crypto", "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
adminRunner := adminPeer.ChaincodeListInstalled()
execute(adminRunner)
Eventually(adminRunner.Buffer()).Should(gbytes.Say("Path: simple/cmd"))
By("waiting for the chaincode to complete instantiation")
listInstantiated := func() bool {
p := components.Peer()
p.ConfigDir = filepath.Join(testDir, "org1.example.com_0")
p.MSPConfigPath = filepath.Join(testDir, "crypto", "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
adminRunner := p.ChaincodeListInstantiated(w.Deployment.Channel)
err := execute(adminRunner)
if err != nil {
return false
}
return strings.Contains(string(adminRunner.Buffer().Contents()), "Path: simple/cmd")
}
Eventually(listInstantiated, 30*time.Second, 500*time.Millisecond).Should(BeTrue())
By("querying the chaincode")
adminPeer = components.Peer()
adminPeer := components.Peer()
adminPeer.LogLevel = "debug"
adminPeer.ConfigDir = filepath.Join(testDir, "org1.example.com_0")
adminPeer.MSPConfigPath = filepath.Join(testDir, "crypto", "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
adminRunner = adminPeer.QueryChaincode(w.Deployment.Chaincode.Name, w.Deployment.Channel, `{"Args":["query","a"]}`)
adminRunner := adminPeer.QueryChaincode(w.Deployment.Chaincode.Name, w.Deployment.Channel, `{"Args":["query","a"]}`)
execute(adminRunner)
Eventually(adminRunner.Buffer()).Should(gbytes.Say("100"))
......@@ -310,21 +285,6 @@ func copyFile(src, dest string) {
Expect(err).NotTo(HaveOccurred())
}
func copyDir(src, dest string) {
os.MkdirAll(dest, 0755)
objects, err := ioutil.ReadDir(src)
for _, obj := range objects {
srcfileptr := src + "/" + obj.Name()
destfileptr := dest + "/" + obj.Name()
if obj.IsDir() {
copyDir(srcfileptr, destfileptr)
} else {
copyFile(srcfileptr, destfileptr)
}
}
Expect(err).NotTo(HaveOccurred())
}
func execute(r ifrit.Runner) (err error) {
p := ifrit.Invoke(r)
Eventually(p.Ready()).Should(BeClosed())
......
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package simple
import (
"fmt"
"strconv"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
fmt.Println("Init invoked")
_, args := stub.GetFunctionAndParameters()
var A, B string // Entities
var Aval, Bval int // Asset holdings
var err error
if len(args) != 4 {
return shim.Error("Incorrect number of arguments. Expecting 4")
}
// Initialize the chaincode
A = args[0]
Aval, err = strconv.Atoi(args[1])
if err != nil {
return shim.Error("Expecting integer value for asset holding")
}
B = args[2]
Bval, err = strconv.Atoi(args[3])
if err != nil {
return shim.Error("Expecting integer value for asset holding")
}
fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
// Write the state to the ledger
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
if err != nil {
return shim.Error(err.Error())
}
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
if err != nil {
return shim.Error(err.Error())
}
fmt.Println("Init returning with success")
return shim.Success(nil)
}
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
fmt.Println("ex02 Invoke")
function, args := stub.GetFunctionAndParameters()
if function == "invoke" {
// Make payment of X units from A to B
return t.invoke(stub, args)
} else if function == "delete" {
// Deletes an entity from its state
return t.delete(stub, args)
} else if function == "query" {
// the old "Query" is now implemtned in invoke
return t.query(stub, args)
}
return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"")
}
// Transaction makes payment of X units from A to B
func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response {
var A, B string // Entities
var Aval, Bval int // Asset holdings
var X int // Transaction value
var err error
if len(args) != 3 {
return shim.Error("Incorrect number of arguments. Expecting 3")
}
A = args[0]
B = args[1]
// Get the state from the ledger
// TODO: will be nice to have a GetAllState call to ledger
Avalbytes, err := stub.GetState(A)
if err != nil {
return shim.Error("Failed to get state")
}
if Avalbytes == nil {
return shim.Error("Entity not found")
}
Aval, _ = strconv.Atoi(string(Avalbytes))
Bvalbytes, err := stub.GetState(B)
if err != nil {
return shim.Error("Failed to get state")
}
if Bvalbytes == nil {
return shim.Error("Entity not found")
}
Bval, _ = strconv.Atoi(string(Bvalbytes))
// Perform the execution
X, err = strconv.Atoi(args[2])
if err != nil {
return shim.Error("Invalid transaction amount, expecting a integer value")
}
Aval = Aval - X
Bval = Bval + X
fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
// Write the state back to the ledger
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
if err != nil {
return shim.Error(err.Error())
}
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(nil)
}
// Deletes an entity from state
func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) != 1 {
return shim.Error("Incorrect number of arguments. Expecting 1")
}
A := args[0]
// Delete the key from the state in ledger
err := stub.DelState(A)
if err != nil {
return shim.Error("Failed to delete state")
}
return shim.Success(nil)
}
// query callback representing the query of a chaincode
func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {
var A string // Entities
var err error
if len(args) != 1 {
return shim.Error("Incorrect number of arguments. Expecting name of the person to query")
}
A = args[0]
// Get the state from the ledger
Avalbytes, err := stub.GetState(A)
if err != nil {
jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
return shim.Error(jsonResp)
}
if Avalbytes == nil {
jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
return shim.Error(jsonResp)
}
jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
fmt.Printf("Query Response:%s\n", jsonResp)
return shim.Success(Avalbytes)
}
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package main
import (
"fmt"
"os"
"simple"
"github.com/hyperledger/fabric/core/chaincode/shim"
)
func main() {
err := shim.Start(&simple.SimpleChaincode{})
if err != nil {
fmt.Fprintf(os.Stderr, "Exiting Simple chaincode: %s", err)
os.Exit(2)
}
}
......@@ -7,11 +7,9 @@ SPDX-License-Identifier: Apache-2.0
package runner_test
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"syscall"
"time"
......@@ -166,8 +164,8 @@ var _ = Describe("Peer", func() {
fRunner := fetchRun.FetchChannel("mychan", filepath.Join(tempDir, "mychan.block"), "0", "127.0.0.1:8050")
execute(fRunner)
time.Sleep(5 * time.Second)
Expect(string(ordererRunner.Err().Contents())).To(ContainSubstring(`[channel: mychan] Done delivering `))
Expect(string(fRunner.Err().Contents())).To(ContainSubstring("Received block: 0"))
Expect(ordererRunner.Err()).To(gbytes.Say(`\Q[channel: mychan] Done delivering \E`))
Expect(fRunner.Err()).To(gbytes.Say("Received block: 0"))
By("join channel")
joinRun := components.Peer()
......@@ -176,20 +174,19 @@ var _ = Describe("Peer", func() {
jRunner := joinRun.JoinChannel(filepath.Join(tempDir, "mychan.block"))
err = execute(jRunner)
Expect(err).NotTo(HaveOccurred())
Expect(jRunner.Err().Contents()).To(ContainSubstring("Successfully submitted proposal to join channel"))
Expect(jRunner.Err()).To(gbytes.Say("Successfully submitted proposal to join channel"))
By("installs chaincode")
copyDir(filepath.Join("testdata", "chaincode"), filepath.Join(tempDir, "chaincode"))
installCC := components.Peer()
installCC.ConfigDir = tempDir
installCC.LogLevel = "debug"
installCC.MSPConfigPath = filepath.Join(cryptoDir, "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
installCC.ExecPath = os.Getenv("PATH")
installCC.GoPath = filepath.Join(tempDir, "chaincode")
iRunner := installCC.InstallChaincode("mytest", "1.0", filepath.Join("simple", "cmd"))
execute(iRunner)
Expect(string(iRunner.Err().Contents())).To(ContainSubstring(`Installed remotely response:<status:200 payload:"OK" >`))
Expect(string(peerRunner.Err().Contents())).To(ContainSubstring(`Installed Chaincode [mytest] Version [1.0] to peer`))
iRunner := installCC.InstallChaincode("mytest", "1.0", "github.com/hyperledger/fabric/integration/chaincode/simple/cmd")
err = execute(iRunner)
Expect(err).NotTo(HaveOccurred())
Expect(iRunner.Err()).To(gbytes.Say(`\QInstalled remotely response:<status:200 payload:"OK" >\E`))
Expect(peerRunner.Err()).To(gbytes.Say(`\QInstalled Chaincode [mytest] Version [1.0] to peer\E`))
By("list installed chaincode")
listInstalled := components.Peer()
......@@ -199,10 +196,8 @@ var _ = Describe("Peer", func() {
liRunner := listInstalled.ChaincodeListInstalled()
liProcess := ifrit.Invoke(liRunner)
Eventually(liProcess.Ready(), 2*time.Second).Should(BeClosed())
Eventually(liRunner.Buffer()).Should(gbytes.Say("Path: simple/cmd"))
Eventually(liProcess.Wait(), 5*time.Second).ShouldNot(Receive(BeNil()))
Expect(liRunner.Buffer().Contents()).To(ContainSubstring("Name: mytest"))
Expect(liRunner.Buffer().Contents()).To(ContainSubstring("Version: 1.0"))
Eventually(liProcess.Wait(), 5*time.Second).Should(Receive(BeNil()))
Expect(liRunner).To(gbytes.Say("Name: mytest, Version: 1.0,"))
By("instantiate channel")
instantiateCC := components.Peer()
......@@ -214,26 +209,25 @@ var _ = Describe("Peer", func() {
Eventually(instProcess.Wait(), 10*time.Second).ShouldNot(Receive(BeNil()))
By("list instantiated chaincode")
listInstantiated := func() bool {
listInstantiated := func() *gbytes.Buffer {
listInstan := components.Peer()
listInstan.ConfigDir = tempDir
listInstan.MSPConfigPath = filepath.Join(cryptoDir, "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
linstRunner := listInstan.ChaincodeListInstantiated("mychan")
err := execute(linstRunner)
if err != nil {
return false
return nil
}
return strings.Contains(string(linstRunner.Buffer().Contents()), fmt.Sprintf("Path: %s", "simple/cmd"))
return linstRunner.Buffer()
}
Eventually(listInstantiated, 30*time.Second, 500*time.Millisecond).Should(BeTrue())
Eventually(listInstantiated, 30*time.Second, 500*time.Millisecond).Should(gbytes.Say("Name: mytest, Version: 1.0,"))
listInstan := components.Peer()
listInstan.ConfigDir = tempDir
listInstan.MSPConfigPath = filepath.Join(cryptoDir, "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
linstRunner := listInstan.ChaincodeListInstantiated("mychan")
execute(linstRunner)
Expect(linstRunner.Buffer().Contents()).To(ContainSubstring("Name: mytest"))
Expect(linstRunner.Buffer().Contents()).To(ContainSubstring("Version: 1.0"))
Expect(linstRunner).To(gbytes.Say("Name: mytest, Version: 1.0"))
By("query channel")
queryChan := components.Peer()
......@@ -241,7 +235,7 @@ var _ = Describe("Peer", func() {
queryChan.MSPConfigPath = filepath.Join(cryptoDir, "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
qRunner := queryChan.QueryChaincode("mytest", "mychan", `{"Args":["query","a"]}`)
execute(qRunner)
Expect(qRunner.Buffer().Contents()).To(ContainSubstring("100"))
Expect(qRunner).To(gbytes.Say("100"))
By("invoke channel")
invokeChan := components.Peer()
......@@ -249,7 +243,6 @@ var _ = Describe("Peer", func() {
invokeChan.MSPConfigPath = filepath.Join(cryptoDir, "peerOrganizations", "org1.example.com", "users", "Admin@org1.example.com", "msp")
invkeRunner := invokeChan.InvokeChaincode("mytest", "mychan", `{"Args":["invoke","a","b","10"]}`, "127.0.0.1:8050")
execute(invkeRunner)
Expect(invkeRunner.Err().Contents()).To(ContainSubstring("Chaincode invoke successful. result: status:200"))
Expect(invkeRunner.Err()).To(gbytes.Say("Chaincode invoke successful. result: status:200"))
})
})
......@@ -9,7 +9,6 @@ package runner_test
import (
"encoding/json"
"io/ioutil"
"os"
"time"
"github.com/hyperledger/fabric/integration/world"
......@@ -54,24 +53,10 @@ func copyFile(src, dest string) {
Expect(err).NotTo(HaveOccurred())
}
func execute(r ifrit.Runner) (err error) {
func execute(r ifrit.Runner) error {
var err error
p := ifrit.Invoke(r)
EventuallyWithOffset(1, p.Ready()).Should(BeClosed())
EventuallyWithOffset(1, p.Wait(), 5*time.Second).Should(Receive(&err))
return err
}
func copyDir(src, dest string) {
os.MkdirAll(dest, 0755)
objects, err := ioutil.ReadDir(src)
for _, obj := range objects {
srcfileptr := src + "/" + obj.Name()
destfileptr := dest + "/" + obj.Name()
if obj.IsDir() {
copyDir(srcfileptr, destfileptr)
} else {
copyFile(srcfileptr, destfileptr)
}
}
Expect(err).NotTo(HaveOccurred())
}
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package simple
import (
"fmt"
"strconv"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
fmt.Println("Init invoked")
_, args := stub.GetFunctionAndParameters()
var A, B string // Entities
var Aval, Bval int // Asset holdings
var err error
if len(args) != 4 {
return shim.Error("Incorrect number of arguments. Expecting 4")
}
// Initialize the chaincode
A = args[0]
Aval, err = strconv.Atoi(args[1])
if err != nil {
return shim.Error("Expecting integer value for asset holding")
}
B = args[2]
Bval, err = strconv.Atoi(args[3])
if err != nil {
return shim.Error("Expecting integer value for asset holding")
}
fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
// Write the state to the ledger
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
if err != nil {
return shim.Error(err.Error())
}
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
if err != nil {
return shim.Error(err.Error())
}
fmt.Println("Init returning with success")
return shim.Success(nil)
}
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
fmt.Println("ex02 Invoke")
function, args := stub.GetFunctionAndParameters()
if function == "invoke" {
// Make payment of X units from A to B
return t.invoke(stub, args)
} else if function == "delete" {
// Deletes an entity from its state
return t.delete(stub, args)
} else if function == "query" {
// the old "Query" is now implemtned in invoke
return t.query(stub, args)
}
return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"")
}