diff --git a/internal/cmdlxcconfig/BUILD b/internal/cmdlxcconfig/BUILD index c738ba3..965205a 100644 --- a/internal/cmdlxcconfig/BUILD +++ b/internal/cmdlxcconfig/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", @@ -11,3 +11,14 @@ go_library( "@org_uber_go_multierr//:go_default_library", ], ) + +go_test( + name = "go_default_test", + srcs = ["cmdlxcconfig_test.go"], + embed = [":go_default_library"], + deps = [ + "@com_github_jessevdk_go_flags//:go_default_library", + "@com_github_stretchr_testify//assert:go_default_library", + "@com_github_stretchr_testify//require:go_default_library", + ], +) diff --git a/internal/cmdlxcconfig/cmdlxcconfig.go b/internal/cmdlxcconfig/cmdlxcconfig.go index bd56ecb..4175983 100644 --- a/internal/cmdlxcconfig/cmdlxcconfig.go +++ b/internal/cmdlxcconfig/cmdlxcconfig.go @@ -11,10 +11,13 @@ import ( "go.uber.org/multierr" ) -// Command is "lxcconfig" command +const _description = "Create an LXC-compatible container configuration" + type ( + // Command is an implementation of go-flags.Command Command struct { - Stdout io.Writer + configer func(io.ReadSeeker, io.Writer) error + Stdout io.Writer PositionalArgs struct { Infile goflags.Filename `long:"infile" description:"Input tarball"` @@ -25,12 +28,13 @@ type ( func NewCommand() *Command { return &Command{ - Stdout: os.Stdout, + configer: lxcconfig.LXCConfig, + Stdout: os.Stdout, } } -func (*Command) ShortDesc() string { return "Create an LXC-compatible container configuration" } -func (*Command) LongDesc() string { return "" } +func (*Command) ShortDesc() string { return _description } +func (*Command) LongDesc() string { return _description } // Execute executes lxcconfig Command func (c *Command) Execute(args []string) (err error) { @@ -57,5 +61,5 @@ func (c *Command) Execute(args []string) (err error) { out = outf } - return lxcconfig.LXCConfig(rd, out) + return c.configer(rd, out) } diff --git a/internal/cmdlxcconfig/cmdlxcconfig_test.go b/internal/cmdlxcconfig/cmdlxcconfig_test.go new file mode 100644 index 0000000..c0f12de --- /dev/null +++ b/internal/cmdlxcconfig/cmdlxcconfig_test.go @@ -0,0 +1,93 @@ +package cmdlxcconfig + +import ( + "bytes" + "io" + "io/ioutil" + "path/filepath" + "testing" + + goflags "github.com/jessevdk/go-flags" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestExecute(t *testing.T) { + var _foo = []byte("foo foo") + + tests := []struct { + name string + fixture func(*testing.T, string) + infile string + outfile string + wantErr string + }{ + { + name: "ok passthrough via stdout", + infile: "t10-in.txt", + fixture: func(t *testing.T, dir string) { + fname := filepath.Join(dir, "t10-in.txt") + require.NoError(t, ioutil.WriteFile(fname, _foo, 0644)) + }, + outfile: "-", + }, + { + name: "ok passthrough via file", + infile: "t20-in.txt", + fixture: func(t *testing.T, dir string) { + fname := filepath.Join(dir, "t20-in.txt") + require.NoError(t, ioutil.WriteFile(fname, _foo, 0644)) + }, + outfile: "t20-out.txt", + }, + { + name: "infile does not exist", + infile: "t3-does-not-exist.txt", + wantErr: "^open .*t3-does-not-exist.txt: no such file or directory$", + }, + { + name: "outpath dir not writable", + outfile: filepath.Join("t4", "does", "not", "exist"), + wantErr: "^create: open .*/t4/does/not/exist: no such file or directory", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dir := t.TempDir() + var stdout bytes.Buffer + c := &Command{Stdout: &stdout} + if tt.fixture != nil { + tt.fixture(t, dir) + } + if tt.outfile != "-" { + tt.outfile = filepath.Join(dir, tt.outfile) + } + inf := filepath.Join(dir, tt.infile) + c.PositionalArgs.Infile = goflags.Filename(inf) + c.PositionalArgs.Outfile = tt.outfile + c.configer = configerPassthrough + + err := c.Execute(nil) + if tt.wantErr != "" { + require.Error(t, err) + assert.Regexp(t, tt.wantErr, err.Error()) + return + } + var out []byte + require.NoError(t, err) + if tt.outfile == "-" { + out = stdout.Bytes() + } else { + out, err = ioutil.ReadFile(tt.outfile) + require.NoError(t, err) + } + assert.Equal(t, []byte("foo foo"), out) + }) + } +} + +func configerPassthrough(r io.ReadSeeker, w io.Writer) error { + _, err := io.Copy(w, r) + return err +} diff --git a/internal/cmdrootfs/cmdrootfs.go b/internal/cmdrootfs/cmdrootfs.go index 25351dc..e19ff24 100644 --- a/internal/cmdrootfs/cmdrootfs.go +++ b/internal/cmdrootfs/cmdrootfs.go @@ -11,7 +11,10 @@ import ( "go.uber.org/multierr" ) +const _description = "Flatten a docker container image to a tarball" + type ( + // Command is an implementation of go-flags.Command Command struct { flattener func(io.ReadSeeker, io.Writer) error Stdout io.Writer @@ -30,8 +33,8 @@ func NewCommand() *Command { } } -func (*Command) ShortDesc() string { return "Flatten a docker container image to a tarball" } -func (*Command) LongDesc() string { return "" } +func (*Command) ShortDesc() string { return _description } +func (*Command) LongDesc() string { return _description } // Execute executes rootfs Command func (c *Command) Execute(args []string) (err error) {