feat(ansible): support list-valued package targets
This commit is contained in:
parent
2b32f453db
commit
909aac859a
4 changed files with 142 additions and 50 deletions
|
|
@ -1161,7 +1161,7 @@ func moduleSystemdWithClient(e *Executor, client sshRunner, args map[string]any)
|
||||||
// --- Package module shims ---
|
// --- Package module shims ---
|
||||||
|
|
||||||
func moduleAptWithClient(_ *Executor, client sshRunner, args map[string]any) (*TaskResult, error) {
|
func moduleAptWithClient(_ *Executor, client sshRunner, args map[string]any) (*TaskResult, error) {
|
||||||
name := getStringArg(args, "name", "")
|
names := normalizeStringArgs(args["name"])
|
||||||
state := getStringArg(args, "state", "present")
|
state := getStringArg(args, "state", "present")
|
||||||
updateCache := getBoolArg(args, "update_cache", false)
|
updateCache := getBoolArg(args, "update_cache", false)
|
||||||
|
|
||||||
|
|
@ -1173,13 +1173,17 @@ func moduleAptWithClient(_ *Executor, client sshRunner, args map[string]any) (*T
|
||||||
|
|
||||||
switch state {
|
switch state {
|
||||||
case "present", "installed":
|
case "present", "installed":
|
||||||
if name != "" {
|
if len(names) > 0 {
|
||||||
cmd = sprintf("DEBIAN_FRONTEND=noninteractive apt-get install -y -qq %s", name)
|
cmd = sprintf("DEBIAN_FRONTEND=noninteractive apt-get install -y -qq %s", join(" ", names))
|
||||||
}
|
}
|
||||||
case "absent", "removed":
|
case "absent", "removed":
|
||||||
cmd = sprintf("DEBIAN_FRONTEND=noninteractive apt-get remove -y -qq %s", name)
|
if len(names) > 0 {
|
||||||
|
cmd = sprintf("DEBIAN_FRONTEND=noninteractive apt-get remove -y -qq %s", join(" ", names))
|
||||||
|
}
|
||||||
case "latest":
|
case "latest":
|
||||||
cmd = sprintf("DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --only-upgrade %s", name)
|
if len(names) > 0 {
|
||||||
|
cmd = sprintf("DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --only-upgrade %s", join(" ", names))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd == "" {
|
if cmd == "" {
|
||||||
|
|
@ -1283,7 +1287,7 @@ func moduleDnfWithClient(_ *Executor, client sshRunner, args map[string]any) (*T
|
||||||
}
|
}
|
||||||
|
|
||||||
func moduleRPMWithClient(client sshRunner, args map[string]any, manager string) (*TaskResult, error) {
|
func moduleRPMWithClient(client sshRunner, args map[string]any, manager string) (*TaskResult, error) {
|
||||||
name := getStringArg(args, "name", "")
|
names := normalizeStringArgs(args["name"])
|
||||||
state := getStringArg(args, "state", "present")
|
state := getStringArg(args, "state", "present")
|
||||||
updateCache := getBoolArg(args, "update_cache", false)
|
updateCache := getBoolArg(args, "update_cache", false)
|
||||||
|
|
||||||
|
|
@ -1294,29 +1298,29 @@ func moduleRPMWithClient(client sshRunner, args map[string]any, manager string)
|
||||||
var cmd string
|
var cmd string
|
||||||
switch state {
|
switch state {
|
||||||
case "present", "installed":
|
case "present", "installed":
|
||||||
if name != "" {
|
if len(names) > 0 {
|
||||||
if manager == "rpm" {
|
if manager == "rpm" {
|
||||||
cmd = sprintf("rpm -ivh %s", name)
|
cmd = sprintf("rpm -ivh %s", join(" ", names))
|
||||||
} else {
|
} else {
|
||||||
cmd = sprintf("%s install -y -q %s", manager, name)
|
cmd = sprintf("%s install -y -q %s", manager, join(" ", names))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "absent", "removed":
|
case "absent", "removed":
|
||||||
if name != "" {
|
if len(names) > 0 {
|
||||||
if manager == "rpm" {
|
if manager == "rpm" {
|
||||||
cmd = sprintf("rpm -e %s", name)
|
cmd = sprintf("rpm -e %s", join(" ", names))
|
||||||
} else {
|
} else {
|
||||||
cmd = sprintf("%s remove -y -q %s", manager, name)
|
cmd = sprintf("%s remove -y -q %s", manager, join(" ", names))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "latest":
|
case "latest":
|
||||||
if name != "" {
|
if len(names) > 0 {
|
||||||
if manager == "rpm" {
|
if manager == "rpm" {
|
||||||
cmd = sprintf("rpm -Uvh %s", name)
|
cmd = sprintf("rpm -Uvh %s", join(" ", names))
|
||||||
} else if manager == "dnf" {
|
} else if manager == "dnf" {
|
||||||
cmd = sprintf("%s upgrade -y -q %s", manager, name)
|
cmd = sprintf("%s upgrade -y -q %s", manager, join(" ", names))
|
||||||
} else {
|
} else {
|
||||||
cmd = sprintf("%s update -y -q %s", manager, name)
|
cmd = sprintf("%s update -y -q %s", manager, join(" ", names))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1334,7 +1338,7 @@ func moduleRPMWithClient(client sshRunner, args map[string]any, manager string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func modulePipWithClient(_ *Executor, client sshRunner, args map[string]any) (*TaskResult, error) {
|
func modulePipWithClient(_ *Executor, client sshRunner, args map[string]any) (*TaskResult, error) {
|
||||||
name := getStringArg(args, "name", "")
|
names := normalizeStringArgs(args["name"])
|
||||||
state := getStringArg(args, "state", "present")
|
state := getStringArg(args, "state", "present")
|
||||||
executable := getStringArg(args, "executable", "pip3")
|
executable := getStringArg(args, "executable", "pip3")
|
||||||
virtualenv := getStringArg(args, "virtualenv", "")
|
virtualenv := getStringArg(args, "virtualenv", "")
|
||||||
|
|
@ -1355,26 +1359,26 @@ func modulePipWithClient(_ *Executor, client sshRunner, args map[string]any) (*T
|
||||||
switch {
|
switch {
|
||||||
case requirements != "":
|
case requirements != "":
|
||||||
parts = append(parts, sprintf("-r %q", requirements))
|
parts = append(parts, sprintf("-r %q", requirements))
|
||||||
case name != "":
|
case len(names) > 0:
|
||||||
parts = append(parts, name)
|
parts = append(parts, join(" ", names))
|
||||||
}
|
}
|
||||||
cmd = join(" ", parts)
|
cmd = join(" ", parts)
|
||||||
case "absent", "removed":
|
case "absent", "removed":
|
||||||
if name != "" {
|
if len(names) > 0 {
|
||||||
parts := []string{executable, "uninstall", "-y"}
|
parts := []string{executable, "uninstall", "-y"}
|
||||||
if extraArgs != "" {
|
if extraArgs != "" {
|
||||||
parts = append(parts, extraArgs)
|
parts = append(parts, extraArgs)
|
||||||
}
|
}
|
||||||
parts = append(parts, name)
|
parts = append(parts, join(" ", names))
|
||||||
cmd = join(" ", parts)
|
cmd = join(" ", parts)
|
||||||
}
|
}
|
||||||
case "latest":
|
case "latest":
|
||||||
if name != "" {
|
if len(names) > 0 {
|
||||||
parts := []string{executable, "install", "--upgrade"}
|
parts := []string{executable, "install", "--upgrade"}
|
||||||
if extraArgs != "" {
|
if extraArgs != "" {
|
||||||
parts = append(parts, extraArgs)
|
parts = append(parts, extraArgs)
|
||||||
}
|
}
|
||||||
parts = append(parts, name)
|
parts = append(parts, join(" ", names))
|
||||||
cmd = join(" ", parts)
|
cmd = join(" ", parts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1416,8 +1420,8 @@ func moduleUserWithClient(_ *Executor, client sshRunner, args map[string]any) (*
|
||||||
if group := getStringArg(args, "group", ""); group != "" {
|
if group := getStringArg(args, "group", ""); group != "" {
|
||||||
opts = append(opts, "-g", group)
|
opts = append(opts, "-g", group)
|
||||||
}
|
}
|
||||||
if groups := getStringArg(args, "groups", ""); groups != "" {
|
if groups := normalizeStringArgs(args["groups"]); len(groups) > 0 {
|
||||||
opts = append(opts, "-G", groups)
|
opts = append(opts, "-G", join(",", groups))
|
||||||
}
|
}
|
||||||
if home := getStringArg(args, "home", ""); home != "" {
|
if home := getStringArg(args, "home", ""); home != "" {
|
||||||
opts = append(opts, "-d", home)
|
opts = append(opts, "-d", home)
|
||||||
|
|
|
||||||
96
modules.go
96
modules.go
|
|
@ -1012,7 +1012,7 @@ func (e *Executor) moduleGetURL(ctx context.Context, client sshExecutorClient, a
|
||||||
// --- Package Modules ---
|
// --- Package Modules ---
|
||||||
|
|
||||||
func (e *Executor) moduleApt(ctx context.Context, client sshExecutorClient, args map[string]any) (*TaskResult, error) {
|
func (e *Executor) moduleApt(ctx context.Context, client sshExecutorClient, args map[string]any) (*TaskResult, error) {
|
||||||
name := getStringArg(args, "name", "")
|
names := normalizeStringArgs(args["name"])
|
||||||
state := getStringArg(args, "state", "present")
|
state := getStringArg(args, "state", "present")
|
||||||
updateCache := getBoolArg(args, "update_cache", false)
|
updateCache := getBoolArg(args, "update_cache", false)
|
||||||
|
|
||||||
|
|
@ -1024,13 +1024,17 @@ func (e *Executor) moduleApt(ctx context.Context, client sshExecutorClient, args
|
||||||
|
|
||||||
switch state {
|
switch state {
|
||||||
case "present", "installed":
|
case "present", "installed":
|
||||||
if name != "" {
|
if len(names) > 0 {
|
||||||
cmd = sprintf("DEBIAN_FRONTEND=noninteractive apt-get install -y -qq %s", name)
|
cmd = sprintf("DEBIAN_FRONTEND=noninteractive apt-get install -y -qq %s", join(" ", names))
|
||||||
}
|
}
|
||||||
case "absent", "removed":
|
case "absent", "removed":
|
||||||
cmd = sprintf("DEBIAN_FRONTEND=noninteractive apt-get remove -y -qq %s", name)
|
if len(names) > 0 {
|
||||||
|
cmd = sprintf("DEBIAN_FRONTEND=noninteractive apt-get remove -y -qq %s", join(" ", names))
|
||||||
|
}
|
||||||
case "latest":
|
case "latest":
|
||||||
cmd = sprintf("DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --only-upgrade %s", name)
|
if len(names) > 0 {
|
||||||
|
cmd = sprintf("DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --only-upgrade %s", join(" ", names))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd == "" {
|
if cmd == "" {
|
||||||
|
|
@ -1137,7 +1141,7 @@ func (e *Executor) moduleDnf(ctx context.Context, client sshExecutorClient, args
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Executor) moduleRPM(ctx context.Context, client sshExecutorClient, args map[string]any, manager string) (*TaskResult, error) {
|
func (e *Executor) moduleRPM(ctx context.Context, client sshExecutorClient, args map[string]any, manager string) (*TaskResult, error) {
|
||||||
name := getStringArg(args, "name", "")
|
names := normalizeStringArgs(args["name"])
|
||||||
state := getStringArg(args, "state", "present")
|
state := getStringArg(args, "state", "present")
|
||||||
updateCache := getBoolArg(args, "update_cache", false)
|
updateCache := getBoolArg(args, "update_cache", false)
|
||||||
|
|
||||||
|
|
@ -1148,29 +1152,29 @@ func (e *Executor) moduleRPM(ctx context.Context, client sshExecutorClient, args
|
||||||
var cmd string
|
var cmd string
|
||||||
switch state {
|
switch state {
|
||||||
case "present", "installed":
|
case "present", "installed":
|
||||||
if name != "" {
|
if len(names) > 0 {
|
||||||
if manager == "rpm" {
|
if manager == "rpm" {
|
||||||
cmd = sprintf("rpm -ivh %s", name)
|
cmd = sprintf("rpm -ivh %s", join(" ", names))
|
||||||
} else {
|
} else {
|
||||||
cmd = sprintf("%s install -y -q %s", manager, name)
|
cmd = sprintf("%s install -y -q %s", manager, join(" ", names))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "absent", "removed":
|
case "absent", "removed":
|
||||||
if name != "" {
|
if len(names) > 0 {
|
||||||
if manager == "rpm" {
|
if manager == "rpm" {
|
||||||
cmd = sprintf("rpm -e %s", name)
|
cmd = sprintf("rpm -e %s", join(" ", names))
|
||||||
} else {
|
} else {
|
||||||
cmd = sprintf("%s remove -y -q %s", manager, name)
|
cmd = sprintf("%s remove -y -q %s", manager, join(" ", names))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "latest":
|
case "latest":
|
||||||
if name != "" {
|
if len(names) > 0 {
|
||||||
if manager == "rpm" {
|
if manager == "rpm" {
|
||||||
cmd = sprintf("rpm -Uvh %s", name)
|
cmd = sprintf("rpm -Uvh %s", join(" ", names))
|
||||||
} else if manager == "dnf" {
|
} else if manager == "dnf" {
|
||||||
cmd = sprintf("%s upgrade -y -q %s", manager, name)
|
cmd = sprintf("%s upgrade -y -q %s", manager, join(" ", names))
|
||||||
} else {
|
} else {
|
||||||
cmd = sprintf("%s update -y -q %s", manager, name)
|
cmd = sprintf("%s update -y -q %s", manager, join(" ", names))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1188,7 +1192,7 @@ func (e *Executor) moduleRPM(ctx context.Context, client sshExecutorClient, args
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Executor) modulePip(ctx context.Context, client sshExecutorClient, args map[string]any) (*TaskResult, error) {
|
func (e *Executor) modulePip(ctx context.Context, client sshExecutorClient, args map[string]any) (*TaskResult, error) {
|
||||||
name := getStringArg(args, "name", "")
|
names := normalizeStringArgs(args["name"])
|
||||||
state := getStringArg(args, "state", "present")
|
state := getStringArg(args, "state", "present")
|
||||||
executable := getStringArg(args, "executable", "pip3")
|
executable := getStringArg(args, "executable", "pip3")
|
||||||
virtualenv := getStringArg(args, "virtualenv", "")
|
virtualenv := getStringArg(args, "virtualenv", "")
|
||||||
|
|
@ -1209,26 +1213,26 @@ func (e *Executor) modulePip(ctx context.Context, client sshExecutorClient, args
|
||||||
switch {
|
switch {
|
||||||
case requirements != "":
|
case requirements != "":
|
||||||
parts = append(parts, sprintf("-r %q", requirements))
|
parts = append(parts, sprintf("-r %q", requirements))
|
||||||
case name != "":
|
case len(names) > 0:
|
||||||
parts = append(parts, name)
|
parts = append(parts, join(" ", names))
|
||||||
}
|
}
|
||||||
cmd = join(" ", parts)
|
cmd = join(" ", parts)
|
||||||
case "absent", "removed":
|
case "absent", "removed":
|
||||||
if name != "" {
|
if len(names) > 0 {
|
||||||
parts := []string{executable, "uninstall", "-y"}
|
parts := []string{executable, "uninstall", "-y"}
|
||||||
if extraArgs != "" {
|
if extraArgs != "" {
|
||||||
parts = append(parts, extraArgs)
|
parts = append(parts, extraArgs)
|
||||||
}
|
}
|
||||||
parts = append(parts, name)
|
parts = append(parts, join(" ", names))
|
||||||
cmd = join(" ", parts)
|
cmd = join(" ", parts)
|
||||||
}
|
}
|
||||||
case "latest":
|
case "latest":
|
||||||
if name != "" {
|
if len(names) > 0 {
|
||||||
parts := []string{executable, "install", "--upgrade"}
|
parts := []string{executable, "install", "--upgrade"}
|
||||||
if extraArgs != "" {
|
if extraArgs != "" {
|
||||||
parts = append(parts, extraArgs)
|
parts = append(parts, extraArgs)
|
||||||
}
|
}
|
||||||
parts = append(parts, name)
|
parts = append(parts, join(" ", names))
|
||||||
cmd = join(" ", parts)
|
cmd = join(" ", parts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1323,8 +1327,8 @@ func (e *Executor) moduleUser(ctx context.Context, client sshExecutorClient, arg
|
||||||
if group := getStringArg(args, "group", ""); group != "" {
|
if group := getStringArg(args, "group", ""); group != "" {
|
||||||
opts = append(opts, "-g", group)
|
opts = append(opts, "-g", group)
|
||||||
}
|
}
|
||||||
if groups := getStringArg(args, "groups", ""); groups != "" {
|
if groups := normalizeStringArgs(args["groups"]); len(groups) > 0 {
|
||||||
opts = append(opts, "-G", groups)
|
opts = append(opts, "-G", join(",", groups))
|
||||||
}
|
}
|
||||||
if home := getStringArg(args, "home", ""); home != "" {
|
if home := getStringArg(args, "home", ""); home != "" {
|
||||||
opts = append(opts, "-d", home)
|
opts = append(opts, "-d", home)
|
||||||
|
|
@ -1992,6 +1996,48 @@ func normalizeStringList(value any) []string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// normalizeStringArgs collects one or more string values from a scalar or list
|
||||||
|
// input without splitting comma-separated content.
|
||||||
|
func normalizeStringArgs(value any) []string {
|
||||||
|
switch v := value.(type) {
|
||||||
|
case nil:
|
||||||
|
return nil
|
||||||
|
case string:
|
||||||
|
if trimmed := corexTrimSpace(v); trimmed != "" {
|
||||||
|
return []string{trimmed}
|
||||||
|
}
|
||||||
|
case []string:
|
||||||
|
out := make([]string, 0, len(v))
|
||||||
|
for _, item := range v {
|
||||||
|
if trimmed := corexTrimSpace(item); trimmed != "" {
|
||||||
|
out = append(out, trimmed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
case []any:
|
||||||
|
out := make([]string, 0, len(v))
|
||||||
|
for _, item := range v {
|
||||||
|
if s, ok := item.(string); ok {
|
||||||
|
if trimmed := corexTrimSpace(s); trimmed != "" {
|
||||||
|
out = append(out, trimmed)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
s := corexTrimSpace(corexSprint(item))
|
||||||
|
if s != "" && s != "<nil>" {
|
||||||
|
out = append(out, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
default:
|
||||||
|
s := corexTrimSpace(corexSprint(v))
|
||||||
|
if s != "" && s != "<nil>" {
|
||||||
|
return []string{s}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func ensureInventoryGroup(parent *InventoryGroup, name string) *InventoryGroup {
|
func ensureInventoryGroup(parent *InventoryGroup, name string) *InventoryGroup {
|
||||||
if parent == nil {
|
if parent == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,22 @@ func TestModulesAdv_ModuleUser_Good_ModifyExistingUser(t *testing.T) {
|
||||||
assert.True(t, mock.containsSubstring("-s /bin/zsh"))
|
assert.True(t, mock.containsSubstring("-s /bin/zsh"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestModulesAdv_ModuleUser_Good_GroupListInput(t *testing.T) {
|
||||||
|
e, mock := newTestExecutorWithMock("host1")
|
||||||
|
mock.expectCommand(`id deploy >/dev/null 2>&1`, "", "no such user", 1)
|
||||||
|
mock.expectCommand(`useradd`, "", "", 0)
|
||||||
|
|
||||||
|
result, err := moduleUserWithClient(e, mock, map[string]any{
|
||||||
|
"name": "deploy",
|
||||||
|
"groups": []any{"docker", "sudo"},
|
||||||
|
})
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, result.Changed)
|
||||||
|
assert.False(t, result.Failed)
|
||||||
|
assert.True(t, mock.containsSubstring("-G docker,sudo"))
|
||||||
|
}
|
||||||
|
|
||||||
func TestModulesAdv_ModuleUser_Good_RemoveUser(t *testing.T) {
|
func TestModulesAdv_ModuleUser_Good_RemoveUser(t *testing.T) {
|
||||||
e, mock := newTestExecutorWithMock("host1")
|
e, mock := newTestExecutorWithMock("host1")
|
||||||
mock.expectCommand(`userdel -r deploy`, "", "", 0)
|
mock.expectCommand(`userdel -r deploy`, "", "", 0)
|
||||||
|
|
|
||||||
|
|
@ -424,6 +424,19 @@ func TestModulesSvc_ModuleApt_Good_DefaultStateIsPresent(t *testing.T) {
|
||||||
assert.True(t, mock.hasExecuted(`apt-get install -y -qq vim`))
|
assert.True(t, mock.hasExecuted(`apt-get install -y -qq vim`))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestModulesSvc_ModuleApt_Good_InstallMultiplePackages(t *testing.T) {
|
||||||
|
e, mock := newTestExecutorWithMock("host1")
|
||||||
|
mock.expectCommand(`apt-get install -y -qq nginx curl`, "", "", 0)
|
||||||
|
|
||||||
|
result, err := moduleAptWithClient(e, mock, map[string]any{
|
||||||
|
"name": []any{"nginx", "curl"},
|
||||||
|
})
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, result.Changed)
|
||||||
|
assert.True(t, mock.hasExecuted(`apt-get install -y -qq nginx curl`))
|
||||||
|
}
|
||||||
|
|
||||||
// --- apt_key module ---
|
// --- apt_key module ---
|
||||||
|
|
||||||
func TestModulesSvc_ModuleAptKey_Good_AddWithKeyring(t *testing.T) {
|
func TestModulesSvc_ModuleAptKey_Good_AddWithKeyring(t *testing.T) {
|
||||||
|
|
@ -902,6 +915,19 @@ func TestModulesSvc_ModulePip_Good_DefaultStateIsPresent(t *testing.T) {
|
||||||
assert.True(t, mock.hasExecuted(`pip3 install django`))
|
assert.True(t, mock.hasExecuted(`pip3 install django`))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestModulesSvc_ModulePip_Good_InstallMultiplePackages(t *testing.T) {
|
||||||
|
e, mock := newTestExecutorWithMock("host1")
|
||||||
|
mock.expectCommand(`pip3 install requests flask`, "", "", 0)
|
||||||
|
|
||||||
|
result, err := modulePipWithClient(e, mock, map[string]any{
|
||||||
|
"name": []any{"requests", "flask"},
|
||||||
|
})
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, result.Changed)
|
||||||
|
assert.True(t, mock.hasExecuted(`pip3 install requests flask`))
|
||||||
|
}
|
||||||
|
|
||||||
func TestModulesSvc_ModulePip_Good_CommandFailure(t *testing.T) {
|
func TestModulesSvc_ModulePip_Good_CommandFailure(t *testing.T) {
|
||||||
e, mock := newTestExecutorWithMock("host1")
|
e, mock := newTestExecutorWithMock("host1")
|
||||||
mock.expectCommand(`pip3 install`, "", "ERROR: No matching distribution found", 1)
|
mock.expectCommand(`pip3 install`, "", "ERROR: No matching distribution found", 1)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue