Add tests

This commit is contained in:
sophia 2021-11-11 17:56:26 -06:00 committed by Paul Hinze
parent c48afe423d
commit e77cb42171
No known key found for this signature in database
GPG Key ID: B69DEDF2D55501C0
5 changed files with 247 additions and 32 deletions

View File

@ -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
}

View File

@ -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),

View 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)
}

View File

@ -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()

View File

@ -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
}