mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 08:32:16 +01:00
chore: minor refactor of gotenberg pkg
This commit is contained in:
@@ -25,11 +25,11 @@ type Cmd struct {
|
||||
// children without creating orphans.
|
||||
//
|
||||
// See https://medium.com/@felixge/killing-a-child-process-and-all-of-its-children-in-go-54079af94773.
|
||||
func Command(logger *zap.Logger, binPath string, args ...string) Cmd {
|
||||
func Command(logger *zap.Logger, binPath string, args ...string) *Cmd {
|
||||
cmd := exec.Command(binPath, args...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
|
||||
return Cmd{
|
||||
return &Cmd{
|
||||
ctx: nil,
|
||||
logger: logger.Named(strings.ReplaceAll(binPath, "/", "")),
|
||||
process: cmd,
|
||||
@@ -41,15 +41,15 @@ func Command(logger *zap.Logger, binPath string, args ...string) Cmd {
|
||||
// children without creating orphans.
|
||||
//
|
||||
// See https://medium.com/@felixge/killing-a-child-process-and-all-of-its-children-in-go-54079af94773.
|
||||
func CommandContext(ctx context.Context, logger *zap.Logger, binPath string, args ...string) (Cmd, error) {
|
||||
func CommandContext(ctx context.Context, logger *zap.Logger, binPath string, args ...string) (*Cmd, error) {
|
||||
if ctx == nil {
|
||||
return Cmd{}, errors.New("nil context")
|
||||
return nil, errors.New("nil context")
|
||||
}
|
||||
|
||||
cmd := exec.CommandContext(ctx, binPath, args...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
|
||||
return Cmd{
|
||||
return &Cmd{
|
||||
ctx: ctx,
|
||||
logger: logger.Named(strings.ReplaceAll(binPath, "/", "")),
|
||||
process: cmd,
|
||||
@@ -57,7 +57,7 @@ func CommandContext(ctx context.Context, logger *zap.Logger, binPath string, arg
|
||||
}
|
||||
|
||||
// Start starts the command but does not wait for its completion.
|
||||
func (cmd Cmd) Start() error {
|
||||
func (cmd *Cmd) Start() error {
|
||||
err := cmd.pipeOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("pipe unix process output: %w", err)
|
||||
@@ -75,7 +75,7 @@ func (cmd Cmd) Start() error {
|
||||
|
||||
// Wait waits for the command to complete. It should be called when using the
|
||||
// Start method, so that the command does not leak zombies.
|
||||
func (cmd Cmd) Wait() error {
|
||||
func (cmd *Cmd) Wait() error {
|
||||
err := cmd.process.Wait()
|
||||
if err != nil {
|
||||
return fmt.Errorf("wait for unix process: %w", err)
|
||||
@@ -86,7 +86,7 @@ func (cmd Cmd) Wait() error {
|
||||
|
||||
// Exec executes the command and wait for its completion or until the context
|
||||
// is done. In any case, it kills the unix process and all its children.
|
||||
func (cmd Cmd) Exec() (int, error) {
|
||||
func (cmd *Cmd) Exec() (int, error) {
|
||||
if cmd.ctx == nil {
|
||||
return 10, errors.New("nil context")
|
||||
}
|
||||
@@ -134,7 +134,7 @@ func (cmd Cmd) Exec() (int, error) {
|
||||
|
||||
// pipeOutput creates logs entries according to the process stdout and stderr.
|
||||
// It does nothing if the logging level is not debug.
|
||||
func (cmd Cmd) pipeOutput() error {
|
||||
func (cmd *Cmd) pipeOutput() error {
|
||||
checkedEntry := cmd.logger.Check(zap.DebugLevel, "check for debug level before piping unix process output")
|
||||
if checkedEntry == nil {
|
||||
return nil
|
||||
@@ -154,7 +154,12 @@ func (cmd Cmd) pipeOutput() error {
|
||||
// (either stdout or stderr).
|
||||
logCommandOutput := func(logger *zap.Logger, reader io.ReadCloser) {
|
||||
r := bufio.NewReader(reader)
|
||||
defer reader.Close()
|
||||
defer func(reader io.ReadCloser) {
|
||||
err := reader.Close()
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("close reader: %s", err))
|
||||
}
|
||||
}(reader)
|
||||
|
||||
for {
|
||||
line, _, err := r.ReadLine()
|
||||
@@ -181,7 +186,7 @@ func (cmd Cmd) pipeOutput() error {
|
||||
// Kill kills the unix process and all its children without creating orphans.
|
||||
//
|
||||
// See https://medium.com/@felixge/killing-a-child-process-and-all-of-its-children-in-go-54079af94773.
|
||||
func (cmd Cmd) Kill() error {
|
||||
func (cmd *Cmd) Kill() error {
|
||||
if cmd.process == nil {
|
||||
// We cannot use the logger here, because for whatever reason using it
|
||||
// result to a panic.
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
|
||||
func TestCommand(t *testing.T) {
|
||||
cmd := Command(zap.NewNop(), "foo")
|
||||
|
||||
if !cmd.process.SysProcAttr.Setpgid {
|
||||
t.Error("expected cmd.process.SysProcAttr.Setpgid to be true")
|
||||
}
|
||||
@@ -18,34 +17,36 @@ func TestCommand(t *testing.T) {
|
||||
|
||||
func TestCommandContext(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
ctx context.Context
|
||||
expectCommandContextErr bool
|
||||
scenario string
|
||||
ctx context.Context
|
||||
expectCommandContextError bool
|
||||
}{
|
||||
{
|
||||
name: "nominal behavior",
|
||||
ctx: context.Background(),
|
||||
scenario: "nominal behavior",
|
||||
ctx: context.Background(),
|
||||
expectCommandContextError: false,
|
||||
},
|
||||
{
|
||||
name: "nil context",
|
||||
expectCommandContextErr: true,
|
||||
scenario: "nil context",
|
||||
ctx: nil,
|
||||
expectCommandContextError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
cmd, err := CommandContext(tc.ctx, zap.NewNop(), "foo")
|
||||
|
||||
if err == nil && !cmd.process.SysProcAttr.Setpgid {
|
||||
t.Fatal("expected cmd.process.SysProcAttr.Setpgid to be true")
|
||||
}
|
||||
|
||||
if tc.expectCommandContextErr && err == nil {
|
||||
t.Error("expected error from CommandContext(), but got none")
|
||||
if !tc.expectCommandContextError && err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
if !tc.expectCommandContextErr && err != nil {
|
||||
t.Errorf("expected no error from CommandContext(), but got: %v", err)
|
||||
if tc.expectCommandContextError && err == nil {
|
||||
t.Fatal("expected error but got none")
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -53,31 +54,32 @@ func TestCommandContext(t *testing.T) {
|
||||
|
||||
func TestCmd_Start(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cmd Cmd
|
||||
expectStartErr bool
|
||||
scenario string
|
||||
cmd *Cmd
|
||||
expectStartError bool
|
||||
}{
|
||||
{
|
||||
name: "nominal behavior",
|
||||
cmd: Command(zap.NewNop(), "echo", "Hello", "World"),
|
||||
scenario: "nominal behavior",
|
||||
cmd: Command(zap.NewNop(), "echo", "Hello", "World"),
|
||||
expectStartError: false,
|
||||
},
|
||||
{
|
||||
name: "start error",
|
||||
cmd: Command(zap.NewNop(), "foo"),
|
||||
expectStartErr: true,
|
||||
scenario: "start error",
|
||||
cmd: Command(zap.NewNop(), "foo"),
|
||||
expectStartError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
err := tc.cmd.Start()
|
||||
|
||||
if tc.expectStartErr && err == nil {
|
||||
t.Error("expected error from cmd.Start(), but got none")
|
||||
if !tc.expectStartError && err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
if !tc.expectStartErr && err != nil {
|
||||
t.Errorf("expected no error from cmd.Start(), but got: %v", err)
|
||||
if tc.expectStartError && err == nil {
|
||||
t.Fatal("expected error but got none")
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -85,54 +87,50 @@ func TestCmd_Start(t *testing.T) {
|
||||
|
||||
func TestCmd_Wait(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cmd Cmd
|
||||
expectWaitErr bool
|
||||
scenario string
|
||||
cmd *Cmd
|
||||
expectWaitError bool
|
||||
}{
|
||||
{
|
||||
name: "nominal behavior",
|
||||
cmd: func() Cmd {
|
||||
scenario: "nominal behavior",
|
||||
cmd: func() *Cmd {
|
||||
cmd := Command(zap.NewNop(), "echo", "Hello", "World")
|
||||
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error from cmd.Start(), but got: %v", err)
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}(),
|
||||
expectWaitError: false,
|
||||
},
|
||||
{
|
||||
name: "wait error",
|
||||
cmd: func() Cmd {
|
||||
scenario: "wait error",
|
||||
cmd: func() *Cmd {
|
||||
cmd := Command(zap.NewNop(), "echo", "Hello", "World")
|
||||
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error from cmd.Start(), but got: %v", err)
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
err = cmd.Kill()
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error from cmd.Kill(), but got: %v", err)
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}(),
|
||||
expectWaitErr: true,
|
||||
expectWaitError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
err := tc.cmd.Wait()
|
||||
|
||||
if tc.expectWaitErr && err == nil {
|
||||
t.Error("expected error from cmd.Wait(), but got none")
|
||||
if !tc.expectWaitError && err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
if !tc.expectWaitErr && err != nil {
|
||||
t.Errorf("expected no error from cmd.Wait(), but got: %v", err)
|
||||
if tc.expectWaitError && err == nil {
|
||||
t.Fatal("expected error but got none")
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -140,49 +138,48 @@ func TestCmd_Wait(t *testing.T) {
|
||||
|
||||
func TestCmd_Exec(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cmd Cmd
|
||||
timeout time.Duration
|
||||
expectExecErr bool
|
||||
scenario string
|
||||
cmd *Cmd
|
||||
timeout time.Duration
|
||||
expectExecError bool
|
||||
}{
|
||||
{
|
||||
name: "nominal behavior",
|
||||
cmd: func() Cmd {
|
||||
scenario: "nominal behavior",
|
||||
cmd: func() *Cmd {
|
||||
cmd, err := CommandContext(context.Background(), zap.NewNop(), "echo", "Hello", "World")
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error from CommandContext(), but got: %v", err)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}(),
|
||||
expectExecError: false,
|
||||
},
|
||||
{
|
||||
name: "nil context",
|
||||
cmd: Command(zap.NewNop(), "echo", "Hello", "World"),
|
||||
expectExecErr: true,
|
||||
scenario: "nil context",
|
||||
cmd: Command(zap.NewNop(), "echo", "Hello", "World"),
|
||||
expectExecError: true,
|
||||
},
|
||||
{
|
||||
name: "start error",
|
||||
cmd: func() Cmd {
|
||||
scenario: "start error",
|
||||
cmd: func() *Cmd {
|
||||
cmd, err := CommandContext(context.Background(), zap.NewNop(), "foo")
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error from CommandContext(), but got: %v", err)
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}(),
|
||||
expectExecErr: true,
|
||||
expectExecError: true,
|
||||
},
|
||||
{
|
||||
name: "context done",
|
||||
cmd: Command(zap.NewNop(), "sleep", "2"),
|
||||
timeout: time.Duration(1) * time.Second,
|
||||
expectExecErr: true,
|
||||
scenario: "context done",
|
||||
cmd: Command(zap.NewNop(), "sleep", "2"),
|
||||
timeout: time.Duration(1) * time.Second,
|
||||
expectExecError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
if tc.timeout > 0 {
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), tc.timeout)
|
||||
defer cancel()
|
||||
@@ -192,12 +189,12 @@ func TestCmd_Exec(t *testing.T) {
|
||||
|
||||
_, err := tc.cmd.Exec()
|
||||
|
||||
if tc.expectExecErr && err == nil {
|
||||
t.Error("expected error from cmd.Exec(), but got none")
|
||||
if !tc.expectExecError && err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
if !tc.expectExecErr && err != nil {
|
||||
t.Errorf("expected no error from cmd.Exec(), but got: %v", err)
|
||||
if tc.expectExecError && err == nil {
|
||||
t.Fatal("expected error but got none")
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -205,67 +202,68 @@ func TestCmd_Exec(t *testing.T) {
|
||||
|
||||
func TestCmd_pipeOutput(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cmd Cmd
|
||||
run bool
|
||||
expectPipeOutputErr bool
|
||||
scenario string
|
||||
cmd *Cmd
|
||||
run bool
|
||||
expectPipeOutputError bool
|
||||
}{
|
||||
{
|
||||
name: "nominal behavior",
|
||||
cmd: Command(zap.NewExample(), "echo", "Hello", "World"),
|
||||
run: true,
|
||||
scenario: "nominal behavior",
|
||||
cmd: Command(zap.NewExample(), "echo", "Hello", "World"),
|
||||
run: true,
|
||||
expectPipeOutputError: false,
|
||||
},
|
||||
{
|
||||
name: "no debug, no pipe",
|
||||
cmd: Command(zap.NewNop(), "echo", "Hello", "World"),
|
||||
scenario: "no debug, no pipe",
|
||||
cmd: Command(zap.NewNop(), "echo", "Hello", "World"),
|
||||
run: false,
|
||||
expectPipeOutputError: false,
|
||||
},
|
||||
{
|
||||
name: "stdout already piped",
|
||||
cmd: func() Cmd {
|
||||
scenario: "stdout already piped",
|
||||
cmd: func() *Cmd {
|
||||
cmd := Command(zap.NewExample(), "echo", "Hello", "World")
|
||||
|
||||
_, err := cmd.process.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error from cmd.process.StdoutPipe(), but got: %v", err)
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}(),
|
||||
expectPipeOutputErr: true,
|
||||
run: false,
|
||||
expectPipeOutputError: true,
|
||||
},
|
||||
{
|
||||
name: "stderr already piped",
|
||||
cmd: func() Cmd {
|
||||
scenario: "stderr already piped",
|
||||
cmd: func() *Cmd {
|
||||
cmd := Command(zap.NewExample(), "echo", "Hello", "World")
|
||||
|
||||
_, err := cmd.process.StderrPipe()
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error from cmd.process.StderrPipe(), but got: %v", err)
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}(),
|
||||
expectPipeOutputErr: true,
|
||||
run: false,
|
||||
expectPipeOutputError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
err := tc.cmd.pipeOutput()
|
||||
|
||||
if tc.run {
|
||||
errStart := tc.cmd.process.Start()
|
||||
if errStart != nil {
|
||||
t.Fatalf("expected no error from tc.cmd.process.Start(), but got: %v", errStart)
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if tc.expectPipeOutputErr && err == nil {
|
||||
t.Error("expected error from cmd.pipeOutput(), but got none")
|
||||
if !tc.expectPipeOutputError && err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
if !tc.expectPipeOutputErr && err != nil {
|
||||
t.Errorf("expected no error from cmd.pipeOutput(), but got: %v", err)
|
||||
if tc.expectPipeOutputError && err == nil {
|
||||
t.Fatal("expected error but got none")
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -273,51 +271,46 @@ func TestCmd_pipeOutput(t *testing.T) {
|
||||
|
||||
func TestCmd_Kill(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cmd Cmd
|
||||
scenario string
|
||||
cmd *Cmd
|
||||
}{
|
||||
{
|
||||
name: "nominal behavior",
|
||||
cmd: func() Cmd {
|
||||
scenario: "nominal behavior",
|
||||
cmd: func() *Cmd {
|
||||
cmd := Command(zap.NewNop(), "sleep", "60")
|
||||
|
||||
err := cmd.process.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error from cmd.process.Start(), but got: %v", err)
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "no process",
|
||||
cmd: Cmd{logger: zap.NewNop()},
|
||||
scenario: "no process",
|
||||
cmd: &Cmd{logger: zap.NewNop()},
|
||||
},
|
||||
{
|
||||
name: "process already killed",
|
||||
cmd: func() Cmd {
|
||||
scenario: "process already killed",
|
||||
cmd: func() *Cmd {
|
||||
cmd := Command(zap.NewNop(), "sleep", "60")
|
||||
|
||||
err := cmd.process.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error from cmd.process.Start(), but got: %v", err)
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
err = cmd.Kill()
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error from cmd.Kill(), but got: %v", err)
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
err := tc.cmd.Kill()
|
||||
if err != nil {
|
||||
t.Errorf("expected no error from cmd.Kill(), but got: %v", err)
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -23,173 +23,212 @@ func TestContext_ParsedFlags(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestContext_Module(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
mods []ModuleDescriptor
|
||||
kind interface{}
|
||||
expectErr bool
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
mods []ModuleDescriptor
|
||||
kind interface{}
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
scenario: "module with error on provision",
|
||||
mods: func() []ModuleDescriptor {
|
||||
mod := struct{ ProtoProvisioner }{}
|
||||
mod.descriptor = func() ModuleDescriptor {
|
||||
mod := &struct {
|
||||
ModuleMock
|
||||
ProvisionerMock
|
||||
}{}
|
||||
mod.DescriptorMock = func() ModuleDescriptor {
|
||||
return ModuleDescriptor{ID: "foo", New: func() Module { return mod }}
|
||||
}
|
||||
mod.provision = func(ctx *Context) error { return errors.New("foo") }
|
||||
|
||||
mod.ProvisionMock = func(ctx *Context) error { return errors.New("foo") }
|
||||
return []ModuleDescriptor{mod.Descriptor()}
|
||||
}(),
|
||||
kind: new(Provisioner),
|
||||
expectErr: true,
|
||||
kind: new(Provisioner),
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
scenario: "two modules instead of one",
|
||||
mods: func() []ModuleDescriptor {
|
||||
mod := struct{ ProtoProvisioner }{}
|
||||
mod.descriptor = func() ModuleDescriptor {
|
||||
mod := &struct {
|
||||
ModuleMock
|
||||
ProvisionerMock
|
||||
}{}
|
||||
mod.DescriptorMock = func() ModuleDescriptor {
|
||||
return ModuleDescriptor{ID: "foo", New: func() Module { return mod }}
|
||||
}
|
||||
mod.provision = func(ctx *Context) error { return nil }
|
||||
|
||||
mod.ProvisionMock = func(ctx *Context) error { return nil }
|
||||
return []ModuleDescriptor{mod.Descriptor(), mod.Descriptor()}
|
||||
}(),
|
||||
kind: new(Provisioner),
|
||||
expectErr: true,
|
||||
kind: new(Provisioner),
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
scenario: "success",
|
||||
mods: func() []ModuleDescriptor {
|
||||
mod := struct{ ProtoProvisioner }{}
|
||||
mod.descriptor = func() ModuleDescriptor {
|
||||
mod := &struct {
|
||||
ModuleMock
|
||||
ProvisionerMock
|
||||
}{}
|
||||
mod.DescriptorMock = func() ModuleDescriptor {
|
||||
return ModuleDescriptor{ID: "foo", New: func() Module { return mod }}
|
||||
}
|
||||
mod.provision = func(ctx *Context) error { return nil }
|
||||
|
||||
mod.ProvisionMock = func(ctx *Context) error { return nil }
|
||||
return []ModuleDescriptor{mod.Descriptor()}
|
||||
}(),
|
||||
kind: new(Provisioner),
|
||||
kind: new(Provisioner),
|
||||
expectError: false,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
ctx := NewContext(ParsedFlags{}, tc.mods)
|
||||
_, err := ctx.Module(tc.kind)
|
||||
|
||||
ctx := NewContext(ParsedFlags{}, tc.mods)
|
||||
_, err := ctx.Module(tc.kind)
|
||||
if !tc.expectError && err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
if tc.expectErr && err == nil {
|
||||
t.Errorf("test %d: expected error but got: %v", i, err)
|
||||
}
|
||||
|
||||
if !tc.expectErr && err != nil {
|
||||
t.Errorf("test %d: expected no error but got: %v", i, err)
|
||||
}
|
||||
if tc.expectError && err == nil {
|
||||
t.Fatal("expected error but got none")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext_Modules(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
mods []ModuleDescriptor
|
||||
kind interface{}
|
||||
expectErr bool
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
mods []ModuleDescriptor
|
||||
kind interface{}
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
scenario: "module with error on provision",
|
||||
mods: func() []ModuleDescriptor {
|
||||
mod := struct{ ProtoProvisioner }{}
|
||||
mod.descriptor = func() ModuleDescriptor {
|
||||
mod := &struct {
|
||||
ModuleMock
|
||||
ProvisionerMock
|
||||
}{}
|
||||
mod.DescriptorMock = func() ModuleDescriptor {
|
||||
return ModuleDescriptor{ID: "foo", New: func() Module { return mod }}
|
||||
}
|
||||
mod.provision = func(ctx *Context) error { return errors.New("foo") }
|
||||
|
||||
mod.ProvisionMock = func(ctx *Context) error { return errors.New("foo") }
|
||||
return []ModuleDescriptor{mod.Descriptor()}
|
||||
}(),
|
||||
kind: new(Provisioner),
|
||||
expectErr: true,
|
||||
kind: new(Provisioner),
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
scenario: "success (module)",
|
||||
mods: func() []ModuleDescriptor {
|
||||
mod := struct{ ProtoProvisioner }{}
|
||||
mod.descriptor = func() ModuleDescriptor {
|
||||
mod := &struct {
|
||||
ModuleMock
|
||||
ProvisionerMock
|
||||
}{}
|
||||
mod.DescriptorMock = func() ModuleDescriptor {
|
||||
return ModuleDescriptor{ID: "foo", New: func() Module { return mod }}
|
||||
}
|
||||
mod.provision = func(ctx *Context) error { return nil }
|
||||
|
||||
mod.ProvisionMock = func(ctx *Context) error { return nil }
|
||||
return []ModuleDescriptor{mod.Descriptor(), mod.Descriptor()}
|
||||
}(),
|
||||
kind: new(Provisioner),
|
||||
kind: new(Provisioner),
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
scenario: "success (one module)",
|
||||
mods: func() []ModuleDescriptor {
|
||||
mod := struct{ ProtoProvisioner }{}
|
||||
mod.descriptor = func() ModuleDescriptor {
|
||||
mod := &struct {
|
||||
ModuleMock
|
||||
ProvisionerMock
|
||||
}{}
|
||||
mod.DescriptorMock = func() ModuleDescriptor {
|
||||
return ModuleDescriptor{ID: "foo", New: func() Module { return mod }}
|
||||
}
|
||||
mod.provision = func(ctx *Context) error { return nil }
|
||||
mod.ProvisionMock = func(ctx *Context) error { return nil }
|
||||
|
||||
return []ModuleDescriptor{mod.Descriptor()}
|
||||
}(),
|
||||
kind: new(Provisioner),
|
||||
kind: new(Provisioner),
|
||||
expectError: false,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
ctx := NewContext(ParsedFlags{}, tc.mods)
|
||||
_, err := ctx.Modules(tc.kind)
|
||||
|
||||
ctx := NewContext(ParsedFlags{}, tc.mods)
|
||||
_, err := ctx.Modules(tc.kind)
|
||||
if !tc.expectError && err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
if tc.expectErr && err == nil {
|
||||
t.Errorf("test %d: expected error but got: %v", i, err)
|
||||
}
|
||||
|
||||
if !tc.expectErr && err != nil {
|
||||
t.Errorf("test %d: expected no error but got: %v", i, err)
|
||||
}
|
||||
if tc.expectError && err == nil {
|
||||
t.Fatal("expected error but got none")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext_loadModule(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
instance interface{}
|
||||
expectErr bool
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
instance interface{}
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
scenario: "module with error on provision",
|
||||
instance: func() interface{} {
|
||||
mod := struct{ ProtoProvisioner }{}
|
||||
mod.descriptor = func() ModuleDescriptor {
|
||||
mod := &struct {
|
||||
ModuleMock
|
||||
ProvisionerMock
|
||||
}{}
|
||||
mod.DescriptorMock = func() ModuleDescriptor {
|
||||
return ModuleDescriptor{ID: "foo", New: func() Module { return mod }}
|
||||
}
|
||||
mod.provision = func(ctx *Context) error { return errors.New("foo") }
|
||||
|
||||
mod.ProvisionMock = func(ctx *Context) error { return errors.New("foo") }
|
||||
return mod
|
||||
}(),
|
||||
expectErr: true,
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
scenario: "module with error on validation",
|
||||
instance: func() interface{} {
|
||||
mod := struct{ ProtoValidator }{}
|
||||
mod.descriptor = func() ModuleDescriptor {
|
||||
mod := &struct {
|
||||
ModuleMock
|
||||
ValidatorMock
|
||||
}{}
|
||||
mod.DescriptorMock = func() ModuleDescriptor {
|
||||
return ModuleDescriptor{ID: "foo", New: func() Module { return mod }}
|
||||
}
|
||||
mod.validate = func() error { return errors.New("foo") }
|
||||
|
||||
mod.ValidateMock = func() error { return errors.New("foo") }
|
||||
return mod
|
||||
}(),
|
||||
expectErr: true,
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
scenario: "success",
|
||||
instance: func() interface{} {
|
||||
mod := struct{ ProtoValidator }{}
|
||||
mod.descriptor = func() ModuleDescriptor {
|
||||
mod := &struct {
|
||||
ModuleMock
|
||||
ValidatorMock
|
||||
}{}
|
||||
mod.DescriptorMock = func() ModuleDescriptor {
|
||||
return ModuleDescriptor{ID: "foo", New: func() Module { return mod }}
|
||||
}
|
||||
mod.validate = func() error { return nil }
|
||||
mod.ValidateMock = func() error { return nil }
|
||||
|
||||
return mod
|
||||
}(),
|
||||
expectError: false,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
ctx := NewContext(ParsedFlags{}, nil)
|
||||
err := ctx.loadModule("foo", tc.instance)
|
||||
|
||||
ctx := NewContext(ParsedFlags{}, nil)
|
||||
err := ctx.loadModule("foo", tc.instance)
|
||||
if !tc.expectError && err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
if tc.expectErr && err == nil {
|
||||
t.Errorf("test %d: expected error but got: %v", i, err)
|
||||
}
|
||||
|
||||
if !tc.expectErr && err != nil {
|
||||
t.Errorf("test %d: expected no error but got: %v", i, err)
|
||||
}
|
||||
if tc.expectError && err == nil {
|
||||
t.Fatal("expected error but got none")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,23 +20,27 @@ func TestParsedFlags_MustString(t *testing.T) {
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
name string
|
||||
expectPanic bool
|
||||
}{
|
||||
{
|
||||
name: "foo",
|
||||
scenario: "success",
|
||||
name: "foo",
|
||||
expectPanic: false,
|
||||
},
|
||||
{
|
||||
scenario: "non-existing flag",
|
||||
name: "bar",
|
||||
expectPanic: true,
|
||||
},
|
||||
} {
|
||||
func() {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
if tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("test %d: expected panic but got none", i)
|
||||
t.Fatal("expected panic but got none")
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -44,49 +48,55 @@ func TestParsedFlags_MustString(t *testing.T) {
|
||||
if !tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Errorf("test %d: expected no panic but got: %v", i, r)
|
||||
t.Fatalf("expected no panic but got: %v", r)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
parsedFlags.MustString(tc.name)
|
||||
}()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParsedFlags_MustDeprecatedString(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
rawFlags []string
|
||||
expectValue string
|
||||
}{
|
||||
{
|
||||
scenario: "deprecated flag value",
|
||||
rawFlags: []string{"--foo=foo"},
|
||||
expectValue: "foo",
|
||||
},
|
||||
{
|
||||
scenario: "non-deprecated flag value",
|
||||
rawFlags: []string{"--bar=bar"},
|
||||
expectValue: "bar",
|
||||
},
|
||||
{
|
||||
scenario: "deprecated flag value > non-deprecated flag value",
|
||||
rawFlags: []string{"--foo=foo", "--bar=bar"},
|
||||
expectValue: "foo",
|
||||
},
|
||||
} {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.String("foo", "", "")
|
||||
fs.String("bar", "", "")
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.String("foo", "", "")
|
||||
fs.String("bar", "", "")
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("test %d: expected no error but got: %v", i, err)
|
||||
}
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
actual := parsedFlags.MustDeprecatedString("foo", "bar")
|
||||
if actual != tc.expectValue {
|
||||
t.Errorf("test %d: expected '%s' but got '%s'", i, tc.expectValue, actual)
|
||||
}
|
||||
actual := parsedFlags.MustDeprecatedString("foo", "bar")
|
||||
if actual != tc.expectValue {
|
||||
t.Errorf("expected '%s' but got '%s'", tc.expectValue, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,23 +111,27 @@ func TestParsedFlags_MustStringSlice(t *testing.T) {
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
name string
|
||||
expectPanic bool
|
||||
}{
|
||||
{
|
||||
name: "foo",
|
||||
scenario: "success",
|
||||
name: "foo",
|
||||
expectPanic: false,
|
||||
},
|
||||
{
|
||||
scenario: "non-existing flag",
|
||||
name: "bar",
|
||||
expectPanic: true,
|
||||
},
|
||||
} {
|
||||
func() {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
if tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("test %d: expected panic but got none", i)
|
||||
t.Fatal("expected panic but got none")
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -125,49 +139,55 @@ func TestParsedFlags_MustStringSlice(t *testing.T) {
|
||||
if !tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Errorf("test %d: expected no panic but got: %v", i, r)
|
||||
t.Fatalf("expected no panic but got: %v", r)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
parsedFlags.MustStringSlice(tc.name)
|
||||
}()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParsedFlags_MustDeprecatedStringSlice(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
rawFlags []string
|
||||
expectValue []string
|
||||
}{
|
||||
{
|
||||
scenario: "deprecated flag value",
|
||||
rawFlags: []string{"--foo=foo"},
|
||||
expectValue: []string{"foo"},
|
||||
},
|
||||
{
|
||||
scenario: "non-deprecated flag value",
|
||||
rawFlags: []string{"--bar=bar"},
|
||||
expectValue: []string{"bar"},
|
||||
},
|
||||
{
|
||||
scenario: "deprecated flag value > non-deprecated flag value",
|
||||
rawFlags: []string{"--foo=foo", "--bar=bar"},
|
||||
expectValue: []string{"foo"},
|
||||
},
|
||||
} {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.StringSlice("foo", make([]string, 0), "")
|
||||
fs.StringSlice("bar", make([]string, 0), "")
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.StringSlice("foo", make([]string, 0), "")
|
||||
fs.StringSlice("bar", make([]string, 0), "")
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("test %d: expected no error but got: %v", i, err)
|
||||
}
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
actual := parsedFlags.MustDeprecatedStringSlice("foo", "bar")
|
||||
if !reflect.DeepEqual(actual, tc.expectValue) {
|
||||
t.Errorf("test %d: expected %+v but got %+v", i, tc.expectValue, actual)
|
||||
}
|
||||
actual := parsedFlags.MustDeprecatedStringSlice("foo", "bar")
|
||||
if !reflect.DeepEqual(actual, tc.expectValue) {
|
||||
t.Errorf("expected %+v but got %+v", tc.expectValue, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,23 +202,27 @@ func TestParsedFlags_MustBool(t *testing.T) {
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
name string
|
||||
expectPanic bool
|
||||
}{
|
||||
{
|
||||
name: "foo",
|
||||
scenario: "success",
|
||||
name: "foo",
|
||||
expectPanic: false,
|
||||
},
|
||||
{
|
||||
scenario: "non-existing flag",
|
||||
name: "bar",
|
||||
expectPanic: true,
|
||||
},
|
||||
} {
|
||||
func() {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
if tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("test %d: expected panic but got none", i)
|
||||
t.Fatal("expected panic but got none")
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -206,49 +230,55 @@ func TestParsedFlags_MustBool(t *testing.T) {
|
||||
if !tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Errorf("test %d: expected no panic but got: %v", i, r)
|
||||
t.Fatalf("expected no panic but got: %v", r)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
parsedFlags.MustBool(tc.name)
|
||||
}()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParsedFlags_MustDeprecatedBool(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
rawFlags []string
|
||||
expectValue bool
|
||||
}{
|
||||
{
|
||||
scenario: "deprecated flag value",
|
||||
rawFlags: []string{"--foo=true"},
|
||||
expectValue: true,
|
||||
},
|
||||
{
|
||||
scenario: "non-deprecated flag value",
|
||||
rawFlags: []string{"--bar=false"},
|
||||
expectValue: false,
|
||||
},
|
||||
{
|
||||
scenario: "deprecated flag value > non-deprecated flag value",
|
||||
rawFlags: []string{"--foo=true", "--bar=false"},
|
||||
expectValue: true,
|
||||
},
|
||||
} {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.Bool("foo", false, "")
|
||||
fs.Bool("bar", true, "")
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.Bool("foo", false, "")
|
||||
fs.Bool("bar", true, "")
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("test %d: expected no error but got: %v", i, err)
|
||||
}
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
actual := parsedFlags.MustDeprecatedBool("foo", "bar")
|
||||
if actual != tc.expectValue {
|
||||
t.Errorf("test %d: expected %v but got %v", i, tc.expectValue, actual)
|
||||
}
|
||||
actual := parsedFlags.MustDeprecatedBool("foo", "bar")
|
||||
if actual != tc.expectValue {
|
||||
t.Errorf("expected %v but got %v", tc.expectValue, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,23 +293,27 @@ func TestParsedFlags_MustInt64(t *testing.T) {
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
name string
|
||||
expectPanic bool
|
||||
}{
|
||||
{
|
||||
name: "foo",
|
||||
scenario: "success",
|
||||
name: "foo",
|
||||
expectPanic: false,
|
||||
},
|
||||
{
|
||||
scenario: "non-existing flag",
|
||||
name: "bar",
|
||||
expectPanic: true,
|
||||
},
|
||||
} {
|
||||
func() {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
if tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("test %d: expected panic but got none", i)
|
||||
t.Fatal("expected panic but got none")
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -287,30 +321,34 @@ func TestParsedFlags_MustInt64(t *testing.T) {
|
||||
if !tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Errorf("test %d: expected no panic but got: %v", i, r)
|
||||
t.Fatalf("expected no panic but got: %v", r)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
parsedFlags.MustInt64(tc.name)
|
||||
}()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParsedFlags_MustDeprecatedInt64(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
rawFlags []string
|
||||
expectValue int64
|
||||
}{
|
||||
{
|
||||
scenario: "deprecated flag value",
|
||||
rawFlags: []string{"--foo=1"},
|
||||
expectValue: 1,
|
||||
},
|
||||
{
|
||||
scenario: "non-deprecated flag value",
|
||||
rawFlags: []string{"--bar=2"},
|
||||
expectValue: 2,
|
||||
},
|
||||
{
|
||||
scenario: "deprecated flag value > non-deprecated flag value",
|
||||
rawFlags: []string{"--foo=1", "--bar=2"},
|
||||
expectValue: 1,
|
||||
},
|
||||
@@ -323,12 +361,12 @@ func TestParsedFlags_MustDeprecatedInt64(t *testing.T) {
|
||||
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("test %d: expected no error but got: %v", i, err)
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
actual := parsedFlags.MustDeprecatedInt64("foo", "bar")
|
||||
if actual != tc.expectValue {
|
||||
t.Errorf("test %d: expected %d but got %d", i, tc.expectValue, actual)
|
||||
t.Errorf("expected %d but got %d", tc.expectValue, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -344,23 +382,27 @@ func TestParsedFlags_MustInt(t *testing.T) {
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
name string
|
||||
expectPanic bool
|
||||
}{
|
||||
{
|
||||
name: "foo",
|
||||
scenario: "success",
|
||||
name: "foo",
|
||||
expectPanic: false,
|
||||
},
|
||||
{
|
||||
scenario: "non-existing flag",
|
||||
name: "bar",
|
||||
expectPanic: true,
|
||||
},
|
||||
} {
|
||||
func() {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
if tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("test %d: expected panic but got none", i)
|
||||
t.Fatal("expected panic but got none")
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -368,49 +410,55 @@ func TestParsedFlags_MustInt(t *testing.T) {
|
||||
if !tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Errorf("test %d: expected no panic but got: %v", i, r)
|
||||
t.Fatalf("expected no panic but got: %v", r)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
parsedFlags.MustInt(tc.name)
|
||||
}()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParsedFlags_MustDeprecatedInt(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
rawFlags []string
|
||||
expectValue int
|
||||
}{
|
||||
{
|
||||
scenario: "deprecated flag value",
|
||||
rawFlags: []string{"--foo=1"},
|
||||
expectValue: 1,
|
||||
},
|
||||
{
|
||||
scenario: "non-deprecated flag value",
|
||||
rawFlags: []string{"--bar=2"},
|
||||
expectValue: 2,
|
||||
},
|
||||
{
|
||||
scenario: "deprecated flag value > non-deprecated flag value",
|
||||
rawFlags: []string{"--foo=1", "--bar=2"},
|
||||
expectValue: 1,
|
||||
},
|
||||
} {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.Int("foo", 0, "")
|
||||
fs.Int("bar", 0, "")
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.Int("foo", 0, "")
|
||||
fs.Int("bar", 0, "")
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("test %d: expected no error but got: %v", i, err)
|
||||
}
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
actual := parsedFlags.MustDeprecatedInt("foo", "bar")
|
||||
if actual != tc.expectValue {
|
||||
t.Errorf("test %d: expected %d but got %d", i, tc.expectValue, actual)
|
||||
}
|
||||
actual := parsedFlags.MustDeprecatedInt("foo", "bar")
|
||||
if actual != tc.expectValue {
|
||||
t.Errorf("expected %d but got %d", tc.expectValue, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,23 +473,27 @@ func TestParsedFlags_MustFloat64(t *testing.T) {
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
name string
|
||||
expectPanic bool
|
||||
}{
|
||||
{
|
||||
name: "foo",
|
||||
scenario: "success",
|
||||
name: "foo",
|
||||
expectPanic: false,
|
||||
},
|
||||
{
|
||||
scenario: "non-existing flag",
|
||||
name: "bar",
|
||||
expectPanic: true,
|
||||
},
|
||||
} {
|
||||
func() {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
if tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("test %d: expected panic but got none", i)
|
||||
t.Fatal("expected panic but got none")
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -449,49 +501,55 @@ func TestParsedFlags_MustFloat64(t *testing.T) {
|
||||
if !tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Errorf("test %d: expected no panic but got: %v", i, r)
|
||||
t.Fatalf("expected no panic but got: %v", r)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
parsedFlags.MustFloat64(tc.name)
|
||||
}()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParsedFlags_MustDeprecatedFloat64(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
rawFlags []string
|
||||
expectValue float64
|
||||
}{
|
||||
{
|
||||
scenario: "deprecated flag value",
|
||||
rawFlags: []string{"--foo=1.0"},
|
||||
expectValue: 1.0,
|
||||
},
|
||||
{
|
||||
scenario: "non-deprecated flag value",
|
||||
rawFlags: []string{"--bar=2.0"},
|
||||
expectValue: 2.0,
|
||||
},
|
||||
{
|
||||
scenario: "deprecated flag value > non-deprecated flag value",
|
||||
rawFlags: []string{"--foo=1.0", "--bar=2.0"},
|
||||
expectValue: 1.0,
|
||||
},
|
||||
} {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.Float64("foo", 0, "")
|
||||
fs.Float64("bar", 0, "")
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.Float64("foo", 0, "")
|
||||
fs.Float64("bar", 0, "")
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("test %d: expected no error but got: %v", i, err)
|
||||
}
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
actual := parsedFlags.MustDeprecatedFloat64("foo", "bar")
|
||||
if actual != tc.expectValue {
|
||||
t.Errorf("test %d: expected %f but got %f", i, tc.expectValue, actual)
|
||||
}
|
||||
actual := parsedFlags.MustDeprecatedFloat64("foo", "bar")
|
||||
if actual != tc.expectValue {
|
||||
t.Errorf("expected %f but got %f", tc.expectValue, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,23 +564,27 @@ func TestParsedFlags_MustDuration(t *testing.T) {
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
name string
|
||||
expectPanic bool
|
||||
}{
|
||||
{
|
||||
name: "foo",
|
||||
scenario: "success",
|
||||
name: "foo",
|
||||
expectPanic: false,
|
||||
},
|
||||
{
|
||||
scenario: "non-existing flag",
|
||||
name: "bar",
|
||||
expectPanic: true,
|
||||
},
|
||||
} {
|
||||
func() {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
if tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("test %d: expected panic but got none", i)
|
||||
t.Fatal("expected panic but got none")
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -530,49 +592,55 @@ func TestParsedFlags_MustDuration(t *testing.T) {
|
||||
if !tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Errorf("test %d: expected no panic but got: %v", i, r)
|
||||
t.Fatalf("expected no panic but got: %v", r)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
parsedFlags.MustDuration(tc.name)
|
||||
}()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParsedFlags_MustDeprecatedDuration(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
rawFlags []string
|
||||
expectValue time.Duration
|
||||
}{
|
||||
{
|
||||
scenario: "deprecated flag value",
|
||||
rawFlags: []string{"--foo=1s"},
|
||||
expectValue: time.Duration(1) * time.Second,
|
||||
},
|
||||
{
|
||||
scenario: "non-deprecated flag value",
|
||||
rawFlags: []string{"--bar=2s"},
|
||||
expectValue: time.Duration(2) * time.Second,
|
||||
},
|
||||
{
|
||||
scenario: "deprecated flag value > non-deprecated flag value",
|
||||
rawFlags: []string{"--foo=1s", "--bar=2s"},
|
||||
expectValue: time.Duration(1) * time.Second,
|
||||
},
|
||||
} {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.Duration("foo", 0, "")
|
||||
fs.Duration("bar", 0, "")
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.Duration("foo", 0, "")
|
||||
fs.Duration("bar", 0, "")
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("test %d: expected no error but got: %v", i, err)
|
||||
}
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
actual := parsedFlags.MustDeprecatedDuration("foo", "bar")
|
||||
if actual != tc.expectValue {
|
||||
t.Errorf("test %d: expected '%s' but got '%s'", i, tc.expectValue, actual)
|
||||
}
|
||||
actual := parsedFlags.MustDeprecatedDuration("foo", "bar")
|
||||
if actual != tc.expectValue {
|
||||
t.Errorf("expected '%s' but got '%s'", tc.expectValue, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,27 +656,27 @@ func TestParsedFlags_MustHumanReadableBytesString(t *testing.T) {
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
name string
|
||||
expectPanic bool
|
||||
}{
|
||||
{
|
||||
name: "foo",
|
||||
scenario: "success",
|
||||
name: "foo",
|
||||
expectPanic: false,
|
||||
},
|
||||
{
|
||||
scenario: "non-existing flag",
|
||||
name: "bar",
|
||||
expectPanic: true,
|
||||
},
|
||||
{
|
||||
name: "baz",
|
||||
expectPanic: true,
|
||||
},
|
||||
} {
|
||||
func() {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
if tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("test %d: expected panic but got none", i)
|
||||
t.Fatal("expected panic but got none")
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -616,49 +684,55 @@ func TestParsedFlags_MustHumanReadableBytesString(t *testing.T) {
|
||||
if !tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Errorf("test %d: expected no panic but got: %v", i, r)
|
||||
t.Fatalf("expected no panic but got: %v", r)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
parsedFlags.MustHumanReadableBytesString(tc.name)
|
||||
}()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParsedFlags_MustDeprecatedHumanReadableBytesString(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
rawFlags []string
|
||||
expectValue string
|
||||
}{
|
||||
{
|
||||
scenario: "deprecated flag value",
|
||||
rawFlags: []string{"--foo=1MB"},
|
||||
expectValue: "1MB",
|
||||
},
|
||||
{
|
||||
scenario: "non-deprecated flag value",
|
||||
rawFlags: []string{"--bar=2MB"},
|
||||
expectValue: "2MB",
|
||||
},
|
||||
{
|
||||
scenario: "deprecated flag value > non-deprecated flag value",
|
||||
rawFlags: []string{"--foo=1MB", "--bar=2MB"},
|
||||
expectValue: "1MB",
|
||||
},
|
||||
} {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.String("foo", "", "")
|
||||
fs.String("bar", "", "")
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.String("foo", "", "")
|
||||
fs.String("bar", "", "")
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("test %d: expected no error but got: %v", i, err)
|
||||
}
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
actual := parsedFlags.MustDeprecatedHumanReadableBytesString("foo", "bar")
|
||||
if actual != tc.expectValue {
|
||||
t.Errorf("test %d: expected '%s' but got '%s'", i, tc.expectValue, actual)
|
||||
}
|
||||
actual := parsedFlags.MustDeprecatedHumanReadableBytesString("foo", "bar")
|
||||
if actual != tc.expectValue {
|
||||
t.Errorf("expected '%s' but got '%s'", tc.expectValue, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,27 +748,27 @@ func TestParsedFlags_MustRegexp(t *testing.T) {
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
name string
|
||||
expectPanic bool
|
||||
}{
|
||||
{
|
||||
name: "foo",
|
||||
scenario: "success",
|
||||
name: "foo",
|
||||
expectPanic: false,
|
||||
},
|
||||
{
|
||||
scenario: "non-existing flag",
|
||||
name: "bar",
|
||||
expectPanic: true,
|
||||
},
|
||||
{
|
||||
name: "baz",
|
||||
expectPanic: true,
|
||||
},
|
||||
} {
|
||||
func() {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
if tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("test %d: expected panic but got none", i)
|
||||
t.Fatal("expected panic but got none")
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -702,48 +776,54 @@ func TestParsedFlags_MustRegexp(t *testing.T) {
|
||||
if !tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Errorf("test %d: expected no panic but got: %v", i, r)
|
||||
t.Fatalf("expected no panic but got: %v", r)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
parsedFlags.MustRegexp(tc.name)
|
||||
}()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParsedFlags_MustDeprecatedRegexp(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
rawFlags []string
|
||||
expectValue *regexp.Regexp
|
||||
}{
|
||||
{
|
||||
scenario: "deprecated flag value",
|
||||
rawFlags: []string{"--foo=foo"},
|
||||
expectValue: regexp.MustCompile("foo"),
|
||||
},
|
||||
{
|
||||
scenario: "non-deprecated flag value",
|
||||
rawFlags: []string{"--bar=bar"},
|
||||
expectValue: regexp.MustCompile("bar"),
|
||||
},
|
||||
{
|
||||
scenario: "deprecated flag value > non-deprecated flag value",
|
||||
rawFlags: []string{"--foo=foo", "--bar=bar"},
|
||||
expectValue: regexp.MustCompile("foo"),
|
||||
},
|
||||
} {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.String("foo", "", "")
|
||||
fs.String("bar", "", "")
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
fs := flag.NewFlagSet("tests", flag.ContinueOnError)
|
||||
fs.String("foo", "", "")
|
||||
fs.String("bar", "", "")
|
||||
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
parsedFlags := ParsedFlags{FlagSet: fs}
|
||||
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("test %d: expected no error but got: %v", i, err)
|
||||
}
|
||||
err := parsedFlags.Parse(tc.rawFlags)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
actual := parsedFlags.MustDeprecatedRegexp("foo", "bar")
|
||||
if actual.String() != tc.expectValue.String() {
|
||||
t.Errorf("test %d: expected '%s' but got '%s'", i, tc.expectValue.String(), actual.String())
|
||||
}
|
||||
actual := parsedFlags.MustDeprecatedRegexp("foo", "bar")
|
||||
if actual.String() != tc.expectValue.String() {
|
||||
t.Errorf("expected '%s' but got '%s'", tc.expectValue.String(), actual.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,14 +14,14 @@ func TestGarbageCollect(t *testing.T) {
|
||||
scenario string
|
||||
rootPath string
|
||||
includeSubstr []string
|
||||
expectErr bool
|
||||
expectError bool
|
||||
expectNotExists []string
|
||||
expectExists []string
|
||||
}{
|
||||
{
|
||||
scenario: "root path does not exist",
|
||||
rootPath: uuid.NewString(),
|
||||
expectErr: true,
|
||||
scenario: "root path does not exist",
|
||||
rootPath: uuid.NewString(),
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
scenario: "remove include substrings",
|
||||
@@ -51,29 +51,30 @@ func TestGarbageCollect(t *testing.T) {
|
||||
return path
|
||||
}(),
|
||||
includeSubstr: []string{"foo", fmt.Sprintf("%s/a_directory/a_bar_file", os.TempDir())},
|
||||
expectError: false,
|
||||
expectExists: []string{"a_baz_file"},
|
||||
expectNotExists: []string{"a_foo_file", "a_bar_file"},
|
||||
},
|
||||
} {
|
||||
func() {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
defer func() {
|
||||
err := os.RemoveAll(tc.rootPath)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: expected no error while cleaning up but got: %v", tc.scenario, err)
|
||||
t.Fatalf("expected no error while cleaning up but got: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
err := GarbageCollect(zap.NewNop(), tc.rootPath, tc.includeSubstr)
|
||||
|
||||
if !tc.expectErr && err != nil {
|
||||
t.Fatalf("%s: expected no error but got: %v", tc.scenario, err)
|
||||
if !tc.expectError && err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
if tc.expectErr && err == nil {
|
||||
t.Fatalf("%s: expected error but got: %v", tc.scenario, err)
|
||||
if tc.expectError && err == nil {
|
||||
t.Fatal("expected error but got none")
|
||||
}
|
||||
|
||||
if tc.expectErr && err != nil {
|
||||
if tc.expectError && err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -81,7 +82,7 @@ func TestGarbageCollect(t *testing.T) {
|
||||
path := fmt.Sprintf("%s/%s", tc.rootPath, name)
|
||||
_, err = os.Stat(path)
|
||||
if !os.IsNotExist(err) {
|
||||
t.Errorf("%s: expected '%s' not to exist but it does: %v", tc.scenario, path, err)
|
||||
t.Errorf("expected '%s' not to exist but it does: %v", path, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,9 +90,9 @@ func TestGarbageCollect(t *testing.T) {
|
||||
path := fmt.Sprintf("%s/%s", tc.rootPath, name)
|
||||
_, err = os.Stat(path)
|
||||
if os.IsNotExist(err) {
|
||||
t.Errorf("%s: expected '%s' to exist but it does not: %v", tc.scenario, path, err)
|
||||
t.Errorf("expected '%s' to exist but it does not: %v", path, err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,15 @@ func (mod *ModuleMock) Descriptor() ModuleDescriptor {
|
||||
return mod.DescriptorMock()
|
||||
}
|
||||
|
||||
// ProvisionerMock is a mock for the [Provisioner] interface.
|
||||
type ProvisionerMock struct {
|
||||
ProvisionMock func(*Context) error
|
||||
}
|
||||
|
||||
func (mod *ProvisionerMock) Provision(ctx *Context) error {
|
||||
return mod.ProvisionMock(ctx)
|
||||
}
|
||||
|
||||
// ValidatorMock is a mock for the [Validator] interface.
|
||||
type ValidatorMock struct {
|
||||
ValidateMock func() error
|
||||
|
||||
@@ -21,6 +21,19 @@ func TestModuleMock(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvisionerMock(t *testing.T) {
|
||||
mock := &ProvisionerMock{
|
||||
ProvisionMock: func(*Context) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
err := mock.Provision(&Context{})
|
||||
if err != nil {
|
||||
t.Errorf("expected no error from ProvisionerMock.Provision, but got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidatorMock(t *testing.T) {
|
||||
mock := &ValidatorMock{
|
||||
ValidateMock: func() error {
|
||||
|
||||
@@ -5,32 +5,6 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type ProtoModule struct {
|
||||
descriptor func() ModuleDescriptor
|
||||
}
|
||||
|
||||
func (mod ProtoModule) Descriptor() ModuleDescriptor {
|
||||
return mod.descriptor()
|
||||
}
|
||||
|
||||
type ProtoProvisioner struct {
|
||||
ProtoModule
|
||||
provision func(ctx *Context) error
|
||||
}
|
||||
|
||||
func (mod ProtoProvisioner) Provision(ctx *Context) error {
|
||||
return mod.provision(ctx)
|
||||
}
|
||||
|
||||
type ProtoValidator struct {
|
||||
ProtoModule
|
||||
validate func() error
|
||||
}
|
||||
|
||||
func (mod ProtoValidator) Validate() error {
|
||||
return mod.validate()
|
||||
}
|
||||
|
||||
func TestMustRegisterModule(t *testing.T) {
|
||||
descriptorsMu.RLock()
|
||||
descriptors = map[string]ModuleDescriptor{
|
||||
@@ -38,44 +12,51 @@ func TestMustRegisterModule(t *testing.T) {
|
||||
}
|
||||
descriptorsMu.RUnlock()
|
||||
|
||||
for i, tc := range []struct {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
ID string
|
||||
New func() Module
|
||||
expectPanic bool
|
||||
}{
|
||||
{
|
||||
scenario: "no ID",
|
||||
ID: "",
|
||||
New: func() Module { return new(ProtoModule) },
|
||||
New: func() Module { return new(ModuleMock) },
|
||||
expectPanic: true,
|
||||
},
|
||||
{
|
||||
scenario: "nil New method",
|
||||
ID: "b",
|
||||
New: nil,
|
||||
expectPanic: true,
|
||||
},
|
||||
{
|
||||
scenario: "nil module",
|
||||
ID: "b",
|
||||
New: func() Module { return nil },
|
||||
expectPanic: true,
|
||||
},
|
||||
{
|
||||
scenario: "existing module",
|
||||
ID: "a",
|
||||
New: func() Module { return new(ProtoModule) },
|
||||
New: func() Module { return new(ModuleMock) },
|
||||
expectPanic: true,
|
||||
},
|
||||
{
|
||||
ID: "b",
|
||||
New: func() Module { return new(ProtoModule) },
|
||||
scenario: "success",
|
||||
ID: "b",
|
||||
New: func() Module { return new(ModuleMock) },
|
||||
expectPanic: false,
|
||||
},
|
||||
} {
|
||||
func() {
|
||||
mod := struct{ ProtoModule }{}
|
||||
mod.descriptor = func() ModuleDescriptor { return ModuleDescriptor{ID: tc.ID, New: tc.New} }
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
mod := &struct{ ModuleMock }{}
|
||||
mod.DescriptorMock = func() ModuleDescriptor { return ModuleDescriptor{ID: tc.ID, New: tc.New} }
|
||||
|
||||
if tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("test %d: expected panic but got none", i)
|
||||
t.Error("expected panic but got none")
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -83,13 +64,13 @@ func TestMustRegisterModule(t *testing.T) {
|
||||
if !tc.expectPanic {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Errorf("test %d: expected no panic but got: %v", i, r)
|
||||
t.Errorf("expected no panic but got: %v", r)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
MustRegisterModule(mod)
|
||||
}()
|
||||
})
|
||||
}
|
||||
|
||||
descriptorsMu.RLock()
|
||||
@@ -124,12 +105,3 @@ func TestGetModuleDescriptors(t *testing.T) {
|
||||
descriptors = make(map[string]ModuleDescriptor)
|
||||
descriptorsMu.RUnlock()
|
||||
}
|
||||
|
||||
// Interface guards.
|
||||
var (
|
||||
_ Module = (*ProtoModule)(nil)
|
||||
_ Provisioner = (*ProtoProvisioner)(nil)
|
||||
_ Module = (*ProtoProvisioner)(nil)
|
||||
_ Validator = (*ProtoValidator)(nil)
|
||||
_ Module = (*ProtoValidator)(nil)
|
||||
)
|
||||
|
||||
@@ -76,6 +76,6 @@ type PdfEngine interface {
|
||||
// engine, _ := provider.(gotenberg.PdfEngineProvider).PdfEngine()
|
||||
// }
|
||||
type PdfEngineProvider interface {
|
||||
// PdfEngine returns an instance of the PdfEngine interface for PDF operations.
|
||||
// PdfEngine returns an instance of the [PdfEngine] interface for PDF operations.
|
||||
PdfEngine() (PdfEngine, error)
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ type libreOfficeArguments struct {
|
||||
type libreOfficeProcess struct {
|
||||
socketPort int
|
||||
userProfileDirPath string
|
||||
cmd gotenberg.Cmd
|
||||
cmd *gotenberg.Cmd
|
||||
cfgMu sync.RWMutex
|
||||
isStarted atomic.Bool
|
||||
|
||||
@@ -213,7 +213,7 @@ func (p *libreOfficeProcess) Stop(logger *zap.Logger) error {
|
||||
|
||||
p.socketPort = 0
|
||||
p.userProfileDirPath = ""
|
||||
p.cmd = gotenberg.Cmd{} // FIXME: pointer.
|
||||
p.cmd = nil
|
||||
p.isStarted.Store(false)
|
||||
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user