Skip to content
This repository was archived by the owner on Feb 16, 2023. It is now read-only.

Commit 92ec851

Browse files
Merge pull request #246 from secrethub/feature/test-run-command
Add temporary tests to run command
2 parents d20ccf8 + 84158bb commit 92ec851

2 files changed

Lines changed: 298 additions & 3 deletions

File tree

internals/secrethub/run.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,14 +238,14 @@ func (cmd *RunCommand) Run() error {
238238
}
239239
}
240240

241-
maskedStdout := masker.NewMaskedWriter(os.Stdout, valuesToMask, maskString, cmd.maskingTimeout)
241+
maskedStdout := masker.NewMaskedWriter(cmd.io.Stdout(), valuesToMask, maskString, cmd.maskingTimeout)
242242
maskedStderr := masker.NewMaskedWriter(os.Stderr, valuesToMask, maskString, cmd.maskingTimeout)
243243

244244
command := exec.Command(cmd.command[0], cmd.command[1:]...)
245245
command.Env = append(passthroughEnv, mapToKeyValueStrings(environment)...)
246-
command.Stdin = os.Stdin
246+
command.Stdin = cmd.io.Stdin()
247247
if cmd.noMasking {
248-
command.Stdout = os.Stdout
248+
command.Stdout = cmd.io.Stdout()
249249
command.Stderr = os.Stderr
250250
} else {
251251
command.Stdout = maskedStdout

internals/secrethub/run_test.go

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@ package secrethub
22

33
import (
44
"errors"
5+
"io/ioutil"
6+
"log"
7+
"os"
8+
"path/filepath"
59
"strings"
610
"testing"
711

12+
"github.com/secrethub/secrethub-cli/internals/cli/ui"
13+
814
"github.com/secrethub/secrethub-cli/internals/secrethub/tpl"
915
"github.com/secrethub/secrethub-cli/internals/secrethub/tpl/fakes"
1016
generictpl "github.com/secrethub/secrethub-cli/internals/tpl"
@@ -458,6 +464,7 @@ func TestRunCommand_Run(t *testing.T) {
458464
}{
459465
"success, no secrets": {
460466
command: RunCommand{
467+
io: ui.NewFakeIO(),
461468
command: []string{"echo", "test"},
462469
},
463470
},
@@ -488,6 +495,7 @@ func TestRunCommand_Run(t *testing.T) {
488495
envar: map[string]string{
489496
"missing": "path/to/unexisting/secret",
490497
},
498+
io: ui.NewFakeIO(),
491499
newClient: func() (secrethub.ClientInterface, error) {
492500
return fakeclient.Client{
493501
SecretService: &fakeclient.SecretService{
@@ -509,6 +517,7 @@ func TestRunCommand_Run(t *testing.T) {
509517
envar: map[string]string{
510518
"missing": "unexisting/repo/secret",
511519
},
520+
io: ui.NewFakeIO(),
512521
newClient: func() (secrethub.ClientInterface, error) {
513522
return fakeclient.Client{
514523
SecretService: &fakeclient.SecretService{
@@ -548,6 +557,7 @@ func TestRunCommand_Run(t *testing.T) {
548557
command: RunCommand{
549558
osEnv: []string{"TEST=secrethub://nonexistent/secret/path"},
550559
command: []string{"echo", "test"},
560+
io: ui.NewFakeIO(),
551561
newClient: func() (secrethub.ClientInterface, error) {
552562
return fakeclient.Client{
553563
SecretService: &fakeclient.SecretService{
@@ -567,6 +577,7 @@ func TestRunCommand_Run(t *testing.T) {
567577
osEnv: []string{"TEST=secrethub://nonexistent/secret/path"},
568578
ignoreMissingSecrets: true,
569579
command: []string{"echo", "test"},
580+
io: ui.NewFakeIO(),
570581
newClient: func() (secrethub.ClientInterface, error) {
571582
return fakeclient.Client{
572583
SecretService: &fakeclient.SecretService{
@@ -590,6 +601,290 @@ func TestRunCommand_Run(t *testing.T) {
590601
}
591602
}
592603

604+
func TestRunCommand_RunWithFile(t *testing.T) {
605+
cases := map[string]struct {
606+
envFileContent string
607+
script string
608+
command RunCommand
609+
err error
610+
expectedStdOut string
611+
}{
612+
"invalid template syntax": {
613+
envFileContent: "TEST= {{ unexistent/secret/path }",
614+
command: RunCommand{
615+
command: []string{"echo", "test"},
616+
envFile: "secrethub.env",
617+
templateVersion: "2",
618+
},
619+
err: ErrParsingTemplate(os.TempDir()+"/secrethub.env", "template syntax error at 1:34: expected the closing of a secret tag `}}`, but reached the end of the template. (template.secret_tag_not_closed) "),
620+
},
621+
"env file secret does not exist": {
622+
envFileContent: "TEST= {{ unexistent/secret/path }}",
623+
command: RunCommand{
624+
command: []string{"echo", "test"},
625+
envFile: "secrethub.env",
626+
templateVersion: "2",
627+
newClient: func() (secrethub.ClientInterface, error) {
628+
return fakeclient.Client{
629+
SecretService: &fakeclient.SecretService{
630+
VersionService: &fakeclient.SecretVersionService{
631+
WithDataGetter: fakeclient.WithDataGetter{
632+
Err: api.ErrSecretNotFound,
633+
},
634+
},
635+
},
636+
}, nil
637+
},
638+
},
639+
err: ErrParsingTemplate(os.TempDir()+"/secrethub.env", api.ErrSecretNotFound),
640+
},
641+
"envar flag has precedence over env file": {
642+
envFileContent: "TEST=aaa",
643+
script: "echo $TEST",
644+
command: RunCommand{
645+
command: []string{"/bin/sh", "./test.sh"},
646+
noMasking: true,
647+
envFile: "secrethub.env",
648+
envar: map[string]string{
649+
"TEST": "test/test/test",
650+
},
651+
templateVersion: "2",
652+
newClient: func() (secrethub.ClientInterface, error) {
653+
return fakeclient.Client{
654+
SecretService: &fakeclient.SecretService{
655+
VersionService: &fakeclient.SecretVersionService{
656+
WithDataGetter: fakeclient.WithDataGetter{
657+
ReturnsVersion: &api.SecretVersion{Data: []byte("bbb")},
658+
},
659+
},
660+
},
661+
}, nil
662+
},
663+
},
664+
expectedStdOut: "bbb\n",
665+
},
666+
"--no-masking flag": {
667+
script: "echo $TEST",
668+
command: RunCommand{
669+
command: []string{"/bin/sh", "./test.sh"},
670+
noMasking: true,
671+
envFile: "secrethub.env",
672+
envar: map[string]string{
673+
"TEST": "test/test/test",
674+
},
675+
templateVersion: "2",
676+
newClient: func() (secrethub.ClientInterface, error) {
677+
return fakeclient.Client{
678+
SecretService: &fakeclient.SecretService{
679+
VersionService: &fakeclient.SecretVersionService{
680+
WithDataGetter: fakeclient.WithDataGetter{
681+
ReturnsVersion: &api.SecretVersion{Data: []byte("bbb")},
682+
},
683+
},
684+
},
685+
}, nil
686+
},
687+
},
688+
expectedStdOut: "bbb\n",
689+
},
690+
"secret masking": {
691+
script: "echo $TEST",
692+
command: RunCommand{
693+
command: []string{"/bin/sh", "./test.sh"},
694+
envFile: "secrethub.env",
695+
envar: map[string]string{
696+
"TEST": "test/test/test",
697+
},
698+
templateVersion: "2",
699+
newClient: func() (secrethub.ClientInterface, error) {
700+
return fakeclient.Client{
701+
SecretService: &fakeclient.SecretService{
702+
VersionService: &fakeclient.SecretVersionService{
703+
WithDataGetter: fakeclient.WithDataGetter{
704+
ReturnsVersion: &api.SecretVersion{Data: []byte("bbb")},
705+
},
706+
},
707+
},
708+
}, nil
709+
},
710+
},
711+
expectedStdOut: maskString + "\n",
712+
},
713+
"ignore missing secrets": {
714+
script: "echo $TEST",
715+
command: RunCommand{
716+
command: []string{"/bin/sh", "./test.sh"},
717+
noMasking: true,
718+
ignoreMissingSecrets: true,
719+
envFile: "secrethub.env",
720+
envar: map[string]string{
721+
"TEST": "test/test/test",
722+
},
723+
templateVersion: "2",
724+
newClient: func() (secrethub.ClientInterface, error) {
725+
return fakeclient.Client{
726+
SecretService: &fakeclient.SecretService{
727+
VersionService: &fakeclient.SecretVersionService{
728+
WithDataGetter: fakeclient.WithDataGetter{
729+
Err: api.ErrSecretNotFound,
730+
},
731+
},
732+
},
733+
}, nil
734+
},
735+
},
736+
expectedStdOut: "\n",
737+
},
738+
"--no-prompt": {
739+
script: "echo $TEST",
740+
envFileContent: "TEST = {{ test/$variable/test }}",
741+
command: RunCommand{
742+
command: []string{"/bin/sh", "./test.sh"},
743+
noMasking: true,
744+
dontPromptMissingTemplateVar: true,
745+
envFile: "secrethub.env",
746+
templateVersion: "2",
747+
newClient: func() (secrethub.ClientInterface, error) {
748+
return fakeclient.Client{
749+
SecretService: &fakeclient.SecretService{
750+
VersionService: &fakeclient.SecretVersionService{
751+
WithDataGetter: fakeclient.WithDataGetter{
752+
Err: api.ErrSecretNotFound,
753+
},
754+
},
755+
},
756+
}, nil
757+
},
758+
},
759+
err: ErrParsingTemplate(os.TempDir()+"/secrethub.env", tpl.ErrTemplateVarNotFound("variable")),
760+
},
761+
"template var set in os environment": {
762+
script: "echo $TEST",
763+
envFileContent: "TEST = {{ test/$variable/test }}",
764+
command: RunCommand{
765+
command: []string{"/bin/sh", "./test.sh"},
766+
noMasking: true,
767+
dontPromptMissingTemplateVar: true,
768+
envFile: "secrethub.env",
769+
templateVersion: "2",
770+
osEnv: []string{"SECRETHUB_VAR_VARIABLE=test"},
771+
newClient: func() (secrethub.ClientInterface, error) {
772+
return fakeclient.Client{
773+
SecretService: &fakeclient.SecretService{
774+
VersionService: &fakeclient.SecretVersionService{
775+
WithDataGetter: fakeclient.WithDataGetter{
776+
Err: api.ErrSecretNotFound,
777+
},
778+
},
779+
},
780+
}, nil
781+
},
782+
},
783+
err: ErrParsingTemplate(os.TempDir()+"/secrethub.env", api.ErrSecretNotFound),
784+
},
785+
"template var set by flag": {
786+
script: "echo $TEST",
787+
envFileContent: "TEST = {{ test/$variable/test }}",
788+
command: RunCommand{
789+
command: []string{"/bin/sh", "./test.sh"},
790+
noMasking: true,
791+
dontPromptMissingTemplateVar: true,
792+
envFile: "secrethub.env",
793+
templateVersion: "2",
794+
templateVars: map[string]string{"variable": "test"},
795+
newClient: func() (secrethub.ClientInterface, error) {
796+
return fakeclient.Client{
797+
SecretService: &fakeclient.SecretService{
798+
VersionService: &fakeclient.SecretVersionService{
799+
WithDataGetter: fakeclient.WithDataGetter{
800+
Err: api.ErrSecretNotFound,
801+
},
802+
},
803+
},
804+
}, nil
805+
},
806+
},
807+
err: ErrParsingTemplate(os.TempDir()+"/secrethub.env", api.ErrSecretNotFound),
808+
},
809+
"secret reference has priority over .env file": {
810+
script: "echo $TEST",
811+
envFileContent: "TEST=aaa",
812+
command: RunCommand{
813+
command: []string{"/bin/sh", "./test.sh"},
814+
noMasking: true,
815+
dontPromptMissingTemplateVar: true,
816+
envFile: "secrethub.env",
817+
templateVersion: "2",
818+
osEnv: []string{"TEST=secrethub://test/test/test"},
819+
newClient: func() (secrethub.ClientInterface, error) {
820+
return fakeclient.Client{
821+
SecretService: &fakeclient.SecretService{
822+
VersionService: &fakeclient.SecretVersionService{
823+
WithDataGetter: fakeclient.WithDataGetter{
824+
ReturnsVersion: &api.SecretVersion{Data: []byte("bbb")},
825+
},
826+
},
827+
},
828+
}, nil
829+
},
830+
},
831+
expectedStdOut: "bbb\n",
832+
},
833+
"v1 template syntax success": {
834+
envFileContent: "TEST= ${path/to/secret}",
835+
script: "echo $TEST",
836+
command: RunCommand{
837+
command: []string{"/bin/sh", "./test.sh"},
838+
noMasking: true,
839+
envFile: "secrethub.env",
840+
templateVersion: "1",
841+
newClient: func() (secrethub.ClientInterface, error) {
842+
return fakeclient.Client{
843+
SecretService: &fakeclient.SecretService{
844+
VersionService: &fakeclient.SecretVersionService{
845+
WithDataGetter: fakeclient.WithDataGetter{
846+
ReturnsVersion: &api.SecretVersion{Data: []byte("bbb")},
847+
},
848+
},
849+
},
850+
}, nil
851+
},
852+
},
853+
expectedStdOut: "bbb\n",
854+
},
855+
}
856+
857+
for name, tc := range cases {
858+
t.Run(name, func(t *testing.T) {
859+
envFile := filepath.Join(os.TempDir(), tc.command.envFile)
860+
err := ioutil.WriteFile(envFile, []byte(tc.envFileContent), os.ModePerm)
861+
if err != nil {
862+
log.Fatal("Cannot create file for test", err)
863+
}
864+
defer os.Remove(envFile)
865+
866+
if tc.script != "" {
867+
scriptFile := filepath.Join(os.TempDir(), tc.command.command[1])
868+
err = ioutil.WriteFile(scriptFile, []byte(tc.script), os.ModePerm)
869+
if err != nil {
870+
log.Fatal("Cannot create file for test", err)
871+
}
872+
tc.command.command[1] = scriptFile
873+
defer os.Remove(scriptFile)
874+
}
875+
876+
fakeIO := ui.NewFakeIO()
877+
tc.command.io = fakeIO
878+
879+
tc.command.envFile = envFile
880+
881+
err = tc.command.Run()
882+
assert.Equal(t, err, tc.err)
883+
assert.Equal(t, fakeIO.StdOut.String(), tc.expectedStdOut)
884+
})
885+
}
886+
}
887+
593888
func TestTrimQuotes(t *testing.T) {
594889
cases := map[string]struct {
595890
in string

0 commit comments

Comments
 (0)