chore: cmd test cleanup (#1289)

All tests which are directory-sensitive now also:
- reset viper
- use t.Cleanup
- use t.TempDir
- use a clean XDG_CONFIG_HOME
- specify explict name when creating
- moves helpers to root_test
This commit is contained in:
Luke Kingland 2022-10-03 12:03:28 -10:00 committed by GitHub
parent dc14ec7753
commit c9861ec24e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 168 additions and 198 deletions

View File

@ -6,7 +6,6 @@ import (
fn "knative.dev/kn-plugin-func"
"knative.dev/kn-plugin-func/mock"
. "knative.dev/kn-plugin-func/testing"
)
// TestBuild_ImageFlag ensures that the image flag is used when specified.
@ -15,9 +14,7 @@ func TestBuild_ImageFlag(t *testing.T) {
args = []string{"--image", "docker.io/tigerteam/foo"}
builder = mock.NewBuilder()
)
root, cleanup := Mktemp(t)
defer cleanup()
root := fromTempDirectory(t)
if err := fn.New().Create(fn.Function{Runtime: "go", Root: root, Registry: TestRegistry}); err != nil {
t.Fatal(err)
@ -48,9 +45,7 @@ func TestBuild_ImageFlag(t *testing.T) {
// provided (or exist on the function already), and the client has not been
// instantiated with a default registry, an ErrRegistryRequired is received.
func TestBuild_RegistryOrImageRequired(t *testing.T) {
t.Helper()
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
if err := fn.New().Create(fn.Function{Runtime: "go", Root: root}); err != nil {
t.Fatal(err)
@ -106,8 +101,7 @@ func TestBuild_BuilderValidated(t *testing.T) {
// - Push not triggered after an unsuccessful build
// - Push can be disabled
func TestBuild_Push(t *testing.T) {
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
f := fn.Function{
Root: root,

View File

@ -14,7 +14,6 @@ import (
)
func TestListEnvs(t *testing.T) {
mock := newMockLoaderSaver()
foo := "foo"
bar := "bar"

View File

@ -5,17 +5,16 @@ import (
"path/filepath"
"testing"
. "knative.dev/kn-plugin-func/testing"
"knative.dev/kn-plugin-func/utils"
)
// TestCreate_Execute ensures that an invocation of create with minimal settings
// and valid input completes without error; degenerate case.
func TestCreate_Execute(t *testing.T) {
defer Fromtemp(t)()
_ = fromTempDirectory(t)
cmd := NewCreateCmd(NewClient)
cmd.SetArgs([]string{"--language", "go"})
cmd.SetArgs([]string{"--language", "go", "myfunc"})
if err := cmd.Execute(); err != nil {
t.Fatal(err)
@ -25,10 +24,10 @@ func TestCreate_Execute(t *testing.T) {
// TestCreate_NoRuntime ensures that an invocation of create must be
// done with a runtime.
func TestCreate_NoRuntime(t *testing.T) {
defer Fromtemp(t)()
_ = fromTempDirectory(t)
cmd := NewCreateCmd(NewClient)
cmd.SetArgs([]string{}) // Do not use test command args
cmd.SetArgs([]string{"myfunc"}) // Do not use test command args
err := cmd.Execute()
var e ErrNoRuntime
@ -40,10 +39,10 @@ func TestCreate_NoRuntime(t *testing.T) {
// TestCreate_WithNoRuntime ensures that an invocation of create must be
// done with one of the valid runtimes only.
func TestCreate_WithInvalidRuntime(t *testing.T) {
defer Fromtemp(t)()
_ = fromTempDirectory(t)
cmd := NewCreateCmd(NewClient)
cmd.SetArgs([]string{"--language", "invalid"})
cmd.SetArgs([]string{"--language", "invalid", "myfunc"})
err := cmd.Execute()
var e ErrInvalidRuntime
@ -55,10 +54,10 @@ func TestCreate_WithInvalidRuntime(t *testing.T) {
// TestCreate_InvalidTemplate ensures that an invocation of create must be
// done with one of the valid templates only.
func TestCreate_InvalidTemplate(t *testing.T) {
defer Fromtemp(t)()
_ = fromTempDirectory(t)
cmd := NewCreateCmd(NewClient)
cmd.SetArgs([]string{"--language", "go", "--template", "invalid"})
cmd.SetArgs([]string{"--language", "go", "--template", "invalid", "myfunc"})
err := cmd.Execute()
var e ErrInvalidTemplate
@ -70,7 +69,7 @@ func TestCreate_InvalidTemplate(t *testing.T) {
// TestCreate_ValidatesName ensures that the create command only accepts
// DNS-1123 labels for function name.
func TestCreate_ValidatesName(t *testing.T) {
defer Fromtemp(t)()
_ = fromTempDirectory(t)
// Execute the command with a function name containing invalid characters and
// confirm the expected error is returned
@ -87,9 +86,10 @@ func TestCreate_ValidatesName(t *testing.T) {
// the expected repositories path, respecting the setting for XDG_CONFIG_PATH
// when deriving the default
func TestCreateConfig_RepositoriesPath(t *testing.T) {
defer Fromtemp(t)()
_ = fromTempDirectory(t)
// Update XDG_CONFIG_HOME to point to some arbitrary location.
// Update XDG_CONFIG_HOME to point to some arbitrary location which we know
// The above call to fromTempDirectory also updates, but value is not returned.
xdgConfigHome := t.TempDir()
t.Setenv("XDG_CONFIG_HOME", xdgConfigHome)
@ -97,7 +97,7 @@ func TestCreateConfig_RepositoriesPath(t *testing.T) {
expected := filepath.Join(xdgConfigHome, "func", "repositories")
cmd := NewCreateCmd(NewClient)
cmd.SetArgs([]string{}) // Do not use test command args
cmd.SetArgs([]string{"myfunc"}) // Do not use test command args
cfg, err := newCreateConfig(cmd, []string{}, NewClient)
if err != nil {
t.Fatal(err)
@ -111,19 +111,12 @@ func TestCreateConfig_RepositoriesPath(t *testing.T) {
// TestCreate_ConfigOptional ensures that the system can be used without
// any additional configuration being required.
func TestCreate_ConfigOptional(t *testing.T) {
// Empty Home
// the func directory, and other static assets will be created here
// if they do not exist.
home, rm := Mktemp(t)
defer rm()
t.Setenv("XDG_CONFIG_HOME", home)
_ = fromTempDirectory(t)
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
// Immediately using "create" in a new empty directory should not fail;
// even when this home directory is devoid of config files.
_, rm2 := Mktemp(t)
defer rm2()
cmd := NewCreateCmd(NewClient)
cmd.SetArgs([]string{"--language=go"})
cmd.SetArgs([]string{"--language=go", "myfunc"})
if err := cmd.Execute(); err != nil {
t.Fatal(err)
}

View File

@ -6,7 +6,6 @@ import (
fn "knative.dev/kn-plugin-func"
"knative.dev/kn-plugin-func/mock"
. "knative.dev/kn-plugin-func/testing"
)
// TestDelete_ByName ensures that running delete specifying the name of the
@ -46,8 +45,7 @@ func TestDelete_ByName(t *testing.T) {
// TestDelete_ByProject ensures that running delete with a valid project as its
// context invokes remove and with the correct name (reads name from func.yaml)
func TestDelete_ByProject(t *testing.T) {
// from within a new temporary directory
defer Fromtemp(t)()
_ = fromTempDirectory(t)
// Write a func.yaml config which specifies a name
funcYaml := `name: bar

View File

@ -14,7 +14,6 @@ import (
fn "knative.dev/kn-plugin-func"
"knative.dev/kn-plugin-func/builders"
"knative.dev/kn-plugin-func/mock"
. "knative.dev/kn-plugin-func/testing"
)
const TestRegistry = "example.com/alice"
@ -24,8 +23,7 @@ type commandConstructor func(ClientFactory) *cobra.Command
// TestDeploy_Default ensures that running deploy on a valid default Function
// (only required options populated; all else default) completes successfully.
func TestDeploy_Default(t *testing.T) {
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
// A Function with the minimum required values for deployment populated.
f := fn.Function{
@ -57,8 +55,7 @@ func TestDeploy_RegistryOrImageRequired(t *testing.T) {
func testRegistryOrImageRequired(cmdFn commandConstructor, t *testing.T) {
t.Helper()
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
if err := fn.New().Create(fn.Function{Runtime: "go", Root: root}); err != nil {
t.Fatal(err)
@ -95,8 +92,7 @@ func TestDeploy_ImageAndRegistry(t *testing.T) {
func testImageAndRegistry(cmdFn commandConstructor, t *testing.T) {
t.Helper()
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
if err := fn.New().Create(fn.Function{Runtime: "go", Root: root}); err != nil {
t.Fatal(err)
@ -171,8 +167,7 @@ func TestDeploy_InvalidRegistry(t *testing.T) {
func testInvalidRegistry(cmdFn commandConstructor, t *testing.T) {
t.Helper()
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
f := fn.Function{
Root: root,
@ -204,8 +199,7 @@ func TestDeploy_RegistryLoads(t *testing.T) {
func testRegistryLoads(cmdFn commandConstructor, t *testing.T) {
t.Helper()
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
f := fn.Function{
Root: root,
@ -246,11 +240,9 @@ func TestDeploy_BuilderPersists(t *testing.T) {
}
func testBuilderPersists(cmdFn commandConstructor, t *testing.T) {
t.Setenv("KUBECONFIG", fmt.Sprintf("%s/testdata/kubeconfig_deploy_namespace", cwd()))
t.Helper()
root, rm := Mktemp(t)
defer rm()
t.Setenv("KUBECONFIG", fmt.Sprintf("%s/testdata/kubeconfig_deploy_namespace", cwd()))
root := fromTempDirectory(t)
if err := fn.New().Create(fn.Function{Runtime: "go", Root: root}); err != nil {
t.Fatal(err)
@ -340,8 +332,7 @@ func TestDeploy_BuilderValidated(t *testing.T) {
func testBuilderValidated(cmdFn commandConstructor, t *testing.T) {
t.Helper()
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
if err := fn.New().Create(fn.Function{Runtime: "go", Root: root}); err != nil {
t.Fatal(err)
@ -406,8 +397,7 @@ func TestDeploy_RemoteBuildURLPermutations(t *testing.T) {
// returns a single test function for one possible permutation of the flags.
newTestFn := func(remote, build, url string) func(t *testing.T) {
return func(t *testing.T) {
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
// Create a new Function in the temp directory
if err := fn.New().Create(fn.Function{Runtime: "go", Root: root}); err != nil {
@ -580,8 +570,7 @@ func Test_ImageWithDigestErrors(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Move into a new temp directory
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
// Create a new Function in the temp directory
if err := fn.New().Create(fn.Function{Runtime: "go", Root: root}); err != nil {
@ -677,8 +666,7 @@ func Test_namespace(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
t.Helper()
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
// if running with an active kubeconfig
if test.context {
@ -736,8 +724,7 @@ Test_namespaceCheck cases were refactored into:
// TestDeploy_GitArgsPersist ensures that the git flags, if provided, are
// persisted to the Function for subsequent deployments.
func TestDeploy_GitArgsPersist(t *testing.T) {
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
var (
url = "https://example.com/user/repo"
@ -778,8 +765,7 @@ func TestDeploy_GitArgsPersist(t *testing.T) {
// TestDeploy_GitArgsUsed ensures that any git values provided as flags are used
// when invoking a remote deployment.
func TestDeploy_GitArgsUsed(t *testing.T) {
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
var (
url = "https://example.com/user/repo"
@ -821,8 +807,7 @@ func TestDeploy_GitArgsUsed(t *testing.T) {
// TestDeploy_GitURLBranch ensures that a --git-url which specifies the branch
// in the URL is equivalent to providing --git-branch
func TestDeploy_GitURLBranch(t *testing.T) {
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
if err := fn.New().Create(fn.Function{Runtime: "go", Root: root}); err != nil {
t.Fatal(err)
@ -861,12 +846,8 @@ func TestDeploy_GitURLBranch(t *testing.T) {
// TestDeploy_NamespaceDefaults ensures that when not specified, a users's
// active kubernetes context is used for the namespace if available.
func TestDeploy_NamespaceDefaults(t *testing.T) {
// Set kube context to test context
t.Setenv("KUBECONFIG", filepath.Join(cwd(), "testdata", "kubeconfig_deploy_namespace"))
// from a temp directory
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
// Create a new function
if err := fn.New().Create(fn.Function{Runtime: "go", Root: root}); err != nil {
@ -913,8 +894,7 @@ func TestDeploy_NamespaceDefaults(t *testing.T) {
// Also implicitly checks that the --namespace flag takes precidence over
// the namespace of a previously deployed Function.
func TestDeploy_NamespaceUpdateWarning(t *testing.T) {
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
// Create a Function which appears to have been deployed to 'myns'
f := fn.Function{
@ -975,10 +955,7 @@ func TestDeploy_NamespaceUpdateWarning(t *testing.T) {
func TestDeploy_NamespaceRedeployWarning(t *testing.T) {
// Change profile to one whose current profile is 'test-ns-deploy'
t.Setenv("KUBECONFIG", filepath.Join(cwd(), "testdata", "kubeconfig_deploy_namespace"))
// From within a temp directory
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
// Create a Function which appears to have been deployed to 'myns'
f := fn.Function{

View File

@ -12,13 +12,11 @@ import (
fn "knative.dev/kn-plugin-func"
"knative.dev/kn-plugin-func/mock"
. "knative.dev/kn-plugin-func/testing"
)
// TestInvoke command executes the invocation path.
func TestInvoke(t *testing.T) {
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
var invoked int32
@ -78,8 +76,7 @@ func TestInvoke(t *testing.T) {
// TestInvoke_Namespace ensures that invocation uses the Function's namespace
// despite the currently active.
func TestInvoke_Namespace(t *testing.T) {
root, rm := Mktemp(t)
defer rm()
root := fromTempDirectory(t)
// Create a Function in a non-active namespace
f := fn.Function{Runtime: "go", Root: root, Deploy: fn.DeploySpec{Namespace: "ns"}}

View File

@ -10,8 +10,9 @@ import (
// all supported languages is to print a plain text list of all the builtin
// language runtimes.
func TestLanguages_Default(t *testing.T) {
t.Setenv("XDG_CONFIG_HOME", t.TempDir()) // ignore user-added
buf := piped(t) // gather output
_ = fromTempDirectory(t)
buf := piped(t) // gather output
cmd := NewLanguagesCmd(NewClientFactory(func() *fn.Client {
return fn.New()
}))
@ -35,8 +36,9 @@ typescript`
// TestLanguages_JSON ensures that listing languages in --json format returns
// builtin languages as a JSON array.
func TestLanguages_JSON(t *testing.T) {
t.Setenv("XDG_CONFIG_HOME", t.TempDir()) // ignore user-added
buf := piped(t) // gather output
_ = fromTempDirectory(t)
buf := piped(t) // gather output
cmd := NewLanguagesCmd(NewClientFactory(func() *fn.Client {
return fn.New()
}))

View File

@ -1,9 +1,6 @@
package cmd
import (
"io"
"os"
"strings"
"testing"
. "knative.dev/kn-plugin-func/testing"
@ -13,7 +10,8 @@ import (
// set of repositories by name for builtin repositories, by explicitly
// setting the repositories' path to a new path which includes no others.
func TestRepository_List(t *testing.T) {
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
_ = fromTempDirectory(t)
cmd := NewRepositoryListCmd(NewClient)
cmd.SetArgs([]string{}) // Do not use test command args
@ -35,7 +33,9 @@ func TestRepository_List(t *testing.T) {
// arguments, respects the repositories' path flag, and the expected name is echoed
// upon subsequent 'list'.
func TestRepository_Add(t *testing.T) {
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
url := ServeRepo("repository.git", t)
_ = fromTempDirectory(t)
var (
add = NewRepositoryAddCmd(NewClient)
list = NewRepositoryListCmd(NewClient)
@ -48,7 +48,7 @@ func TestRepository_Add(t *testing.T) {
// add [flags] <old> <new>
add.SetArgs([]string{
"newrepo",
TestRepoURI("repository", t),
url,
})
// Parse flags and args, performing action
@ -73,7 +73,9 @@ func TestRepository_Add(t *testing.T) {
// positional arguments, respects the repositories' path flag, and the name is
// reflected as having been renamed upon subsequent 'list'.
func TestRepository_Rename(t *testing.T) {
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
url := ServeRepo("repository.git", t)
_ = fromTempDirectory(t)
var (
add = NewRepositoryAddCmd(NewClient)
rename = NewRepositoryRenameCmd(NewClient)
@ -86,7 +88,7 @@ func TestRepository_Rename(t *testing.T) {
list.SetArgs([]string{})
// add a repo which will be renamed
add.SetArgs([]string{"newrepo", TestRepoURI("repository", t)})
add.SetArgs([]string{"newrepo", url})
if err := add.Execute(); err != nil {
t.Fatal(err)
}
@ -119,7 +121,9 @@ func TestRepository_Rename(t *testing.T) {
// its argument, respects the repositories' flag, and the entry is removed upon
// subsequent 'list'.
func TestRepository_Remove(t *testing.T) {
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
url := ServeRepo("repository.git", t)
_ = fromTempDirectory(t)
var (
add = NewRepositoryAddCmd(NewClient)
remove = NewRepositoryRemoveCmd(NewClient)
@ -132,7 +136,7 @@ func TestRepository_Remove(t *testing.T) {
list.SetArgs([]string{})
// add a repo which will be removed
add.SetArgs([]string{"newrepo", TestRepoURI("repository", t)})
add.SetArgs([]string{"newrepo", url})
if err := add.Execute(); err != nil {
t.Fatal(err)
}
@ -159,42 +163,3 @@ func TestRepository_Remove(t *testing.T) {
t.Fatalf("expected:\n'%v'\ngot:\n'%v'\n", expect, output)
}
}
// Helpers
// -------
// pipe the output of stdout to a buffer whose value is returned
// from the returned function. Call pipe() to start piping output
// to the buffer, call the returned function to access the data in
// the buffer.
func piped(t *testing.T) func() string {
t.Helper()
var (
o = os.Stdout
c = make(chan error, 1)
b strings.Builder
)
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
os.Stdout = w
go func() {
_, err := io.Copy(&b, r)
r.Close()
c <- err
}()
return func() string {
os.Stdout = o
w.Close()
err := <-c
if err != nil {
t.Fatal(err)
}
return strings.TrimSpace(b.String())
}
}

View File

@ -3,6 +3,8 @@ package cmd
import (
"bytes"
"fmt"
"io"
"os"
"reflect"
"strings"
"testing"
@ -37,10 +39,11 @@ func TestRoot_PersistentFlags(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer Fromtemp(t)() // from a temp dir, deferred cleanup
cmd := NewCreateCmd(NewClient) // Create a new function
cmd.SetArgs([]string{"--language", "go"}) // providing language (the only required param)
if err := cmd.Execute(); err != nil { // fail on any errors
_ = fromTempDirectory(t)
cmd := NewCreateCmd(NewClient) // Create a function
cmd.SetArgs([]string{"--language", "go", "myfunc"}) // providing language
if err := cmd.Execute(); err != nil { // fail on any errors
t.Fatal(err)
}
@ -252,3 +255,55 @@ func TestVerbose(t *testing.T) {
})
}
}
// Helpers
// -------
// pipe the output of stdout to a buffer whose value is returned
// from the returned function. Call pipe() to start piping output
// to the buffer, call the returned function to access the data in
// the buffer.
func piped(t *testing.T) func() string {
t.Helper()
var (
o = os.Stdout
c = make(chan error, 1)
b strings.Builder
)
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
os.Stdout = w
go func() {
_, err := io.Copy(&b, r)
r.Close()
c <- err
}()
return func() string {
os.Stdout = o
w.Close()
err := <-c
if err != nil {
t.Fatal(err)
}
return strings.TrimSpace(b.String())
}
}
// fromTempDirectory is a cli-specific test helper which
// - creates a temp directory and changes to it as the new working directory
// - creates a temp directory and uses it for XDG_CONFIG_HOME
// - removes temp directories on cleanup
// - resets viper on cleanum (the reason this is "cli-specific")
func fromTempDirectory(t *testing.T) string {
t.Helper()
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
d, done := Mktemp(t) // creates and CDs to 'tmp'
t.Cleanup(func() { done(); viper.Reset() })
return d
}

View File

@ -8,7 +8,6 @@ import (
fn "knative.dev/kn-plugin-func"
"knative.dev/kn-plugin-func/mock"
. "knative.dev/kn-plugin-func/testing"
)
func TestRun_Run(t *testing.T) {
@ -100,7 +99,7 @@ created: 2009-11-10 23:00:00`,
for _, tt := range tests {
// run as a sub-test
t.Run(tt.name, func(t *testing.T) {
defer Fromtemp(t)()
_ = fromTempDirectory(t)
runner := mock.NewRunner()
if tt.runError != nil {

View File

@ -12,8 +12,9 @@ import (
// TestTemplates_Default ensures that the default behavior is listing all
// templates for all language runtimes.
func TestTemplates_Default(t *testing.T) {
t.Setenv("XDG_CONFIG_HOME", t.TempDir()) // ignore user-added
buf := piped(t) // gather output
_ = fromTempDirectory(t)
buf := piped(t) // gather output
cmd := NewTemplatesCmd(NewClientFactory(func() *fn.Client {
return fn.New()
}))
@ -45,8 +46,9 @@ typescript http`
// TestTemplates_JSON ensures that listing templates respects the --json
// output format.
func TestTemplates_JSON(t *testing.T) {
t.Setenv("XDG_CONFIG_HOME", t.TempDir()) // ignore user-added
buf := piped(t) // gather output
_ = fromTempDirectory(t)
buf := piped(t) // gather output
cmd := NewTemplatesCmd(NewClientFactory(func() *fn.Client {
return fn.New()
}))
@ -104,7 +106,8 @@ func TestTemplates_JSON(t *testing.T) {
// TestTemplates_ByLanguage ensures that the output is correctly filtered
// by language runtime when provided.
func TestTemplates_ByLanguage(t *testing.T) {
t.Setenv("XDG_CONFIG_HOME", t.TempDir()) // ignore user-added
_ = fromTempDirectory(t)
cmd := NewTemplatesCmd(NewClientFactory(func() *fn.Client {
return fn.New()
}))
@ -144,7 +147,8 @@ http`
}
func TestTemplates_ErrTemplateRepoDoesNotExist(t *testing.T) {
defer t.Setenv("XDG_CONFIG_HOME", t.TempDir())
_ = fromTempDirectory(t)
cmd := NewTemplatesCmd(NewClientFactory(func() *fn.Client {
return fn.New()
}))
@ -155,7 +159,8 @@ func TestTemplates_ErrTemplateRepoDoesNotExist(t *testing.T) {
}
func TestTemplates_WrongRepositoryUrl(t *testing.T) {
defer t.Setenv("XDG_CONFIG_HOME", t.TempDir())
_ = fromTempDirectory(t)
cmd := NewTemplatesCmd(NewClientFactory(func() *fn.Client {
return fn.New()
}))

View File

@ -18,7 +18,7 @@ import (
// test. Others do eist with specific test requirements that are mutually
// exclusive, such as manifest differences, and are specified inline to their
// requisite test.
const RepositoriesTestRepo = "repository"
const RepositoriesTestRepo = "repository.git"
// TestRepositories_List ensures the base case of listing
// repositories without error in the default scenario of builtin only.
@ -69,7 +69,7 @@ func TestRepositories_Get(t *testing.T) {
// TestRepositories_All ensures repos are returned from
// .All accessor. Tests both builtin and buitlin+extensible cases.
func TestRepositories_All(t *testing.T) {
uri := TestRepoURI(RepositoriesTestRepo, t)
uri := ServeRepo(RepositoriesTestRepo, t)
root, rm := Mktemp(t)
defer rm()
@ -99,15 +99,15 @@ func TestRepositories_All(t *testing.T) {
// Assert it now includes both builtin and extended
if len(repositories) != 2 ||
repositories[0].Name != fn.DefaultRepositoryName ||
repositories[1].Name != RepositoriesTestRepo {
repositories[1].Name != "repository" {
t.Fatal("Repositories list does not pass shallow repository membership check")
}
}
// TestRepositories_Add checks basic adding of a repository by URI.
func TestRepositories_Add(t *testing.T) {
uri := TestRepoURI(RepositoriesTestRepo, t) // ./testdata/$RepositoriesTestRepo.git
root, rm := Mktemp(t) // create and cd to a temp dir, returning path.
uri := ServeRepo(RepositoriesTestRepo, t) // ./testdata/$RepositoriesTestRepo.git
root, rm := Mktemp(t) // create and cd to a temp dir, returning path.
defer rm()
// Instantiate the client using the current temp directory as the
@ -144,7 +144,7 @@ func TestRepositories_AddDeafultName(t *testing.T) {
// repo meant to exemplify the simplest use case: a repo with no metadata
// that simply contains templates, grouped by runtime. It therefore does
// not have a manifest and the default name will therefore be the repo name
uri := TestRepoURI(RepositoriesTestRepo, t) // ./testdata/$RepositoriesTestRepo.git
uri := ServeRepo(RepositoriesTestRepo, t) // ./testdata/$RepositoriesTestRepo.git
root, rm := Mktemp(t)
defer rm()
@ -156,7 +156,7 @@ func TestRepositories_AddDeafultName(t *testing.T) {
}
// The name returned should be the repo name
if name != RepositoriesTestRepo {
if name != "repository" {
t.Fatalf("expected returned name '%v', got '%v'", RepositoriesTestRepo, name)
}
@ -165,7 +165,7 @@ func TestRepositories_AddDeafultName(t *testing.T) {
if err != nil {
t.Fatal(err)
}
expected := []string{"default", RepositoriesTestRepo}
expected := []string{"default", "repository"}
if diff := cmp.Diff(expected, rr); diff != "" {
t.Error("Repositories differed (-want, +got):", diff)
}
@ -179,7 +179,7 @@ func TestRepositories_AddWithManifest(t *testing.T) {
// defines a custom language pack and makes full use of the manifest.yaml.
// The manifest.yaml is included which specifies things like custom templates
// location and (appropos to this test) a default name/
uri := TestRepoURI("repository-a", t) // ./testdata/repository-a.git
uri := ServeRepo("repository-a", t) // ./testdata/repository-a.git
root, rm := Mktemp(t)
defer rm()
@ -210,7 +210,7 @@ func TestRepositories_AddWithManifest(t *testing.T) {
// TestRepositories_AddExistingErrors ensures that adding a repository that
// already exists yields an error.
func TestRepositories_AddExistingErrors(t *testing.T) {
uri := TestRepoURI(RepositoriesTestRepo, t)
uri := ServeRepo(RepositoriesTestRepo, t)
root, rm := Mktemp(t) // create and cd to a temp dir, returning path.
defer rm()
@ -244,7 +244,7 @@ func TestRepositories_AddExistingErrors(t *testing.T) {
// TestRepositories_Rename ensures renaming a repository succeeds.
func TestRepositories_Rename(t *testing.T) {
uri := TestRepoURI(RepositoriesTestRepo, t)
uri := ServeRepo(RepositoriesTestRepo, t)
root, rm := Mktemp(t) // create and cd to a temp dir, returning path.
defer rm()
@ -278,8 +278,8 @@ func TestRepositories_Rename(t *testing.T) {
// TestRepositories_Remove ensures that removing a repository by name
// removes it from the list and FS.
func TestRepositories_Remove(t *testing.T) {
uri := TestRepoURI(RepositoriesTestRepo, t) // ./testdata/repository.git
root, rm := Mktemp(t) // create and cd to a temp dir
uri := ServeRepo(RepositoriesTestRepo, t) // ./testdata/repository.git
root, rm := Mktemp(t) // create and cd to a temp dir
defer rm()
// Instantiate the client using the current temp directory as the
@ -313,7 +313,7 @@ func TestRepositories_Remove(t *testing.T) {
// TestRepositories_URL ensures that a repository populates its URL member
// from the git repository's origin url (if it is a git repo and exists)
func TestRepositories_URL(t *testing.T) {
uri := TestRepoURI(RepositoriesTestRepo, t)
uri := ServeRepo(RepositoriesTestRepo, t)
root, rm := Mktemp(t)
defer rm()

View File

@ -163,7 +163,7 @@ func TestTemplates_Remote(t *testing.T) {
root := "testdata/testTemplatesRemote"
defer Using(t, root)()
url := TestRepoURI(RepositoriesTestRepo, t)
url := ServeRepo(RepositoriesTestRepo, t)
// Create a client which explicitly specifies the Git repo at URL
// rather than relying on the default internally builtin template repo
@ -328,7 +328,7 @@ func TestTemplates_ModeRemote(t *testing.T) {
root := "testdata/testTemplates_ModeRemote"
defer Using(t, root)()
url := TestRepoURI(RepositoriesTestRepo, t)
url := ServeRepo(RepositoriesTestRepo, t)
client := fn.New(
fn.WithRegistry(TestRegistry),

View File

@ -82,11 +82,10 @@ func Within(t *testing.T, root string) func() {
// errors encountererd fail the current test.
func Mktemp(t *testing.T) (string, func()) {
t.Helper()
tmp := tempdir(t)
tmp := t.TempDir()
owd := pwd(t)
cd(t, tmp)
return tmp, func() {
os.RemoveAll(tmp)
cd(t, owd)
}
}
@ -97,19 +96,6 @@ func Fromtemp(t *testing.T) func() {
return done
}
// tempdir creates a new temporary directory and returns its path.
// errors fail the current test.
func tempdir(t *testing.T) string {
// NOTE: Not using t.TempDir() because it is sometimes helpful during
// debugging to skip running the returned deferred cleanup function
// and manually inspect the contents of the test's temp directory.
d, err := os.MkdirTemp("", "dir")
if err != nil {
t.Fatal(err)
}
return d
}
// pwd prints the current working directory.
// errors fail the test.
func pwd(t *testing.T) string {
@ -129,20 +115,20 @@ func cd(t *testing.T, dir string) {
}
}
// TestRepoURI starts serving HTTP git server with GIT_PROJECT_ROOT=$(pwd)/testdata
// and returns URL for project named `name` under the git root.
//
// For example TestRepoURI("my-repo", t) returns string that could look like:
// http://localhost:4242/my-repo.git
func TestRepoURI(name string, t *testing.T) string {
// ServeRepositry [name] from ./testdata/[name] returning URL at which
// the named repository is available.
// Must be called before any helpers which change test working directory
// such as fromTempDirectory(t)
func ServeRepo(name string, t *testing.T) string {
t.Helper()
wd, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
gitRoot := filepath.Join(wd, "testdata")
hostPort := RunGitServer(t, gitRoot)
return fmt.Sprintf(`http://%s/%s.git`, hostPort, name)
var (
path = filepath.Join("./testdata", name)
dir = filepath.Dir(path)
abs, _ = filepath.Abs(dir)
repo = filepath.Base(path)
url = RunGitServer(abs, t)
)
return fmt.Sprintf("%v/%v", url, repo)
}
// WithExecutable creates an executable of the given name and source in a temp
@ -186,13 +172,13 @@ go.exe run GO_SCRIPT_PATH %*
}
}
// RunGitServer starts serving git HTTP server and returns its address including port
func RunGitServer(t *testing.T, gitRoot string) (hostPort string) {
l, err := net.Listen("tcp", "localhost:0")
// RunGitServer starts serving git HTTP server and returns its address
func RunGitServer(root string, t *testing.T) (url string) {
l, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
hostPort = l.Addr().String()
url = l.Addr().String()
cmd := exec.Command("git", "--exec-path")
out, err := cmd.CombinedOutput()
@ -203,7 +189,7 @@ func RunGitServer(t *testing.T, gitRoot string) (hostPort string) {
server := &http.Server{
Handler: &cgi.Handler{
Path: filepath.Join(strings.Trim(string(out), "\n"), "git-http-backend"),
Env: []string{"GIT_HTTP_EXPORT_ALL=true", fmt.Sprintf("GIT_PROJECT_ROOT=%s", gitRoot)},
Env: []string{"GIT_HTTP_EXPORT_ALL=true", fmt.Sprintf("GIT_PROJECT_ROOT=%s", root)},
},
}
@ -218,7 +204,7 @@ func RunGitServer(t *testing.T, gitRoot string) (hostPort string) {
server.Close()
})
return hostPort
return "http://" + url
}
// Cwd returns the current working directory or panic if unable to determine.