Skip to content

Commit

Permalink
feature: user-defined + 2 built-in output formats
Browse files Browse the repository at this point in the history
This commit adds --format flag, which allows users to specify output
format. --format flag accepts some format known to bombardier as a
string or a path to a user-defined template (prefixed with 'path:').
I also added detailed documentation on user-defined templates to help
users write their own templates.

Closes #26, updates #24.
  • Loading branch information
codesenberg committed Feb 22, 2018
1 parent 122cac7 commit 3a8f621
Show file tree
Hide file tree
Showing 17 changed files with 1,326 additions and 56 deletions.
23 changes: 23 additions & 0 deletions args_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ type kingpinParser struct {

printSpec *nullableString
noPrint bool

formatSpec string
}

func newKingpinParser() argsParser {
Expand All @@ -59,6 +61,7 @@ func newKingpinParser() argsParser {
clientType: fhttp,
printSpec: new(nullableString),
noPrint: false,
formatSpec: "plain-text",
}

app := kingpin.New("", "Fast cross-platform HTTP benchmarking tool").
Expand Down Expand Up @@ -155,6 +158,19 @@ func newKingpinParser() argsParser {
Short('q').
BoolVar(&kparser.noPrint)

app.Flag("format", "Which format to use to output the result. "+
"<spec> is either a name (or its shorthand) of some format "+
"understood by bombardier or a path to the user-defined template, "+
"which uses Go's text/template syntax, prefixed with 'path:' string "+
"(without single quotes), i.e. \"path:/some/path/to/your.template\" "+
" or \"path:C:\\some\\path\\to\\your.template\" in case of Windows. "+
"Formats understood by bombardier are:"+
"\n\t* plain-text (short: pt)"+
"\n\t* json (short: j)").
PlaceHolder("<spec>").
Short('o').
StringVar(&kparser.formatSpec)

app.Arg("url", "Target's URL").Required().
StringVar(&kparser.url)

Expand All @@ -178,6 +194,12 @@ func (k *kingpinParser) parse(args []string) (config, error) {
if k.noPrint {
pi, pp, pr = false, false, false
}
format := formatFromString(k.formatSpec)
if format == nil {
return emptyConf, fmt.Errorf(
"unknown format or invalid format spec %q", k.formatSpec,
)
}
return config{
numConns: k.numConns,
numReqs: k.numReqs.val,
Expand All @@ -198,6 +220,7 @@ func (k *kingpinParser) parse(args []string) (config, error) {
printIntro: pi,
printProgress: pp,
printResult: pr,
format: format,
}, nil
}

Expand Down
155 changes: 155 additions & 0 deletions args_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand Down Expand Up @@ -104,6 +105,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand All @@ -129,6 +131,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand All @@ -154,6 +157,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand Down Expand Up @@ -182,6 +186,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand Down Expand Up @@ -221,6 +226,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand Down Expand Up @@ -256,6 +262,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand Down Expand Up @@ -291,6 +298,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand All @@ -315,6 +323,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand All @@ -335,6 +344,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand All @@ -355,6 +365,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand Down Expand Up @@ -385,6 +396,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand All @@ -410,6 +422,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand All @@ -428,6 +441,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand Down Expand Up @@ -472,6 +486,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand Down Expand Up @@ -516,6 +531,7 @@ func TestArgsParsing(t *testing.T) {
printIntro: true,
printProgress: false,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
Expand All @@ -540,6 +556,127 @@ func TestArgsParsing(t *testing.T) {
printIntro: false,
printProgress: false,
printResult: false,
format: knownFormat("plain-text"),
},
},
{
[][]string{
{
programName,
"--format", "plain-text",
"https://somehost.somedomain",
},
{
programName,
"--format", "pt",
"https://somehost.somedomain",
},
{
programName,
"--format=plain-text",
"https://somehost.somedomain",
},
{
programName,
"--format=pt",
"https://somehost.somedomain",
},
{
programName,
"-o", "plain-text",
"https://somehost.somedomain",
},
{
programName,
"-o", "pt",
"https://somehost.somedomain",
},
},
config{
numConns: defaultNumberOfConns,
timeout: defaultTimeout,
headers: new(headersList),
method: "GET",
url: "https://somehost.somedomain",
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
[][]string{
{
programName,
"--format", "json",
"https://somehost.somedomain",
},
{
programName,
"--format", "j",
"https://somehost.somedomain",
},
{
programName,
"--format=json",
"https://somehost.somedomain",
},
{
programName,
"--format=j",
"https://somehost.somedomain",
},
{
programName,
"-o", "json",
"https://somehost.somedomain",
},
{
programName,
"-o", "j",
"https://somehost.somedomain",
},
},
config{
numConns: defaultNumberOfConns,
timeout: defaultTimeout,
headers: new(headersList),
method: "GET",
url: "https://somehost.somedomain",
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("json"),
},
},
{
[][]string{
{
programName,
"--format", "path:/path/to/tmpl.txt",
"https://somehost.somedomain",
},
{
programName,
"--format=path:/path/to/tmpl.txt",
"https://somehost.somedomain",
},
{
programName,
"-o", "path:/path/to/tmpl.txt",
"https://somehost.somedomain",
},
},
config{
numConns: defaultNumberOfConns,
timeout: defaultTimeout,
headers: new(headersList),
method: "GET",
url: "https://somehost.somedomain",
printIntro: true,
printProgress: true,
printResult: true,
format: userDefinedTemplate("/path/to/tmpl.txt"),
},
},
}
Expand Down Expand Up @@ -635,3 +772,21 @@ func TestArgsParsingWithEmptyPrintSpec(t *testing.T) {
t.Fail()
}
}

func TestArgsParsingWithInvalidPrintSpec(t *testing.T) {
invalidSpecs := [][]string{
{programName, "--format", "noprefix.txt", "somehost.somedomain"},
{programName, "--format=noprefix.txt", "somehost.somedomain"},
{programName, "-o", "noprefix.txt", "somehost.somedomain"},
{programName, "--format", "unknown-format", "somehost.somedomain"},
{programName, "--format=unknown-format", "somehost.somedomain"},
{programName, "-o", "unknown-format", "somehost.somedomain"},
}
p := newKingpinParser()
for _, is := range invalidSpecs {
c, err := p.parse(is)
if err == nil || c != emptyConf {
t.Errorf("invalid print spec %q parsed correctly", is)
}
}
}
Loading

0 comments on commit 3a8f621

Please sign in to comment.