diff --git a/integration_test/index_test.go b/integration_test/index_test.go index fa5b4911..e696d9a5 100644 --- a/integration_test/index_test.go +++ b/integration_test/index_test.go @@ -29,7 +29,7 @@ func TestKrewIndexAdd(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex() if _, err := test.Krew("index", "add").Run(); err == nil { t.Fatal("expected index add with no args to fail") } @@ -51,7 +51,7 @@ func TestKrewIndexAddUnsafe(t *testing.T) { skipShort(t) test, cleanup := NewTest(t) defer cleanup() - test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex() cases := []string{"a/b", `a\b`, "../a", `..\a`} expected := "invalid index name" @@ -72,15 +72,14 @@ func TestKrewIndexList(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex() out := test.Krew("index", "list").RunOrFailOutput() if indexes := lines(out); len(indexes) < 2 { // the first line is the header t.Fatal("expected at least 1 index in output") } - localIndex := test.TempDir().Path("index/" + constants.DefaultIndexName) - test.Krew("index", "add", "foo", localIndex).RunOrFail() + test.WithCustomIndexFromDefault("foo") out = test.Krew("index", "list").RunOrFailOutput() if indexes := lines(out); len(indexes) < 3 { // the first line is the header @@ -94,7 +93,7 @@ func TestKrewIndexList_NoIndexes(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex() index := test.TempDir().Path("index") if err := os.RemoveAll(index); err != nil { t.Fatalf("error removing default index: %v", err) @@ -122,18 +121,16 @@ func TestKrewIndexRemove_nonExisting(t *testing.T) { func TestKrewIndexRemove_ok(t *testing.T) { skipShort(t) test, cleanup := NewTest(t) - test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex().WithCustomIndexFromDefault("foo") defer cleanup() - localIndex := test.TempDir().Path("index/" + constants.DefaultIndexName) - test.Krew("index", "add", "foo", localIndex).RunOrFail() test.Krew("index", "remove", "foo").RunOrFail() } func TestKrewIndexRemove_unsafe(t *testing.T) { skipShort(t) test, cleanup := NewTest(t) - test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex() defer cleanup() expected := "invalid index name" @@ -151,7 +148,7 @@ func TestKrewIndexRemove_unsafe(t *testing.T) { func TestKrewIndexRemoveFailsWhenPluginsInstalled(t *testing.T) { skipShort(t) test, cleanup := NewTest(t) - test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex() defer cleanup() test.Krew("install", validPlugin).RunOrFailOutput() diff --git a/integration_test/info_test.go b/integration_test/info_test.go index df2c2f40..a37cc290 100644 --- a/integration_test/info_test.go +++ b/integration_test/info_test.go @@ -27,7 +27,7 @@ func TestKrewInfo(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - out := string(test.WithIndex().Krew("info", validPlugin).RunOrFailOutput()) + out := string(test.WithDefaultIndex().Krew("info", validPlugin).RunOrFailOutput()) expected := `INDEX: default` if !strings.Contains(out, expected) { t.Fatalf("info output doesn't have %q. output=%q", expected, out) @@ -41,7 +41,7 @@ func TestKrewInfoInvalidPlugin(t *testing.T) { defer cleanup() plugin := "invalid-plugin" - _, err := test.WithIndex().Krew("info", plugin).Run() + _, err := test.WithDefaultIndex().Krew("info", plugin).Run() if err == nil { t.Errorf("Expected `krew info %s` to fail", plugin) } @@ -53,10 +53,7 @@ func TestKrewInfoCustomIndex(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() - defaultIndexRoot := test.TempDir().Path("index/" + constants.DefaultIndexName) - - test.Krew("index", "add", "foo", defaultIndexRoot).RunOrFail() + test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex().WithCustomIndexFromDefault("foo") test.Krew("install", "foo/"+validPlugin).RunOrFail() out := string(test.Krew("info", "foo/"+validPlugin).RunOrFailOutput()) diff --git a/integration_test/install_test.go b/integration_test/install_test.go index 4af6f3e9..ca01b3a8 100644 --- a/integration_test/install_test.go +++ b/integration_test/install_test.go @@ -37,7 +37,7 @@ func TestKrewInstall(t *testing.T) { t.Fatal("expected to fail without initializing the index") } - test = test.WithIndex() + test = test.WithDefaultIndex() if err := test.Krew("install"); err == nil { t.Fatal("expected failure without any args or stdin") } @@ -52,7 +52,7 @@ func TestKrewInstallReRun(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test = test.WithIndex() + test = test.WithDefaultIndex() test.Krew("install", validPlugin).RunOrFail() test.Krew("install", validPlugin).RunOrFail() test.AssertExecutableInPATH("kubectl-" + validPlugin) @@ -62,7 +62,7 @@ func TestKrewInstallUnsafe(t *testing.T) { skipShort(t) test, cleanup := NewTest(t) defer cleanup() - test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex() cases := []string{ `../index/` + validPlugin, @@ -89,7 +89,7 @@ func TestKrewInstall_MultiplePositionalArgs(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test.WithIndex().Krew("install", validPlugin, validPlugin2).RunOrFailOutput() + test.WithDefaultIndex().Krew("install", validPlugin, validPlugin2).RunOrFailOutput() test.AssertExecutableInPATH("kubectl-" + validPlugin) test.AssertExecutableInPATH("kubectl-" + validPlugin2) } @@ -100,7 +100,7 @@ func TestKrewInstall_Stdin(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test.WithIndex().WithStdin(strings.NewReader(validPlugin + "\n" + validPlugin2)). + test.WithDefaultIndex().WithStdin(strings.NewReader(validPlugin + "\n" + validPlugin2)). Krew("install").RunOrFailOutput() test.AssertExecutableInPATH("kubectl-" + validPlugin) @@ -114,7 +114,7 @@ func TestKrewInstall_StdinAndPositionalArguments(t *testing.T) { defer cleanup() // when stdin is detected, it's ignored in favor of positional arguments - test.WithIndex(). + test.WithDefaultIndex(). WithStdin(strings.NewReader(validPlugin2)). Krew("install", validPlugin).RunOrFail() test.AssertExecutableInPATH("kubectl-" + validPlugin) @@ -138,8 +138,7 @@ func TestKrewInstall_CustomIndex(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() - test.Krew("index", "add", "foo", test.TempDir().Path("index/"+constants.DefaultIndexName)).RunOrFail() + test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex().WithCustomIndexFromDefault("foo") test.Krew("install", "foo/"+validPlugin).RunOrFail() test.AssertExecutableInPATH("kubectl-" + validPlugin) test.AssertPluginFromIndex(validPlugin, "foo") diff --git a/integration_test/list_test.go b/integration_test/list_test.go index b04e99c2..d215c782 100644 --- a/integration_test/list_test.go +++ b/integration_test/list_test.go @@ -36,7 +36,7 @@ func TestKrewList(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex().WithCustomIndexFromDefault("foo") initialList := test.Krew("list").RunOrFailOutput() initialOut := []byte{'\n'} @@ -52,7 +52,6 @@ func TestKrewList(t *testing.T) { t.Fatalf("'list' output doesn't match:\n%s", diff) } - test.Krew("index", "add", "foo", test.TempDir().Path("index/"+constants.DefaultIndexName)).RunOrFail() test.Krew("install", "foo/"+validPlugin2).RunOrFail() want := []string{validPlugin, "foo/" + validPlugin2} @@ -67,7 +66,7 @@ func TestKrewListSorted(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex() os.Setenv(constants.EnableMultiIndexSwitch, "1") defer os.Unsetenv(constants.EnableMultiIndexSwitch) diff --git a/integration_test/search_test.go b/integration_test/search_test.go index a44de314..2964dc1b 100644 --- a/integration_test/search_test.go +++ b/integration_test/search_test.go @@ -29,7 +29,7 @@ func TestKrewSearchAll(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - output := test.WithIndex().Krew("search").RunOrFailOutput() + output := test.WithDefaultIndex().Krew("search").RunOrFailOutput() if plugins := lines(output); len(plugins) < 10 { // the first line is the header t.Errorf("Expected at least %d plugins", len(plugins)-1) @@ -42,7 +42,7 @@ func TestKrewSearchOne(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - plugins := lines(test.WithIndex().Krew("search", "krew").RunOrFailOutput()) + plugins := lines(test.WithDefaultIndex().Krew("search", "krew").RunOrFailOutput()) if len(plugins) < 2 { t.Errorf("Expected krew to be a valid plugin") } @@ -54,13 +54,9 @@ func TestKrewSearchOne(t *testing.T) { func TestKrewSearchMultiIndex(t *testing.T) { skipShort(t) test, cleanup := NewTest(t) - test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex().WithCustomIndexFromDefault("foo") defer cleanup() - // alias default plugin index to another - localIndex := test.TempDir().Path("index/" + constants.DefaultIndexName) - test.Krew("index", "add", "foo", localIndex).RunOrFailOutput() - test.Krew("install", validPlugin).RunOrFail() test.Krew("install", "foo/"+validPlugin2).RunOrFail() @@ -81,13 +77,9 @@ func TestKrewSearchMultiIndex(t *testing.T) { func TestKrewSearchMultiIndexSortedByDisplayName(t *testing.T) { skipShort(t) test, cleanup := NewTest(t) - test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex().WithCustomIndexFromDefault("foo") defer cleanup() - // alias default plugin index to another - localIndex := test.TempDir().Path("index/" + constants.DefaultIndexName) - test.Krew("index", "add", "foo", localIndex).RunOrFailOutput() - output := string(test.Krew("search").RunOrFailOutput()) // match first column that is not NAME by matching everything up until a space diff --git a/integration_test/system_test.go b/integration_test/system_test.go index 4c38e8c0..cc03889f 100644 --- a/integration_test/system_test.go +++ b/integration_test/system_test.go @@ -30,7 +30,7 @@ func TestKrewSystem(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test.WithIndex().Krew("install", validPlugin).RunOrFail() + test.WithDefaultIndex().Krew("install", validPlugin).RunOrFail() // needs to be after initial installation prepareOldKrewRoot(test) @@ -50,7 +50,7 @@ func TestKrewSystem_ReceiptForKrew(t *testing.T) { prepareOldKrewRoot(test) touch(test.tempDir, "store/krew/ensure-folder-exists") - test.WithIndex().Krew("system", "receipts-upgrade").RunOrFailOutput() + test.WithDefaultIndex().Krew("system", "receipts-upgrade").RunOrFailOutput() assertReceiptExistsFor(test, "krew") } @@ -64,7 +64,7 @@ func TestKrewSystem_IgnoreAdditionalFolders(t *testing.T) { prepareOldKrewRoot(test) touch(test.tempDir, "store/not-a-plugin/ensure-folder-exists") - out := test.WithIndex().Krew("system", "receipts-upgrade").RunOrFailOutput() + out := test.WithDefaultIndex().Krew("system", "receipts-upgrade").RunOrFailOutput() if !bytes.Contains(out, []byte("Skipping plugin not-a-plugin")) { t.Errorf("Expected a message that 'not-a-plugin' is skipped, but output was:") @@ -85,7 +85,7 @@ func TestKrewSystem_IgnoreUnknownPlugins(t *testing.T) { prepareOldKrewRoot(test) - out := test.WithIndex().Krew("system", "receipts-upgrade").RunOrFailOutput() + out := test.WithDefaultIndex().Krew("system", "receipts-upgrade").RunOrFailOutput() if !bytes.Contains(out, []byte("Skipping plugin foo")) { t.Errorf("Expected a message that 'foo' is skipped, but output was:") diff --git a/integration_test/testutil_test.go b/integration_test/testutil_test.go index dedda345..4fd746c1 100644 --- a/integration_test/testutil_test.go +++ b/integration_test/testutil_test.go @@ -183,12 +183,24 @@ func (it *ITest) Root() string { return it.tempDir.Root() } -// WithIndex initializes the index with the actual krew-index from github/kubernetes-sigs/krew-index. -func (it *ITest) WithIndex() *ITest { +// WithDefaultIndex initializes the index with the actual krew-index from github/kubernetes-sigs/krew-index. +func (it *ITest) WithDefaultIndex() *ITest { it.initializeIndex() return it } +// WithCustomIndexFromDefault initializes a new index by cloning the default index. WithDefaultIndex needs +// to be called before this function. This is a helper function for working with custom indexes in the +// integration tests so that developers don't need to alias the cloned default index each time. +func (it *ITest) WithCustomIndexFromDefault(name string) *ITest { + // TODO(chriskim06) remove this once index migration happens + if !isMultiIndexEnabled(it.env) { + it.t.Fatalf("Cannot add a custom index without %s set", constants.EnableMultiIndexSwitch) + } + it.Krew("index", "add", name, it.TempDir().Path("index/"+constants.DefaultIndexName)).RunOrFail() + return it +} + // WithEnv sets an environment variable for the krew run. func (it *ITest) WithEnv(key string, value interface{}) *ITest { if key == "KREW_ROOT" { @@ -299,13 +311,20 @@ func (it *ITest) initializeIndex() { } // TODO(chriskim06) simplify once multi-index is enabled - for _, e := range it.env { + if isMultiIndexEnabled(it.env) { + if err := indexmigration.Migrate(environment.NewPaths(it.Root())); err != nil { + it.t.Fatalf("error migrating index: %s", err) + } + } +} + +func isMultiIndexEnabled(env []string) bool { + for _, e := range env { if strings.Contains(e, constants.EnableMultiIndexSwitch) { - if err := indexmigration.Migrate(environment.NewPaths(it.Root())); err != nil { - it.t.Fatalf("error migrating index: %s", err) - } + return true } } + return false } func initFromGitClone(t *testing.T) ([]byte, error) { diff --git a/integration_test/uninstall_test.go b/integration_test/uninstall_test.go index 04625c22..d7471055 100644 --- a/integration_test/uninstall_test.go +++ b/integration_test/uninstall_test.go @@ -30,7 +30,7 @@ func TestKrewUninstall(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test = test.WithIndex() + test = test.WithDefaultIndex() if _, err := test.Krew("uninstall").Run(); err == nil { t.Fatal("expected failure without no arguments") @@ -53,8 +53,7 @@ func TestKrewUninstallPluginsFromCustomIndex(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() - test.Krew("index", "add", "foo", test.TempDir().Path("index/"+constants.DefaultIndexName)).RunOrFail() + test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex().WithCustomIndexFromDefault("foo") test.Krew("install", "foo/"+validPlugin).RunOrFail() test.Krew("uninstall", validPlugin).RunOrFail() @@ -67,7 +66,7 @@ func TestKrewUninstall_CannotUseIndexSyntax(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex() out, err := test.Krew("uninstall", "foo/"+validPlugin).Run() if err == nil { t.Error("expected error when uninstalling by canonical name") @@ -83,7 +82,7 @@ func TestKrewRemove_AliasSupported(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test.WithIndex().Krew("install", validPlugin).RunOrFailOutput() + test.WithDefaultIndex().Krew("install", validPlugin).RunOrFailOutput() test.Krew("remove", validPlugin).RunOrFailOutput() test.AssertExecutableNotInPATH("kubectl-" + validPlugin) } @@ -94,7 +93,7 @@ func TestKrewRemove_ManifestRemovedFromIndex(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test = test.WithIndex() + test = test.WithDefaultIndex() manifestDir := environment.NewPaths(test.Root()).IndexPluginsPath(constants.DefaultIndexName) localManifest := filepath.Join(manifestDir, validPlugin+constants.ManifestExtension) if _, err := os.Stat(localManifest); err != nil { @@ -111,7 +110,7 @@ func TestKrewRemove_Unsafe(t *testing.T) { skipShort(t) test, cleanup := NewTest(t) defer cleanup() - test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex() test.Krew("install", validPlugin).RunOrFailOutput() cases := []string{ diff --git a/integration_test/update_test.go b/integration_test/update_test.go index e8ebf084..3d08e7c4 100644 --- a/integration_test/update_test.go +++ b/integration_test/update_test.go @@ -33,7 +33,7 @@ func TestKrewUpdate(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - // nb do not call WithIndex() here + // nb do not call WithDefaultIndex() here updateOut := string(test.Krew("update").RunOrFailOutput()) if strings.Contains(updateOut, "New plugins available:") { t.Fatalf("clean index fetch should not show 'new plugins available': %s", updateOut) @@ -54,13 +54,12 @@ func TestKrewUpdateMultipleIndexes(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex().WithCustomIndexFromDefault("foo") // to enable new paths in environment.NewPaths() os.Setenv(constants.EnableMultiIndexSwitch, "1") defer os.Unsetenv(constants.EnableMultiIndexSwitch) paths := environment.NewPaths(test.Root()) - test.Krew("index", "add", "foo", paths.IndexPath(constants.DefaultIndexName)).RunOrFail() if err := os.RemoveAll(paths.IndexPluginsPath("foo")); err != nil { t.Errorf("error removing plugins directory from index: %s", err) } @@ -79,7 +78,7 @@ func TestKrewUpdateFailedIndex(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test = test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex() os.Setenv(constants.EnableMultiIndexSwitch, "1") defer os.Unsetenv(constants.EnableMultiIndexSwitch) @@ -100,7 +99,7 @@ func TestKrewUpdateListsNewPlugins(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test = test.WithIndex() + test = test.WithDefaultIndex() pluginManifest := filepath.Join(environment.NewPaths(test.Root()).IndexPluginsPath(constants.DefaultIndexName), validPlugin+constants.ManifestExtension) if err := os.Remove(pluginManifest); err != nil { @@ -121,7 +120,7 @@ func TestKrewUpdateListsUpgradesAvailable(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test = test.WithIndex() + test = test.WithDefaultIndex() // set version of some manifests to v0.0.0 pluginManifest := filepath.Join(environment.NewPaths(test.Root()).IndexPluginsPath(constants.DefaultIndexName), validPlugin+constants.ManifestExtension) diff --git a/integration_test/upgrade_test.go b/integration_test/upgrade_test.go index 4e54bdb0..fcf8a02a 100644 --- a/integration_test/upgrade_test.go +++ b/integration_test/upgrade_test.go @@ -38,7 +38,7 @@ func TestKrewUpgrade(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test.WithIndex(). + test.WithDefaultIndex(). Krew("install", "--manifest", filepath.Join("testdata", validPlugin+constants.ManifestExtension)). RunOrFail() initialLocation := resolvePluginSymlink(test, validPlugin) @@ -57,8 +57,7 @@ func TestKrewUpgradePluginsFromCustomIndex(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() - test.Krew("index", "add", "foo", test.TempDir().Path("index/"+constants.DefaultIndexName)).RunOrFail() + test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex().WithCustomIndexFromDefault("foo") test.Krew("install", "foo/"+validPlugin).RunOrFail() receipt := environment.NewPaths(test.Root()).PluginInstallReceiptPath(validPlugin) @@ -94,7 +93,7 @@ func TestKrewUpgradeUnsafe(t *testing.T) { skipShort(t) test, cleanup := NewTest(t) defer cleanup() - test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithIndex() + test.WithEnv(constants.EnableMultiIndexSwitch, 1).WithDefaultIndex() cases := []string{ `../index/` + validPlugin, @@ -121,7 +120,7 @@ func TestKrewUpgradeWhenPlatformNoLongerMatches(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test.WithIndex(). + test.WithDefaultIndex(). Krew("install", validPlugin). RunOrFail() @@ -146,7 +145,7 @@ func TestKrewUpgrade_ValidPluginInstalledFromManifest(t *testing.T) { test, cleanup := NewTest(t) defer cleanup() - test.WithIndex(). + test.WithDefaultIndex(). Krew("install", validPlugin). RunOrFail()