Repository: redhat-openshift-ecosystem/openshift-preflight
Pull request #726 (2022-06-30 12:42:25)

Bump go-rpmdb and go-containerregistry deps
* go-containerregistry => v0.10.0
* go-rpmdb => opdev/preflight-next

Signed-off-by: Brad P. Crochet <brad@redhat.com>

dcibot: -  FAILURE https://www.distributed-ci.io/jobs//jobStates
 from https://github.com/redhat-openshift-ecosystem/openshift-preflight/pull/726

Patch:
diff --git a/certification/engine/engine.go b/certification/engine/engine.go
index 97a47a9..5a132d5 100644
--- a/certification/engine/engine.go
+++ b/certification/engine/engine.go
@@ -5,10 +5,12 @@ import (
 	"context"
 	"fmt"
 	"net/http"
+	"os/exec"
 	"time"
 
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification"
 	internal "github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/engine"
+	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/operatorsdk"
 	containerpol "github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/policy/container"
 	operatorpol "github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/policy/operator"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/policy"
@@ -50,10 +52,10 @@ func initializeChecks(ctx context.Context, p policy.Policy, cfg certification.Co
 	switch p {
 	case policy.PolicyOperator:
 		return []certification.Check{
-			operatorpol.NewScorecardBasicSpecCheck(internal.NewOperatorSdkEngine(cfg.ScorecardImage()), cfg.Namespace(), cfg.ServiceAccount(), cfg.Kubeconfig(), cfg.ScorecardWaitTime()),
-			operatorpol.NewScorecardOlmSuiteCheck(internal.NewOperatorSdkEngine(cfg.ScorecardImage()), cfg.Namespace(), cfg.ServiceAccount(), cfg.Kubeconfig(), cfg.ScorecardWaitTime()),
-			operatorpol.NewDeployableByOlmCheck(internal.NewOperatorSdkEngine(cfg.ScorecardImage()), cfg.IndexImage(), cfg.DockerConfig(), cfg.Channel()),
-			operatorpol.NewValidateOperatorBundleCheck(internal.NewOperatorSdkEngine(cfg.ScorecardImage())),
+			operatorpol.NewScorecardBasicSpecCheck(operatorsdk.New(cfg.ScorecardImage(), exec.Command), cfg.Namespace(), cfg.ServiceAccount(), cfg.Kubeconfig(), cfg.ScorecardWaitTime()),
+			operatorpol.NewScorecardOlmSuiteCheck(operatorsdk.New(cfg.ScorecardImage(), exec.Command), cfg.Namespace(), cfg.ServiceAccount(), cfg.Kubeconfig(), cfg.ScorecardWaitTime()),
+			operatorpol.NewDeployableByOlmCheck(operatorsdk.New(cfg.ScorecardImage(), exec.Command), cfg.IndexImage(), cfg.DockerConfig(), cfg.Channel()),
+			operatorpol.NewValidateOperatorBundleCheck(operatorsdk.New(cfg.ScorecardImage(), exec.Command)),
 		}, nil
 	case policy.PolicyContainer:
 		return []certification.Check{
diff --git a/certification/internal/bundle/bundle.go b/certification/internal/bundle/bundle.go
index bce8f54..8122be5 100644
--- a/certification/internal/bundle/bundle.go
+++ b/certification/internal/bundle/bundle.go
@@ -11,7 +11,7 @@ import (
 
 	"github.com/blang/semver"
 	operatorv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
-	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/cli"
+	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/operatorsdk"
 	log "github.com/sirupsen/logrus"
 	"sigs.k8s.io/yaml"
 )
@@ -21,9 +21,13 @@ const ocpVerV1beta1Unsupported = "4.9"
 // versionsKey is the OpenShift versions in annotations.yaml that lists the versions allowed for an operator
 const versionsKey = "com.redhat.openshift.versions"
 
-func Validate(ctx context.Context, engine cli.OperatorSdkEngine, imagePath string) (*cli.OperatorSdkBundleValidateReport, error) {
+type operatorSdk interface {
+	BundleValidate(context.Context, string, operatorsdk.OperatorSdkBundleValidateOptions) (*operatorsdk.OperatorSdkBundleValidateReport, error)
+}
+
+func Validate(ctx context.Context, operatorSdk operatorSdk, imagePath string) (*operatorsdk.OperatorSdkBundleValidateReport, error) {
 	selector := []string{"community", "operatorhub"}
-	opts := cli.OperatorSdkBundleValidateOptions{
+	opts := operatorsdk.OperatorSdkBundleValidateOptions{
 		Selector:        selector,
 		Verbose:         true,
 		ContainerEngine: "none",
@@ -52,7 +56,7 @@ func Validate(ctx context.Context, engine cli.OperatorSdkEngine, imagePath strin
 		}
 	}
 
-	return engine.BundleValidate(imagePath, opts)
+	return operatorSdk.BundleValidate(ctx, imagePath, opts)
 }
 
 func isTarget49OrGreater(ocpLabelIndex string) bool {
diff --git a/certification/internal/cli/cli.go b/certification/internal/cli/cli.go
deleted file mode 100644
index 7f1e458..0000000
--- a/certification/internal/cli/cli.go
+++ /dev/null
@@ -1,1 +0,0 @@
-package cli
diff --git a/certification/internal/engine/operatorsdk.go b/certification/internal/operatorsdk/operatorsdk.go
similarity index 82%
rename from certification/internal/engine/operatorsdk.go
rename to certification/internal/operatorsdk/operatorsdk.go
index 1ce5d99..3ae96d1 100644
--- a/certification/internal/engine/operatorsdk.go
+++ b/certification/internal/operatorsdk/operatorsdk.go
@@ -1,7 +1,8 @@
-package engine
+package operatorsdk
 
 import (
 	"bytes"
+	"context"
 	"encoding/json"
 	"fmt"
 	"os"
@@ -9,21 +10,26 @@ import (
 	"strings"
 
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/artifacts"
-	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/cli"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/runtime"
 	log "github.com/sirupsen/logrus"
 )
 
-func NewOperatorSdkEngine(userProvidedScorecardImage string) *cli.OperatorSdkEngine {
-	var engine cli.OperatorSdkEngine = operatorSdkEngine{scorecardImage: userProvidedScorecardImage}
+func New(userProvidedScorecardImage string, cmdContext execContext) *operatorSdk {
+	engine := operatorSdk{scorecardImage: userProvidedScorecardImage, cmdContext: cmdContext}
 	return &engine
 }
 
-type operatorSdkEngine struct {
+type operatorSdk struct {
 	scorecardImage string
+	cmdContext     execContext
 }
 
-func (o operatorSdkEngine) Scorecard(image string, opts cli.OperatorSdkScorecardOptions) (*cli.OperatorSdkScorecardReport, error) {
+// Define a type that is the signature of the exec.Command function.
+// This allows us to override that function with our own for
+// testing purposes. This type is only used directly in the New() function.
+type execContext = func(name string, arg ...string) *exec.Cmd
+
+func (o operatorSdk) Scorecard(ctx context.Context, image string, opts OperatorSdkScorecardOptions) (*OperatorSdkScorecardReport, error) {
 	cmdArgs := []string{"scorecard"}
 	if opts.OutputFormat == "" {
 		opts.OutputFormat = "json"
@@ -59,7 +65,7 @@ func (o operatorSdkEngine) Scorecard(image string, opts cli.OperatorSdkScorecard
 
 	cmdArgs = append(cmdArgs, image)
 
-	cmd := exec.Command("operator-sdk", cmdArgs...)
+	cmd := o.cmdContext("operator-sdk", cmdArgs...)
 	log.Trace("running scorecard with the following invocation", cmd.Args)
 	var stdout, stderr bytes.Buffer
 	cmd.Stdout = &stdout
@@ -85,7 +91,7 @@ func (o operatorSdkEngine) Scorecard(image string, opts cli.OperatorSdkScorecard
 		return nil, fmt.Errorf("unable to copy result to artifacts directory: %v", err)
 	}
 
-	var scorecardData cli.OperatorSdkScorecardReport
+	var scorecardData OperatorSdkScorecardReport
 	if err := json.Unmarshal(stdout.Bytes(), &scorecardData); err != nil {
 		return nil, fmt.Errorf("failed to run operator-sdk scorecard: %v", err)
 	}
@@ -94,7 +100,7 @@ func (o operatorSdkEngine) Scorecard(image string, opts cli.OperatorSdkScorecard
 	return &scorecardData, nil
 }
 
-func (o operatorSdkEngine) BundleValidate(image string, opts cli.OperatorSdkBundleValidateOptions) (*cli.OperatorSdkBundleValidateReport, error) {
+func (o operatorSdk) BundleValidate(ctx context.Context, image string, opts OperatorSdkBundleValidateOptions) (*OperatorSdkBundleValidateReport, error) {
 	cmdArgs := []string{"bundle", "validate"}
 	if opts.ContainerEngine == "" {
 		opts.ContainerEngine = "none"
@@ -119,7 +125,7 @@ func (o operatorSdkEngine) BundleValidate(image string, opts cli.OperatorSdkBund
 	}
 	cmdArgs = append(cmdArgs, image)
 
-	cmd := exec.Command("operator-sdk", cmdArgs...)
+	cmd := o.cmdContext("operator-sdk", cmdArgs...)
 	log.Debugf("Command being run: %s", cmd.Args)
 	var stdout, stderr bytes.Buffer
 	cmd.Stdout = &stdout
@@ -140,7 +146,7 @@ func (o operatorSdkEngine) BundleValidate(image string, opts cli.OperatorSdkBund
 		}
 	}
 
-	var bundleValidateData cli.OperatorSdkBundleValidateReport
+	var bundleValidateData OperatorSdkBundleValidateReport
 	if strings.Contains(opts.OutputFormat, "json") {
 		if err := json.Unmarshal(stdout.Bytes(), &bundleValidateData); err != nil {
 			return nil, fmt.Errorf("failed to run operator-sdk bundle validate: %v", err)
@@ -156,12 +162,12 @@ func (o operatorSdkEngine) BundleValidate(image string, opts cli.OperatorSdkBund
 	return &bundleValidateData, nil
 }
 
-func (o operatorSdkEngine) writeScorecardFile(resultFile, stdout string) error {
+func (o operatorSdk) writeScorecardFile(resultFile, stdout string) error {
 	_, err := artifacts.WriteFile(resultFile, stdout)
 	return err
 }
 
-func (o operatorSdkEngine) createScorecardConfigFile() (string, error) {
+func (o operatorSdk) createScorecardConfigFile() (string, error) {
 	img := runtime.ScorecardImage(o.scorecardImage)
 	configTemplate := fmt.Sprintf(`kind: Configuration
 apiversion: scorecard.operatorframework.io/v1alpha3
diff --git a/certification/internal/cli/operatorsdk.go b/certification/internal/operatorsdk/types.go
similarity index 82%
rename from certification/internal/cli/operatorsdk.go
rename to certification/internal/operatorsdk/types.go
index df347a4..9047a46 100644
--- a/certification/internal/cli/operatorsdk.go
+++ b/certification/internal/operatorsdk/types.go
@@ -1,4 +1,4 @@
-package cli
+package operatorsdk
 
 type OperatorSdkScorecardOptions struct {
 	OutputFormat   string
@@ -52,8 +52,3 @@ type OperatorSdkBundleValidateOutput struct {
 	Type    string `json:"type"`
 	Message string `json:"message"`
 }
-
-type OperatorSdkEngine interface {
-	Scorecard(image string, opts OperatorSdkScorecardOptions) (*OperatorSdkScorecardReport, error)
-	BundleValidate(image string, opts OperatorSdkBundleValidateOptions) (*OperatorSdkBundleValidateReport, error)
-}
diff --git a/certification/internal/policy/operator/deployable_by_olm.go b/certification/internal/policy/operator/deployable_by_olm.go
index 78c849e..892b308 100644
--- a/certification/internal/policy/operator/deployable_by_olm.go
+++ b/certification/internal/policy/operator/deployable_by_olm.go
@@ -23,7 +23,6 @@ import (
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/artifacts"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/bundle"
-	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/cli"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/openshift"
 
 	log "github.com/sirupsen/logrus"
@@ -49,11 +48,11 @@ type DeployableByOlmCheck struct {
 	// channel is optional. If empty, we will introspect.
 	channel string
 
-	OperatorSdkEngine cli.OperatorSdkEngine
-	openshiftClient   openshift.Client
-	client            crclient.Client
-	csvReady          bool
-	validImages       bool
+	OperatorSdk     operatorSdk
+	openshiftClient openshift.Client
+	client          crclient.Client
+	csvReady        bool
+	validImages     bool
 }
 
 func (p *DeployableByOlmCheck) initClient() error {
@@ -92,23 +91,23 @@ func (p *DeployableByOlmCheck) initOpenShifeEngine() error {
 // in scope are public. An empty channel value implies that the check should
 // introspect the channel from the bundle. indexImage is required.
 func NewDeployableByOlmCheck(
-	operatorSdkEngine *cli.OperatorSdkEngine,
+	operatorSdk operatorSdk,
 	indexImage,
 	dockerConfig,
 	channel string,
 ) *DeployableByOlmCheck {
 	return &DeployableByOlmCheck{
-		OperatorSdkEngine: *operatorSdkEngine,
-		dockerConfig:      dockerConfig,
-		indexImage:        indexImage,
-		channel:           channel,
+		OperatorSdk:  operatorSdk,
+		dockerConfig: dockerConfig,
+		indexImage:   indexImage,
+		channel:      channel,
 	}
 }
 
 func (p *DeployableByOlmCheck) Validate(ctx context.Context, bundleRef certification.ImageReference) (bool, error) {
 	p.initClient()
 	p.initOpenShifeEngine()
-	if report, err := bundle.Validate(ctx, p.OperatorSdkEngine, bundleRef.ImageFSPath); err != nil || !report.Passed {
+	if report, err := bundle.Validate(ctx, p.OperatorSdk, bundleRef.ImageFSPath); err != nil || !report.Passed {
 		return false, fmt.Errorf("%v", err)
 	}
 
diff --git a/certification/internal/policy/operator/scorecard_basic_check_spec.go b/certification/internal/policy/operator/scorecard_basic_check_spec.go
index b515a6c..ec6e159 100644
--- a/certification/internal/policy/operator/scorecard_basic_check_spec.go
+++ b/certification/internal/policy/operator/scorecard_basic_check_spec.go
@@ -6,7 +6,6 @@ import (
 
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/artifacts"
-	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/cli"
 	log "github.com/sirupsen/logrus"
 )
 
@@ -19,14 +18,14 @@ type ScorecardBasicSpecCheck struct {
 
 const scorecardBasicCheckResult string = "operator_bundle_scorecard_BasicSpecCheck.json"
 
-func NewScorecardBasicSpecCheck(operatorSdkEngine *cli.OperatorSdkEngine, ns, sa, kubeconfig, waittime string) *ScorecardBasicSpecCheck {
+func NewScorecardBasicSpecCheck(operatorSdk operatorSdk, ns, sa, kubeconfig, waittime string) *ScorecardBasicSpecCheck {
 	return &ScorecardBasicSpecCheck{
 		scorecardCheck: scorecardCheck{
-			OperatorSdkEngine: *operatorSdkEngine,
-			namespace:         ns,
-			serviceAccount:    sa,
-			kubeconfig:        kubeconfig,
-			waitTime:          waittime,
+			OperatorSdk:    operatorSdk,
+			namespace:      ns,
+			serviceAccount: sa,
+			kubeconfig:     kubeconfig,
+			waitTime:       waittime,
 		},
 		fatalError: false,
 	}
diff --git a/certification/internal/policy/operator/scorecard_check.go b/certification/internal/policy/operator/scorecard_check.go
index 966c353..55245e3 100644
--- a/certification/internal/policy/operator/scorecard_check.go
+++ b/certification/internal/policy/operator/scorecard_check.go
@@ -5,12 +5,12 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/cli"
+	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/operatorsdk"
 	log "github.com/sirupsen/logrus"
 )
 
 type scorecardCheck struct {
-	OperatorSdkEngine cli.OperatorSdkEngine
+	OperatorSdk operatorSdk
 
 	namespace      string
 	serviceAccount string
@@ -18,7 +18,7 @@ type scorecardCheck struct {
 	waitTime       string
 }
 
-func (p *scorecardCheck) validate(ctx context.Context, items []cli.OperatorSdkScorecardItem) (bool, error) {
+func (p *scorecardCheck) validate(ctx context.Context, items []operatorsdk.OperatorSdkScorecardItem) (bool, error) {
 	foundTestFailed := false
 	var err error
 
@@ -36,8 +36,8 @@ func (p *scorecardCheck) validate(ctx context.Context, items []cli.OperatorSdkSc
 	return !foundTestFailed, err
 }
 
-func (p *scorecardCheck) getDataToValidate(ctx context.Context, bundleImage string, selector []string, resultFile string) (*cli.OperatorSdkScorecardReport, error) {
-	opts := cli.OperatorSdkScorecardOptions{
+func (p *scorecardCheck) getDataToValidate(ctx context.Context, bundleImage string, selector []string, resultFile string) (*operatorsdk.OperatorSdkScorecardReport, error) {
+	opts := operatorsdk.OperatorSdkScorecardOptions{
 		OutputFormat:   "json",
 		Selector:       selector,
 		ResultFile:     resultFile,
@@ -47,7 +47,7 @@ func (p *scorecardCheck) getDataToValidate(ctx context.Context, bundleImage stri
 		Verbose:        true,
 		WaitTime:       fmt.Sprintf("%ss", p.waitTime),
 	}
-	result, err := p.OperatorSdkEngine.Scorecard(bundleImage, opts)
+	result, err := p.OperatorSdk.Scorecard(ctx, bundleImage, opts)
 	if err != nil {
 		return result, fmt.Errorf("%v", err)
 	}
diff --git a/certification/internal/policy/operator/scorecard_olm_suite.go b/certification/internal/policy/operator/scorecard_olm_suite.go
index 9327d2c..9aa2d06 100644
--- a/certification/internal/policy/operator/scorecard_olm_suite.go
+++ b/certification/internal/policy/operator/scorecard_olm_suite.go
@@ -6,7 +6,6 @@ import (
 
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/artifacts"
-	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/cli"
 	log "github.com/sirupsen/logrus"
 )
 
@@ -19,14 +18,14 @@ type ScorecardOlmSuiteCheck struct {
 
 const scorecardOlmSuiteResult string = "operator_bundle_scorecard_OlmSuiteCheck.json"
 
-func NewScorecardOlmSuiteCheck(operatorSdkEngine *cli.OperatorSdkEngine, ns, sa, kubeconfig, waittime string) *ScorecardOlmSuiteCheck {
+func NewScorecardOlmSuiteCheck(operatorSdk operatorSdk, ns, sa, kubeconfig, waittime string) *ScorecardOlmSuiteCheck {
 	return &ScorecardOlmSuiteCheck{
 		scorecardCheck: scorecardCheck{
-			OperatorSdkEngine: *operatorSdkEngine,
-			namespace:         ns,
-			serviceAccount:    sa,
-			kubeconfig:        kubeconfig,
-			waitTime:          waittime,
+			OperatorSdk:    operatorSdk,
+			namespace:      ns,
+			serviceAccount: sa,
+			kubeconfig:     kubeconfig,
+			waitTime:       waittime,
 		},
 		fatalError: false,
 	}
diff --git a/certification/internal/policy/operator/types.go b/certification/internal/policy/operator/types.go
new file mode 100644
index 0000000..835e8b7
--- /dev/null
+++ b/certification/internal/policy/operator/types.go
@@ -0,0 +1,12 @@
+package operator
+
+import (
+	"context"
+
+	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/operatorsdk"
+)
+
+type operatorSdk interface {
+	BundleValidate(context.Context, string, operatorsdk.OperatorSdkBundleValidateOptions) (*operatorsdk.OperatorSdkBundleValidateReport, error)
+	Scorecard(context.Context, string, operatorsdk.OperatorSdkScorecardOptions) (*operatorsdk.OperatorSdkScorecardReport, error)
+}
diff --git a/certification/internal/policy/operator/validate_operator_bundle.go b/certification/internal/policy/operator/validate_operator_bundle.go
index d9ebda3..cab5862 100644
--- a/certification/internal/policy/operator/validate_operator_bundle.go
+++ b/certification/internal/policy/operator/validate_operator_bundle.go
@@ -6,19 +6,19 @@ import (
 
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/bundle"
-	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/cli"
+	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/operatorsdk"
 	log "github.com/sirupsen/logrus"
 )
 
 // ValidateOperatorBundleCheck evaluates the image and ensures that it passes bundle validation
 // as executed by `operator-sdk bundle validate`
 type ValidateOperatorBundleCheck struct {
-	OperatorSdkEngine cli.OperatorSdkEngine
+	OperatorSdk operatorSdk
 }
 
-func NewValidateOperatorBundleCheck(operatorSdkEngine *cli.OperatorSdkEngine) *ValidateOperatorBundleCheck {
+func NewValidateOperatorBundleCheck(operatorSdk operatorSdk) *ValidateOperatorBundleCheck {
 	return &ValidateOperatorBundleCheck{
-		OperatorSdkEngine: *operatorSdkEngine,
+		OperatorSdk: operatorSdk,
 	}
 }
 
@@ -33,11 +33,11 @@ func (p ValidateOperatorBundleCheck) Validate(ctx context.Context, bundleRef cer
 	return p.validate(ctx, report)
 }
 
-func (p ValidateOperatorBundleCheck) getDataToValidate(ctx context.Context, imagePath string) (*cli.OperatorSdkBundleValidateReport, error) {
-	return bundle.Validate(ctx, p.OperatorSdkEngine, imagePath)
+func (p ValidateOperatorBundleCheck) getDataToValidate(ctx context.Context, imagePath string) (*operatorsdk.OperatorSdkBundleValidateReport, error) {
+	return bundle.Validate(ctx, p.OperatorSdk, imagePath)
 }
 
-func (p ValidateOperatorBundleCheck) validate(ctx context.Context, report *cli.OperatorSdkBundleValidateReport) (bool, error) {
+func (p ValidateOperatorBundleCheck) validate(ctx context.Context, report *operatorsdk.OperatorSdkBundleValidateReport) (bool, error) {
 	if !report.Passed || len(report.Outputs) > 0 {
 		for _, output := range report.Outputs {
 			var logFn func(...interface{})
diff --git a/go.mod b/go.mod
index 928df6b..f5f75bf 100644
--- a/go.mod
+++ b/go.mod
@@ -4,9 +4,9 @@ go 1.17
 
 require (
 	github.com/blang/semver v3.5.1+incompatible
-	github.com/docker/cli v20.10.12+incompatible
-	github.com/google/go-containerregistry v0.8.1-0.20220425181515-fc6ff852e45e
-	github.com/knqyf263/go-rpmdb v0.0.0-20201215100354-a9e3110d8ee1
+	github.com/docker/cli v20.10.16+incompatible
+	github.com/google/go-containerregistry v0.10.0
+	github.com/knqyf263/go-rpmdb v0.0.0-20220629110411-9a3bd2ebb923
 	github.com/onsi/ginkgo/v2 v2.1.3
 	github.com/onsi/gomega v1.18.1
 	github.com/openshift/api v0.0.0-20210910062324-a41d3573a3ba
@@ -29,10 +29,10 @@ require (
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/blang/semver/v4 v4.0.0 // indirect
 	github.com/cespare/xxhash/v2 v2.1.2 // indirect
-	github.com/containerd/stargz-snapshotter/estargz v0.11.1 // indirect
+	github.com/containerd/stargz-snapshotter/estargz v0.11.4 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
-	github.com/docker/distribution v2.8.0+incompatible // indirect
-	github.com/docker/docker v20.10.12+incompatible // indirect
+	github.com/docker/distribution v2.8.1+incompatible // indirect
+	github.com/docker/docker v20.10.16+incompatible // indirect
 	github.com/docker/docker-credential-helpers v0.6.4 // indirect
 	github.com/emicklei/go-restful v2.9.5+incompatible // indirect
 	github.com/evanphx/json-patch v4.12.0+incompatible // indirect
@@ -45,7 +45,7 @@ require (
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
 	github.com/golang/protobuf v1.5.2 // indirect
 	github.com/google/gnostic v0.5.7-v3refs // indirect
-	github.com/google/go-cmp v0.5.7 // indirect
+	github.com/google/go-cmp v0.5.8 // indirect
 	github.com/google/gofuzz v1.1.0 // indirect
 	github.com/google/uuid v1.3.0 // indirect
 	github.com/hashicorp/hcl v1.0.0 // indirect
@@ -53,7 +53,8 @@ require (
 	github.com/inconshreveable/mousetrap v1.0.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
-	github.com/klauspost/compress v1.14.4 // indirect
+	github.com/klauspost/compress v1.15.4 // indirect
+	github.com/kr/pretty v0.2.1 // indirect
 	github.com/magiconair/properties v1.8.5 // indirect
 	github.com/mailru/easyjson v0.7.6 // indirect
 	github.com/mattn/go-sqlite3 v1.14.12 // indirect
@@ -77,18 +78,17 @@ require (
 	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/subosito/gotenv v1.2.0 // indirect
 	github.com/vbatts/tar-split v0.11.2 // indirect
-	golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
-	golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect
-	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
-	golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect
+	golang.org/x/net v0.0.0-20220524220425-1d687d428aca // indirect
+	golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401 // indirect
+	golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 // indirect
+	golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
 	golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
 	golang.org/x/text v0.3.7 // indirect
 	golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
-	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
+	golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect
 	gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
-	google.golang.org/protobuf v1.27.1 // indirect
-	gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
+	google.golang.org/protobuf v1.28.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/ini.v1 v1.66.2 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
@@ -103,4 +103,4 @@ require (
 	sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
 )
 
-replace github.com/knqyf263/go-rpmdb v0.0.0-20201215100354-a9e3110d8ee1 => github.com/opdev/go-rpmdb v0.0.0-20220622214440-9ad97f393868
+replace github.com/knqyf263/go-rpmdb => github.com/opdev/go-rpmdb v0.0.0-20220630122500-7186d78a0783
diff --git a/go.sum b/go.sum
index 9d3b666..0a9d8c5 100644
--- a/go.sum
+++ b/go.sum
@@ -157,8 +157,8 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:z
 github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
 github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
 github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
-github.com/containerd/stargz-snapshotter/estargz v0.11.1 h1:mNQqxcAWmDrV6d6yUvzFhfY8puNzoQz9v4diW+Pmei4=
-github.com/containerd/stargz-snapshotter/estargz v0.11.1/go.mod h1:6VoPcf4M1wvnogWxqc4TqBWWErCS+R+ucnPZId2VbpQ=
+github.com/containerd/stargz-snapshotter/estargz v0.11.4 h1:LjrYUZpyOhiSaU7hHrdR82/RBoxfGWSaC0VeSSMXqnk=
+github.com/containerd/stargz-snapshotter/estargz v0.11.4/go.mod h1:7vRJIcImfY8bpifnMjt+HTJoQxASq7T28MYbP15/Nf0=
 github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
 github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@@ -188,12 +188,12 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
-github.com/docker/cli v20.10.12+incompatible h1:lZlz0uzG+GH+c0plStMUdF/qk3ppmgnswpR5EbqzVGA=
-github.com/docker/cli v20.10.12+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
-github.com/docker/distribution v2.8.0+incompatible h1:l9EaZDICImO1ngI+uTifW+ZYvvz7fKISBAKpg+MbWbY=
-github.com/docker/distribution v2.8.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v20.10.12+incompatible h1:CEeNmFM0QZIsJCZKMkZx0ZcahTiewkrgiwfYD+dfl1U=
-github.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/cli v20.10.16+incompatible h1:aLQ8XowgKpR3/IysPj8qZQJBVQ+Qws61icFuZl6iKYs=
+github.com/docker/cli v20.10.16+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
+github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
+github.com/docker/docker v20.10.16+incompatible h1:2Db6ZR/+FUR3hqPMwnogOPHFn405crbpxvWzKovETOQ=
+github.com/docker/docker v20.10.16+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o=
 github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c=
 github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
@@ -372,10 +372,10 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
-github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
-github.com/google/go-containerregistry v0.8.1-0.20220425181515-fc6ff852e45e h1:vd0ii4O+13G22FbjofAKXY7NYJZhp7Sj6hjszOu0+VU=
-github.com/google/go-containerregistry v0.8.1-0.20220425181515-fc6ff852e45e/go.mod h1:eTLvLZaEe2FoQsb25t7BLxQQryyrwHTzFfwxN87mhAw=
+github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
+github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-containerregistry v0.10.0 h1:qd/fv2nQajGZJenaNcdaghlwSPjQ0NphN9hzArr2WWg=
+github.com/google/go-containerregistry v0.10.0/go.mod h1:C7uwbB1QUAtvnknyd3ethxJRd4gtEjU/9WLXzckfI1Y=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
 github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -527,9 +527,9 @@ github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
 github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/klauspost/compress v1.14.3/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/klauspost/compress v1.14.4 h1:eijASRJcobkVtSt81Olfh7JX43osYLwy5krOJo6YEu4=
-github.com/klauspost/compress v1.14.4/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
+github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
+github.com/klauspost/compress v1.15.4 h1:1kn4/7MepF/CHmYub99/nNX8az0IJjfSOU/jbnTVfqQ=
+github.com/klauspost/compress v1.15.4/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -680,8 +680,8 @@ github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAl
 github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
 github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
 github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
-github.com/opdev/go-rpmdb v0.0.0-20220622214440-9ad97f393868 h1:XXxyt5fiiDKjF0rkzvkre52rznX6Vsib11xMqAvT8Q4=
-github.com/opdev/go-rpmdb v0.0.0-20220622214440-9ad97f393868/go.mod h1:ZQDkL8JLWXdoduwq/aZGDfI3Cn0FT5ta1yhDcb3yQAE=
+github.com/opdev/go-rpmdb v0.0.0-20220630122500-7186d78a0783 h1:4grEQK7DNshreUS6QNROenqvotJGlCQZlMZEAmakl/o=
+github.com/opdev/go-rpmdb v0.0.0-20220630122500-7186d78a0783/go.mod h1:ZQDkL8JLWXdoduwq/aZGDfI3Cn0FT5ta1yhDcb3yQAE=
 github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
 github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198 h1:+czc/J8SlhPKLOtVLMQc+xDCFBT73ZStMsRhSsUhsSg=
@@ -1063,8 +1063,8 @@ golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qx
 golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220524220425-1d687d428aca h1:xTaFYiPROfpPhqrfTIDXj0ri1SpfueYT951s4bAuDO8=
+golang.org/x/net v0.0.0-20220524220425-1d687d428aca/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1082,8 +1082,8 @@ golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ
 golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg=
-golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401 h1:zwrSfklXn0gxyLRX/aR+q6cgHbV/ItVyzbPlbA+dkAw=
+golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1095,8 +1095,9 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4=
+golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1189,8 +1190,8 @@ golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs=
-golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1319,13 +1320,14 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.6/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
 golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
-golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717 h1:hI3jKY4Hpf63ns040onEbB3dAkR/H/P83hw1TG8dD3Y=
 golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
+golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618=
+golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
 gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY=
 gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
@@ -1472,15 +1474,15 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
 google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
 gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=


Test patch:
diff --git a/certification/internal/bundle/bundle_suite_test.go b/certification/internal/bundle/bundle_suite_test.go
index 287aa6d..1045758 100644
--- a/certification/internal/bundle/bundle_suite_test.go
+++ b/certification/internal/bundle/bundle_suite_test.go
@@ -1,12 +1,14 @@
 package bundle
 
 import (
+	"context"
 	"errors"
 	"testing"
 
 	. "github.com/onsi/ginkgo/v2/dsl/core"
 	. "github.com/onsi/gomega"
-	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/cli"
+
+	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/operatorsdk"
 )
 
 func TestBundle(t *testing.T) {
@@ -14,19 +16,15 @@ func TestBundle(t *testing.T) {
 	RunSpecs(t, "Bundle Utils Suite")
 }
 
-type FakeOperatorSdkEngine struct {
-	OperatorSdkReport   cli.OperatorSdkScorecardReport
-	OperatorSdkBVReport cli.OperatorSdkBundleValidateReport
+type FakeOperatorSdk struct {
+	OperatorSdkReport   operatorsdk.OperatorSdkScorecardReport
+	OperatorSdkBVReport operatorsdk.OperatorSdkBundleValidateReport
 }
 
-func (f FakeOperatorSdkEngine) BundleValidate(image string, opts cli.OperatorSdkBundleValidateOptions) (*cli.OperatorSdkBundleValidateReport, error) {
+func (f FakeOperatorSdk) BundleValidate(ctx context.Context, image string, opts operatorsdk.OperatorSdkBundleValidateOptions) (*operatorsdk.OperatorSdkBundleValidateReport, error) {
 	return &f.OperatorSdkBVReport, nil
 }
 
-func (f FakeOperatorSdkEngine) Scorecard(image string, opts cli.OperatorSdkScorecardOptions) (*cli.OperatorSdkScorecardReport, error) {
-	return &f.OperatorSdkReport, nil
-}
-
 // In order to test some negative paths, this io.Reader will just throw an error
 type errReader int
 
diff --git a/certification/internal/bundle/bundle_test.go b/certification/internal/bundle/bundle_test.go
index 28602cc..24fd17d 100644
--- a/certification/internal/bundle/bundle_test.go
+++ b/certification/internal/bundle/bundle_test.go
@@ -9,7 +9,6 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification"
-	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/cli"
 )
 
 var _ = Describe("BundleValidateCheck", func() {
@@ -43,7 +42,7 @@ var _ = Describe("BundleValidateCheck", func() {
 	Describe("Bundle validation", func() {
 		var (
 			imageRef   certification.ImageReference
-			fakeEngine cli.OperatorSdkEngine
+			fakeEngine operatorSdk
 		)
 
 		BeforeEach(func() {
@@ -61,7 +60,7 @@ var _ = Describe("BundleValidateCheck", func() {
 			Expect(err).ToNot(HaveOccurred())
 
 			imageRef.ImageFSPath = tmpDir
-			fakeEngine = FakeOperatorSdkEngine{}
+			fakeEngine = FakeOperatorSdk{}
 		})
 
 		AfterEach(func() {
diff --git a/certification/internal/openshift/openshift_test.go b/certification/internal/openshift/openshift_test.go
index adc5614..ab5d257 100644
--- a/certification/internal/openshift/openshift_test.go
+++ b/certification/internal/openshift/openshift_test.go
@@ -108,6 +108,12 @@ var _ = Describe("OpenShift Engine", func() {
 				Expect(err).ToNot(HaveOccurred())
 				Expect(ns).ToNot(BeNil())
 			})
+			By("creating it again should error", func() {
+				ns, err := oc.CreateNamespace(context.TODO(), "testns")
+				Expect(err).To(HaveOccurred())
+				Expect(err).To(MatchError(ErrAlreadyExists))
+				Expect(ns).ToNot(BeNil())
+			})
 			By("getting that Namespace", func() {
 				ns, err := oc.GetNamespace(context.TODO(), "testns")
 				Expect(err).ToNot(HaveOccurred())
@@ -135,6 +141,12 @@ var _ = Describe("OpenShift Engine", func() {
 				Expect(err).ToNot(HaveOccurred())
 				Expect(og).ToNot(BeNil())
 			})
+			By("creating it again should error", func() {
+				og, err := oc.CreateOperatorGroup(context.TODO(), operatorGroupData, "testns")
+				Expect(err).To(HaveOccurred())
+				Expect(err).To(MatchError(ErrAlreadyExists))
+				Expect(og).ToNot(BeNil())
+			})
 			By("getting that OperatorGroup", func() {
 				og, err := oc.GetOperatorGroup(context.TODO(), "testog", "testns")
 				Expect(err).ToNot(HaveOccurred())
@@ -161,6 +173,14 @@ var _ = Describe("OpenShift Engine", func() {
 				Expect(err).ToNot(HaveOccurred())
 				Expect(secret).ToNot(BeNil())
 			})
+			By("creating a Secret again should error", func() {
+				content := make(map[string]string, 1)
+				content["test"] = "testdata"
+				secret, err := oc.CreateSecret(context.TODO(), "testsecret", content, corev1.SecretTypeDockerConfigJson, "testns")
+				Expect(err).To(HaveOccurred())
+				Expect(err).To(MatchError(ErrAlreadyExists))
+				Expect(secret).ToNot(BeNil())
+			})
 			By("getting that Secret", func() {
 				secret, err := oc.GetSecret(context.TODO(), "testsecret", "testns")
 				Expect(err).ToNot(HaveOccurred())
@@ -193,6 +213,17 @@ var _ = Describe("OpenShift Engine", func() {
 				Expect(err).ToNot(HaveOccurred())
 				Expect(cs).ToNot(BeNil())
 			})
+			By("creating a CatalogSource again should error", func() {
+				csData := CatalogSourceData{
+					Name:    "testcs",
+					Image:   "this/is/my-image:now",
+					Secrets: []string{"my-secrets"},
+				}
+				cs, err := oc.CreateCatalogSource(context.TODO(), csData, "testns")
+				Expect(err).To(HaveOccurred())
+				Expect(err).To(MatchError(ErrAlreadyExists))
+				Expect(cs).ToNot(BeNil())
+			})
 			By("getting that CatalogSource", func() {
 				cs, err := oc.GetCatalogSource(context.TODO(), "testcs", "testns")
 				Expect(err).ToNot(HaveOccurred())
@@ -224,6 +255,19 @@ var _ = Describe("OpenShift Engine", func() {
 				Expect(err).ToNot(HaveOccurred())
 				Expect(sub).ToNot(BeNil())
 			})
+			By("creating a Subscription again should error", func() {
+				subData := SubscriptionData{
+					Name:                   "testsub",
+					Channel:                "testchannel",
+					CatalogSource:          "testcs",
+					CatalogSourceNamespace: "testns",
+					Package:                "testpackage",
+				}
+				sub, err := oc.CreateSubscription(context.TODO(), subData, "testns")
+				Expect(err).To(HaveOccurred())
+				Expect(err).To(MatchError(ErrAlreadyExists))
+				Expect(sub).ToNot(BeNil())
+			})
 			By("getting that Subscription", func() {
 				sub, err := oc.GetSubscription(context.TODO(), "testsub", "testns")
 				Expect(err).ToNot(HaveOccurred())
@@ -254,6 +298,18 @@ var _ = Describe("OpenShift Engine", func() {
 				Expect(err).ToNot(HaveOccurred())
 				Expect(rb).ToNot(BeNil())
 			})
+			By("creating a RoleBinding again should error", func() {
+				rbData := RoleBindingData{
+					Name:      "testrb",
+					Subjects:  []string{"testsubject"},
+					Role:      "testrole",
+					Namespace: "testns",
+				}
+				rb, err := oc.CreateRoleBinding(context.TODO(), rbData, "testns")
+				Expect(err).To(HaveOccurred())
+				Expect(err).To(MatchError(ErrAlreadyExists))
+				Expect(rb).ToNot(BeNil())
+			})
 			By("getting that RoleBinding", func() {
 				rb, err := oc.GetRoleBinding(context.TODO(), "testrb", "testns")
 				Expect(err).ToNot(HaveOccurred())
@@ -279,10 +335,16 @@ var _ = Describe("OpenShift Engine", func() {
 		})
 	})
 	Context("CSVs", func() {
-		It("should exercise GetCSV", func() {
+		It("should get a CSV", func() {
 			csv, err := oc.GetCSV(context.TODO(), "testcsv", "testns")
 			Expect(err).ToNot(HaveOccurred())
 			Expect(csv).ToNot(BeNil())
 		})
+		It("should error if CSV doesn't exist", func() {
+			csv, err := oc.GetCSV(context.TODO(), "badcsv", "badns")
+			Expect(err).To(HaveOccurred())
+			Expect(err).To(MatchError(ErrNotFound))
+			Expect(csv).To(BeNil())
+		})
 	})
 })
diff --git a/certification/internal/openshift/openshift_version_test.go b/certification/internal/openshift/openshift_version_test.go
new file mode 100644
index 0000000..568fae0
--- /dev/null
+++ b/certification/internal/openshift/openshift_version_test.go
@@ -0,0 +1,31 @@
+package openshift
+
+import (
+	"os"
+
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/runtime"
+)
+
+var _ = Describe("OpenShift Version", func() {
+	When("no KUBECONFIG is provided", func() {
+		It("should return UnknownVersion and an error", func() {
+			version, err := GetOpenshiftClusterVersion()
+			Expect(version).To(BeEquivalentTo(runtime.UnknownOpenshiftClusterVersion()))
+			Expect(err).To(HaveOccurred())
+		})
+	})
+
+	When("an invalid KUBECONFIG is passed", func() {
+		BeforeEach(func() {
+			os.Setenv("KUBECONFIG", "/bad/kubeconfig")
+			DeferCleanup(os.Unsetenv, "KUBECONFIG")
+		})
+		It("should return UnkownVersion and an error", func() {
+			version, err := GetOpenshiftClusterVersion()
+			Expect(version).To(BeEquivalentTo(runtime.UnknownOpenshiftClusterVersion()))
+			Expect(err).To(HaveOccurred())
+		})
+	})
+})
diff --git a/certification/internal/operatorsdk/operatorsdk_suite_test.go b/certification/internal/operatorsdk/operatorsdk_suite_test.go
new file mode 100644
index 0000000..1f8d7d5
--- /dev/null
+++ b/certification/internal/operatorsdk/operatorsdk_suite_test.go
@@ -0,0 +1,20 @@
+package operatorsdk
+
+import (
+	"testing"
+
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+
+	log "github.com/sirupsen/logrus"
+)
+
+func TestOperatorSdk(t *testing.T) {
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "Operator Suite")
+}
+
+func init() {
+	log.SetFormatter(&log.TextFormatter{})
+	log.SetLevel(log.TraceLevel)
+}
diff --git a/certification/internal/operatorsdk/operatorsdk_test.go b/certification/internal/operatorsdk/operatorsdk_test.go
new file mode 100644
index 0000000..0ae2950
--- /dev/null
+++ b/certification/internal/operatorsdk/operatorsdk_test.go
@@ -0,0 +1,181 @@
+package operatorsdk
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"os/exec"
+	"testing"
+
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/artifacts"
+)
+
+const (
+	testStdoutValue               = `{}`
+	testBundleValidateStdoutValue = `{"passed": true, "outputs": null}`
+)
+
+var _ = Describe("OperatorSdk", func() {
+	var tmpdir string
+	BeforeEach(func() {
+		var err error
+		tmpdir, err = os.MkdirTemp("", "operatorsdk-test-artifacts-*")
+		Expect(err).ToNot(HaveOccurred())
+		DeferCleanup(os.RemoveAll, tmpdir)
+		artifacts.SetDir(tmpdir)
+	})
+	When("The Scorecard result is good", func() {
+		It("should succeed", func() {
+			operatorSdk := New("foo.image", fakeExecCommandSuccess)
+			_, err := operatorSdk.Scorecard(context.TODO(), "foo.image", OperatorSdkScorecardOptions{
+				ResultFile:     "success.txt",
+				OutputFormat:   "json",
+				Selector:       []string{"selector1", "selector2"},
+				Kubeconfig:     "/my/kubeconfig",
+				Namespace:      "awesome-namespace",
+				ServiceAccount: "this-service-account",
+				Verbose:        true,
+				WaitTime:       "120m",
+			})
+			Expect(err).ToNot(HaveOccurred())
+		})
+	})
+	When("The Scorecard result is a failure", func() {
+		It("should fail", func() {
+			operatorSdk := New("foo.image", fakeExecCommandFailure)
+			_, err := operatorSdk.Scorecard(context.TODO(), "foo.image", OperatorSdkScorecardOptions{
+				ResultFile:   "failure.txt",
+				OutputFormat: "text",
+			})
+			Expect(err).To(HaveOccurred())
+		})
+	})
+	When("The Bundle Validate result is good", func() {
+		It("should succeed", func() {
+			operatorSdk := New("foo.image", fakeExecValidateCommandSuccess)
+			_, err := operatorSdk.BundleValidate(context.TODO(), "foo.image", OperatorSdkBundleValidateOptions{
+				OutputFormat:    "json",
+				LogLevel:        "debug",
+				ContainerEngine: "podman",
+				Selector:        []string{"selector1", "selector2"},
+				OptionalValues:  map[string]string{"foo": "bar"},
+				Verbose:         true,
+				WaitTime:        "120m",
+			})
+			Expect(err).ToNot(HaveOccurred())
+		})
+	})
+	When("The scorecard result has an error", func() {
+		It("should return result == failed", func() {
+			operatoSdk := New("foo.image", fakeExecValidateCommandError)
+			result, err := operatoSdk.BundleValidate(context.TODO(), "foo.image", OperatorSdkBundleValidateOptions{
+				OutputFormat: "text",
+			})
+			Expect(err).ToNot(HaveOccurred())
+			Expect(result.Passed).To(BeFalse())
+		})
+	})
+	When("The Bundle Validate result is bad", func() {
+		It("should fail", func() {
+			operatorSdk := New("foo.image", fakeExecValidateCommandFailure)
+			_, err := operatorSdk.BundleValidate(context.TODO(), "foo.image", OperatorSdkBundleValidateOptions{})
+			Expect(err).To(HaveOccurred())
+		})
+	})
+})
+
+// These will be called when the inception occurs.
+// If the GO_TEST_PROCESS envvar is not "1", which would
+// be the case on the full testing run, it just returns.
+// If it is set, then that means we are inside the
+// exec call, and can therefore print whatever we want
+// to stdout, stderr, and set the return value appropriately.
+// When it exits, it goes back to the original test exec.
+func TestShellProcessSuccess(t *testing.T) {
+	if os.Getenv("GO_TEST_PROCESS") != "1" {
+		return
+	}
+	fmt.Fprintf(os.Stdout, testStdoutValue)
+	os.Exit(0)
+}
+
+func TestShellProcessFail(t *testing.T) {
+	if os.Getenv("GO_TEST_PROCESS") != "1" {
+		return
+	}
+	fmt.Fprintf(os.Stderr, "FATA")
+	os.Exit(1)
+}
+
+func TestBundleValidateProcessSuccess(t *testing.T) {
+	if os.Getenv("GO_TEST_PROCESS") != "1" {
+		return
+	}
+	fmt.Fprintf(os.Stdout, testBundleValidateStdoutValue)
+	os.Exit(0)
+}
+
+func TestBundleValidateProcessError(t *testing.T) {
+	if os.Getenv("GO_TEST_PROCESS") != "1" {
+		return
+	}
+	fmt.Fprintf(os.Stdout, "FATA")
+	os.Exit(0)
+}
+
+func TestBundleValidateProcessFail(t *testing.T) {
+	if os.Getenv("GO_TEST_PROCESS") != "1" {
+		return
+	}
+	fmt.Fprintf(os.Stderr, "FATA")
+	os.Exit(1)
+}
+
+// What's happening here?
+//
+// These are the cmdContexts that are being subbed in instead of exec.Command
+// So, when the SUT calls cmdContext(...) it will use this instead.
+// It replaces the command that is passed in with the test args, plus the rest
+// of the original command. It then execs the test binary with these args.
+// The -test.run arg is will exec JUST that function from above.
+func fakeExecCommandSuccess(command string, args ...string) *exec.Cmd {
+	cs := []string{"-test.run=TestShellProcessSuccess", "--", command}
+	cs = append(cs, args...)
+	cmd := exec.Command(os.Args[0], cs...)
+	cmd.Env = []string{"GO_TEST_PROCESS=1"}
+	return cmd
+}
+
+func fakeExecCommandFailure(command string, args ...string) *exec.Cmd {
+	cs := []string{"-test.run=TestShellProcessFail", "--", command}
+	cs = append(cs, args...)
+	cmd := exec.Command(os.Args[0], cs...)
+	cmd.Env = []string{"GO_TEST_PROCESS=1"}
+	return cmd
+}
+
+func fakeExecValidateCommandSuccess(command string, args ...string) *exec.Cmd {
+	cs := []string{"-test.run=TestBundleValidateProcessSuccess", "--", command}
+	cs = append(cs, args...)
+	cmd := exec.Command(os.Args[0], cs...)
+	cmd.Env = []string{"GO_TEST_PROCESS=1"}
+	return cmd
+}
+
+func fakeExecValidateCommandError(command string, args ...string) *exec.Cmd {
+	cs := []string{"-test.run=TestBundleValidateProcessError", "--", command}
+	cs = append(cs, args...)
+	cmd := exec.Command(os.Args[0], cs...)
+	cmd.Env = []string{"GO_TEST_PROCESS=1"}
+	return cmd
+}
+
+func fakeExecValidateCommandFailure(command string, args ...string) *exec.Cmd {
+	cs := []string{"-test.run=TestBundleValidateProcessFail", "--", command}
+	cs = append(cs, args...)
+	cmd := exec.Command(os.Args[0], cs...)
+	cmd.Env = []string{"GO_TEST_PROCESS=1"}
+	return cmd
+}
diff --git a/certification/internal/policy/operator/deployable_by_olm_test.go b/certification/internal/policy/operator/deployable_by_olm_test.go
index 9d0f53b..afc68a7 100644
--- a/certification/internal/policy/operator/deployable_by_olm_test.go
+++ b/certification/internal/policy/operator/deployable_by_olm_test.go
@@ -17,14 +17,15 @@ import (
 
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/artifacts"
-	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/cli"
+
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/openshift"
+	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/operatorsdk"
 )
 
 var _ = Describe("DeployableByOLMCheck", func() {
 	var (
 		deployableByOLMCheck DeployableByOlmCheck
-		fakeEngine           cli.OperatorSdkEngine
+		fakeEngine           operatorSdk
 		imageRef             certification.ImageReference
 		tmpDockerDir         string
 		client               crclient.Client
@@ -93,17 +94,17 @@ var _ = Describe("DeployableByOLMCheck", func() {
 		imageRef.ImageInfo = &fakeImage
 		imageRef.ImageFSPath = tmpDir
 
-		report := cli.OperatorSdkBundleValidateReport{
+		report := operatorsdk.OperatorSdkBundleValidateReport{
 			Passed:  true,
-			Outputs: []cli.OperatorSdkBundleValidateOutput{},
+			Outputs: []operatorsdk.OperatorSdkBundleValidateOutput{},
 		}
-		fakeEngine = FakeOperatorSdkEngine{
+		fakeEngine = FakeOperatorSdk{
 			OperatorSdkBVReport: report,
 		}
 
 		now := metav1.Now()
 		og.Status.LastUpdated = &now
-		deployableByOLMCheck = *NewDeployableByOlmCheck(&fakeEngine, "test_indeximage", "", "")
+		deployableByOLMCheck = *NewDeployableByOlmCheck(fakeEngine, "test_indeximage", "", "")
 		scheme := apiruntime.NewScheme()
 		Expect(openshift.AddSchemes(scheme)).To(Succeed())
 		client = fake.NewClientBuilder().
diff --git a/certification/internal/policy/operator/operator_suite_test.go b/certification/internal/policy/operator/operator_suite_test.go
index 6bcd01c..c69e035 100644
--- a/certification/internal/policy/operator/operator_suite_test.go
+++ b/certification/internal/policy/operator/operator_suite_test.go
@@ -1,6 +1,7 @@
 package operator
 
 import (
+	"context"
 	"errors"
 	"testing"
 
@@ -9,7 +10,7 @@ import (
 	imagestreamv1 "github.com/openshift/api/image/v1"
 	operatorv1 "github.com/operator-framework/api/pkg/operators/v1"
 	operatorv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
-	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/cli"
+	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/operatorsdk"
 	log "github.com/sirupsen/logrus"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -25,36 +26,36 @@ func init() {
 	log.SetLevel(log.TraceLevel)
 }
 
-type FakeOperatorSdkEngine struct {
-	OperatorSdkReport   cli.OperatorSdkScorecardReport
-	OperatorSdkBVReport cli.OperatorSdkBundleValidateReport
+type FakeOperatorSdk struct {
+	OperatorSdkReport   operatorsdk.OperatorSdkScorecardReport
+	OperatorSdkBVReport operatorsdk.OperatorSdkBundleValidateReport
 }
 
-func (f FakeOperatorSdkEngine) BundleValidate(image string, opts cli.OperatorSdkBundleValidateOptions) (*cli.OperatorSdkBundleValidateReport, error) {
+func (f FakeOperatorSdk) BundleValidate(ctx context.Context, image string, opts operatorsdk.OperatorSdkBundleValidateOptions) (*operatorsdk.OperatorSdkBundleValidateReport, error) {
 	return &f.OperatorSdkBVReport, nil
 }
 
-func (f FakeOperatorSdkEngine) Scorecard(image string, opts cli.OperatorSdkScorecardOptions) (*cli.OperatorSdkScorecardReport, error) {
+func (f FakeOperatorSdk) Scorecard(ctx context.Context, image string, opts operatorsdk.OperatorSdkScorecardOptions) (*operatorsdk.OperatorSdkScorecardReport, error) {
 	return &f.OperatorSdkReport, nil
 }
 
-type BadOperatorSdkEngine struct{}
+type BadOperatorSdk struct{}
 
-func (bose BadOperatorSdkEngine) Scorecard(bundleImage string, opts cli.OperatorSdkScorecardOptions) (*cli.OperatorSdkScorecardReport, error) {
-	operatorSdkReport := cli.OperatorSdkScorecardReport{
+func (bose BadOperatorSdk) Scorecard(ctx context.Context, bundleImage string, opts operatorsdk.OperatorSdkScorecardOptions) (*operatorsdk.OperatorSdkScorecardReport, error) {
+	operatorSdkReport := operatorsdk.OperatorSdkScorecardReport{
 		Stdout: "Bad Stdout",
 		Stderr: "Bad Stderr",
-		Items:  []cli.OperatorSdkScorecardItem{},
+		Items:  []operatorsdk.OperatorSdkScorecardItem{},
 	}
 	return &operatorSdkReport, errors.New("the Operator Sdk Scorecard has failed")
 }
 
-func (bose BadOperatorSdkEngine) BundleValidate(bundleImage string, opts cli.OperatorSdkBundleValidateOptions) (*cli.OperatorSdkBundleValidateReport, error) {
-	operatorSdkReport := cli.OperatorSdkBundleValidateReport{
+func (bose BadOperatorSdk) BundleValidate(ctx context.Context, bundleImage string, opts operatorsdk.OperatorSdkBundleValidateOptions) (*operatorsdk.OperatorSdkBundleValidateReport, error) {
+	operatorSdkReport := operatorsdk.OperatorSdkBundleValidateReport{
 		Stdout:  "Bad Stdout",
 		Stderr:  "Bad Stderr",
 		Passed:  false,
-		Outputs: []cli.OperatorSdkBundleValidateOutput{},
+		Outputs: []operatorsdk.OperatorSdkBundleValidateOutput{},
 	}
 	return &operatorSdkReport, errors.New("the Operator Sdk Bundle Validate has failed")
 }
diff --git a/certification/internal/policy/operator/scorecard_basic_check_spec_test.go b/certification/internal/policy/operator/scorecard_basic_check_spec_test.go
index b0ba8af..df1edb3 100644
--- a/certification/internal/policy/operator/scorecard_basic_check_spec_test.go
+++ b/certification/internal/policy/operator/scorecard_basic_check_spec_test.go
@@ -6,13 +6,13 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification"
-	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/cli"
+	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/operatorsdk"
 )
 
 var _ = Describe("ScorecardBasicCheck", func() {
 	var (
 		scorecardBasicCheck ScorecardBasicSpecCheck
-		fakeEngine          cli.OperatorSdkEngine
+		fakeEngine          operatorSdk
 	)
 
 	BeforeEach(func() {
@@ -48,10 +48,10 @@ var _ = Describe("ScorecardBasicCheck", func() {
 		  }
 		  `
 		stderr := ""
-		items := []cli.OperatorSdkScorecardItem{
+		items := []operatorsdk.OperatorSdkScorecardItem{
 			{
-				Status: cli.OperatorSdkScorecardStatus{
-					Results: []cli.OperatorSdkScorecardResult{
+				Status: operatorsdk.OperatorSdkScorecardStatus{
+					Results: []operatorsdk.OperatorSdkScorecardResult{
 						{
 							Name:  "olm-bundle-validation",
 							Log:   "log",
@@ -61,15 +61,15 @@ var _ = Describe("ScorecardBasicCheck", func() {
 				},
 			},
 		}
-		report := cli.OperatorSdkScorecardReport{
+		report := operatorsdk.OperatorSdkScorecardReport{
 			Stdout: stdout,
 			Stderr: stderr,
 			Items:  items,
 		}
-		fakeEngine = FakeOperatorSdkEngine{
+		fakeEngine = FakeOperatorSdk{
 			OperatorSdkReport: report,
 		}
-		scorecardBasicCheck = *NewScorecardBasicSpecCheck(&fakeEngine, "myns", "mysa", "", "20")
+		scorecardBasicCheck = *NewScorecardBasicSpecCheck(fakeEngine, "myns", "mysa", "", "20")
 	})
 	Describe("Operator Bundle Scorecard", func() {
 		Context("When Operator Bundle Scorecard Basic Check has a pass", func() {
@@ -81,10 +81,10 @@ var _ = Describe("ScorecardBasicCheck", func() {
 		})
 		Context("When Operator Bundle Scorecard Basic Check has a fail", func() {
 			BeforeEach(func() {
-				engine := fakeEngine.(FakeOperatorSdkEngine)
+				engine := fakeEngine.(FakeOperatorSdk)
 				engine.OperatorSdkReport.Items[0].Status.Results[0].State = "fail"
 				fakeEngine = engine
-				scorecardBasicCheck = *NewScorecardBasicSpecCheck(&fakeEngine, "myns", "mysa", "", "20")
+				scorecardBasicCheck = *NewScorecardBasicSpecCheck(fakeEngine, "myns", "mysa", "", "20")
 			})
 			It("Should not pass Validate", func() {
 				ok, err := scorecardBasicCheck.Validate(context.TODO(), certification.ImageReference{ImageURI: "dummy/image"})
@@ -93,10 +93,10 @@ var _ = Describe("ScorecardBasicCheck", func() {
 			})
 		})
 	})
-	Describe("Checking that OperatorSdkEngine errors are handled correctly", func() {
+	Describe("Checking that OperatorSdk errors are handled correctly", func() {
 		BeforeEach(func() {
-			fakeEngine = BadOperatorSdkEngine{}
-			scorecardBasicCheck = *NewScorecardBasicSpecCheck(&fakeEngine, "myns", "mysa", "", "20")
+			fakeEngine = BadOperatorSdk{}
+			scorecardBasicCheck = *NewScorecardBasicSpecCheck(fakeEngine, "myns", "mysa", "", "20")
 		})
 		Context("When OperatorSdk throws an error", func() {
 			It("should fail Validate and return an error", func() {
diff --git a/certification/internal/policy/operator/scorecard_olm_suite_test.go b/certification/internal/policy/operator/scorecard_olm_suite_test.go
index 27dd362..dd29896 100644
--- a/certification/internal/policy/operator/scorecard_olm_suite_test.go
+++ b/certification/internal/policy/operator/scorecard_olm_suite_test.go
@@ -6,13 +6,13 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification"
-	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/cli"
+	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/operatorsdk"
 )
 
 var _ = Describe("ScorecardBasicCheck", func() {
 	var (
 		scorecardOlmSuiteCheck ScorecardOlmSuiteCheck
-		fakeEngine             cli.OperatorSdkEngine
+		fakeEngine             operatorSdk
 	)
 
 	BeforeEach(func() {
@@ -48,10 +48,10 @@ var _ = Describe("ScorecardBasicCheck", func() {
 		  }
 		  `
 		stderr := ""
-		items := []cli.OperatorSdkScorecardItem{
+		items := []operatorsdk.OperatorSdkScorecardItem{
 			{
-				Status: cli.OperatorSdkScorecardStatus{
-					Results: []cli.OperatorSdkScorecardResult{
+				Status: operatorsdk.OperatorSdkScorecardStatus{
+					Results: []operatorsdk.OperatorSdkScorecardResult{
 						{
 							Name:  "olm-bundle-validation",
 							Log:   "log",
@@ -61,15 +61,15 @@ var _ = Describe("ScorecardBasicCheck", func() {
 				},
 			},
 		}
-		report := cli.OperatorSdkScorecardReport{
+		report := operatorsdk.OperatorSdkScorecardReport{
 			Stdout: stdout,
 			Stderr: stderr,
 			Items:  items,
 		}
-		fakeEngine = FakeOperatorSdkEngine{
+		fakeEngine = FakeOperatorSdk{
 			OperatorSdkReport: report,
 		}
-		scorecardOlmSuiteCheck = *NewScorecardOlmSuiteCheck(&fakeEngine, "myns", "mysa", "", "20")
+		scorecardOlmSuiteCheck = *NewScorecardOlmSuiteCheck(fakeEngine, "myns", "mysa", "", "20")
 	})
 	Describe("Operator Bundle Scorecard", func() {
 		Context("When Operator Bundle Scorecard OLM Suite Check has a pass", func() {
@@ -81,10 +81,10 @@ var _ = Describe("ScorecardBasicCheck", func() {
 		})
 		Context("When Operator Bundle Scorecard OLM Suite Check has a fail", func() {
 			BeforeEach(func() {
-				engine := fakeEngine.(FakeOperatorSdkEngine)
+				engine := fakeEngine.(FakeOperatorSdk)
 				engine.OperatorSdkReport.Items[0].Status.Results[0].State = "fail"
 				fakeEngine = engine
-				scorecardOlmSuiteCheck = *NewScorecardOlmSuiteCheck(&fakeEngine, "myns", "mysa", "", "20")
+				scorecardOlmSuiteCheck = *NewScorecardOlmSuiteCheck(fakeEngine, "myns", "mysa", "", "20")
 			})
 			It("Should not pass Validate", func() {
 				ok, err := scorecardOlmSuiteCheck.Validate(context.TODO(), certification.ImageReference{ImageURI: "dummy/image"})
@@ -93,10 +93,10 @@ var _ = Describe("ScorecardBasicCheck", func() {
 			})
 		})
 	})
-	Describe("Checking that OperatorSdkEngine errors are handled correctly", func() {
+	Describe("Checking that OperatorSdk errors are handled correctly", func() {
 		BeforeEach(func() {
-			fakeEngine = BadOperatorSdkEngine{}
-			scorecardOlmSuiteCheck = *NewScorecardOlmSuiteCheck(&fakeEngine, "myns", "mysa", "", "20")
+			fakeEngine = BadOperatorSdk{}
+			scorecardOlmSuiteCheck = *NewScorecardOlmSuiteCheck(fakeEngine, "myns", "mysa", "", "20")
 		})
 		Context("When OperatorSdk throws an error", func() {
 			It("should fail Validate and return an error", func() {
diff --git a/certification/internal/policy/operator/validate_operator_bundle_test.go b/certification/internal/policy/operator/validate_operator_bundle_test.go
index 8265783..948d77a 100644
--- a/certification/internal/policy/operator/validate_operator_bundle_test.go
+++ b/certification/internal/policy/operator/validate_operator_bundle_test.go
@@ -8,7 +8,7 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification"
-	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/cli"
+	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/operatorsdk"
 )
 
 var _ = Describe("BundleValidateCheck", func() {
@@ -24,7 +24,7 @@ var _ = Describe("BundleValidateCheck", func() {
 
 	var (
 		bundleValidateCheck ValidateOperatorBundleCheck
-		fakeEngine          cli.OperatorSdkEngine
+		fakeEngine          operatorSdk
 		imageRef            certification.ImageReference
 	)
 
@@ -34,13 +34,13 @@ var _ = Describe("BundleValidateCheck", func() {
 	"outputs": null
 }`
 		stderr := ""
-		report := cli.OperatorSdkBundleValidateReport{
+		report := operatorsdk.OperatorSdkBundleValidateReport{
 			Stdout:  stdout,
 			Stderr:  stderr,
 			Passed:  true,
-			Outputs: []cli.OperatorSdkBundleValidateOutput{},
+			Outputs: []operatorsdk.OperatorSdkBundleValidateOutput{},
 		}
-		fakeEngine = FakeOperatorSdkEngine{
+		fakeEngine = FakeOperatorSdk{
 			OperatorSdkBVReport: report,
 		}
 
@@ -56,7 +56,7 @@ var _ = Describe("BundleValidateCheck", func() {
 
 		imageRef.ImageFSPath = tmpDir
 
-		bundleValidateCheck = *NewValidateOperatorBundleCheck(&fakeEngine)
+		bundleValidateCheck = *NewValidateOperatorBundleCheck(fakeEngine)
 	})
 	Describe("Operator Bundle Validate", func() {
 		Context("When Operator Bundle Validate passes", func() {
@@ -68,14 +68,14 @@ var _ = Describe("BundleValidateCheck", func() {
 		})
 		Context("When Operator Bundle Validate does not Pass", func() {
 			BeforeEach(func() {
-				engine := fakeEngine.(FakeOperatorSdkEngine)
+				engine := fakeEngine.(FakeOperatorSdk)
 				engine.OperatorSdkBVReport.Passed = false
-				engine.OperatorSdkBVReport.Outputs = []cli.OperatorSdkBundleValidateOutput{
+				engine.OperatorSdkBVReport.Outputs = []operatorsdk.OperatorSdkBundleValidateOutput{
 					{Type: "warning", Message: "This is a warning"},
 					{Type: "error", Message: "This is an error"},
 				}
 				fakeEngine = engine
-				bundleValidateCheck = *NewValidateOperatorBundleCheck(&fakeEngine)
+				bundleValidateCheck = *NewValidateOperatorBundleCheck(fakeEngine)
 			})
 			It("Should not pass Validate", func() {
 				ok, err := bundleValidateCheck.Validate(context.TODO(), imageRef)
@@ -84,10 +84,10 @@ var _ = Describe("BundleValidateCheck", func() {
 			})
 		})
 	})
-	Describe("Checking that OperatorSdkEngine errors are handled correctly", func() {
+	Describe("Checking that OperatorSdk errors are handled correctly", func() {
 		BeforeEach(func() {
-			fakeEngine = BadOperatorSdkEngine{}
-			bundleValidateCheck = *NewValidateOperatorBundleCheck(&fakeEngine)
+			fakeEngine = BadOperatorSdk{}
+			bundleValidateCheck = *NewValidateOperatorBundleCheck(fakeEngine)
 		})
 		Context("When OperatorSdk throws an error", func() {
 			It("should fail Validate and return an error", func() {
diff --git a/cmd/check_operator_test.go b/cmd/check_operator_test.go
index 476f2d0..30c1607 100644
--- a/cmd/check_operator_test.go
+++ b/cmd/check_operator_test.go
@@ -8,6 +8,7 @@ import (
 	. "github.com/onsi/gomega"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/engine"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/formatters"
+	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/policy"
 	"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/runtime"
 	"github.com/spf13/viper"
 )
@@ -119,11 +120,14 @@ var _ = Describe("Check Operator", func() {
 
 		Context("with an invalid policy definition", func() {
 			It("should return the container policy engine anyway", func() {
+				cfg.Policy = "badpolicy"
+				beforeCfg := *cfg
 				runner, err := newCheckOperatorRunner(context.TODO(), cfg)
 				Expect(err).ToNot(HaveOccurred())
 
-				expectedEngine, err := engine.NewForConfig(context.TODO(), cfg.ReadOnly())
-				Expect(runner.eng).To(BeEquivalentTo(expectedEngine))
+				_, err = engine.NewForConfig(context.TODO(), cfg.ReadOnly())
+				Expect(runner.cfg.Policy).ToNot(Equal(beforeCfg.Policy))
+				Expect(runner.cfg.Policy).To(Equal(policy.PolicyOperator))
 				Expect(err).ToNot(HaveOccurred())
 			})
 		})