From d3fc6c1ccb35b416c7abe9c71c19113b7ac3001f Mon Sep 17 00:00:00 2001 From: James Taylor Date: Fri, 20 Dec 2024 19:30:38 +0000 Subject: [PATCH] [WIP] testscript experiment Use github.com/rogpeppe/go-internal/testscript instead of ginkgo to test builder commands? Signed-off-by: James Taylor --- cmd/build.go | 3 + cmd/cmd_test.go | 44 +++++++++ cmd/detect.go | 54 ++++++++++ cmd/detect/main.go | 41 +------- cmd/release.go | 3 + cmd/run.go | 97 ++++++++++++++++++ cmd/run/main.go | 80 +-------------- cmd/testdata/build/build.txtar | 2 + cmd/testdata/detect/detect.txtar | 2 + cmd/testdata/release/release.txtar | 2 + cmd/testdata/run/run.txtar | 2 + go.mod | 21 +++- go.sum | 46 ++++++++- test/integration/integration_test.go | 142 +++++++++++++++++++++++++++ test/integration/testdata/tbc.txtar | 29 ++++++ 15 files changed, 448 insertions(+), 120 deletions(-) create mode 100644 cmd/build.go create mode 100644 cmd/cmd_test.go create mode 100644 cmd/detect.go create mode 100644 cmd/release.go create mode 100644 cmd/run.go create mode 100644 cmd/testdata/build/build.txtar create mode 100644 cmd/testdata/detect/detect.txtar create mode 100644 cmd/testdata/release/release.txtar create mode 100644 cmd/testdata/run/run.txtar create mode 100644 test/integration/integration_test.go create mode 100644 test/integration/testdata/tbc.txtar diff --git a/cmd/build.go b/cmd/build.go new file mode 100644 index 0000000..99ce209 --- /dev/null +++ b/cmd/build.go @@ -0,0 +1,3 @@ +// SPDX-License-Identifier: Apache-2.0 + +package cmd diff --git a/cmd/cmd_test.go b/cmd/cmd_test.go new file mode 100644 index 0000000..9483858 --- /dev/null +++ b/cmd/cmd_test.go @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: Apache-2.0 + +package cmd_test + +import ( + "os" + "testing" + + "github.com/hyperledger-labs/fabric-builder-k8s/cmd" + "github.com/rogpeppe/go-internal/testscript" +) + +func TestMain(m *testing.M) { + os.Exit(testscript.RunMain(m, map[string]func() int{ + // "build": cmd.Build, + "detect": cmd.Detect, + // "release": cmd.Release, + // "run": cmd.Run, + })) +} + +func TestBuildCommand(t *testing.T) { + testscript.Run(t, testscript.Params{ + Dir: "testdata/build", + }) +} + +func TestDetectCommand(t *testing.T) { + testscript.Run(t, testscript.Params{ + Dir: "testdata/detect", + }) +} + +func TestReleaseCommand(t *testing.T) { + testscript.Run(t, testscript.Params{ + Dir: "testdata/release", + }) +} + +func TestRunCommand(t *testing.T) { + testscript.Run(t, testscript.Params{ + Dir: "testdata/run", + }) +} diff --git a/cmd/detect.go b/cmd/detect.go new file mode 100644 index 0000000..7ca15e7 --- /dev/null +++ b/cmd/detect.go @@ -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 { + + 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 +} diff --git a/cmd/detect/main.go b/cmd/detect/main.go index bbfc60e..ad931ba 100644 --- a/cmd/detect/main.go +++ b/cmd/detect/main.go @@ -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()) } diff --git a/cmd/release.go b/cmd/release.go new file mode 100644 index 0000000..99ce209 --- /dev/null +++ b/cmd/release.go @@ -0,0 +1,3 @@ +// SPDX-License-Identifier: Apache-2.0 + +package cmd diff --git a/cmd/run.go b/cmd/run.go new file mode 100644 index 0000000..1654830 --- /dev/null +++ b/cmd/run.go @@ -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 { + + 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 +} diff --git a/cmd/run/main.go b/cmd/run/main.go index 4ddad81..15ce10b 100644 --- a/cmd/run/main.go +++ b/cmd/run/main.go @@ -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()) } diff --git a/cmd/testdata/build/build.txtar b/cmd/testdata/build/build.txtar new file mode 100644 index 0000000..423492e --- /dev/null +++ b/cmd/testdata/build/build.txtar @@ -0,0 +1,2 @@ +exec bork +stdout 'hello world\n' diff --git a/cmd/testdata/detect/detect.txtar b/cmd/testdata/detect/detect.txtar new file mode 100644 index 0000000..5914db0 --- /dev/null +++ b/cmd/testdata/detect/detect.txtar @@ -0,0 +1,2 @@ +exec detect +stdout 'hello world\n' diff --git a/cmd/testdata/release/release.txtar b/cmd/testdata/release/release.txtar new file mode 100644 index 0000000..9f25c4a --- /dev/null +++ b/cmd/testdata/release/release.txtar @@ -0,0 +1,2 @@ +exec release +stdout 'hello world\n' diff --git a/cmd/testdata/run/run.txtar b/cmd/testdata/run/run.txtar new file mode 100644 index 0000000..e132e0f --- /dev/null +++ b/cmd/testdata/run/run.txtar @@ -0,0 +1,2 @@ +exec run +stdout 'hello world\n' diff --git a/go.mod b/go.mod index d3ffae7..9ff42ba 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,26 @@ module github.com/hyperledger-labs/fabric-builder-k8s -go 1.22.0 +go 1.22.3 + +toolchain go1.22.10 require ( github.com/onsi/ginkgo/v2 v2.22.0 github.com/onsi/gomega v1.36.0 github.com/otiai10/copy v1.14.0 + github.com/rogpeppe/go-internal v1.13.1 k8s.io/api v0.31.3 k8s.io/apimachinery v0.31.3 k8s.io/client-go v0.31.3 + sigs.k8s.io/e2e-framework v0.5.0 ) require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/emicklei/go-restful/v3 v3.11.2 // indirect + github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect @@ -21,15 +29,26 @@ require ( github.com/google/gnostic-models v0.6.8 // indirect github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/itchyny/gojq v0.12.13 // indirect github.com/itchyny/timefmt-go v0.1.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/moby/spdystream v0.4.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + github.com/vladimirvivien/gexe v0.3.0 // indirect github.com/x448/float16 v0.8.4 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/tools v0.26.0 // indirect + k8s.io/component-base v0.31.1 // indirect mvdan.cc/sh/v3 v3.7.0 // indirect + sigs.k8s.io/controller-runtime v0.19.0 // indirect ) require ( diff --git a/go.sum b/go.sum index d37b30d..ca289e0 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,29 @@ +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bitfield/script v0.23.0 h1:N0R5yLEl6wJIS9PR/A6xXwjMsplMubyxdi05N5l0X28= github.com/bitfield/script v0.23.0/go.mod h1:fv+6x4OzVsRs6qAlc7wiGq8fq1b5orhtQdtW0dwjUHI= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emicklei/go-restful/v3 v3.11.2 h1:1onLa9DcsMYO9P+CXaL0dStDqQ2EHHXLiz+BtnqkLAU= github.com/emicklei/go-restful/v3 v3.11.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= +github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA= github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= @@ -36,6 +48,8 @@ github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgY github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/itchyny/gojq v0.12.13 h1:IxyYlHYIlspQHHTE0f3cJF0NKDMfajxViuhBLnHd/QU= @@ -54,6 +68,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8= +github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -61,6 +77,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v1.36.0 h1:Pb12RlruUtj4XUuPUqeEWc6j5DkVVVA49Uf6YLfC95Y= @@ -74,21 +92,37 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vladimirvivien/gexe v0.3.0 h1:4xwiOwGrDob5OMR6E92B9olDXYDglXdHhzR1ggYtWJM= +github.com/vladimirvivien/gexe v0.3.0/go.mod h1:fp7cy60ON1xjhtEI/+bfSEIXX35qgmI+iRYlGOqbBFM= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -143,10 +177,14 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/api v0.31.3 h1:umzm5o8lFbdN/hIXbrK9oRpOproJO62CV1zqxXrLgk8= k8s.io/api v0.31.3/go.mod h1:UJrkIp9pnMOI9K2nlL6vwpxRzzEX5sWgn8kGQe92kCE= +k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= +k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= k8s.io/apimachinery v0.31.3 h1:6l0WhcYgasZ/wk9ktLq5vLaoXJJr5ts6lkaQzgeYPq4= k8s.io/apimachinery v0.31.3/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= k8s.io/client-go v0.31.3 h1:CAlZuM+PH2cm+86LOBemaJI/lQ5linJ6UFxKX/SoG+4= k8s.io/client-go v0.31.3/go.mod h1:2CgjPUTpv3fE5dNygAr2NcM8nhHzXvxB8KL5gYc3kJs= +k8s.io/component-base v0.31.1 h1:UpOepcrX3rQ3ab5NB6g5iP0tvsgJWzxTyAo20sgYSy8= +k8s.io/component-base v0.31.1/go.mod h1:WGeaw7t/kTsqpVTaCoVEtillbqAhF2/JgvO0LDOMa0w= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= @@ -155,6 +193,10 @@ k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1 k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= mvdan.cc/sh/v3 v3.7.0 h1:lSTjdP/1xsddtaKfGg7Myu7DnlHItd3/M2tomOcNNBg= mvdan.cc/sh/v3 v3.7.0/go.mod h1:K2gwkaesF/D7av7Kxl0HbF5kGOd2ArupNTX3X44+8l8= +sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= +sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= +sigs.k8s.io/e2e-framework v0.5.0 h1:YLhk8R7EHuTFQAe6Fxy5eBzn5Vb+yamR5u8MH1Rq3cE= +sigs.k8s.io/e2e-framework v0.5.0/go.mod h1:jJSH8u2RNmruekUZgHAtmRjb5Wj67GErli9UjLSY7Zc= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/test/integration/integration_test.go b/test/integration/integration_test.go new file mode 100644 index 0000000..660559c --- /dev/null +++ b/test/integration/integration_test.go @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: Apache-2.0 + +package integration_test + +import ( + "context" + "os" + "testing" + "time" + + "github.com/hyperledger-labs/fabric-builder-k8s/cmd" + "github.com/rogpeppe/go-internal/testscript" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" + "sigs.k8s.io/e2e-framework/klient/k8s/resources" + "sigs.k8s.io/e2e-framework/klient/wait" + "sigs.k8s.io/e2e-framework/klient/wait/conditions" + "sigs.k8s.io/e2e-framework/pkg/env" + "sigs.k8s.io/e2e-framework/pkg/envconf" + "sigs.k8s.io/e2e-framework/pkg/envfuncs" + "sigs.k8s.io/e2e-framework/support/kind" +) + +// TODO make this less hacky!!! +type Bork struct { + wm *testing.M +} + +func (b Bork) Run() int { + return testenv.Run(b.wm) +} + +var ( + testenv env.Environment +) + +func setupTestEnv(t *testing.T, e *testscript.Env) error { + e.Setenv("KUBECONFIG_PATH", testenv.EnvConf().KubeconfigFile()) + + return nil +} + +func TestMain(m *testing.M) { + + testenv = env.New() + clusterName := envconf.RandomName("hlf-builder", 16) + namespace := "chaincode" + + // Setup uses pre-defined funcs to create kind cluster + // and create a namespace for the environment + testenv.Setup( + envfuncs.CreateCluster(kind.NewProvider(), clusterName), + envfuncs.CreateNamespace(namespace), + ) + + testenv.BeforeEachTest() + + // Finish uses pre-defined funcs to + // remove namespace, then delete cluster + testenv.Finish( + envfuncs.DeleteNamespace(namespace), + envfuncs.DestroyCluster(clusterName), + ) + + // TODO make this less hacky!!! + tm := Bork{ + wm: m, + } + os.Exit(testscript.RunMain(tm, map[string]func() int{ + "run": cmd.Run, + })) +} + +func TestAllTheThings(t *testing.T) { + testscript.Run(t, testscript.Params{ + Files: []string{"testdata/tbc.txtar"}, + Setup: func(e *testscript.Env) error { return setupTestEnv(t, e) }, + Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){ + "podkill": cmdPodKill, + "podwait": cmdPodWait, + }, + }) +} + +// TODO a podcheck command to combine wait and kill with some label, taint, etc output? + +func cmdPodWait(ts *testscript.TestScript, neg bool, args []string) { + // TODO add arg for chaincode label? + + pods := &v1.PodList{} + // var pod corev1.Pod + + cfg := testenv.EnvConf() + // client, err := cfg.NewClient() + // ts.Check(err) + + err := wait.For(conditions.New(cfg.Client().Resources()).ResourceListN(pods, 1, resources.WithLabelSelector(labels.FormatLabels(map[string]string{"fabric-builder-k8s-cclabel": "CHAINCODE_LABEL"}))), wait.WithInterval(2*time.Second), wait.WithTimeout(5*time.Minute)) + if err != nil { + ts.Fatalf("failed waiting for chaincode job pod to be created: %v", err) + } + + err = wait.For(conditions.New(cfg.Client().Resources()).PodReady(&pods.Items[0]), wait.WithInterval(2*time.Second), wait.WithTimeout(5*time.Minute)) + if err != nil { + ts.Fatalf("failed to wait for chaincode pod to reach Ready condition: %v", err) + } + +} + +func cmdPodKill(ts *testscript.TestScript, neg bool, args []string) { + // TODO add arg for chaincode label? + + pods := &v1.PodList{} + // var pod corev1.Pod + + cfg := testenv.EnvConf() + // client, err := cfg.NewClient() + // ts.Check(err) + + err := wait.For(conditions.New(cfg.Client().Resources()).ResourceListN(pods, 1, resources.WithLabelSelector(labels.FormatLabels(map[string]string{"fabric-builder-k8s-cclabel": "CHAINCODE_LABEL"})))) + if err != nil { + ts.Fatalf("failed waiting for chaincode job pod to be created: %v", err) + } + + pod := &pods.Items[0] + + err = wait.For(conditions.New(cfg.Client().Resources()).ContainersReady(pod)) + if err != nil { + ts.Fatalf("failed to wait for containers to reach Ready condition: %v", err) + } + + go func() { + err := cfg.Client().Resources().Delete(context.TODO(), pod) + if err != nil { + ts.Fatalf("failed deleting chaincode job pod: %v", err) + } + }() + err = wait.For(conditions.New(cfg.Client().Resources()).ResourceDeleted(pod), wait.WithInterval(2*time.Second), wait.WithTimeout(5*time.Minute)) + if err != nil { + ts.Fatalf("failed waiting for pod resource to be deleted: %v", err) + } + +} diff --git a/test/integration/testdata/tbc.txtar b/test/integration/testdata/tbc.txtar new file mode 100644 index 0000000..6e9ca81 --- /dev/null +++ b/test/integration/testdata/tbc.txtar @@ -0,0 +1,29 @@ +env CORE_PEER_ID=core-peer-id-abcdefghijklmnopqrstuvwxyz-0123456789 +env FABRIC_K8S_BUILDER_DEBUG=true +env FABRIC_K8S_BUILDER_NAMESPACE=chaincode +###env FABRIC_K8S_BUILDER_SERVICE_ACCOUNT=chaincode + +exec run build_output_dir run_metadata_dir &builder& + +###podwait +podkill + +###wait builder +###kill builder +stdout 'hello world\n' + +-- build_output_dir/image.json -- +{ + "name": "nginx", + "digest": "sha256:da3cc3053314be9ca3871307366f6e30ce2b11e1ea6a72e5957244d99b2515bf" +} + +-- run_metadata_dir/chaincode.json -- +{ + "chaincode_id": "CHAINCODE_LABEL:6f98c4bb29414771312eddd1a813eef583df2121c235c4797792f141a46d4b45", + "peer_address": "PEER_ADDRESS", + "client_cert": "CLIENT_CERT", + "client_key": "CLIENT_KEY", + "root_cert": "ROOT_CERT", + "mspid": "MSPID" +}