Add tests
This commit is contained in:
parent
c48afe423d
commit
e77cb42171
@ -3,6 +3,7 @@ package core
|
||||
import (
|
||||
"archive/tar"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -62,13 +63,12 @@ func NewBox(opts ...BoxOption) (b *Box, err error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
metadata, err := LoadBoxMetadata(data)
|
||||
if err != nil {
|
||||
if err := json.Unmarshal(data, &b.box.Metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mapstructure.Decode(metadata, &b.box.Metadata)
|
||||
// The metadata should have provider info
|
||||
b.box.Provider = b.box.Metadata["provider"]
|
||||
b.box.Id = b.box.Name + "-" + b.box.Version + "-" + b.box.Provider
|
||||
b.Save()
|
||||
return
|
||||
}
|
||||
|
||||
@ -198,7 +198,10 @@ func (b *Box) AutomaticUpdateCheckAllowed() (allowed bool, err error) {
|
||||
|
||||
// This deletes the box. This is NOT undoable.
|
||||
func (b *Box) Destroy() (err error) {
|
||||
return os.RemoveAll(b.box.Directory)
|
||||
if _, err := os.Stat(b.box.Directory); err != nil {
|
||||
return os.RemoveAll(b.box.Directory)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (b *Box) Directory() (path string, err error) {
|
||||
@ -297,6 +300,7 @@ func (b *Box) Repackage(outputPath string) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
header.Name = filepath.ToSlash(path)
|
||||
if err := tw.WriteHeader(header); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -305,6 +309,7 @@ func (b *Box) Repackage(outputPath string) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer data.Close()
|
||||
if _, err := io.Copy(tw, data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -7,7 +7,6 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/vagrant-plugin-sdk/proto/vagrant_plugin_sdk"
|
||||
@ -24,7 +23,6 @@ const (
|
||||
type BoxCollection struct {
|
||||
basis *Basis
|
||||
directory string
|
||||
m sync.Mutex
|
||||
logger hclog.Logger
|
||||
}
|
||||
|
||||
@ -46,8 +44,10 @@ func (b *BoxCollection) Add(path, name, version string, force bool, providers ..
|
||||
if exists != nil && !force {
|
||||
return nil, fmt.Errorf("Box already exits, can't add %s v%s", name, version)
|
||||
} else {
|
||||
// If the box already exists but force is enabled, then delete the box
|
||||
exists.Destroy()
|
||||
if exists != nil {
|
||||
// If the box already exists but force is enabled, then delete the box
|
||||
exists.Destroy()
|
||||
}
|
||||
}
|
||||
|
||||
tempDir := b.basis.dir.TempDir().String()
|
||||
@ -61,9 +61,15 @@ func (b *BoxCollection) Add(path, name, version string, force bool, providers ..
|
||||
reader := tar.NewReader(boxFile)
|
||||
for {
|
||||
header, err := reader.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if header == nil {
|
||||
continue
|
||||
}
|
||||
dest := filepath.Join(tempDir, header.Name)
|
||||
switch header.Typeflag {
|
||||
case tar.TypeDir:
|
||||
@ -75,6 +81,12 @@ func (b *BoxCollection) Add(path, name, version string, force bool, providers ..
|
||||
}
|
||||
}
|
||||
case tar.TypeReg:
|
||||
if _, err := os.Stat(filepath.Dir(dest)); err != nil {
|
||||
err = os.MkdirAll(filepath.Dir(dest), 0755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// copy the file
|
||||
f, err := os.OpenFile(dest, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
|
||||
if err != nil {
|
||||
@ -95,25 +107,65 @@ func (b *BoxCollection) Add(path, name, version string, force bool, providers ..
|
||||
Directory: tempDir,
|
||||
}),
|
||||
)
|
||||
newBox.Save()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
provider := newBox.box.Provider
|
||||
foundProvider := false
|
||||
for _, p := range providers {
|
||||
if p == provider {
|
||||
foundProvider = true
|
||||
break
|
||||
|
||||
if providers != nil {
|
||||
foundProvider := false
|
||||
for _, p := range providers {
|
||||
if p == provider {
|
||||
foundProvider = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !foundProvider {
|
||||
return nil, fmt.Errorf("could not add box %s, provider '%s' does not match the expected providers %s", path, provider, providers)
|
||||
}
|
||||
}
|
||||
if !foundProvider {
|
||||
return nil, fmt.Errorf("could not add box %s, provider '%s' does not match the expected providers %s", path, provider, providers)
|
||||
}
|
||||
|
||||
destDir := b.generateDirectoryName(filepath.Join(b.directory, name, version, provider))
|
||||
destDir := filepath.Join(b.directory, b.generateDirectoryName(name), version, provider)
|
||||
b.logger.Debug("Box directory: %s", destDir)
|
||||
os.Rename(tempDir, destDir)
|
||||
os.MkdirAll(destDir, 0755)
|
||||
// Copy the contents of the tempdir to the final dir
|
||||
err = filepath.Walk(tempDir, func(path string, info os.FileInfo, erro error) (err error) {
|
||||
// TODO: only copy in the files that were extracted into the tempdir
|
||||
destPath := filepath.Join(destDir, info.Name())
|
||||
if info.IsDir() {
|
||||
err = os.MkdirAll(destPath, info.Mode())
|
||||
return err
|
||||
} else {
|
||||
data, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer data.Close()
|
||||
dest, err := os.Create(destPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dest.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(dest, data); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return
|
||||
})
|
||||
|
||||
newBox, err = NewBox(
|
||||
BoxWithBasis(b.basis),
|
||||
BoxWithBox(&vagrant_server.Box{
|
||||
Name: name,
|
||||
Version: version,
|
||||
Directory: destDir,
|
||||
Provider: provider,
|
||||
}),
|
||||
)
|
||||
newBox.Save()
|
||||
return newBox, nil
|
||||
}
|
||||
|
||||
@ -156,7 +208,7 @@ func (b *BoxCollection) Find(name, version string, providers ...string) (box *Bo
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp != nil {
|
||||
if resp.Box != nil {
|
||||
// Return the first box that is found
|
||||
return NewBox(
|
||||
BoxWithBasis(b.basis),
|
||||
|
||||
155
internal/core/box_collection_test.go
Normal file
155
internal/core/box_collection_test.go
Normal file
@ -0,0 +1,155 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"context"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/vagrant/internal/plugin"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func seedDB(t *testing.T, basis *Basis) {
|
||||
box1 := newFullBox(t, hashicorpBionicBoxData(), basis)
|
||||
box1.Save()
|
||||
box2 := newFullBox(t, testboxBoxData(), basis)
|
||||
box2.Save()
|
||||
}
|
||||
|
||||
func newBoxCollection(t *testing.T) *BoxCollection {
|
||||
pluginManager := plugin.NewManager(
|
||||
context.Background(),
|
||||
hclog.New(&hclog.LoggerOptions{}),
|
||||
)
|
||||
basis := TestBasis(t, WithPluginManager(pluginManager))
|
||||
seedDB(t, basis)
|
||||
td, err := ioutil.TempDir(basis.dir.DataDir().String(), "boxes")
|
||||
t.Cleanup(func() { os.RemoveAll(td) })
|
||||
require.NoError(t, err)
|
||||
return &BoxCollection{
|
||||
basis: basis,
|
||||
directory: td,
|
||||
logger: hclog.New(&hclog.LoggerOptions{}),
|
||||
}
|
||||
}
|
||||
|
||||
func generateTestBox(t *testing.T, path string, basis *Basis) string {
|
||||
metafile := filepath.Join(path, "box", "metadata.json")
|
||||
os.Mkdir(filepath.Dir(metafile), 0755)
|
||||
data := []byte("{\"provider\":\"virtualbox\"}")
|
||||
err := os.WriteFile(metafile, data, 0644)
|
||||
require.NoError(t, err)
|
||||
outputPath := filepath.Join(path, "output", "box")
|
||||
os.Mkdir(filepath.Dir(outputPath), 0755)
|
||||
|
||||
tarFile, err := os.Create(outputPath)
|
||||
require.NoError(t, err)
|
||||
defer tarFile.Close()
|
||||
tw := tar.NewWriter(tarFile)
|
||||
defer tw.Close()
|
||||
file, err := os.Open(metafile)
|
||||
require.NoError(t, err)
|
||||
defer file.Close()
|
||||
info, err := file.Stat()
|
||||
require.NoError(t, err)
|
||||
header, err := tar.FileInfoHeader(info, info.Name())
|
||||
require.NoError(t, err)
|
||||
err = tw.WriteHeader(header)
|
||||
require.NoError(t, err)
|
||||
_, err = io.Copy(tw, file)
|
||||
require.NoError(t, err)
|
||||
|
||||
return outputPath
|
||||
}
|
||||
|
||||
func TestAddErrors(t *testing.T) {
|
||||
bc := newBoxCollection(t)
|
||||
|
||||
td, err := ioutil.TempDir("/tmp", "box")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { os.RemoveAll(td) })
|
||||
|
||||
_, err = bc.Add("/path/that/doesntexist", "test", "1.2.3", true)
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = bc.Add(td, "test/box", "1.2.3", false)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestAddNoProviders(t *testing.T) {
|
||||
bc := newBoxCollection(t)
|
||||
|
||||
td, err := ioutil.TempDir("/tmp", "box")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { os.RemoveAll(td) })
|
||||
|
||||
testBoxPath := generateTestBox(t, td, bc.basis)
|
||||
box, err := bc.Add(testBoxPath, "test/box", "1.2.3", true)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, box)
|
||||
}
|
||||
|
||||
func TestAddWithProviders(t *testing.T) {
|
||||
bc := newBoxCollection(t)
|
||||
|
||||
td, err := ioutil.TempDir("/tmp", "box")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { os.RemoveAll(td) })
|
||||
|
||||
testBoxPath := generateTestBox(t, td, bc.basis)
|
||||
box, err := bc.Add(testBoxPath, "test/box", "1.2.3", true, "virtualbox", "vmware")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, box)
|
||||
}
|
||||
|
||||
func TestAddBadProviders(t *testing.T) {
|
||||
bc := newBoxCollection(t)
|
||||
|
||||
td, err := ioutil.TempDir("/tmp", "box")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { os.RemoveAll(td) })
|
||||
|
||||
testBoxPath := generateTestBox(t, td, bc.basis)
|
||||
_, err = bc.Add(testBoxPath, "test/box", "1.2.4", true, "vmware")
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestAll(t *testing.T) {
|
||||
bc := newBoxCollection(t)
|
||||
boxes, err := bc.All()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(boxes), 2)
|
||||
}
|
||||
|
||||
func TestFind(t *testing.T) {
|
||||
bc := newBoxCollection(t)
|
||||
|
||||
boxes, err := bc.Find("test/box", "1.2.3")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, boxes)
|
||||
|
||||
boxes, err = bc.Find("test/box", "1.2.3", "virtualbox")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, boxes)
|
||||
|
||||
boxes, err = bc.Find("test/box", "1.2.3", "idontexist")
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, boxes)
|
||||
|
||||
boxes, err = bc.Find("test/box", "9.9.9", "virtualbox")
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, boxes)
|
||||
|
||||
boxes, err = bc.Find("test/box", "9.9.9")
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, boxes)
|
||||
|
||||
boxes, err = bc.Find("test/box", "1.2.3", "vmware", "virtualbox")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, boxes)
|
||||
}
|
||||
@ -52,15 +52,18 @@ func hashicorpBionicTestBox() *Box {
|
||||
}
|
||||
}
|
||||
|
||||
func newFullBox(t *testing.T, boxData *vagrant_server.Box) *Box {
|
||||
pluginManager := plugin.NewManager(
|
||||
context.Background(),
|
||||
hclog.New(&hclog.LoggerOptions{}),
|
||||
)
|
||||
basis := TestBasis(t, WithPluginManager(pluginManager))
|
||||
func newFullBox(t *testing.T, boxData *vagrant_server.Box, testBasis *Basis) *Box {
|
||||
basis := testBasis
|
||||
if basis == nil {
|
||||
pluginManager := plugin.NewManager(
|
||||
context.Background(),
|
||||
hclog.New(&hclog.LoggerOptions{}),
|
||||
)
|
||||
basis = TestBasis(t, WithPluginManager(pluginManager))
|
||||
}
|
||||
td, err := ioutil.TempDir("", "box-metadata")
|
||||
require.NoError(t, err)
|
||||
data := []byte("{}")
|
||||
data := []byte("{\"provider\":\"virtualbox\"}")
|
||||
err = os.WriteFile(filepath.Join(td, "metadata.json"), data, 0644)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { os.RemoveAll(td) })
|
||||
@ -75,13 +78,13 @@ func newFullBox(t *testing.T, boxData *vagrant_server.Box) *Box {
|
||||
}
|
||||
|
||||
func TestNewBox(t *testing.T) {
|
||||
box := newFullBox(t, testboxBoxData())
|
||||
box := newFullBox(t, testboxBoxData(), nil)
|
||||
require.NotNil(t, box)
|
||||
require.Equal(t, "test/box", box.box.Name)
|
||||
}
|
||||
|
||||
func TestBoxAutomaticUpdateCheckAllowed(t *testing.T) {
|
||||
testBox := newFullBox(t, testboxBoxData())
|
||||
testBox := newFullBox(t, testboxBoxData(), nil)
|
||||
// just did automated check
|
||||
testBox.box.LastUpdate = timestamppb.Now()
|
||||
allowed1, err := testBox.AutomaticUpdateCheckAllowed()
|
||||
|
||||
@ -7,7 +7,7 @@ import (
|
||||
"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
|
||||
)
|
||||
|
||||
func (s *service) ListBox(
|
||||
func (s *service) ListBoxes(
|
||||
ctx context.Context,
|
||||
req *empty.Empty,
|
||||
) (*vagrant_server.ListBoxesResponse, error) {
|
||||
@ -55,7 +55,7 @@ func (s *service) FindBox(
|
||||
ctx context.Context,
|
||||
req *vagrant_server.FindBoxRequest,
|
||||
) (*vagrant_server.FindBoxResponse, error) {
|
||||
result, err:= s.state.BoxFind(req.Box)
|
||||
result, err := s.state.BoxFind(req.Box)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user