Repository: code-ready/crc
Pull request #1802 (2020-12-24 09:54:18)

Import 90% of machine code in crc
Only drivers (rpc, driver interface, hyperkit and libvirt structs) and state are left in code-ready/machine.

It will be easier to refactor machine code: better tests in the future, etc. All the persistence is now done in crc side. code-ready/machine is stateless and also all drivers.

will enable https://github.com/code-ready/machine/pull/54

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

This pull-request has been approved by: *<a href="https://github.com/code-ready/crc/pull/1802#" 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":[]} -->
guillaumerose: Ready for an other round of review :)
openshift-ci-robot: @guillaumerose: PR needs rebase.

<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.
</details>
guillaumerose: I also hesitated for hyperv driver but at the end, it is much easier to have machine reduced to the strict minimum. The major benefits is the ability to share code between preflights and the driver (how we invoke powershell, etc).
praveenkumar: /needs-rebase
guillaumerose: rebased!

Patch:
diff --git a/Makefile b/Makefile
index e17520a54..16a5b83c9 100644
--- a/Makefile
+++ b/Makefile
@@ -102,7 +102,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)" ./pkg/... ./cmd/...
+	go test -race --tags build -v -ldflags="$(VERSION_VARIABLES)" ./pkg/... ./cmd/...
 
 .PHONY: build_docs
 build_docs:
diff --git a/appveyor.yml b/appveyor.yml
index ccf77c985..2d04c171f 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -4,6 +4,7 @@ environment:
   GOPATH: c:\gopath
 stack: go 1.14
 before_test:
+  - choco install mingw
   - choco install make
   - make cross
 test_script:
diff --git a/pkg/crc/machine/driver.go b/pkg/crc/machine/driver.go
index 12aa40b06..249265bf3 100644
--- a/pkg/crc/machine/driver.go
+++ b/pkg/crc/machine/driver.go
@@ -2,8 +2,8 @@ package machine
 
 import (
 	"github.com/code-ready/crc/pkg/crc/machine/config"
+	"github.com/code-ready/crc/pkg/libmachine/host"
 	libmachine "github.com/code-ready/machine/libmachine/drivers"
-	"github.com/code-ready/machine/libmachine/host"
 )
 
 type valueSetter func(driver *libmachine.VMDriver) bool
