mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-25 01:00:16 -05:00
feat: init and get command support json format output (#1453)
Signed-off-by: Syasusu <syasusu@163.com>
This commit is contained in:
@@ -62,33 +62,67 @@ func TestInitProvidersInternal(t *testing.T) {
|
||||
// This test should _not_ reach out anywhere because the "terraform"
|
||||
// provider is internal to the core tofu binary.
|
||||
|
||||
fixturePath := filepath.Join("testdata", "tf-provider")
|
||||
tf := e2e.NewBinary(t, tofuBin, fixturePath)
|
||||
t.Run("output in human readable format", func(t *testing.T) {
|
||||
fixturePath := filepath.Join("testdata", "tf-provider")
|
||||
tf := e2e.NewBinary(t, tofuBin, fixturePath)
|
||||
|
||||
stdout, stderr, err := tf.Run("init")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %s", err)
|
||||
}
|
||||
stdout, stderr, err := tf.Run("init")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
if stderr != "" {
|
||||
t.Errorf("unexpected stderr output:\n%s", stderr)
|
||||
}
|
||||
if stderr != "" {
|
||||
t.Errorf("unexpected stderr output:\n%s", stderr)
|
||||
}
|
||||
|
||||
if !strings.Contains(stdout, "OpenTofu has been successfully initialized!") {
|
||||
t.Errorf("success message is missing from output:\n%s", stdout)
|
||||
}
|
||||
if !strings.Contains(stdout, "OpenTofu has been successfully initialized!") {
|
||||
t.Errorf("success message is missing from output:\n%s", stdout)
|
||||
}
|
||||
|
||||
if strings.Contains(stdout, "Installing hashicorp/terraform") {
|
||||
// Shouldn't have downloaded anything with this config, because the
|
||||
// provider is built in.
|
||||
t.Errorf("provider download message appeared in output:\n%s", stdout)
|
||||
}
|
||||
if strings.Contains(stdout, "Installing hashicorp/terraform") {
|
||||
// Shouldn't have downloaded anything with this config, because the
|
||||
// provider is built in.
|
||||
t.Errorf("provider download message appeared in output:\n%s", stdout)
|
||||
}
|
||||
|
||||
if strings.Contains(stdout, "Installing terraform.io/builtin/terraform") {
|
||||
// Shouldn't have downloaded anything with this config, because the
|
||||
// provider is built in.
|
||||
t.Errorf("provider download message appeared in output:\n%s", stdout)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("output in machine readable format", func(t *testing.T) {
|
||||
fixturePath := filepath.Join("testdata", "tf-provider")
|
||||
tf := e2e.NewBinary(t, tofuBin, fixturePath)
|
||||
|
||||
stdout, stderr, err := tf.Run("init", "-json")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
if stderr != "" {
|
||||
t.Errorf("unexpected stderr output:\n%s", stderr)
|
||||
}
|
||||
|
||||
// we can not check timestamp, so the sub string is not a valid json object
|
||||
if !strings.Contains(stdout, `{"@level":"info","@message":"OpenTofu has been successfully initialized!","@module":"tofu.ui"`) {
|
||||
t.Errorf("success message is missing from output:\n%s", stdout)
|
||||
}
|
||||
|
||||
if strings.Contains(stdout, "Installing hashicorp/terraform") {
|
||||
// Shouldn't have downloaded anything with this config, because the
|
||||
// provider is built in.
|
||||
t.Errorf("provider download message appeared in output:\n%s", stdout)
|
||||
}
|
||||
|
||||
if strings.Contains(stdout, "Installing terraform.io/builtin/terraform") {
|
||||
// Shouldn't have downloaded anything with this config, because the
|
||||
// provider is built in.
|
||||
t.Errorf("provider download message appeared in output:\n%s", stdout)
|
||||
}
|
||||
})
|
||||
|
||||
if strings.Contains(stdout, "Installing terraform.io/builtin/terraform") {
|
||||
// Shouldn't have downloaded anything with this config, because the
|
||||
// provider is built in.
|
||||
t.Errorf("provider download message appeared in output:\n%s", stdout)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitProvidersVendored(t *testing.T) {
|
||||
@@ -144,42 +178,85 @@ func TestInitProvidersLocalOnly(t *testing.T) {
|
||||
// to the host "example.com", which is the placeholder domain we use in
|
||||
// the test fixture.)
|
||||
|
||||
fixturePath := filepath.Join("testdata", "local-only-provider")
|
||||
tf := e2e.NewBinary(t, tofuBin, fixturePath)
|
||||
// If you run this test on a workstation with a plugin-cache directory
|
||||
// configured, it will leave a bad directory behind and tofu init will
|
||||
// not work until you remove it.
|
||||
//
|
||||
// To avoid this, we will "zero out" any existing cli config file.
|
||||
tf.AddEnv("TF_CLI_CONFIG_FILE=")
|
||||
t.Run("output in human readable format", func(t *testing.T) {
|
||||
fixturePath := filepath.Join("testdata", "local-only-provider")
|
||||
tf := e2e.NewBinary(t, tofuBin, fixturePath)
|
||||
// If you run this test on a workstation with a plugin-cache directory
|
||||
// configured, it will leave a bad directory behind and tofu init will
|
||||
// not work until you remove it.
|
||||
//
|
||||
// To avoid this, we will "zero out" any existing cli config file.
|
||||
tf.AddEnv("TF_CLI_CONFIG_FILE=")
|
||||
|
||||
// Our fixture dir has a generic os_arch dir, which we need to customize
|
||||
// to the actual OS/arch where this test is running in order to get the
|
||||
// desired result.
|
||||
fixtMachineDir := tf.Path("terraform.d/plugins/example.com/awesomecorp/happycloud/1.2.0/os_arch")
|
||||
wantMachineDir := tf.Path("terraform.d/plugins/example.com/awesomecorp/happycloud/1.2.0/", fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH))
|
||||
err := os.Rename(fixtMachineDir, wantMachineDir)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
// Our fixture dir has a generic os_arch dir, which we need to customize
|
||||
// to the actual OS/arch where this test is running in order to get the
|
||||
// desired result.
|
||||
fixtMachineDir := tf.Path("terraform.d/plugins/example.com/awesomecorp/happycloud/1.2.0/os_arch")
|
||||
wantMachineDir := tf.Path("terraform.d/plugins/example.com/awesomecorp/happycloud/1.2.0/", fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH))
|
||||
err := os.Rename(fixtMachineDir, wantMachineDir)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
stdout, stderr, err := tf.Run("init")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %s", err)
|
||||
}
|
||||
stdout, stderr, err := tf.Run("init")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
if stderr != "" {
|
||||
t.Errorf("unexpected stderr output:\n%s", stderr)
|
||||
}
|
||||
if stderr != "" {
|
||||
t.Errorf("unexpected stderr output:\n%s", stderr)
|
||||
}
|
||||
|
||||
if !strings.Contains(stdout, "OpenTofu has been successfully initialized!") {
|
||||
t.Errorf("success message is missing from output:\n%s", stdout)
|
||||
}
|
||||
if !strings.Contains(stdout, "OpenTofu has been successfully initialized!") {
|
||||
t.Errorf("success message is missing from output:\n%s", stdout)
|
||||
}
|
||||
|
||||
if !strings.Contains(stdout, "- Installing example.com/awesomecorp/happycloud v1.2.0") {
|
||||
t.Errorf("provider download message is missing from output:\n%s", stdout)
|
||||
t.Logf("(this can happen if you have a conflicting copy of the plugin in one of the global plugin search dirs)")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("output in machine readable format", func(t *testing.T) {
|
||||
fixturePath := filepath.Join("testdata", "local-only-provider")
|
||||
tf := e2e.NewBinary(t, tofuBin, fixturePath)
|
||||
// If you run this test on a workstation with a plugin-cache directory
|
||||
// configured, it will leave a bad directory behind and tofu init will
|
||||
// not work until you remove it.
|
||||
//
|
||||
// To avoid this, we will "zero out" any existing cli config file.
|
||||
tf.AddEnv("TF_CLI_CONFIG_FILE=")
|
||||
|
||||
// Our fixture dir has a generic os_arch dir, which we need to customize
|
||||
// to the actual OS/arch where this test is running in order to get the
|
||||
// desired result.
|
||||
fixtMachineDir := tf.Path("terraform.d/plugins/example.com/awesomecorp/happycloud/1.2.0/os_arch")
|
||||
wantMachineDir := tf.Path("terraform.d/plugins/example.com/awesomecorp/happycloud/1.2.0/", fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH))
|
||||
err := os.Rename(fixtMachineDir, wantMachineDir)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
stdout, stderr, err := tf.Run("init", "-json")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
if stderr != "" {
|
||||
t.Errorf("unexpected stderr output:\n%s", stderr)
|
||||
}
|
||||
|
||||
// we can not check timestamp, so the sub string is not a valid json object
|
||||
if !strings.Contains(stdout, `{"@level":"info","@message":"OpenTofu has been successfully initialized!","@module":"tofu.ui"`) {
|
||||
t.Errorf("success message is missing from output:\n%s", stdout)
|
||||
}
|
||||
|
||||
if !strings.Contains(stdout, `{"@level":"info","@message":"- Installing example.com/awesomecorp/happycloud v1.2.0...","@module":"tofu.ui"`) {
|
||||
t.Errorf("provider download message is missing from output:\n%s", stdout)
|
||||
t.Logf("(this can happen if you have a conflicting copy of the plugin in one of the global plugin search dirs)")
|
||||
}
|
||||
})
|
||||
|
||||
if !strings.Contains(stdout, "- Installing example.com/awesomecorp/happycloud v1.2.0") {
|
||||
t.Errorf("provider download message is missing from output:\n%s", stdout)
|
||||
t.Logf("(this can happen if you have a conflicting copy of the plugin in one of the global plugin search dirs)")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitProvidersCustomMethod(t *testing.T) {
|
||||
@@ -347,9 +424,21 @@ func TestInitProviderNotFound(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("registry provider not found output in json format", func(t *testing.T) {
|
||||
stdout, _, err := tf.Run("init", "-no-color", "-json")
|
||||
if err == nil {
|
||||
t.Fatal("expected error, got success")
|
||||
}
|
||||
|
||||
oneLineStdout := strings.ReplaceAll(stdout, "\n", " ")
|
||||
if !strings.Contains(oneLineStdout, `"diagnostic":{"severity":"error","summary":"Failed to query available provider packages","detail":"Could not retrieve the list of available versions for provider hashicorp/nonexist: provider registry registry.opentofu.org does not have a provider named registry.opentofu.org/hashicorp/nonexist\n\nAll modules should specify their required_providers so that external consumers will get the correct providers when using a module. To see which modules are currently depending on hashicorp/nonexist, run the following command:\n tofu providers\n\nIf you believe this provider is missing from the registry, please submit a issue on the OpenTofu Registry https://github.com/opentofu/registry/issues/"},"type":"diagnostic"}`) {
|
||||
t.Errorf("expected error message is missing from output:\n%s", stdout)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("local provider not found", func(t *testing.T) {
|
||||
// The -plugin-dir directory must exist for the provider installer to search it.
|
||||
pluginDir := tf.Path("empty")
|
||||
pluginDir := tf.Path("empty-for-json")
|
||||
if err := os.Mkdir(pluginDir, os.ModePerm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -364,6 +453,23 @@ func TestInitProviderNotFound(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("local provider not found output in json format", func(t *testing.T) {
|
||||
// The -plugin-dir directory must exist for the provider installer to search it.
|
||||
pluginDir := tf.Path("empty")
|
||||
if err := os.Mkdir(pluginDir, os.ModePerm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
stdout, _, err := tf.Run("init", "-no-color", "-plugin-dir="+pluginDir, "-json")
|
||||
if err == nil {
|
||||
t.Fatal("expected error, got success")
|
||||
}
|
||||
|
||||
if !strings.Contains(stdout, `"diagnostic":{"severity":"error","summary":"Failed to query available provider packages","detail":"Could not retrieve the list of available versions for provider hashicorp/nonexist: provider registry.opentofu.org/hashicorp/nonexist was not found in any of the search locations\n\n - `+pluginDir+`"},"type":"diagnostic"}`) {
|
||||
t.Errorf("expected error message is missing from output:\n%s", stdout)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("special characters enabled", func(t *testing.T) {
|
||||
_, stderr, err := tf.Run("init")
|
||||
if err == nil {
|
||||
|
||||
Reference in New Issue
Block a user