From ada12524809f2a4be21340e37b5c47dd05f4cddb Mon Sep 17 00:00:00 2001 From: Matt Keeler Date: Thu, 29 Mar 2018 14:30:05 -0400 Subject: [PATCH 1/5] GH-3996: Add config-format flag to validate subcommand --- command/validate/validate.go | 7 ++- command/validate/validate_test.go | 76 +++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/command/validate/validate.go b/command/validate/validate.go index 1b3923239c..f4bf9053c8 100644 --- a/command/validate/validate.go +++ b/command/validate/validate.go @@ -18,12 +18,17 @@ func New(ui cli.Ui) *cmd { type cmd struct { UI cli.Ui flags *flag.FlagSet + // ConfigFormat forces all config files to be interpreted as this + // format independent of their extension. + configFormat string quiet bool help string } func (c *cmd) init() { c.flags = flag.NewFlagSet("", flag.ContinueOnError) + c.flags.StringVar(&c.configFormat, "config-format", "", + "Config files are in this format irrespective of their extension. Must be 'hcl' or 'json'") c.flags.BoolVar(&c.quiet, "quiet", false, "When given, a successful run will produce no output.") c.help = flags.Usage(help, c.flags) @@ -40,7 +45,7 @@ func (c *cmd) Run(args []string) int { c.UI.Error("Must specify at least one config file or directory") return 1 } - b, err := config.NewBuilder(config.Flags{ConfigFiles: configFiles}) + b, err := config.NewBuilder(config.Flags{ConfigFiles: configFiles, ConfigFormat: &c.configFormat}) if err != nil { c.UI.Error(fmt.Sprintf("Config validation failed: %v", err.Error())) return 1 diff --git a/command/validate/validate_test.go b/command/validate/validate_test.go index 517e02b620..a375b02fcb 100644 --- a/command/validate/validate_test.go +++ b/command/validate/validate_test.go @@ -50,6 +50,63 @@ func TestValidateCommand_SucceedOnMinimalConfigFile(t *testing.T) { } } +func TestValidateCommand_SucceedWithMinimalJSONConfigFormat(t * testing.T) { + t.Parallel() + td := testutil.TempDir(t, "consul") + defer os.RemoveAll(td) + + fp := filepath.Join(td, "json.conf") + err := ioutil.WriteFile(fp, []byte(`{"bind_addr":"10.0.0.1", "data_dir":"`+td+`"}`), 0644) + if err != nil { + t.Fatalf("err: %s", err) + } + + cmd := New(cli.NewMockUi()) + args := []string{"--config-format", "json", fp} + + if code := cmd.Run(args); code != 0 { + t.Fatalf("bad: %d", code) + } +} + +func TestValidateCommand_SucceedWithMinimalHCLConfigFormat(t * testing.T) { + t.Parallel() + td := testutil.TempDir(t, "consul") + defer os.RemoveAll(td) + + fp := filepath.Join(td, "hcl.conf") + err := ioutil.WriteFile(fp, []byte("bind_addr = \"10.0.0.1\"\ndata_dir = \""+td+"\""), 0644) + if err != nil { + t.Fatalf("err: %s", err) + } + + cmd := New(cli.NewMockUi()) + args := []string{"--config-format", "hcl", fp} + + if code := cmd.Run(args); code != 0 { + t.Fatalf("bad: %d", code) + } +} + +func TestValidateCommand_SucceedWithJSONAsHCL(t * testing.T) { + t.Parallel() + td := testutil.TempDir(t, "consul") + defer os.RemoveAll(td) + + fp := filepath.Join(td, "json.conf") + err := ioutil.WriteFile(fp, []byte(`{"bind_addr":"10.0.0.1", "data_dir":"`+td+`"}`), 0644) + if err != nil { + t.Fatalf("err: %s", err) + } + + cmd := New(cli.NewMockUi()) + args := []string{"--config-format", "hcl", fp} + + if code := cmd.Run(args); code != 0 { + t.Fatalf("bad: %d", code) + } +} + func TestValidateCommand_SucceedOnMinimalConfigDir(t *testing.T) { t.Parallel() td := testutil.TempDir(t, "consul") @@ -68,6 +125,25 @@ func TestValidateCommand_SucceedOnMinimalConfigDir(t *testing.T) { } } +func TestValidateCommand_FailForInvalidJSONConfigFormat(t * testing.T) { + t.Parallel() + td := testutil.TempDir(t, "consul") + defer os.RemoveAll(td) + + fp := filepath.Join(td, "hcl.conf") + err := ioutil.WriteFile(fp, []byte(`bind_addr = "10.0.0.1"\ndata_dir = "`+td+`"`), 0644) + if err != nil { + t.Fatalf("err: %s", err) + } + + cmd := New(cli.NewMockUi()) + args := []string{"--config-format", "json", fp} + + if code := cmd.Run(args); code == 0 { + t.Fatalf("bad: %d", code) + } +} + func TestValidateCommand_Quiet(t *testing.T) { t.Parallel() td := testutil.TempDir(t, "consul") From 4e6f0f9a7978db4c2448379c91671a23ef96f825 Mon Sep 17 00:00:00 2001 From: Matt Keeler Date: Thu, 29 Mar 2018 14:35:49 -0400 Subject: [PATCH 2/5] Formatting update --- command/validate/validate.go | 4 ++-- command/validate/validate_test.go | 32 +++++++++++++++---------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/command/validate/validate.go b/command/validate/validate.go index f4bf9053c8..673f49a99b 100644 --- a/command/validate/validate.go +++ b/command/validate/validate.go @@ -21,8 +21,8 @@ type cmd struct { // ConfigFormat forces all config files to be interpreted as this // format independent of their extension. configFormat string - quiet bool - help string + quiet bool + help string } func (c *cmd) init() { diff --git a/command/validate/validate_test.go b/command/validate/validate_test.go index a375b02fcb..f6bd6717ac 100644 --- a/command/validate/validate_test.go +++ b/command/validate/validate_test.go @@ -50,58 +50,58 @@ func TestValidateCommand_SucceedOnMinimalConfigFile(t *testing.T) { } } -func TestValidateCommand_SucceedWithMinimalJSONConfigFormat(t * testing.T) { +func TestValidateCommand_SucceedWithMinimalJSONConfigFormat(t *testing.T) { t.Parallel() td := testutil.TempDir(t, "consul") defer os.RemoveAll(td) - + fp := filepath.Join(td, "json.conf") err := ioutil.WriteFile(fp, []byte(`{"bind_addr":"10.0.0.1", "data_dir":"`+td+`"}`), 0644) if err != nil { t.Fatalf("err: %s", err) } - + cmd := New(cli.NewMockUi()) args := []string{"--config-format", "json", fp} - + if code := cmd.Run(args); code != 0 { t.Fatalf("bad: %d", code) } } -func TestValidateCommand_SucceedWithMinimalHCLConfigFormat(t * testing.T) { +func TestValidateCommand_SucceedWithMinimalHCLConfigFormat(t *testing.T) { t.Parallel() td := testutil.TempDir(t, "consul") defer os.RemoveAll(td) - + fp := filepath.Join(td, "hcl.conf") err := ioutil.WriteFile(fp, []byte("bind_addr = \"10.0.0.1\"\ndata_dir = \""+td+"\""), 0644) if err != nil { t.Fatalf("err: %s", err) } - + cmd := New(cli.NewMockUi()) args := []string{"--config-format", "hcl", fp} - + if code := cmd.Run(args); code != 0 { t.Fatalf("bad: %d", code) } } -func TestValidateCommand_SucceedWithJSONAsHCL(t * testing.T) { +func TestValidateCommand_SucceedWithJSONAsHCL(t *testing.T) { t.Parallel() td := testutil.TempDir(t, "consul") defer os.RemoveAll(td) - + fp := filepath.Join(td, "json.conf") err := ioutil.WriteFile(fp, []byte(`{"bind_addr":"10.0.0.1", "data_dir":"`+td+`"}`), 0644) if err != nil { t.Fatalf("err: %s", err) } - + cmd := New(cli.NewMockUi()) args := []string{"--config-format", "hcl", fp} - + if code := cmd.Run(args); code != 0 { t.Fatalf("bad: %d", code) } @@ -125,20 +125,20 @@ func TestValidateCommand_SucceedOnMinimalConfigDir(t *testing.T) { } } -func TestValidateCommand_FailForInvalidJSONConfigFormat(t * testing.T) { +func TestValidateCommand_FailForInvalidJSONConfigFormat(t *testing.T) { t.Parallel() td := testutil.TempDir(t, "consul") defer os.RemoveAll(td) - + fp := filepath.Join(td, "hcl.conf") err := ioutil.WriteFile(fp, []byte(`bind_addr = "10.0.0.1"\ndata_dir = "`+td+`"`), 0644) if err != nil { t.Fatalf("err: %s", err) } - + cmd := New(cli.NewMockUi()) args := []string{"--config-format", "json", fp} - + if code := cmd.Run(args); code == 0 { t.Fatalf("bad: %d", code) } From 92ceaaad81b6e36d782439e3fa997dbf472bb756 Mon Sep 17 00:00:00 2001 From: Matt Keeler Date: Thu, 29 Mar 2018 15:06:48 -0400 Subject: [PATCH 3/5] Update case of member in comment --- command/validate/validate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/validate/validate.go b/command/validate/validate.go index 673f49a99b..cee9656f82 100644 --- a/command/validate/validate.go +++ b/command/validate/validate.go @@ -18,7 +18,7 @@ func New(ui cli.Ui) *cmd { type cmd struct { UI cli.Ui flags *flag.FlagSet - // ConfigFormat forces all config files to be interpreted as this + // configFormat forces all config files to be interpreted as this // format independent of their extension. configFormat string quiet bool From 9f64d4856a38372d22aae7d6684b16bda00972bd Mon Sep 17 00:00:00 2001 From: Matt Keeler Date: Fri, 30 Mar 2018 10:55:21 -0400 Subject: [PATCH 4/5] Update unit-tests to use requirements instead of manual checks. --- command/validate/validate_test.go | 74 +++++++++++-------------------- 1 file changed, 26 insertions(+), 48 deletions(-) diff --git a/command/validate/validate_test.go b/command/validate/validate_test.go index f6bd6717ac..27126d7877 100644 --- a/command/validate/validate_test.go +++ b/command/validate/validate_test.go @@ -7,6 +7,7 @@ import ( "strings" "testing" + require "github.com/stretchr/testify/require" "github.com/hashicorp/consul/testutil" "github.com/mitchellh/cli" ) @@ -26,9 +27,8 @@ func TestValidateCommand_FailOnEmptyFile(t *testing.T) { cmd := New(cli.NewMockUi()) args := []string{tmpFile.Name()} - if code := cmd.Run(args); code == 0 { - t.Fatalf("bad: %d", code) - } + code := cmd.Run(args) + require.NotEqualf(t, 0, code, "bad: %d", code) } func TestValidateCommand_SucceedOnMinimalConfigFile(t *testing.T) { @@ -38,16 +38,13 @@ func TestValidateCommand_SucceedOnMinimalConfigFile(t *testing.T) { fp := filepath.Join(td, "config.json") err := ioutil.WriteFile(fp, []byte(`{"bind_addr":"10.0.0.1", "data_dir":"`+td+`"}`), 0644) - if err != nil { - t.Fatalf("err: %s", err) - } + require.Nilf(t, err, "err: %s", err) cmd := New(cli.NewMockUi()) args := []string{fp} - if code := cmd.Run(args); code != 0 { - t.Fatalf("bad: %d", code) - } + code := cmd.Run(args) + require.Equalf(t, 0, code, "bad: %d", code) } func TestValidateCommand_SucceedWithMinimalJSONConfigFormat(t *testing.T) { @@ -57,16 +54,13 @@ func TestValidateCommand_SucceedWithMinimalJSONConfigFormat(t *testing.T) { fp := filepath.Join(td, "json.conf") err := ioutil.WriteFile(fp, []byte(`{"bind_addr":"10.0.0.1", "data_dir":"`+td+`"}`), 0644) - if err != nil { - t.Fatalf("err: %s", err) - } + require.Nilf(t, err, "err: %s", err) cmd := New(cli.NewMockUi()) args := []string{"--config-format", "json", fp} - if code := cmd.Run(args); code != 0 { - t.Fatalf("bad: %d", code) - } + code := cmd.Run(args) + require.Equalf(t, 0, code, "bad: %d", code) } func TestValidateCommand_SucceedWithMinimalHCLConfigFormat(t *testing.T) { @@ -76,16 +70,14 @@ func TestValidateCommand_SucceedWithMinimalHCLConfigFormat(t *testing.T) { fp := filepath.Join(td, "hcl.conf") err := ioutil.WriteFile(fp, []byte("bind_addr = \"10.0.0.1\"\ndata_dir = \""+td+"\""), 0644) - if err != nil { - t.Fatalf("err: %s", err) - } + require.Nilf(t, err, "err: %s", err) + cmd := New(cli.NewMockUi()) args := []string{"--config-format", "hcl", fp} - if code := cmd.Run(args); code != 0 { - t.Fatalf("bad: %d", code) - } + code := cmd.Run(args) + require.Equalf(t, 0, code, "bad: %d", code) } func TestValidateCommand_SucceedWithJSONAsHCL(t *testing.T) { @@ -95,16 +87,13 @@ func TestValidateCommand_SucceedWithJSONAsHCL(t *testing.T) { fp := filepath.Join(td, "json.conf") err := ioutil.WriteFile(fp, []byte(`{"bind_addr":"10.0.0.1", "data_dir":"`+td+`"}`), 0644) - if err != nil { - t.Fatalf("err: %s", err) - } + require.Nilf(t, err, "err: %s", err) cmd := New(cli.NewMockUi()) args := []string{"--config-format", "hcl", fp} - if code := cmd.Run(args); code != 0 { - t.Fatalf("bad: %d", code) - } + code := cmd.Run(args) + require.Equalf(t, 0, code, "bad: %d", code) } func TestValidateCommand_SucceedOnMinimalConfigDir(t *testing.T) { @@ -113,16 +102,13 @@ func TestValidateCommand_SucceedOnMinimalConfigDir(t *testing.T) { defer os.RemoveAll(td) err := ioutil.WriteFile(filepath.Join(td, "config.json"), []byte(`{"bind_addr":"10.0.0.1", "data_dir":"`+td+`"}`), 0644) - if err != nil { - t.Fatalf("err: %s", err) - } + require.Nilf(t, err, "err: %s", err) cmd := New(cli.NewMockUi()) args := []string{td} - if code := cmd.Run(args); code != 0 { - t.Fatalf("bad: %d", code) - } + code := cmd.Run(args) + require.Equalf(t, 0, code, "bad: %d", code) } func TestValidateCommand_FailForInvalidJSONConfigFormat(t *testing.T) { @@ -132,16 +118,13 @@ func TestValidateCommand_FailForInvalidJSONConfigFormat(t *testing.T) { fp := filepath.Join(td, "hcl.conf") err := ioutil.WriteFile(fp, []byte(`bind_addr = "10.0.0.1"\ndata_dir = "`+td+`"`), 0644) - if err != nil { - t.Fatalf("err: %s", err) - } + require.Nilf(t, err, "err: %s", err) cmd := New(cli.NewMockUi()) args := []string{"--config-format", "json", fp} - if code := cmd.Run(args); code == 0 { - t.Fatalf("bad: %d", code) - } + code := cmd.Run(args) + require.NotEqualf(t, 0, code, "bad: %d", code) } func TestValidateCommand_Quiet(t *testing.T) { @@ -151,18 +134,13 @@ func TestValidateCommand_Quiet(t *testing.T) { fp := filepath.Join(td, "config.json") err := ioutil.WriteFile(fp, []byte(`{"bind_addr":"10.0.0.1", "data_dir":"`+td+`"}`), 0644) - if err != nil { - t.Fatalf("err: %s", err) - } + require.Nilf(t, err, "err: %s", err) ui := cli.NewMockUi() cmd := New(ui) args := []string{"-quiet", td} - if code := cmd.Run(args); code != 0 { - t.Fatalf("bad: %d, %s", code, ui.ErrorWriter.String()) - } - if ui.OutputWriter.String() != "" { - t.Fatalf("bad: %v", ui.OutputWriter.String()) - } + code := cmd.Run(args) + require.Equalf(t, 0, code, "bad: %d, %s", code, ui.ErrorWriter.String()) + require.Equalf(t, "", ui.OutputWriter.String(), "bad: %v", ui.OutputWriter.String()) } From 48bd84073a53bde4d45cbf79f6e149520ff5345f Mon Sep 17 00:00:00 2001 From: Matt Keeler Date: Mon, 2 Apr 2018 09:23:01 -0400 Subject: [PATCH 5/5] Address PR feedback --- command/validate/validate.go | 6 ++++++ command/validate/validate_test.go | 18 +++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/command/validate/validate.go b/command/validate/validate.go index cee9656f82..96a84d6148 100644 --- a/command/validate/validate.go +++ b/command/validate/validate.go @@ -45,6 +45,12 @@ func (c *cmd) Run(args []string) int { c.UI.Error("Must specify at least one config file or directory") return 1 } + + if c.configFormat != "" && c.configFormat != "json" && c.configFormat != "hcl" { + c.UI.Error("-config-format must be either 'hcl' or 'json") + return 1 + } + b, err := config.NewBuilder(config.Flags{ConfigFiles: configFiles, ConfigFormat: &c.configFormat}) if err != nil { c.UI.Error(fmt.Sprintf("Config validation failed: %v", err.Error())) diff --git a/command/validate/validate_test.go b/command/validate/validate_test.go index 27126d7877..c3f3dacc61 100644 --- a/command/validate/validate_test.go +++ b/command/validate/validate_test.go @@ -28,7 +28,7 @@ func TestValidateCommand_FailOnEmptyFile(t *testing.T) { args := []string{tmpFile.Name()} code := cmd.Run(args) - require.NotEqualf(t, 0, code, "bad: %d", code) + require.NotEqual(t, 0, code) } func TestValidateCommand_SucceedOnMinimalConfigFile(t *testing.T) { @@ -44,7 +44,7 @@ func TestValidateCommand_SucceedOnMinimalConfigFile(t *testing.T) { args := []string{fp} code := cmd.Run(args) - require.Equalf(t, 0, code, "bad: %d", code) + require.Equal(t, 0, code) } func TestValidateCommand_SucceedWithMinimalJSONConfigFormat(t *testing.T) { @@ -60,7 +60,7 @@ func TestValidateCommand_SucceedWithMinimalJSONConfigFormat(t *testing.T) { args := []string{"--config-format", "json", fp} code := cmd.Run(args) - require.Equalf(t, 0, code, "bad: %d", code) + require.Equal(t, 0, code) } func TestValidateCommand_SucceedWithMinimalHCLConfigFormat(t *testing.T) { @@ -77,7 +77,7 @@ func TestValidateCommand_SucceedWithMinimalHCLConfigFormat(t *testing.T) { args := []string{"--config-format", "hcl", fp} code := cmd.Run(args) - require.Equalf(t, 0, code, "bad: %d", code) + require.Equal(t, 0, code) } func TestValidateCommand_SucceedWithJSONAsHCL(t *testing.T) { @@ -93,7 +93,7 @@ func TestValidateCommand_SucceedWithJSONAsHCL(t *testing.T) { args := []string{"--config-format", "hcl", fp} code := cmd.Run(args) - require.Equalf(t, 0, code, "bad: %d", code) + require.Equal(t, 0, code) } func TestValidateCommand_SucceedOnMinimalConfigDir(t *testing.T) { @@ -108,7 +108,7 @@ func TestValidateCommand_SucceedOnMinimalConfigDir(t *testing.T) { args := []string{td} code := cmd.Run(args) - require.Equalf(t, 0, code, "bad: %d", code) + require.Equal(t, 0, code) } func TestValidateCommand_FailForInvalidJSONConfigFormat(t *testing.T) { @@ -124,7 +124,7 @@ func TestValidateCommand_FailForInvalidJSONConfigFormat(t *testing.T) { args := []string{"--config-format", "json", fp} code := cmd.Run(args) - require.NotEqualf(t, 0, code, "bad: %d", code) + require.NotEqual(t, 0, code) } func TestValidateCommand_Quiet(t *testing.T) { @@ -141,6 +141,6 @@ func TestValidateCommand_Quiet(t *testing.T) { args := []string{"-quiet", td} code := cmd.Run(args) - require.Equalf(t, 0, code, "bad: %d, %s", code, ui.ErrorWriter.String()) - require.Equalf(t, "", ui.OutputWriter.String(), "bad: %v", ui.OutputWriter.String()) + require.Equalf(t, 0, code, "return code - expected: 0, bad: %d, %s", code, ui.ErrorWriter.String()) + require.Equal(t, "", ui.OutputWriter.String()) }