diff --git a/pkg/crc/machine/driver_darwin.go b/pkg/crc/machine/driver_darwin.go
index 92ad9b960..2c1387a6d 100644
--- a/pkg/crc/machine/driver_darwin.go
+++ b/pkg/crc/machine/driver_darwin.go
@@ -7,9 +7,9 @@ import (
 	"github.com/code-ready/crc/pkg/crc/constants"
 	"github.com/code-ready/crc/pkg/crc/machine/config"
 	"github.com/code-ready/crc/pkg/crc/machine/hyperkit"
+	"github.com/code-ready/crc/pkg/libmachine"
+	"github.com/code-ready/crc/pkg/libmachine/host"
 	machineHyperkit "github.com/code-ready/machine/drivers/hyperkit"
-	"github.com/code-ready/machine/libmachine"
-	"github.com/code-ready/machine/libmachine/host"
 )
 
 func newHost(api libmachine.API, machineConfig config.MachineConfig) (*host.Host, error) {
diff --git a/pkg/crc/machine/driver_linux.go b/pkg/crc/machine/driver_linux.go
index 65336ee90..6613d44c8 100644
--- a/pkg/crc/machine/driver_linux.go
+++ b/pkg/crc/machine/driver_linux.go
@@ -7,9 +7,9 @@ import (
 	"github.com/code-ready/crc/pkg/crc/constants"
 	"github.com/code-ready/crc/pkg/crc/machine/config"
 	"github.com/code-ready/crc/pkg/crc/machine/libvirt"
+	"github.com/code-ready/crc/pkg/libmachine"
+	"github.com/code-ready/crc/pkg/libmachine/host"
 	machineLibvirt "github.com/code-ready/machine/drivers/libvirt"
-	"github.com/code-ready/machine/libmachine"
-	"github.com/code-ready/machine/libmachine/host"
 )
 
 func newHost(api libmachine.API, machineConfig config.MachineConfig) (*host.Host, error) {
diff --git a/pkg/crc/machine/driver_windows.go b/pkg/crc/machine/driver_windows.go
index ffcc4ad49..1f9993788 100644
--- a/pkg/crc/machine/driver_windows.go
+++ b/pkg/crc/machine/driver_windows.go
@@ -6,9 +6,9 @@ import (
 
 	"github.com/code-ready/crc/pkg/crc/machine/config"
 	"github.com/code-ready/crc/pkg/crc/machine/hyperv"
-	machineHyperv "github.com/code-ready/machine/drivers/hyperv"
-	"github.com/code-ready/machine/libmachine"
-	"github.com/code-ready/machine/libmachine/host"
+	machineHyperv "github.com/code-ready/crc/pkg/drivers/hyperv"
+	"github.com/code-ready/crc/pkg/libmachine"
+	"github.com/code-ready/crc/pkg/libmachine/host"
 )
 
 func newHost(api libmachine.API, machineConfig config.MachineConfig) (*host.Host, error) {
diff --git a/pkg/crc/machine/hyperv/driver_windows.go b/pkg/crc/machine/hyperv/driver_windows.go
index f63ef4f57..be4dae9ed 100644
--- a/pkg/crc/machine/hyperv/driver_windows.go
+++ b/pkg/crc/machine/hyperv/driver_windows.go
@@ -2,11 +2,9 @@ package hyperv
 
 import (
 	"github.com/code-ready/crc/pkg/crc/constants"
-	"github.com/code-ready/crc/pkg/crc/network"
-	"github.com/code-ready/machine/drivers/hyperv"
-
 	"github.com/code-ready/crc/pkg/crc/machine/config"
-
+	"github.com/code-ready/crc/pkg/crc/network"
+	"github.com/code-ready/crc/pkg/drivers/hyperv"
 	winnet "github.com/code-ready/crc/pkg/os/windows/network"
 )
 
@@ -18,6 +16,7 @@ func CreateHost(machineConfig config.MachineConfig) *hyperv.Driver {
 	hypervDriver.DisableDynamicMemory = true
 
 	if machineConfig.NetworkMode == network.VSockMode {
+
 		hypervDriver.VirtualSwitch = ""
 	} else {
 		// Determine the Virtual Switch to be used
diff --git a/pkg/crc/machine/machine.go b/pkg/crc/machine/machine.go
index 4f14c9d94..cdb1599c2 100644
--- a/pkg/crc/machine/machine.go
+++ b/pkg/crc/machine/machine.go
@@ -9,9 +9,9 @@ import (
 	"github.com/code-ready/crc/pkg/crc/logging"
 	"github.com/code-ready/crc/pkg/crc/machine/bundle"
 	"github.com/code-ready/crc/pkg/crc/network"
-	"github.com/code-ready/machine/libmachine"
+	"github.com/code-ready/crc/pkg/libmachine"
+	"github.com/code-ready/crc/pkg/libmachine/host"
 	"github.com/code-ready/machine/libmachine/drivers"
-	"github.com/code-ready/machine/libmachine/host"
 	"github.com/code-ready/machine/libmachine/log"
 )
 
diff --git a/pkg/crc/machine/start.go b/pkg/crc/machine/start.go
index b844edbab..f5ac9fe91 100644
--- a/pkg/crc/machine/start.go
+++ b/pkg/crc/machine/start.go
@@ -23,10 +23,10 @@ import (
 	"github.com/code-ready/crc/pkg/crc/ssh"
 	crcssh "github.com/code-ready/crc/pkg/crc/ssh"
 	"github.com/code-ready/crc/pkg/crc/systemd"
+	"github.com/code-ready/crc/pkg/libmachine"
+	"github.com/code-ready/crc/pkg/libmachine/host"
 	crcos "github.com/code-ready/crc/pkg/os"
-	"github.com/code-ready/machine/libmachine"
 	"github.com/code-ready/machine/libmachine/drivers"
-	"github.com/code-ready/machine/libmachine/host"
 	"github.com/code-ready/machine/libmachine/state"
 	"github.com/docker/go-units"
 	"github.com/pkg/errors"
diff --git a/vendor/github.com/code-ready/machine/drivers/hyperv/hyperv.go b/pkg/drivers/hyperv/hyperv.go
similarity index 98%
rename from vendor/github.com/code-ready/machine/drivers/hyperv/hyperv.go
rename to pkg/drivers/hyperv/hyperv.go
index f521544ac..3c054d24a 100644
--- a/vendor/github.com/code-ready/machine/drivers/hyperv/hyperv.go
+++ b/pkg/drivers/hyperv/hyperv.go
@@ -6,9 +6,9 @@ import (
 	"fmt"
 	"time"
 
+	log "github.com/code-ready/crc/pkg/crc/logging"
+	"github.com/code-ready/crc/pkg/libmachine/mcnutils"
 	"github.com/code-ready/machine/libmachine/drivers"
-	"github.com/code-ready/machine/libmachine/log"
-	"github.com/code-ready/machine/libmachine/mcnutils"
 	"github.com/code-ready/machine/libmachine/state"
 )
 
diff --git a/vendor/github.com/code-ready/machine/drivers/hyperv/powershell.go b/pkg/drivers/hyperv/powershell.go
similarity index 98%
rename from vendor/github.com/code-ready/machine/drivers/hyperv/powershell.go
rename to pkg/drivers/hyperv/powershell.go
index ba1b81c1e..dbfa652ea 100644
--- a/vendor/github.com/code-ready/machine/drivers/hyperv/powershell.go
+++ b/pkg/drivers/hyperv/powershell.go
@@ -9,7 +9,7 @@ import (
 
 	"fmt"
 
-	"github.com/code-ready/machine/libmachine/log"
+	log "github.com/code-ready/crc/pkg/crc/logging"
 )
 
 var powershell string
diff --git a/vendor/github.com/code-ready/machine/drivers/none/driver.go b/pkg/drivers/none/driver.go
similarity index 100%
rename from vendor/github.com/code-ready/machine/drivers/none/driver.go
rename to pkg/drivers/none/driver.go
diff --git a/vendor/github.com/code-ready/machine/libmachine/host/host.go b/pkg/libmachine/host/host.go
similarity index 92%
rename from vendor/github.com/code-ready/machine/libmachine/host/host.go
rename to pkg/libmachine/host/host.go
index 7dccbbc09..f257ca694 100644
--- a/vendor/github.com/code-ready/machine/libmachine/host/host.go
+++ b/pkg/libmachine/host/host.go
@@ -5,10 +5,10 @@ import (
 	"net/rpc"
 	"regexp"
 
+	log "github.com/code-ready/crc/pkg/crc/logging"
+	"github.com/code-ready/crc/pkg/libmachine/mcnerror"
+	"github.com/code-ready/crc/pkg/libmachine/mcnutils"
 	"github.com/code-ready/machine/libmachine/drivers"
-	"github.com/code-ready/machine/libmachine/log"
-	"github.com/code-ready/machine/libmachine/mcnerror"
-	"github.com/code-ready/machine/libmachine/mcnutils"
 	"github.com/code-ready/machine/libmachine/state"
 )
 
diff --git a/vendor/github.com/code-ready/machine/libmachine/host/migrate.go b/pkg/libmachine/host/migrate.go
similarity index 91%
rename from vendor/github.com/code-ready/machine/libmachine/host/migrate.go
rename to pkg/libmachine/host/migrate.go
index f63bb4a3f..e5d3a7dc6 100644
--- a/vendor/github.com/code-ready/machine/libmachine/host/migrate.go
+++ b/pkg/libmachine/host/migrate.go
@@ -5,8 +5,8 @@ import (
 	"errors"
 	"fmt"
 
-	"github.com/code-ready/machine/drivers/none"
-	"github.com/code-ready/machine/libmachine/version"
+	"github.com/code-ready/crc/pkg/drivers/none"
+	"github.com/code-ready/crc/pkg/libmachine/version"
 )
 
 var (
diff --git a/vendor/github.com/code-ready/machine/libmachine/libmachine.go b/pkg/libmachine/libmachine.go
similarity index 90%
rename from vendor/github.com/code-ready/machine/libmachine/libmachine.go
rename to pkg/libmachine/libmachine.go
index 1e122a56e..8a7109a1f 100644
--- a/vendor/github.com/code-ready/machine/libmachine/libmachine.go
+++ b/pkg/libmachine/libmachine.go
@@ -5,16 +5,16 @@ import (
 	"fmt"
 	"io"
 
-	"github.com/code-ready/machine/drivers/hyperv"
+	log "github.com/code-ready/crc/pkg/crc/logging"
+	"github.com/code-ready/crc/pkg/drivers/hyperv"
+	"github.com/code-ready/crc/pkg/libmachine/host"
+	"github.com/code-ready/crc/pkg/libmachine/mcnerror"
+	"github.com/code-ready/crc/pkg/libmachine/mcnutils"
+	"github.com/code-ready/crc/pkg/libmachine/persist"
+	"github.com/code-ready/crc/pkg/libmachine/version"
 	"github.com/code-ready/machine/libmachine/drivers"
 	rpcdriver "github.com/code-ready/machine/libmachine/drivers/rpc"
-	"github.com/code-ready/machine/libmachine/host"
-	"github.com/code-ready/machine/libmachine/log"
-	"github.com/code-ready/machine/libmachine/mcnerror"
-	"github.com/code-ready/machine/libmachine/mcnutils"
-	"github.com/code-ready/machine/libmachine/persist"
 	"github.com/code-ready/machine/libmachine/state"
-	"github.com/code-ready/machine/libmachine/version"
 )
 
 type API interface {
diff --git a/vendor/github.com/code-ready/machine/libmachine/persist/filestore.go b/pkg/libmachine/persist/filestore.go
similarity index 94%
rename from vendor/github.com/code-ready/machine/libmachine/persist/filestore.go
rename to pkg/libmachine/persist/filestore.go
index ef43f9f45..2ee5e0b6b 100644
--- a/vendor/github.com/code-ready/machine/libmachine/persist/filestore.go
+++ b/pkg/libmachine/persist/filestore.go
@@ -7,9 +7,9 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/code-ready/machine/libmachine/host"
-	"github.com/code-ready/machine/libmachine/log"
-	"github.com/code-ready/machine/libmachine/mcnerror"
+	log "github.com/code-ready/crc/pkg/crc/logging"
+	"github.com/code-ready/crc/pkg/libmachine/host"
+	"github.com/code-ready/crc/pkg/libmachine/mcnerror"
 )
 
 type Filestore struct {
diff --git a/vendor/github.com/code-ready/machine/libmachine/persist/store.go b/pkg/libmachine/persist/store.go
similarity index 87%
rename from vendor/github.com/code-ready/machine/libmachine/persist/store.go
rename to pkg/libmachine/persist/store.go
index fcda4656f..4bee232e4 100644
--- a/vendor/github.com/code-ready/machine/libmachine/persist/store.go
+++ b/pkg/libmachine/persist/store.go
@@ -1,7 +1,7 @@
 package persist
 
 import (
-	"github.com/code-ready/machine/libmachine/host"
+	"github.com/code-ready/crc/pkg/libmachine/host"
 )
 
 type Store interface {
diff --git a/pkg/libmachine/version/version.go b/pkg/libmachine/version/version.go
new file mode 100644
index 000000000..3cacffdb0
--- /dev/null
+++ b/pkg/libmachine/version/version.go
@@ -0,0 +1,11 @@
+package version
+
+var (
+	// APIVersion dictates which version of the libmachine API this is.
+	APIVersion = 1
+
+	// ConfigVersion dictates which version of the config.json format is
+	// used. It needs to be bumped if there is a breaking change, and
+	// therefore migration, introduced to the config file format.
+	ConfigVersion = 3
+)
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 26119e3f7..a6e259a90 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -43,18 +43,11 @@ github.com/code-ready/gvisor-tap-vsock/pkg/virtualnetwork
 # github.com/code-ready/machine v0.0.0-20201202090222-9558ae8c05b9
 ## explicit
 github.com/code-ready/machine/drivers/hyperkit
-github.com/code-ready/machine/drivers/hyperv
 github.com/code-ready/machine/drivers/libvirt
-github.com/code-ready/machine/drivers/none
-github.com/code-ready/machine/libmachine
 github.com/code-ready/machine/libmachine/drivers
 github.com/code-ready/machine/libmachine/drivers/plugin/localbinary
 github.com/code-ready/machine/libmachine/drivers/rpc
-github.com/code-ready/machine/libmachine/host
 github.com/code-ready/machine/libmachine/log
-github.com/code-ready/machine/libmachine/mcnerror
-github.com/code-ready/machine/libmachine/mcnutils
-github.com/code-ready/machine/libmachine/persist
 github.com/code-ready/machine/libmachine/state
 github.com/code-ready/machine/libmachine/version
 # github.com/cucumber/gherkin-go/v11 v11.0.0


Test patch:
diff --git a/pkg/libmachine/host/host_test.go b/pkg/libmachine/host/host_test.go
new file mode 100644
index 000000000..9b724352f
--- /dev/null
+++ b/pkg/libmachine/host/host_test.go
@@ -0,0 +1,37 @@
+package host
+
+import (
+	"testing"
+
+	_ "github.com/code-ready/crc/pkg/drivers/none"
+)
+
+func TestValidateHostnameValid(t *testing.T) {
+	hosts := []string{
+		"zomg",
+		"test-ing",
+		"some.h0st",
+	}
+
+	for _, v := range hosts {
+		isValid := ValidateHostName(v)
+		if !isValid {
+			t.Fatalf("Thought a valid hostname was invalid: %s", v)
+		}
+	}
+}
+
+func TestValidateHostnameInvalid(t *testing.T) {
+	hosts := []string{
+		"zom_g",
+		"test$ing",
+		"some😄host",
+	}
+
+	for _, v := range hosts {
+		isValid := ValidateHostName(v)
+		if isValid {
+			t.Fatalf("Thought an invalid hostname was valid: %s", v)
+		}
+	}
+}
diff --git a/pkg/libmachine/host/migrate_test.go b/pkg/libmachine/host/migrate_test.go
new file mode 100644
index 000000000..6d1f9b3f3
--- /dev/null
+++ b/pkg/libmachine/host/migrate_test.go
@@ -0,0 +1,44 @@
+package host
+
+import (
+	"testing"
+
+	"github.com/code-ready/crc/pkg/drivers/none"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestLoadUnsupportedConfiguration(t *testing.T) {
+	_, err := MigrateHost("default", []byte(`{"ConfigVersion": 4}`))
+	assert.Equal(t, err, errUnexpectedConfigVersion)
+}
+
+func TestLoadHost(t *testing.T) {
+	driverJSON := `{
+        "IPAddress": "192.168.130.11",
+        "MachineName": "crc",
+        "BundleName": "crc_libvirt_4.6.6.crcbundle",
+        "Memory": 9216,
+        "CPU": 4
+    }`
+
+	host, err := MigrateHost("default", []byte(`{
+    "ConfigVersion": 3,
+    "Driver": `+driverJSON+`,
+    "DriverName": "libvirt",
+    "DriverPath": "/home/john/.crc/bin",
+    "Name": "crc"
+}`))
+
+	assert.NoError(t, err)
+	assert.Equal(t, &Host{
+		ConfigVersion: 3,
+		Name:          "crc",
+		DriverName:    "libvirt",
+		DriverPath:    "/home/john/.crc/bin",
+		RawDriver:     []byte(driverJSON),
+		Driver: &RawDataDriver{
+			Data:   []byte(driverJSON),
+			Driver: none.NewDriver("default", ""),
+		},
+	}, host)
+}
diff --git a/pkg/libmachine/hosttest/default_test_host.go b/pkg/libmachine/hosttest/default_test_host.go
new file mode 100644
index 000000000..1bd92d365
--- /dev/null
+++ b/pkg/libmachine/hosttest/default_test_host.go
@@ -0,0 +1,22 @@
+package hosttest
+
+import (
+	"github.com/code-ready/crc/pkg/drivers/none"
+	"github.com/code-ready/crc/pkg/libmachine/host"
+	"github.com/code-ready/crc/pkg/libmachine/version"
+)
+
+const (
+	DefaultHostName = "test-host"
+)
+
+func GetDefaultTestHost() (*host.Host, error) {
+	driver := none.NewDriver(DefaultHostName, "/tmp/artifacts")
+
+	return &host.Host{
+		ConfigVersion: version.ConfigVersion,
+		Name:          DefaultHostName,
+		Driver:        driver,
+		DriverName:    "none",
+	}, nil
+}
diff --git a/vendor/github.com/code-ready/machine/libmachine/mcnerror/errors.go b/pkg/libmachine/mcnerror/errors.go
similarity index 100%
rename from vendor/github.com/code-ready/machine/libmachine/mcnerror/errors.go
rename to pkg/libmachine/mcnerror/errors.go
diff --git a/vendor/github.com/code-ready/machine/libmachine/mcnutils/utils.go b/pkg/libmachine/mcnutils/utils.go
similarity index 100%
rename from vendor/github.com/code-ready/machine/libmachine/mcnutils/utils.go
rename to pkg/libmachine/mcnutils/utils.go
diff --git a/pkg/libmachine/mcnutils/utils_test.go b/pkg/libmachine/mcnutils/utils_test.go
new file mode 100644
index 000000000..e447b41db
--- /dev/null
+++ b/pkg/libmachine/mcnutils/utils_test.go
@@ -0,0 +1,85 @@
+package mcnutils
+
+import (
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"testing"
+)
+
+func TestCopyFile(t *testing.T) {
+	testStr := "test-machine"
+
+	srcFile, err := ioutil.TempFile("", "machine-test-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	srcFi, err := srcFile.Stat()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	_, _ = srcFile.Write([]byte(testStr))
+	srcFile.Close()
+
+	srcFilePath := filepath.Join(os.TempDir(), srcFi.Name())
+
+	destFile, err := ioutil.TempFile("", "machine-copy-test-")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	destFi, err := destFile.Stat()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	destFile.Close()
+
+	destFilePath := filepath.Join(os.TempDir(), destFi.Name())
+
+	if err := CopyFile(srcFilePath, destFilePath); err != nil {
+		t.Fatal(err)
+	}
+
+	data, err := ioutil.ReadFile(destFilePath)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if string(data) != testStr {
+		t.Fatalf("expected data \"%s\"; received \"%s\"", testStr, string(data))
+	}
+}
+
+func TestGenerateRandomID(t *testing.T) {
+	id := GenerateRandomID()
+
+	if len(id) != 64 {
+		t.Fatalf("Id returned is incorrect: %s", id)
+	}
+}
+
+func TestShortenId(t *testing.T) {
+	id := GenerateRandomID()
+	truncID := TruncateID(id)
+	if len(truncID) != 12 {
+		t.Fatalf("Id returned is incorrect: truncate on %s returned %s", id, truncID)
+	}
+}
+
+func TestShortenIdEmpty(t *testing.T) {
+	id := ""
+	truncID := TruncateID(id)
+	if len(truncID) > len(id) {
+		t.Fatalf("Id returned is incorrect: truncate on %s returned %s", id, truncID)
+	}
+}
+
+func TestShortenIdInvalid(t *testing.T) {
+	id := "1234"
+	truncID := TruncateID(id)
+	if len(truncID) != len(id) {
+		t.Fatalf("Id returned is incorrect: truncate on %s returned %s", id, truncID)
+	}
+}
diff --git a/pkg/libmachine/persist/filestore_test.go b/pkg/libmachine/persist/filestore_test.go
new file mode 100644
index 000000000..bd8a62d7d
--- /dev/null
+++ b/pkg/libmachine/persist/filestore_test.go
@@ -0,0 +1,205 @@
+package persist
+
+import (
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"regexp"
+	"testing"
+
+	"github.com/code-ready/crc/pkg/drivers/none"
+	"github.com/code-ready/crc/pkg/libmachine/host"
+	"github.com/code-ready/crc/pkg/libmachine/hosttest"
+)
+
+func cleanup() {
+	os.RemoveAll(os.Getenv("MACHINE_STORAGE_PATH"))
+}
+
+func getTestStore() Filestore {
+	tmpDir, err := ioutil.TempDir("", "machine-test-")
+	if err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+
+	return Filestore{
+		Path: tmpDir,
+	}
+}
+
+func TestStoreSave(t *testing.T) {
+	defer cleanup()
+
+	store := getTestStore()
+
+	h, err := hosttest.GetDefaultTestHost()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if err := store.Save(h); err != nil {
+		t.Fatal(err)
+	}
+
+	path := filepath.Join(store.GetMachinesDir(), h.Name)
+	if _, err := os.Stat(path); os.IsNotExist(err) {
+		t.Fatalf("Host path doesn't exist: %s", path)
+	}
+
+	files, _ := ioutil.ReadDir(path)
+	for _, f := range files {
+		r := regexp.MustCompile("config.json.tmp*")
+		if r.MatchString(f.Name()) {
+			t.Fatalf("Failed to remove temp filestore:%s", f.Name())
+		}
+	}
+}
+
+func TestStoreSaveOmitRawDriver(t *testing.T) {
+	defer cleanup()
+
+	store := getTestStore()
+
+	h, err := hosttest.GetDefaultTestHost()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if err := store.Save(h); err != nil {
+		t.Fatal(err)
+	}
+
+	configJSONPath := filepath.Join(store.GetMachinesDir(), h.Name, "config.json")
+
+	f, err := os.Open(configJSONPath)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	configData, err := ioutil.ReadAll(f)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	fakeHost := make(map[string]interface{})
+
+	if err := json.Unmarshal(configData, &fakeHost); err != nil {
+		t.Fatal(err)
+	}
+
+	if rawDriver, ok := fakeHost["RawDriver"]; ok {
+		t.Fatal("Should not have gotten a value for RawDriver reading host from disk but got one: ", rawDriver)
+	}
+
+}
+
+func TestStoreRemove(t *testing.T) {
+	defer cleanup()
+
+	store := getTestStore()
+
+	h, err := hosttest.GetDefaultTestHost()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if err := store.Save(h); err != nil {
+		t.Fatal(err)
+	}
+
+	path := filepath.Join(store.GetMachinesDir(), h.Name)
+	if _, err := os.Stat(path); os.IsNotExist(err) {
+		t.Fatalf("Host path doesn't exist: %s", path)
+	}
+
+	err = store.Remove(h.Name)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if _, err := os.Stat(path); err == nil {
+		t.Fatalf("Host path still exists after remove: %s", path)
+	}
+}
+
+func TestStoreExists(t *testing.T) {
+	defer cleanup()
+	store := getTestStore()
+
+	h, err := hosttest.GetDefaultTestHost()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	exists, err := store.Exists(h.Name)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if exists {
+		t.Fatal("Host should not exist before saving")
+	}
+
+	if err := store.Save(h); err != nil {
+		t.Fatal(err)
+	}
+
+	if err := store.SetExists(h.Name); err != nil {
+		t.Fatal(err)
+	}
+
+	exists, err = store.Exists(h.Name)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if !exists {
+		t.Fatal("Host should exist after saving")
+	}
+
+	if err := store.Remove(h.Name); err != nil {
+		t.Fatal(err)
+	}
+
+	exists, err = store.Exists(h.Name)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if exists {
+		t.Fatal("Host should not exist after removing")
+	}
+}
+
+func TestStoreLoad(t *testing.T) {
+	defer cleanup()
+
+	store := getTestStore()
+
+	h, err := hosttest.GetDefaultTestHost()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if err := store.Save(h); err != nil {
+		t.Fatal(err)
+	}
+
+	h, err = store.Load(h.Name)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	rawDataDriver, ok := h.Driver.(*host.RawDataDriver)
+	if !ok {
+		t.Fatal("Expected driver loaded from store to be of type *host.RawDataDriver and it was not")
+	}
+
+	realDriver := none.NewDriver(h.Name, store.Path)
+
+	if err := json.Unmarshal(rawDataDriver.Data, &realDriver); err != nil {
+		t.Fatalf("Error unmarshaling rawDataDriver data into concrete 'none' driver: %s", err)
+	}
+}