wip tests

main
Motiejus Jakštys 2021-05-24 00:11:58 +03:00
parent 6d6bf4f076
commit 62db51d979
4 changed files with 95 additions and 31 deletions

View File

@ -7,9 +7,9 @@ import (
// BaseCommand provides common fields to all commands. // BaseCommand provides common fields to all commands.
type BaseCommand struct { type BaseCommand struct {
Stdin io.ReadCloser Stdin io.Reader
Stdout io.WriteCloser Stdout io.Writer
Stderr io.WriteCloser Stderr io.Writer
} }
// Init initializes BaseCommand with default arguments // Init initializes BaseCommand with default arguments

View File

@ -9,7 +9,6 @@ go_library(
"//src/undocker/internal/cmd:go_default_library", "//src/undocker/internal/cmd:go_default_library",
"//src/undocker/rootfs:go_default_library", "//src/undocker/rootfs:go_default_library",
"@com_github_jessevdk_go_flags//:go_default_library", "@com_github_jessevdk_go_flags//:go_default_library",
"@com_github_ulikunitz_xz//:go_default_library",
"@org_uber_go_multierr//:go_default_library", "@org_uber_go_multierr//:go_default_library",
], ],
) )
@ -18,4 +17,10 @@ go_test(
name = "go_default_test", name = "go_default_test",
srcs = ["cmdrootfs_test.go"], srcs = ["cmdrootfs_test.go"],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [
"//src/undocker/internal/cmd:go_default_library",
"@com_github_jessevdk_go_flags//:go_default_library",
"@com_github_stretchr_testify//assert:go_default_library",
"@com_github_stretchr_testify//require:go_default_library",
],
) )

View File

@ -2,29 +2,31 @@ package cmdrootfs
import ( import (
"errors" "errors"
"fmt"
"io" "io"
"os" "os"
goflags "github.com/jessevdk/go-flags" goflags "github.com/jessevdk/go-flags"
"github.com/motiejus/code/undocker/internal/cmd" "github.com/motiejus/code/undocker/internal/cmd"
"github.com/motiejus/code/undocker/rootfs" "github.com/motiejus/code/undocker/rootfs"
"github.com/ulikunitz/xz"
"go.uber.org/multierr" "go.uber.org/multierr"
) )
// Command is "rootfs" command type (
type Command struct { rootfsFactory func(io.ReadSeeker) io.WriterTo
cmd.BaseCommand
PositionalArgs struct { // Command is "rootfs" command
Infile goflags.Filename `long:"infile" description:"Input tarball"` Command struct {
Outfile string `long:"outfile" description:"Output path, stdout is '-'"` cmd.BaseCommand
} `positional-args:"yes" required:"yes"`
Xz bool `short:"J" long:"xz" description:"create XZ archive"` PositionalArgs struct {
Infile goflags.Filename `long:"infile" description:"Input tarball"`
Outfile string `long:"outfile" description:"Output path, stdout is '-'"`
} `positional-args:"yes" required:"yes"`
rootfsNew func(io.ReadSeeker) io.WriterTo rootfsNew rootfsFactory
} }
)
// Execute executes rootfs Command // Execute executes rootfs Command
func (c *Command) Execute(args []string) (err error) { func (c *Command) Execute(args []string) (err error) {
@ -42,25 +44,15 @@ func (c *Command) Execute(args []string) (err error) {
defer func() { err = multierr.Append(err, rd.Close()) }() defer func() { err = multierr.Append(err, rd.Close()) }()
var out io.Writer var out io.Writer
var outf *os.File
if fname := string(c.PositionalArgs.Outfile); fname == "-" { if fname := string(c.PositionalArgs.Outfile); fname == "-" {
outf = os.Stdout out = c.Stdout
} else { } else {
outf, err = os.Create(fname) outf, err := os.Create(fname)
if err != nil { if err != nil {
return err return fmt.Errorf("create: %w", err)
} }
} defer func() { err = multierr.Append(err, outf.Close()) }()
out = outf out = outf
defer func() { err = multierr.Append(err, outf.Close()) }()
if c.Xz {
outz, err := xz.NewWriter(out)
if err != nil {
return err
}
defer func() { err = multierr.Append(err, outz.Close()) }()
out = outz
} }
if _, err := c.rootfsNew(rd).WriteTo(out); err != nil { if _, err := c.rootfsNew(rd).WriteTo(out); err != nil {

View File

@ -1,6 +1,73 @@
package cmdrootfs package cmdrootfs
import "testing" import (
"bytes"
"io"
"path/filepath"
"testing"
goflags "github.com/jessevdk/go-flags"
"github.com/motiejus/code/undocker/internal/cmd"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestExecute(t *testing.T) { func TestExecute(t *testing.T) {
dir := t.TempDir()
tests := []struct {
name string
in []byte
infile string
outfile string
want []byte
wantErr string
}{
{
name: "ok passthrough via stdout",
in: []byte("foo"),
outfile: "-",
want: []byte("foo"),
},
{
name: "ok passthrough via file",
in: []byte("foo"),
outfile: filepath.Join(dir, "t1.txt"),
want: []byte("foo"),
},
{
name: "infile does not exist",
infile: filepath.Join(dir, "does", "not", "exist"),
wantErr: "open <...>/does/not/exist: enoent",
},
{
name: "outpath dir not writable",
outfile: filepath.Join(dir, "does", "not", "exist"),
wantErr: "create: stat <...>/does/not/exist: enoent",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var stdout bytes.Buffer
c := &Command{BaseCommand: cmd.BaseCommand{Stdout: &stdout}}
c.PositionalArgs.Infile = goflags.Filename(tt.infile)
c.PositionalArgs.Outfile = tt.outfile
c.rootfsNew = func(r io.ReadSeeker) io.WriterTo {
return &passthrough{r}
}
err := c.Execute(nil)
if tt.wantErr != "" {
assert.EqualError(t, err, tt.wantErr)
return
}
require.NoError(t, err)
assert.Equal(t, tt.want, stdout.Bytes())
})
}
} }
type passthrough struct{ r io.Reader }
func (p *passthrough) WriteTo(w io.Writer) (int64, error) { return io.Copy(w, p.r) }