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