Repository: code-ready/crc
Pull request #1437 (2020-08-05 08:52:28)

Remove integration build tag
Simplify the build code and fix lint errors.

openshift-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/code-ready/crc/pull/1437#" title="Author self-approved">guillaumerose</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=code-ready%2Fcrc).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/code-ready/crc/blob/master/OWNERS)~~ [guillaumerose]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
openshift-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/code-ready/crc/pull/1437#" title="Author self-approved">guillaumerose</a>*, *<a href="https://github.com/code-ready/crc/pull/1437#pullrequestreview-461487154" title="Approved">jsliacan</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=code-ready%2Fcrc).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/code-ready/crc/blob/master/OWNERS)~~ [guillaumerose,jsliacan]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
openshift-ci-robot: @guillaumerose: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/e2e-crc | 5e03b2c3bc68f1f3071c940d8c95da7cbf478ff9 | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/code-ready_crc/1437/pull-ci-code-ready-crc-master-e2e-crc/1290933687566733313) | `/test e2e-crc`

[Full PR test history](https://prow.ci.openshift.org/pr-history?org=code-ready&repo=crc&pr=1437). [Your PR dashboard](https://prow.ci.openshift.org/pr?query=is:pr+state:open+author:guillaumerose).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
openshift-ci-robot: New changes are detected. LGTM label has been removed.

Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 9daa243ee..ab724ad73 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -45,6 +45,9 @@ jobs:
     - run:
         name: Run unit tests
         command: make test
+    - run:
+        name: Compile integration tests
+        command: make build_integration
     - store_artifacts:
         path: ~/project/out
         destination: crc
diff --git a/.travis.yml b/.travis.yml
index 715a4309c..9e13186c3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,4 +17,5 @@ script:
 - make cross-lint
 - make cross
 - make test
+- make build_integration
 - make BUNDLE_DIR=/tmp MOCK_BUNDLE=true release
diff --git a/Makefile b/Makefile
index 328e3b784..a07273610 100644
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,6 @@ GOPATH ?= $(shell go env GOPATH)
 ORG := github.com/code-ready
 REPOPATH ?= $(ORG)/crc
 
-PACKAGES := go list --tags build ./...
 SOURCES := $(shell git ls-files  *.go ":^vendor")
 
 RELEASE_INFO := release-info.json
@@ -96,7 +95,7 @@ cross: $(BUILD_DIR)/macos-amd64/crc $(BUILD_DIR)/linux-amd64/crc $(BUILD_DIR)/wi
 
 .PHONY: test
 test:
-	go test --tags build -v -ldflags="$(VERSION_VARIABLES)" $(shell $(PACKAGES))
+	go test --tags build -v -ldflags="$(VERSION_VARIABLES)" ./pkg/... ./cmd/...
 
 .PHONY: build_docs
 build_docs:
@@ -119,7 +118,12 @@ clean: clean_docs
 	rm -rf $(BUILD_DIR)
 	rm -f $(GOPATH)/bin/crc
 	rm -rf $(RELEASE_DIR)
-       
+
+.PHONY: build_integration
+build_integration: $(SOURCES)
+	GOOS=linux   go test ./test/integration/ -c -o $(BUILD_DIR)/linux-amd64/integration.test
+	GOOS=windows go test ./test/integration/ -c -o $(BUILD_DIR)/windows-amd64/integration.test.exe
+	GOOS=darwin  go test ./test/integration/ -c -o $(BUILD_DIR)/macos-amd64/integration.test
 
 .PHONY: integration ## Run integration tests
 integration:
@@ -134,7 +138,7 @@ ifndef CRC_BINARY
 	CRC_BINARY = --crc-binary=$(GOPATH)/bin
 endif
 integration:
-	@go test --timeout=120m $(REPOPATH)/test/integration -v $(PULL_SECRET_FILE) $(BUNDLE_LOCATION) $(CRC_BINARY) --bundle-version=$(BUNDLE_VERSION) --tags=integration $(GODOG_OPTS)
+	@go test --timeout=120m $(REPOPATH)/test/integration -v $(PULL_SECRET_FILE) $(BUNDLE_LOCATION) $(CRC_BINARY) --bundle-version=$(BUNDLE_VERSION) $(GODOG_OPTS)
 
 .PHONY: fmt
 fmt:
diff --git a/cmd/crc/cmd/json.go b/cmd/crc/cmd/json.go
new file mode 100644
index 000000000..e988d901c
--- /dev/null
+++ b/cmd/crc/cmd/json.go
@@ -0,0 +1,36 @@
+package cmd
+
+import (
+	"encoding/json"
+	"fmt"
+	"io"
+
+	"github.com/spf13/cobra"
+)
+
+const jsonFormat = "json"
+
+var (
+	outputFormat string
+)
+
+func addOutputFormatFlag(cmd *cobra.Command) {
+	cmd.Flags().StringVarP(&outputFormat, "output", "o", "", "Output format. One of: json")
+}
+
+type prettyPrintable interface {
+	prettyPrintTo(writer io.Writer) error
+}
+
+func render(obj prettyPrintable, writer io.Writer, outputFormat string) error {
+	switch outputFormat {
+	case jsonFormat:
+		encoder := json.NewEncoder(writer)
+		encoder.SetIndent("", "  ")
+		return encoder.Encode(obj)
+	case "":
+		return obj.prettyPrintTo(writer)
+	default:
+		return fmt.Errorf("invalid format: %s", outputFormat)
+	}
+}
diff --git a/cmd/crc/cmd/root.go b/cmd/crc/cmd/root.go
index 3c05bcd05..b7433b413 100644
--- a/cmd/crc/cmd/root.go
+++ b/cmd/crc/cmd/root.go
@@ -57,7 +57,8 @@ func runPrerun() {
 	// Setting up logrus
 	logging.InitLogrus(logging.LogLevel, constants.LogFilePath)
 	setProxyDefaults()
-	for _, str := range GetVersionStrings() {
+
+	for _, str := range defaultVersion().lines() {
 		logging.Debugf(str)
 	}
 }
diff --git a/cmd/crc/cmd/start.go b/cmd/crc/cmd/start.go
index 64f3d51fa..1db24f7a0 100644
--- a/cmd/crc/cmd/start.go
+++ b/cmd/crc/cmd/start.go
@@ -15,7 +15,7 @@ import (
 	"github.com/code-ready/crc/pkg/crc/output"
 	"github.com/code-ready/crc/pkg/crc/preflight"
 	"github.com/code-ready/crc/pkg/crc/validation"
-	"github.com/code-ready/crc/pkg/crc/version"
+	crcversion "github.com/code-ready/crc/pkg/crc/version"
 	"github.com/spf13/cobra"
 	"github.com/spf13/pflag"
 )
@@ -141,7 +141,7 @@ func checkIfNewVersionAvailable(noUpdateCheck bool) {
 	if noUpdateCheck {
 		return
 	}
-	isNewVersionAvailable, newVersion, err := version.NewVersionAvailable()
+	isNewVersionAvailable, newVersion, err := crcversion.NewVersionAvailable()
 	if err != nil {
 		logging.Debugf("Unable to find out if a new version is available: %v", err)
 		return
diff --git a/cmd/crc/cmd/status.go b/cmd/crc/cmd/status.go
index f259d9534..5dadfd01d 100644
--- a/cmd/crc/cmd/status.go
+++ b/cmd/crc/cmd/status.go
@@ -1,7 +1,6 @@
 package cmd
 
 import (
-	"encoding/json"
 	"fmt"
 	"io"
 	"os"
@@ -15,14 +14,8 @@ import (
 	"github.com/spf13/cobra"
 )
 
-const jsonFormat = "json"
-
-var (
-	outputFormat string
-)
-
 func init() {
-	statusCmd.Flags().StringVarP(&outputFormat, "output", "o", "", "Output format. One of: json")
+	addOutputFormatFlag(statusCmd)
 	rootCmd.AddCommand(statusCmd)
 }
 
@@ -37,7 +30,7 @@ var statusCmd = &cobra.Command{
 	},
 }
 
-type Status struct {
+type status struct {
 	CrcStatus        string `json:"crcStatus"`
 	OpenShiftStatus  string `json:"openshiftStatus"`
 	OpenShiftVersion string `json:"openshiftVersion"`
@@ -68,7 +61,7 @@ func runStatus(writer io.Writer, client client, cacheDir, outputFormat string) e
 	if err != nil {
 		return fmt.Errorf("Error finding size of cache: %s", err.Error())
 	}
-	status := Status{
+	status := &status{
 		CrcStatus:        clusterStatus.CrcStatus,
 		OpenShiftStatus:  clusterStatus.OpenshiftStatus,
 		OpenShiftVersion: clusterStatus.OpenshiftVersion,
@@ -77,29 +70,23 @@ func runStatus(writer io.Writer, client client, cacheDir, outputFormat string) e
 		CacheUsage:       size,
 		CacheDir:         cacheDir,
 	}
-
-	if outputFormat == jsonFormat {
-		encoder := json.NewEncoder(writer)
-		encoder.SetIndent("", "  ")
-		return encoder.Encode(status)
-	}
-	return printStatus(writer, status)
+	return render(status, writer, outputFormat)
 }
 
-func printStatus(writer io.Writer, status Status) error {
+func (s *status) prettyPrintTo(writer io.Writer) error {
 	w := tabwriter.NewWriter(writer, 0, 0, 1, ' ', 0)
 
 	lines := []struct {
 		left, right string
 	}{
-		{"CRC VM", status.CrcStatus},
-		{"OpenShift", openshiftStatus(status)},
+		{"CRC VM", s.CrcStatus},
+		{"OpenShift", openshiftStatus(s)},
 		{"Disk Usage", fmt.Sprintf(
 			"%s of %s (Inside the CRC VM)",
-			units.HumanSize(float64(status.DiskUsage)),
-			units.HumanSize(float64(status.DiskSize)))},
-		{"Cache Usage", units.HumanSize(float64(status.CacheUsage))},
-		{"Cache Directory", status.CacheDir},
+			units.HumanSize(float64(s.DiskUsage)),
+			units.HumanSize(float64(s.DiskSize)))},
+		{"Cache Usage", units.HumanSize(float64(s.CacheUsage))},
+		{"Cache Directory", s.CacheDir},
 	}
 	for _, line := range lines {
 		if err := printLine(w, line.left, line.right); err != nil {
@@ -109,7 +96,7 @@ func printStatus(writer io.Writer, status Status) error {
 	return w.Flush()
 }
 
-func openshiftStatus(status Status) string {
+func openshiftStatus(status *status) string {
 	if status.OpenShiftVersion != "" {
 		return fmt.Sprintf("%s (v%s)", status.OpenShiftStatus, status.OpenShiftVersion)
 	}
diff --git a/cmd/crc/cmd/version.go b/cmd/crc/cmd/version.go
index 2e8e59897..8f26caf60 100644
--- a/cmd/crc/cmd/version.go
+++ b/cmd/crc/cmd/version.go
@@ -2,14 +2,17 @@ package cmd
 
 import (
 	"fmt"
-	"strings"
+	"io"
+	"os"
 
 	"github.com/code-ready/crc/pkg/crc/constants"
-	"github.com/code-ready/crc/pkg/crc/version"
+	"github.com/code-ready/crc/pkg/crc/exit"
+	crcversion "github.com/code-ready/crc/pkg/crc/version"
 	"github.com/spf13/cobra"
 )
 
 func init() {
+	addOutputFormatFlag(versionCmd)
 	rootCmd.AddCommand(versionCmd)
 }
 
@@ -18,21 +21,48 @@ var versionCmd = &cobra.Command{
 	Short: "Print version information",
 	Long:  "Print version information",
 	Run: func(cmd *cobra.Command, args []string) {
-		runPrintVersion(args)
+		if err := runPrintVersion(os.Stdout, defaultVersion(), outputFormat); err != nil {
+			exit.WithMessage(1, err.Error())
+		}
 	},
 }
 
-func GetVersionStrings() []string {
+func runPrintVersion(writer io.Writer, version *version, outputFormat string) error {
+	return render(version, writer, outputFormat)
+}
+
+type version struct {
+	Version          string `json:"version"`
+	Commit           string `json:"commit"`
+	OpenshiftVersion string `json:"openshiftVersion"`
+	Embedded         bool   `json:"embedded"`
+}
+
+func defaultVersion() *version {
+	return &version{
+		Version:          crcversion.GetCRCVersion(),
+		Commit:           crcversion.GetCommitSha(),
+		OpenshiftVersion: crcversion.GetBundleVersion(),
+		Embedded:         constants.BundleEmbedded(),
+	}
+}
+
+func (v *version) prettyPrintTo(writer io.Writer) error {
+	for _, line := range v.lines() {
+		if _, err := fmt.Fprint(writer, line); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (v *version) lines() []string {
 	var embedded string
-	if !constants.BundleEmbedded() {
+	if !v.Embedded {
 		embedded = "not "
 	}
 	return []string{
-		fmt.Sprintf("CodeReady Containers version: %s+%s", version.GetCRCVersion(), version.GetCommitSha()),
-		fmt.Sprintf("OpenShift version: %s (%sembedded in binary)", version.GetBundleVersion(), embedded),
+		fmt.Sprintf("CodeReady Containers version: %s+%s\n", v.Version, v.Commit),
+		fmt.Sprintf("OpenShift version: %s (%sembedded in binary)\n", v.OpenshiftVersion, embedded),
 	}
 }
-
-func runPrintVersion(arguments []string) {
-	fmt.Println(strings.Join(GetVersionStrings(), "\n"))
-}
diff --git a/pkg/crc/cluster/cluster.go b/pkg/crc/cluster/cluster.go
index 6e0f667ec..ed1770160 100644
--- a/pkg/crc/cluster/cluster.go
+++ b/pkg/crc/cluster/cluster.go
@@ -145,11 +145,11 @@ Environment=HTTPS_PROXY=%s
 Environment=NO_PROXY=.cluster.local,.svc,10.128.0.0/14,172.30.0.0/16,%s`
 	p := fmt.Sprintf(proxyTemplate, proxy.HTTPProxy, proxy.HTTPSProxy, proxy.GetNoProxyString())
 	// This will create a systemd drop-in configuration for proxy (both for kubelet and crio services) on the VM.
-	err := sshRunner.SetTextContentAsRoot("/etc/systemd/system/crio.service.d/10-default-env.conf", p, 0644)
+	err := sshRunner.CopyData([]byte(p), "/etc/systemd/system/crio.service.d/10-default-env.conf", 0644)
 	if err != nil {
 		return err
 	}
-	err = sshRunner.SetTextContentAsRoot("/etc/systemd/system/kubelet.service.d/10-default-env.conf", p, 0644)
+	err = sshRunner.CopyData([]byte(p), "/etc/systemd/system/kubelet.service.d/10-default-env.conf", 0644)
 	if err != nil {
 		return err
 	}
@@ -157,7 +157,7 @@ Environment=NO_PROXY=.cluster.local,.svc,10.128.0.0/14,172.30.0.0/16,%s`
 }
 
 func addPullSecretToInstanceDisk(sshRunner *ssh.Runner, pullSec string) error {
-	err := sshRunner.SetTextContentAsRoot("/var/lib/kubelet/config.json", pullSec, 0600)
+	err := sshRunner.CopyData([]byte(pullSec), "/var/lib/kubelet/config.json", 0600)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/crc/machine/machine.go b/pkg/crc/machine/machine.go
index 04311dfe3..987446692 100644
--- a/pkg/crc/machine/machine.go
+++ b/pkg/crc/machine/machine.go
@@ -246,11 +246,11 @@ func Start(startConfig StartConfig) (StartResult, error) {
 	}
 	logging.Info("CodeReady Containers VM is running")
 
-	// Start network time synchronization if `CRC_DEBUG_ENABLE_STOP_NTP` not set
-	if b, _ := strconv.ParseBool(os.Getenv("CRC_DEBUG_ENABLE_STOP_NTP")); !b {
-		logging.Info("Stopping network time synchronization in CodeReady Containers VM")
+	// Start network time synchronization if `CRC_DEBUG_ENABLE_STOP_NTP` is not set
+	if stopNtp, _ := strconv.ParseBool(os.Getenv("CRC_DEBUG_ENABLE_STOP_NTP")); !stopNtp {
+		logging.Info("Starting network time synchronization in CodeReady Containers VM")
 		if _, err := sshRunner.Run("sudo timedatectl set-ntp on"); err != nil {
-			return startError(startConfig.Name, "Failed to stop network time synchronization", err)
+			return startError(startConfig.Name, "Failed to start network time synchronization", err)
 		}
 	}
 
@@ -347,9 +347,9 @@ func Start(startConfig StartConfig) (StartResult, error) {
 		if err != nil {
 			return startError(startConfig.Name, "Error copying kubeconfig file", err)
 		}
-		// Copy kubeconfig file inside the VM
-		kubeconfigContent, _ := ioutil.ReadFile(kubeConfigFilePath)
-		_, err = sshRunner.RunPrivate(fmt.Sprintf("cat <<EOF | sudo tee /opt/kubeconfig\n%s\nEOF", string(kubeconfigContent)))
+
+		logging.Info("Copying kubeconfig file to CRC VM ...")
+		err = sshRunner.CopyFile(kubeConfigFilePath, "/opt/kubeconfig", 0644)
 		if err != nil {
 			return startError(startConfig.Name, "Error copying kubeconfig file in VM", err)
 		}
diff --git a/pkg/crc/network/nameservers.go b/pkg/crc/network/nameservers.go
index 60282cd94..8bdb6bb79 100644
--- a/pkg/crc/network/nameservers.go
+++ b/pkg/crc/network/nameservers.go
@@ -34,7 +34,7 @@ func GetResolvValuesFromInstance(sshRunner *ssh.Runner) (*ResolvFileValues, erro
 func CreateResolvFileOnInstance(sshRunner *ssh.Runner, resolvFileValues ResolvFileValues) error {
 	resolvFile, _ := CreateResolvFile(resolvFileValues)
 
-	err := sshRunner.CopyData([]byte(resolvFile), "/etc/resolv.conf")
+	err := sshRunner.CopyData([]byte(resolvFile), "/etc/resolv.conf", 0644)
 	if err != nil {
 		return fmt.Errorf("Error creating /etc/resolv on instance: %s", err.Error())
 	}
diff --git a/pkg/crc/services/dns/template.go b/pkg/crc/services/dns/template.go
index 6009277c5..56be88a44 100644
--- a/pkg/crc/services/dns/template.go
+++ b/pkg/crc/services/dns/template.go
@@ -52,7 +52,7 @@ func createDnsmasqDNSConfig(serviceConfig services.ServicePostStartConfig) error
 		return err
 	}
 
-	return serviceConfig.SSHRunner.CopyData([]byte(dnsConfig), "/var/srv/dnsmasq.conf")
+	return serviceConfig.SSHRunner.CopyData([]byte(dnsConfig), "/var/srv/dnsmasq.conf", 0644)
 }
 
 func createDNSConfigFile(values dnsmasqConfFileValues, tmpl string) (string, error) {
diff --git a/pkg/crc/ssh/ssh.go b/pkg/crc/ssh/ssh.go
index 61c21a22d..c80ca4b3d 100644
--- a/pkg/crc/ssh/ssh.go
+++ b/pkg/crc/ssh/ssh.go
@@ -3,6 +3,7 @@ package ssh
 import (
 	"encoding/base64"
 	"fmt"
+	"io/ioutil"
 	"os"
 
 	"github.com/code-ready/crc/pkg/crc/constants"
@@ -28,14 +29,6 @@ func (runner *Runner) Run(command string) (string, error) {
 	return runner.runSSHCommandFromDriver(command, false)
 }
 
-func (runner *Runner) SetTextContentAsRoot(destFilename string, content string, mode os.FileMode) error {
-	logging.Debugf("Creating %s with permissions 0%o in the CRC VM", destFilename, mode)
-	command := fmt.Sprintf("sudo install -m 0%o /dev/null %s && cat <<EOF | sudo tee %s\n%s\nEOF", mode, destFilename, destFilename, content)
-	_, err := runner.RunPrivate(command)
-
-	return err
-}
-
 func (runner *Runner) RunPrivate(command string) (string, error) {
 	return runner.runSSHCommandFromDriver(command, true)
 }
@@ -44,14 +37,23 @@ func (runner *Runner) SetPrivateKeyPath(path string) {
 	runner.privateSSHKey = path
 }
 
-func (runner *Runner) CopyData(data []byte, destFilename string) error {
+func (runner *Runner) CopyData(data []byte, destFilename string, mode os.FileMode) error {
+	logging.Debugf("Creating %s with permissions 0%o in the CRC VM", destFilename, mode)
 	base64Data := base64.StdEncoding.EncodeToString(data)
-	command := fmt.Sprintf("echo %s | base64 --decode | sudo tee %s > /dev/null", base64Data, destFilename)
-	_, err := runner.Run(command)
+	command := fmt.Sprintf("sudo install -m 0%o /dev/null %s && cat <<EOF | base64 --decode | sudo tee %s\n%s\nEOF", mode, destFilename, destFilename, base64Data)
+	_, err := runner.RunPrivate(command)
 
 	return err
 }
 
+func (runner *Runner) CopyFile(srcFilename string, destFilename string, mode os.FileMode) error {
+	data, err := ioutil.ReadFile(srcFilename)
+	if err != nil {
+		return err
+	}
+	return runner.CopyData(data, destFilename, mode)
+}
+
 func (runner *Runner) runSSHCommandFromDriver(command string, runPrivate bool) (string, error) {
 	client, err := drivers.GetSSHClientFromDriver(runner.driver, runner.privateSSHKey)
 	if err != nil {


Test patch:
diff --git a/cmd/crc/cmd/version_test.go b/cmd/crc/cmd/version_test.go
new file mode 100644
index 000000000..dd2e0c34e
--- /dev/null
+++ b/cmd/crc/cmd/version_test.go
@@ -0,0 +1,40 @@
+package cmd
+
+import (
+	"bytes"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestPlainVersion(t *testing.T) {
+	out := new(bytes.Buffer)
+	assert.NoError(t, runPrintVersion(out, &version{
+		Version:          "1.13",
+		Commit:           "aabbcc",
+		OpenshiftVersion: "4.5.4",
+		Embedded:         false,
+	}, ""))
+	assert.Equal(t, `CodeReady Containers version: 1.13+aabbcc
+OpenShift version: 4.5.4 (not embedded in binary)
+`, out.String())
+}
+
+func TestJsonVersion(t *testing.T) {
+	out := new(bytes.Buffer)
+	assert.NoError(t, runPrintVersion(out, &version{
+		Version:          "1.13",
+		Commit:           "aabbcc",
+		OpenshiftVersion: "4.5.4",
+		Embedded:         false,
+	}, "json"))
+
+	expected := `{
+  "version": "1.13",
+  "commit": "aabbcc",
+  "openshiftVersion": "4.5.4",
+  "embedded": false
+}
+`
+	assert.Equal(t, expected, out.String())
+}
diff --git a/test/integration/crcsuite/crcsuite.go b/test/integration/crcsuite/crcsuite.go
index 7dd98b247..76a54631a 100644
--- a/test/integration/crcsuite/crcsuite.go
+++ b/test/integration/crcsuite/crcsuite.go
@@ -1,5 +1,3 @@
-// +build integration
-
 package crcsuite
 
 import (
@@ -30,7 +28,6 @@ var (
 	bundleURL      string
 	bundleVersion  string
 	pullSecretFile string
-	goPath         string
 )
 
 // FeatureContext defines godog.Suite steps for the test suite.
@@ -137,13 +134,17 @@ func FeatureContext(s *godog.Suite) {
 		}
 	})
 
+	// nolint:staticcheck
 	s.BeforeFeature(func(this *messages.GherkinDocument) {
-
 		// copy data/config files to test dir
 		CopyFilesToTestDir()
 
-		if bundleEmbedded == false {
-			if _, err := os.Stat(bundleName); os.IsNotExist(err) {
+		if !bundleEmbedded {
+			if _, err := os.Stat(bundleName); err != nil {
+				if !os.IsNotExist(err) {
+					fmt.Printf("Unexpected error obtaining the bundle %v.\n", bundleName)
+					os.Exit(1)
+				}
 				// Obtain the bundle to current dir
 				fmt.Println("Obtaining bundle...")
 				bundle, err := DownloadBundle(bundleURL, ".")
@@ -152,9 +153,6 @@ func FeatureContext(s *godog.Suite) {
 					os.Exit(1)
 				}
 				fmt.Println("Using bundle:", bundle)
-			} else if err != nil {
-				fmt.Printf("Unexpected error obtaining the bundle %v.\n", bundleName)
-				os.Exit(1)
 			} else {
 				fmt.Println("Using existing bundle:", bundleName)
 			}
@@ -175,13 +173,13 @@ func CheckClusterOperatorsWithRetry(retryCount int, retryWait string) error {
 		if err != nil {
 			return err
 		}
-		if s.Available == true {
+		if s.Available {
 			return nil
 		}
 		time.Sleep(retryDuration)
 	}
 
-	return fmt.Errorf("Some cluster operators are still not running.\n")
+	return fmt.Errorf("Some cluster operators are still not running")
 }
 
 func CheckHTTPResponseWithRetry(retryCount int, retryWait string, address string, expectedStatusCode int) error {
@@ -192,6 +190,7 @@ func CheckHTTPResponseWithRetry(retryCount int, retryWait string, address string
 	}
 
 	tr := &http.Transport{
+		// #nosec G402
 		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
 	}
 	client := &http.Client{Transport: tr}
@@ -208,7 +207,7 @@ func CheckHTTPResponseWithRetry(retryCount int, retryWait string, address string
 		time.Sleep(retryDuration)
 	}
 
-	return fmt.Errorf("Got %d as Status Code instead of expected %d.", resp.StatusCode, expectedStatusCode)
+	return fmt.Errorf("Got %d as Status Code instead of expected %d", resp.StatusCode, expectedStatusCode)
 }
 
 func CheckOutputMatchWithRetry(retryCount int, retryTime string, command string, expected string, expectedOutput string) error {
@@ -218,24 +217,24 @@ func CheckOutputMatchWithRetry(retryCount int, retryTime string, command string,
 		return err
 	}
 
-	var match_err error
+	var matchErr error
 
 	for i := 0; i < retryCount; i++ {
-		exec_err := clicumber.ExecuteCommand(command)
-		if exec_err == nil {
+		execErr := clicumber.ExecuteCommand(command)
+		if execErr == nil {
 			if strings.Contains(expected, " not ") {
-				match_err = clicumber.CommandReturnShouldNotMatch("stdout", expectedOutput)
+				matchErr = clicumber.CommandReturnShouldNotMatch("stdout", expectedOutput)
 			} else {
-				match_err = clicumber.CommandReturnShouldMatch("stdout", expectedOutput)
+				matchErr = clicumber.CommandReturnShouldMatch("stdout", expectedOutput)
 			}
-			if match_err == nil {
+			if matchErr == nil {
 				return nil
 			}
 		}
 		time.Sleep(retryDuration)
 	}
 
-	return match_err
+	return matchErr
 }
 
 func DeleteFileFromCRCHome(fileName string) error {
@@ -246,9 +245,8 @@ func DeleteFileFromCRCHome(fileName string) error {
 		return nil
 	}
 
-	err := clicumber.DeleteFile(theFile)
-	if err != nil {
-		fmt.Errorf("Error deleting file %v", theFile)
+	if err := clicumber.DeleteFile(theFile); err != nil {
+		return fmt.Errorf("Error deleting file %v", theFile)
 	}
 	return nil
 }
@@ -285,12 +283,12 @@ func ConfigFileInCRCHomeContainsKeyMatchingValue(format string, configFile strin
 	matches, err := clicumber.PerformRegexMatch(expectedValue, keyValue)
 	if err != nil {
 		return err
-	} else if (condition == "contains") && !matches {
+	}
+	if (condition == "contains") && !matches {
 		return fmt.Errorf("For key '%s' config contains unexpected value '%s'", keyPath, keyValue)
 	} else if (condition == "does not contain") && matches {
 		return fmt.Errorf("For key '%s' config contains value '%s', which it should not contain", keyPath, keyValue)
 	}
-
 	return nil
 }
 
@@ -339,7 +337,7 @@ func StartCRCWithDefaultBundleSucceedsOrFails(expected string) error {
 	var cmd string
 	var extraBundleArgs string
 
-	if bundleEmbedded == false {
+	if !bundleEmbedded {
 		extraBundleArgs = fmt.Sprintf("-b %s", bundleName)
 	}
 	cmd = fmt.Sprintf("crc start -p '%s' %s --log-level debug", pullSecretFile, extraBundleArgs)
@@ -353,7 +351,7 @@ func StartCRCWithDefaultBundleWithStopNetworkTimeSynchronizationSucceedsOrFails(
 	var cmd string
 	var extraBundleArgs string
 
-	if bundleEmbedded == false {
+	if !bundleEmbedded {
 		extraBundleArgs = fmt.Sprintf("-b %s", bundleName)
 	}
 	cmd = fmt.Sprintf("CRC_DEBUG_ENABLE_STOP_NTP=true crc start -p '%s' %s --log-level debug", pullSecretFile, extraBundleArgs)
@@ -365,34 +363,26 @@ func StartCRCWithDefaultBundleWithStopNetworkTimeSynchronizationSucceedsOrFails(
 func StartCRCWithDefaultBundleAndNameServerSucceedsOrFails(nameserver string, expected string) error {
 
 	var extraBundleArgs string
-	if bundleEmbedded == false {
+	if !bundleEmbedded {
 		extraBundleArgs = fmt.Sprintf("-b %s", bundleName)
 	}
 
-	var cmd string
-
-	cmd = fmt.Sprintf("crc start -n %s -p '%s' %s --log-level debug", nameserver, pullSecretFile, extraBundleArgs)
-	err := clicumber.ExecuteCommandSucceedsOrFails(cmd, expected)
-
-	return err
+	cmd := fmt.Sprintf("crc start -n %s -p '%s' %s --log-level debug", nameserver, pullSecretFile, extraBundleArgs)
+	return clicumber.ExecuteCommandSucceedsOrFails(cmd, expected)
 }
 
 func StdoutContainsIfBundleEmbeddedOrNot(value string, expected string) error {
-
 	if expected == "is" { // expect embedded
 		if bundleEmbedded { // really embedded
 			return clicumber.CommandReturnShouldContain("stdout", value)
-		} else {
-			return clicumber.CommandReturnShouldNotContain("stdout", value)
-		}
-	} else { // expect not embedded
-		if !bundleEmbedded { // really not embedded
-			return clicumber.CommandReturnShouldContain("stdout", value)
-		} else {
-			return clicumber.CommandReturnShouldNotContain("stdout", value)
 		}
+		return clicumber.CommandReturnShouldNotContain("stdout", value)
 	}
-
+	// expect not embedded
+	if !bundleEmbedded { // really not embedded
+		return clicumber.CommandReturnShouldContain("stdout", value)
+	}
+	return clicumber.CommandReturnShouldNotContain("stdout", value)
 }
 
 func SetConfigPropertyToValueSucceedsOrFails(property string, value string, expected string) error {
diff --git a/test/integration/crcsuite/prepare.go b/test/integration/crcsuite/prepare.go
index f0071f451..70f586ca8 100644
--- a/test/integration/crcsuite/prepare.go
+++ b/test/integration/crcsuite/prepare.go
@@ -1,5 +1,3 @@
-// +build integration
-
 package crcsuite
 
 import (
diff --git a/test/integration/crcsuite/util.go b/test/integration/crcsuite/util.go
index b367a63fc..986df8903 100644
--- a/test/integration/crcsuite/util.go
+++ b/test/integration/crcsuite/util.go
@@ -1,5 +1,3 @@
-// +build integration
-
 package crcsuite
 
 import (
@@ -39,5 +37,5 @@ func RemoveCRCHome() error {
 
 	}
 	// keepFile exists
-	return fmt.Errorf("Folder %s not removed as per request: %s present.\n", CRCHome, keepFile)
+	return fmt.Errorf("Folder %s not removed as per request: %s present", CRCHome, keepFile)
 }
diff --git a/test/integration/integration_test.go b/test/integration/integration_test.go
index 86c244d87..7962e5eb0 100644
--- a/test/integration/integration_test.go
+++ b/test/integration/integration_test.go
@@ -1,5 +1,3 @@
-// +build integration
-
 package integration
 
 import (