-
Notifications
You must be signed in to change notification settings - Fork 8.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
integration: backport chaincode_server_test
Signed-off-by: Matthew Sykes <sykesmat@us.ibm.com>
- Loading branch information
1 parent
8843223
commit 6adcbce
Showing
5 changed files
with
264 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
Copyright IBM Corp. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
|
||
"github.com/hyperledger/fabric-chaincode-go/shim" | ||
"github.com/hyperledger/fabric/integration/chaincode/simple" | ||
) | ||
|
||
type config struct { | ||
ListenAddress string `json:"listen_address,omitempty"` | ||
Key string `json:"key,omitempty"` // PEM encoded key | ||
Cert string `json:"cert,omitempty"` // PEM encoded certificate | ||
CA string `json:"ca,omitempty"` // PEM encode CA certificate | ||
} | ||
|
||
func main() { | ||
if len(os.Args) < 2 { | ||
fmt.Println("usage: <package-id>") | ||
os.Exit(1) | ||
} | ||
|
||
configData, err := ioutil.ReadFile("config.json") | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "Cannot read config file: %s", err) | ||
os.Exit(2) | ||
} | ||
|
||
var config config | ||
if err := json.Unmarshal(configData, &config); err != nil { | ||
fmt.Fprintf(os.Stderr, "Cannot read config file: %s", err) | ||
os.Exit(2) | ||
} | ||
|
||
server := &shim.ChaincodeServer{ | ||
CCID: os.Args[1], | ||
Address: config.ListenAddress, | ||
CC: new(simple.SimpleChaincode), | ||
TLSProps: shim.TLSProperties{ | ||
Key: []byte(config.Key), | ||
Cert: []byte(config.Cert), | ||
ClientCACerts: []byte(config.CA), | ||
}, | ||
} | ||
|
||
// do not modify - needed for integration test | ||
fmt.Printf("Starting chaincode %s at %s\n", server.CCID, server.Address) | ||
err = server.Start() | ||
if err != nil { | ||
fmt.Printf("Error starting Simple chaincode: %s", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
/* | ||
Copyright IBM Corp All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package e2e | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"syscall" | ||
"time" | ||
|
||
"github.com/hyperledger/fabric/common/crypto/tlsgen" | ||
"github.com/hyperledger/fabric/core/container/externalbuilder" | ||
"github.com/hyperledger/fabric/integration/nwo" | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
"github.com/tedsuo/ifrit" | ||
"github.com/tedsuo/ifrit/ginkgomon" | ||
) | ||
|
||
var _ = Describe("ChaincodeAsExternalServer", func() { | ||
var ( | ||
testDir string | ||
network *nwo.Network | ||
chaincode nwo.Chaincode | ||
chaincodeServerAddress string | ||
assetDir string | ||
process ifrit.Process | ||
ccserver ifrit.Process | ||
) | ||
|
||
BeforeEach(func() { | ||
var err error | ||
testDir, err = ioutil.TempDir("", "external-chaincode-server") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
network = nwo.New(nwo.BasicSolo(), testDir, nil, StartPort(), components) | ||
network.GenerateConfigTree() | ||
network.Bootstrap() | ||
|
||
// Create the configuration | ||
chaincodeServerAddress = fmt.Sprintf("127.0.0.1:%d", network.ReservePort()) | ||
connData, serverKeyPair := generateChaincodeConfig(chaincodeServerAddress) | ||
|
||
// Create directory for configuration files | ||
assetDir, err = ioutil.TempDir(testDir, "assets") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
// Write the config files | ||
connJSON, err := json.Marshal(connData) | ||
Expect(err).NotTo(HaveOccurred()) | ||
err = ioutil.WriteFile(filepath.Join(assetDir, "connection.json"), connJSON, 0o644) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
configJSON, err := json.Marshal(serverKeyPair) | ||
Expect(err).NotTo(HaveOccurred()) | ||
err = ioutil.WriteFile(filepath.Join(assetDir, "config.json"), configJSON, 0o644) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
// Setup the network | ||
networkRunner := network.NetworkGroupRunner() | ||
process = ifrit.Invoke(networkRunner) | ||
Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed()) | ||
|
||
network.CreateAndJoinChannel(network.Orderer("orderer"), "testchannel") | ||
nwo.EnableCapabilities( | ||
network, | ||
"testchannel", | ||
"Application", "V2_0", | ||
network.Orderer("orderer"), | ||
network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"), | ||
) | ||
|
||
chaincode = nwo.Chaincode{ | ||
Name: "mycc", | ||
Version: "0.0", | ||
Path: components.Build("github.com/hyperledger/fabric/integration/chaincode/server"), | ||
Lang: "binary", | ||
PackageFile: filepath.Join(testDir, "server.tar.gz"), | ||
Ctor: `{"Args":["init","a","100","b","200"]}`, | ||
InitRequired: true, | ||
SignaturePolicy: `AND ('Org1MSP.member','Org2MSP.member')`, | ||
Sequence: "1", | ||
Label: "my_server_chaincode", | ||
CodeFiles: map[string]string{ | ||
filepath.Join(assetDir, "connection.json"): "connection.json", | ||
filepath.Join(assetDir, "config.json"): "config.json", | ||
}, | ||
} | ||
}) | ||
|
||
AfterEach(func() { | ||
if ccserver != nil { | ||
ccserver.Signal(syscall.SIGTERM) | ||
Eventually(ccserver.Wait(), network.EventuallyTimeout).Should(Receive()) | ||
} | ||
|
||
if process != nil { | ||
process.Signal(syscall.SIGTERM) | ||
Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive()) | ||
} | ||
if network != nil { | ||
network.Cleanup() | ||
} | ||
os.RemoveAll(testDir) | ||
}) | ||
|
||
It("executes a basic solo network with 2 orgs and external chaincode server", func() { | ||
orderer := network.Orderer("orderer") | ||
peer := network.Peer("Org1", "peer0") | ||
peers := network.PeersWithChannel("testchannel") | ||
|
||
By("packaging and installing the chaincode") | ||
nwo.PackageAndInstallChaincode(network, chaincode, peers...) | ||
chaincode.SetPackageIDFromPackageFile() | ||
|
||
By("approving and committing the chaincode") | ||
nwo.ApproveChaincodeForMyOrg(network, "testchannel", orderer, chaincode, peers...) | ||
nwo.CheckCommitReadinessUntilReady(network, "testchannel", chaincode, network.PeerOrgs(), peers...) | ||
nwo.CommitChaincode(network, "testchannel", orderer, chaincode, peer, peers...) | ||
|
||
By("starting the chaincode server") | ||
ccserver = ifrit.Invoke(ginkgomon.New(ginkgomon.Config{ | ||
Name: chaincode.PackageID, | ||
Command: &exec.Cmd{ | ||
Path: chaincode.Path, | ||
Args: []string{chaincode.Path, chaincode.PackageID, chaincodeServerAddress}, | ||
Dir: assetDir, | ||
}, | ||
StartCheck: `Starting chaincode ` + chaincode.PackageID + ` at ` + chaincodeServerAddress, | ||
StartCheckTimeout: 15 * time.Second, | ||
})) | ||
Eventually(ccserver.Ready(), network.EventuallyTimeout).Should(BeClosed()) | ||
|
||
By("exercising the chaincode") | ||
nwo.InitChaincode(network, "testchannel", orderer, chaincode, network.PeersWithChannel("testchannel")...) | ||
RunQueryInvokeQuery(network, orderer, peer, "testchannel") | ||
RunRespondWith(network, orderer, peer, "testchannel") | ||
}) | ||
}) | ||
|
||
type chaincodeConfig struct { | ||
ListenAddress string `json:"listen_address,omitempty"` | ||
Key string `json:"key,omitempty"` // PEM encoded key | ||
Cert string `json:"cert,omitempty"` // PEM encoded certificate | ||
CA string `json:"ca,omitempty"` // PEM encode CA certificate | ||
} | ||
|
||
func generateChaincodeConfig(chaincodeAddress string) (externalbuilder.ChaincodeServerUserData, chaincodeConfig) { | ||
tlsCA, err := tlsgen.NewCA() | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
serverPair, err := tlsCA.NewServerCertKeyPair("127.0.0.1") | ||
Expect(err).NotTo(HaveOccurred()) | ||
clientPair, err := tlsCA.NewClientCertKeyPair() | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
config := chaincodeConfig{ | ||
ListenAddress: chaincodeAddress, | ||
Key: string(serverPair.Key), | ||
Cert: string(serverPair.Cert), | ||
CA: string(tlsCA.CertBytes()), | ||
} | ||
|
||
connData := externalbuilder.ChaincodeServerUserData{ | ||
Address: chaincodeAddress, | ||
DialTimeout: externalbuilder.Duration(10 * time.Second), | ||
TLSRequired: true, | ||
ClientAuthRequired: true, | ||
ClientKey: string(clientPair.Key), | ||
ClientCert: string(clientPair.Cert), | ||
RootCert: string(tlsCA.CertBytes()), | ||
} | ||
|
||
return connData, config | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters