Skip to content

Commit

Permalink
[WIP] Improve integration tests
Browse files Browse the repository at this point in the history
Use github.com/rogpeppe/go-internal/testscript and
github.com/kubernetes-sigs/e2e-framework to test the builder run
command with a kind kubernetes cluster

New integration tests should now be easier to add, e.g. for #228

Signed-off-by: James Taylor <[email protected]>
  • Loading branch information
jt-nti committed Jan 10, 2025
1 parent 3e24250 commit 4ec2896
Show file tree
Hide file tree
Showing 14 changed files with 497 additions and 238 deletions.
1 change: 0 additions & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ jobs:
run: go test -v ./...
env:
FABRIC_K8S_BUILDER_DEBUG: 'true'
INCLUDE_KIND_TESTS: ${{ matrix.os == 'ubuntu-latest' && 'true' || 'false' }}

- name: Package
run: |
Expand Down
3 changes: 3 additions & 0 deletions cmd/build.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// SPDX-License-Identifier: Apache-2.0

package cmd
54 changes: 54 additions & 0 deletions cmd/detect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: Apache-2.0

package cmd

import (
"context"
"errors"
"os"

"github.com/hyperledger-labs/fabric-builder-k8s/internal/builder"
"github.com/hyperledger-labs/fabric-builder-k8s/internal/log"
"github.com/hyperledger-labs/fabric-builder-k8s/internal/util"
)

func Detect() int {

Check failure on line 15 in cmd/detect.go

View workflow job for this annotation

GitHub Actions / lint

unnecessary leading newline (whitespace)

const (
expectedArgsLength = 3
chaincodeSourceDirectoryArg = 1
chaincodeMetadataDirectoryArg = 2
)

debug := util.GetOptionalEnv(util.DebugVariable, "false")
ctx := log.NewCmdContext(context.Background(), debug == "true")
logger := log.New(ctx)

if len(os.Args) != expectedArgsLength {
logger.Println("Expected CHAINCODE_SOURCE_DIR and CHAINCODE_METADATA_DIR arguments")

return 1
}

chaincodeSourceDirectory := os.Args[chaincodeSourceDirectoryArg]
chaincodeMetadataDirectory := os.Args[chaincodeMetadataDirectoryArg]

logger.Debugf("Chaincode source directory: %s", chaincodeSourceDirectory)
logger.Debugf("Chaincode metadata directory: %s", chaincodeMetadataDirectory)

detect := &builder.Detect{
ChaincodeSourceDirectory: chaincodeSourceDirectory,
ChaincodeMetadataDirectory: chaincodeMetadataDirectory,
}

if err := detect.Run(ctx); err != nil {
if !errors.Is(err, builder.ErrUnsupportedChaincodeType) {
// don't spam the peer log if it's just chaincode we don't recognise
logger.Printf("Error detecting chaincode: %+v", err)
}

return 1
}

return 0
}
41 changes: 2 additions & 39 deletions cmd/detect/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,11 @@
package main

import (
"context"
"errors"
"os"

"github.com/hyperledger-labs/fabric-builder-k8s/internal/builder"
"github.com/hyperledger-labs/fabric-builder-k8s/internal/log"
"github.com/hyperledger-labs/fabric-builder-k8s/internal/util"
)

const (
expectedArgsLength = 3
chaincodeSourceDirectoryArg = 1
chaincodeMetadataDirectoryArg = 2
"github.com/hyperledger-labs/fabric-builder-k8s/cmd"
)

func main() {
debug := util.GetOptionalEnv(util.DebugVariable, "false")
ctx := log.NewCmdContext(context.Background(), debug == "true")
logger := log.New(ctx)

if len(os.Args) != expectedArgsLength {
logger.Println("Expected CHAINCODE_SOURCE_DIR and CHAINCODE_METADATA_DIR arguments")
os.Exit(1)
}

chaincodeSourceDirectory := os.Args[chaincodeSourceDirectoryArg]
chaincodeMetadataDirectory := os.Args[chaincodeMetadataDirectoryArg]

logger.Debugf("Chaincode source directory: %s", chaincodeSourceDirectory)
logger.Debugf("Chaincode metadata directory: %s", chaincodeMetadataDirectory)

detect := &builder.Detect{
ChaincodeSourceDirectory: chaincodeSourceDirectory,
ChaincodeMetadataDirectory: chaincodeMetadataDirectory,
}

if err := detect.Run(ctx); err != nil {
if !errors.Is(err, builder.ErrUnsupportedChaincodeType) {
// don't spam the peer log if it's just chaincode we don't recognise
logger.Printf("Error detecting chaincode: %+v", err)
}

os.Exit(1)
}
os.Exit(cmd.Detect())
}
3 changes: 3 additions & 0 deletions cmd/release.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// SPDX-License-Identifier: Apache-2.0

package cmd
97 changes: 97 additions & 0 deletions cmd/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// SPDX-License-Identifier: Apache-2.0

package cmd

import (
"context"
"os"

"github.com/hyperledger-labs/fabric-builder-k8s/internal/builder"
"github.com/hyperledger-labs/fabric-builder-k8s/internal/log"
"github.com/hyperledger-labs/fabric-builder-k8s/internal/util"
"k8s.io/apimachinery/pkg/api/validation"
)

func Run() int {

Check failure on line 15 in cmd/run.go

View workflow job for this annotation

GitHub Actions / lint

unnecessary leading newline (whitespace)

const (
expectedArgsLength = 3
buildOutputDirectoryArg = 1
runMetadataDirectoryArg = 2
maximumKubeNamePrefixLength = 30
)

debug := util.GetOptionalEnv(util.DebugVariable, "false")
ctx := log.NewCmdContext(context.Background(), debug == "true")
logger := log.New(ctx)

if len(os.Args) != expectedArgsLength {
logger.Println("Expected BUILD_OUTPUT_DIR and RUN_METADATA_DIR arguments")

return 1
}

buildOutputDirectory := os.Args[buildOutputDirectoryArg]
runMetadataDirectory := os.Args[runMetadataDirectoryArg]

logger.Debugf("Build output directory: %s", buildOutputDirectory)
logger.Debugf("Run metadata directory: %s", runMetadataDirectory)

peerID, err := util.GetRequiredEnv(util.PeerIDVariable)
if err != nil {
logger.Printf("Expected %s environment variable\n", util.PeerIDVariable)

return 1
}

logger.Debugf("%s=%s", util.PeerIDVariable, peerID)

kubeconfigPath := util.GetOptionalEnv(util.KubeconfigPathVariable, "")
logger.Debugf("%s=%s", util.KubeconfigPathVariable, kubeconfigPath)

kubeNamespace := util.GetOptionalEnv(util.ChaincodeNamespaceVariable, "")
logger.Debugf("%s=%s", util.ChaincodeNamespaceVariable, kubeNamespace)

if kubeNamespace == "" {
kubeNamespace, err = util.GetKubeNamespace()
if err != nil {
kubeNamespace = util.DefaultNamespace
}
}

kubeServiceAccount := util.GetOptionalEnv(util.ChaincodeServiceAccountVariable, util.DefaultServiceAccountName)
logger.Debugf("%s=%s", util.ChaincodeServiceAccountVariable, kubeServiceAccount)

kubeNamePrefix := util.GetOptionalEnv(util.ObjectNamePrefixVariable, util.DefaultObjectNamePrefix)
logger.Debugf("%s=%s", util.ObjectNamePrefixVariable, kubeNamePrefix)

if len(kubeNamePrefix) > maximumKubeNamePrefixLength {
logger.Printf("The FABRIC_K8S_BUILDER_OBJECT_NAME_PREFIX environment variable must be a maximum of 30 characters")

return 1
}

if msgs := validation.NameIsDNS1035Label(kubeNamePrefix, true); len(msgs) > 0 {
logger.Printf("The FABRIC_K8S_BUILDER_OBJECT_NAME_PREFIX environment variable must be a valid DNS-1035 label: %s", msgs[0])

return 1
}

run := &builder.Run{
BuildOutputDirectory: buildOutputDirectory,
RunMetadataDirectory: runMetadataDirectory,
PeerID: peerID,
KubeconfigPath: kubeconfigPath,
KubeNamespace: kubeNamespace,
KubeServiceAccount: kubeServiceAccount,
KubeNamePrefix: kubeNamePrefix,
}

if err := run.Run(ctx); err != nil {
logger.Printf("Error running chaincode: %+v", err)

return 1
}

return 0
}
80 changes: 2 additions & 78 deletions cmd/run/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,87 +3,11 @@
package main

import (
"context"
"os"

"github.com/hyperledger-labs/fabric-builder-k8s/internal/builder"
"github.com/hyperledger-labs/fabric-builder-k8s/internal/log"
"github.com/hyperledger-labs/fabric-builder-k8s/internal/util"
"k8s.io/apimachinery/pkg/api/validation"
)

const (
expectedArgsLength = 3
buildOutputDirectoryArg = 1
runMetadataDirectoryArg = 2
maximumKubeNamePrefixLength = 30
"github.com/hyperledger-labs/fabric-builder-k8s/cmd"
)

func main() {
debug := util.GetOptionalEnv(util.DebugVariable, "false")
ctx := log.NewCmdContext(context.Background(), debug == "true")
logger := log.New(ctx)

if len(os.Args) != expectedArgsLength {
logger.Println("Expected BUILD_OUTPUT_DIR and RUN_METADATA_DIR arguments")
os.Exit(1)
}

buildOutputDirectory := os.Args[buildOutputDirectoryArg]
runMetadataDirectory := os.Args[runMetadataDirectoryArg]

logger.Debugf("Build output directory: %s", buildOutputDirectory)
logger.Debugf("Run metadata directory: %s", runMetadataDirectory)

peerID, err := util.GetRequiredEnv(util.PeerIDVariable)
if err != nil {
logger.Printf("Expected %s environment variable\n", util.PeerIDVariable)
os.Exit(1)
}

logger.Debugf("%s=%s", util.PeerIDVariable, peerID)

kubeconfigPath := util.GetOptionalEnv(util.KubeconfigPathVariable, "")
logger.Debugf("%s=%s", util.KubeconfigPathVariable, kubeconfigPath)

kubeNamespace := util.GetOptionalEnv(util.ChaincodeNamespaceVariable, "")
logger.Debugf("%s=%s", util.ChaincodeNamespaceVariable, kubeNamespace)

if kubeNamespace == "" {
kubeNamespace, err = util.GetKubeNamespace()
if err != nil {
kubeNamespace = util.DefaultNamespace
}
}

kubeServiceAccount := util.GetOptionalEnv(util.ChaincodeServiceAccountVariable, util.DefaultServiceAccountName)
logger.Debugf("%s=%s", util.ChaincodeServiceAccountVariable, kubeServiceAccount)

kubeNamePrefix := util.GetOptionalEnv(util.ObjectNamePrefixVariable, util.DefaultObjectNamePrefix)
logger.Debugf("%s=%s", util.ObjectNamePrefixVariable, kubeNamePrefix)

if len(kubeNamePrefix) > maximumKubeNamePrefixLength {
logger.Printf("The FABRIC_K8S_BUILDER_OBJECT_NAME_PREFIX environment variable must be a maximum of 30 characters")
os.Exit(1)
}

if msgs := validation.NameIsDNS1035Label(kubeNamePrefix, true); len(msgs) > 0 {
logger.Printf("The FABRIC_K8S_BUILDER_OBJECT_NAME_PREFIX environment variable must be a valid DNS-1035 label: %s", msgs[0])
os.Exit(1)
}

run := &builder.Run{
BuildOutputDirectory: buildOutputDirectory,
RunMetadataDirectory: runMetadataDirectory,
PeerID: peerID,
KubeconfigPath: kubeconfigPath,
KubeNamespace: kubeNamespace,
KubeServiceAccount: kubeServiceAccount,
KubeNamePrefix: kubeNamePrefix,
}

if err := run.Run(ctx); err != nil {
logger.Printf("Error running chaincode: %+v", err)
os.Exit(1)
}
os.Exit(cmd.Run())
}
71 changes: 0 additions & 71 deletions cmd/run/main_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package main_test

import (
"fmt"
"os"
"os/exec"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand Down Expand Up @@ -66,73 +64,4 @@ var _ = Describe("Main", func() {
Entry("When the FABRIC_K8S_BUILDER_OBJECT_NAME_PREFIX starts with a number", "1prefix", `run \[\d+\]: The FABRIC_K8S_BUILDER_OBJECT_NAME_PREFIX environment variable must be a valid DNS-1035 label: a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character`),
Entry("When the FABRIC_K8S_BUILDER_OBJECT_NAME_PREFIX starts with a dash", "-prefix", `run \[\d+\]: The FABRIC_K8S_BUILDER_OBJECT_NAME_PREFIX environment variable must be a valid DNS-1035 label: a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character`),
)

It(
"should start a chaincode job using the supplied configuration environment variables",
Label("kind"),
func() {
homedir, err := os.UserHomeDir()
Expect(err).NotTo(HaveOccurred())

args := []string{"./testdata/validimage", "./testdata/validchaincode"}
command := exec.Command(runCmdPath, args...)
command.Env = append(os.Environ(),
fmt.Sprintf("KUBECONFIG_PATH=%s/.kube/config", homedir),
"CORE_PEER_ID=core-peer-id-abcdefghijklmnopqrstuvwxyz-0123456789",
"FABRIC_K8S_BUILDER_DEBUG=true",
"FABRIC_K8S_BUILDER_NAMESPACE=chaincode",
"FABRIC_K8S_BUILDER_SERVICE_ACCOUNT=chaincode",
)
session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())

Eventually(session).ShouldNot(gexec.Exit())
Eventually(
session.Err,
).Should(gbytes.Say(`run \[\d+\] DEBUG: FABRIC_K8S_BUILDER_NAMESPACE=chaincode`))
Eventually(
session.Err,
).Should(gbytes.Say(`run \[\d+\] DEBUG: FABRIC_K8S_BUILDER_SERVICE_ACCOUNT=chaincode`))
Eventually(
session.Err,
).Should(gbytes.Say(`run \[\d+\]: Running chaincode ID CHAINCODE_LABEL:6f98c4bb29414771312eddd1a813eef583df2121c235c4797792f141a46d4b45 with kubernetes job chaincode/hlfcc-chaincodelabel-piihcaj6ryttc`))

waitArgs := []string{
"wait",
"--for=jsonpath=.status.ready=1",
"job",
"--timeout=120s",
"--namespace=chaincode",
"-l",
"fabric-builder-k8s-cclabel=CHAINCODE_LABEL",
}
waitCommand := exec.Command("kubectl", waitArgs...)
waitSession, err := gexec.Start(waitCommand, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())
Eventually(waitSession).WithTimeout(240 * time.Second).Should(gexec.Exit(0))

descArgs := []string{
"describe",
"job",
"--namespace=chaincode",
"-l",
"fabric-builder-k8s-cclabel=CHAINCODE_LABEL",
}
descCommand := exec.Command("kubectl", descArgs...)
descSession, err := gexec.Start(descCommand, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())

Eventually(descSession).Should(gexec.Exit(0))
Eventually(descSession.Out).Should(gbytes.Say(`Namespace:\s+chaincode`))
Eventually(
descSession.Out,
).Should(gbytes.Say(`fabric-builder-k8s-ccid:\s+CHAINCODE_LABEL:6f98c4bb29414771312eddd1a813eef583df2121c235c4797792f141a46d4b45`))
Eventually(descSession.Out).Should(gbytes.Say(`fabric-builder-k8s-mspid:\s+MSPID`))
Eventually(descSession.Out).Should(gbytes.Say(`fabric-builder-k8s-peeraddress:\s+PEER_ADDRESS`))
Eventually(descSession.Out).Should(gbytes.Say(`fabric-builder-k8s-peerid:\s+core-peer-id-abcdefghijklmnopqrstuvwxyz-0123456789`))
Eventually(descSession.Out).Should(gbytes.Say(`CORE_CHAINCODE_ID_NAME:\s+CHAINCODE_LABEL:6f98c4bb29414771312eddd1a813eef583df2121c235c4797792f141a46d4b45`))
Eventually(descSession.Out).Should(gbytes.Say(`CORE_PEER_ADDRESS:\s+PEER_ADDRESS`))
Eventually(descSession.Out).Should(gbytes.Say(`CORE_PEER_LOCALMSPID:\s+MSPID`))
},
)
})
Loading

0 comments on commit 4ec2896

Please sign in to comment.