github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/integration/e2e/chaincode_server_test.go (about)

     1  /*
     2  Copyright hechain All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package e2e
     8  
     9  import (
    10  	"encoding/json"
    11  	"fmt"
    12  	"io/ioutil"
    13  	"os"
    14  	"os/exec"
    15  	"path/filepath"
    16  	"syscall"
    17  	"time"
    18  
    19  	"github.com/hechain20/hechain/common/crypto/tlsgen"
    20  	"github.com/hechain20/hechain/core/container/externalbuilder"
    21  	"github.com/hechain20/hechain/integration/nwo"
    22  	. "github.com/onsi/ginkgo"
    23  	. "github.com/onsi/gomega"
    24  	"github.com/tedsuo/ifrit"
    25  	"github.com/tedsuo/ifrit/ginkgomon"
    26  )
    27  
    28  var _ = Describe("ChaincodeAsExternalServer", func() {
    29  	var (
    30  		testDir                string
    31  		network                *nwo.Network
    32  		chaincode              nwo.Chaincode
    33  		chaincodeServerAddress string
    34  		assetDir               string
    35  		process                ifrit.Process
    36  		ccserver               ifrit.Process
    37  	)
    38  
    39  	BeforeEach(func() {
    40  		var err error
    41  		testDir, err = ioutil.TempDir("", "external-chaincode-server")
    42  		Expect(err).NotTo(HaveOccurred())
    43  
    44  		network = nwo.New(nwo.BasicSolo(), testDir, nil, StartPort(), components)
    45  		network.GenerateConfigTree()
    46  		network.Bootstrap()
    47  
    48  		// Create the configuration
    49  		chaincodeServerAddress = fmt.Sprintf("127.0.0.1:%d", network.ReservePort())
    50  		connData, serverKeyPair := generateChaincodeConfig(chaincodeServerAddress)
    51  
    52  		// Create directory for configuration files
    53  		assetDir, err = ioutil.TempDir(testDir, "assets")
    54  		Expect(err).NotTo(HaveOccurred())
    55  
    56  		// Write the config files
    57  		connJSON, err := json.Marshal(connData)
    58  		Expect(err).NotTo(HaveOccurred())
    59  		err = ioutil.WriteFile(filepath.Join(assetDir, "connection.json"), connJSON, 0o644)
    60  		Expect(err).NotTo(HaveOccurred())
    61  
    62  		configJSON, err := json.Marshal(serverKeyPair)
    63  		Expect(err).NotTo(HaveOccurred())
    64  		err = ioutil.WriteFile(filepath.Join(assetDir, "config.json"), configJSON, 0o644)
    65  		Expect(err).NotTo(HaveOccurred())
    66  
    67  		// Setup the network
    68  		networkRunner := network.NetworkGroupRunner()
    69  		process = ifrit.Invoke(networkRunner)
    70  		Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
    71  
    72  		network.CreateAndJoinChannel(network.Orderer("orderer"), "testchannel")
    73  		nwo.EnableCapabilities(
    74  			network,
    75  			"testchannel",
    76  			"Application", "V2_0",
    77  			network.Orderer("orderer"),
    78  			network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"),
    79  		)
    80  
    81  		// set to use the 'ccaas' builder rathern than binary
    82  		// binary build remains as an example of a scripted approach
    83  		chaincode = nwo.Chaincode{
    84  			Name:            "mycc",
    85  			Version:         "0.0",
    86  			Path:            components.Build("github.com/hechain20/hechain/integration/chaincode/server"),
    87  			Lang:            "ccaas",
    88  			PackageFile:     filepath.Join(testDir, "server.tar.gz"),
    89  			Ctor:            `{"Args":["init","a","100","b","200"]}`,
    90  			InitRequired:    true,
    91  			SignaturePolicy: `AND ('Org1MSP.member','Org2MSP.member')`,
    92  			Sequence:        "1",
    93  			Label:           "my_server_chaincode",
    94  			CodeFiles: map[string]string{
    95  				filepath.Join(assetDir, "connection.json"): "connection.json",
    96  				filepath.Join(assetDir, "config.json"):     "config.json",
    97  			},
    98  		}
    99  	})
   100  
   101  	AfterEach(func() {
   102  		if ccserver != nil {
   103  			ccserver.Signal(syscall.SIGTERM)
   104  			Eventually(ccserver.Wait(), network.EventuallyTimeout).Should(Receive())
   105  		}
   106  
   107  		if process != nil {
   108  			process.Signal(syscall.SIGTERM)
   109  			Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive())
   110  		}
   111  		if network != nil {
   112  			network.Cleanup()
   113  		}
   114  		os.RemoveAll(testDir)
   115  	})
   116  
   117  	It("executes a basic solo network with 2 orgs and external chaincode server", func() {
   118  		orderer := network.Orderer("orderer")
   119  		peer := network.Peer("Org1", "peer0")
   120  		peers := network.PeersWithChannel("testchannel")
   121  
   122  		By("packaging and installing the chaincode")
   123  		nwo.PackageAndInstallChaincode(network, chaincode, peers...)
   124  		chaincode.SetPackageIDFromPackageFile()
   125  
   126  		By("approving and committing the chaincode")
   127  		nwo.ApproveChaincodeForMyOrg(network, "testchannel", orderer, chaincode, peers...)
   128  		nwo.CheckCommitReadinessUntilReady(network, "testchannel", chaincode, network.PeerOrgs(), peers...)
   129  		nwo.CommitChaincode(network, "testchannel", orderer, chaincode, peer, peers...)
   130  
   131  		By("starting the chaincode server")
   132  		ccserver = ifrit.Invoke(ginkgomon.New(ginkgomon.Config{
   133  			Name: chaincode.PackageID,
   134  			Command: &exec.Cmd{
   135  				Path: chaincode.Path,
   136  				Args: []string{chaincode.Path, chaincode.PackageID, chaincodeServerAddress},
   137  				Dir:  assetDir,
   138  			},
   139  			StartCheck:        `Starting chaincode ` + chaincode.PackageID + ` at ` + chaincodeServerAddress,
   140  			StartCheckTimeout: 15 * time.Second,
   141  		}))
   142  		Eventually(ccserver.Ready(), network.EventuallyTimeout).Should(BeClosed())
   143  
   144  		By("exercising the chaincode")
   145  		nwo.InitChaincode(network, "testchannel", orderer, chaincode, network.PeersWithChannel("testchannel")...)
   146  		RunQueryInvokeQuery(network, orderer, peer, "testchannel")
   147  		RunRespondWith(network, orderer, peer, "testchannel")
   148  	})
   149  })
   150  
   151  type chaincodeConfig struct {
   152  	ListenAddress string `json:"listen_address,omitempty"`
   153  	Key           string `json:"key,omitempty"`  // PEM encoded key
   154  	Cert          string `json:"cert,omitempty"` // PEM encoded certificate
   155  	CA            string `json:"ca,omitempty"`   // PEM encode CA certificate
   156  }
   157  
   158  func generateChaincodeConfig(chaincodeAddress string) (externalbuilder.ChaincodeServerUserData, chaincodeConfig) {
   159  	tlsCA, err := tlsgen.NewCA()
   160  	Expect(err).NotTo(HaveOccurred())
   161  
   162  	serverPair, err := tlsCA.NewServerCertKeyPair("127.0.0.1")
   163  	Expect(err).NotTo(HaveOccurred())
   164  	clientPair, err := tlsCA.NewClientCertKeyPair()
   165  	Expect(err).NotTo(HaveOccurred())
   166  
   167  	config := chaincodeConfig{
   168  		ListenAddress: chaincodeAddress,
   169  		Key:           string(serverPair.Key),
   170  		Cert:          string(serverPair.Cert),
   171  		CA:            string(tlsCA.CertBytes()),
   172  	}
   173  
   174  	connData := externalbuilder.ChaincodeServerUserData{
   175  		Address:            chaincodeAddress,
   176  		DialTimeout:        externalbuilder.Duration(10 * time.Second),
   177  		TLSRequired:        true,
   178  		ClientAuthRequired: true,
   179  		ClientKey:          string(clientPair.Key),
   180  		ClientCert:         string(clientPair.Cert),
   181  		RootCert:           string(tlsCA.CertBytes()),
   182  	}
   183  
   184  	return connData, config
   185  }