Skip to content

Commit

Permalink
refactoring main / client package. adding docs
Browse files Browse the repository at this point in the history
  • Loading branch information
rogerwelin committed Feb 3, 2020
1 parent 05c62a2 commit 28cb6f0
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 28 deletions.
1 change: 1 addition & 0 deletions README-ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ $ go mod init test && go get github.com/rogerwelin/cassowary/pkg/client
package main

import (
"encoding/json"
"fmt"

"github.com/rogerwelin/cassowary/pkg/client"
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ And below show a simple example on how to trigger a load test from your code and
package main

import (
"encoding/json"
"fmt"

"github.com/rogerwelin/cassowary/pkg/client"
Expand Down Expand Up @@ -225,6 +226,9 @@ func main() {
}
```

More library examples [can be found here](docs/LIBRARY.md)


Versioning
--------

Expand Down
16 changes: 6 additions & 10 deletions cmd/cassowary/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"strconv"

Expand Down Expand Up @@ -67,14 +66,6 @@ func runLoadTest(c *client.Cassowary) error {
return nil
}

func readFile(file string) ([]byte, error) {
fileContent, err := ioutil.ReadFile(file)
if err != nil {
return []byte{}, err
}
return fileContent, nil
}

func validateCLI(c *cli.Context) error {

prometheusEnabled := false
Expand Down Expand Up @@ -167,9 +158,13 @@ func validateCLIFile(c *cli.Context) error {
}
}

urlSuffixes, err := readLocalRemoteFile(c.String("file"))
if err != nil {
return nil
}

cass := &client.Cassowary{
FileMode: true,
InputFile: c.String("file"),
BaseURL: c.String("url"),
ConcurrencyLevel: c.Int("concurrency"),
RequestHeader: header,
Expand All @@ -180,6 +175,7 @@ func validateCLIFile(c *cli.Context) error {
DisableKeepAlive: c.Bool("diable-keep-alive"),
Timeout: c.Int("timeout"),
Requests: c.Int("requests"),
URLPaths: urlSuffixes,
HTTPMethod: "GET",
}

Expand Down
13 changes: 11 additions & 2 deletions pkg/client/fileops.go → cmd/cassowary/fileops.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package client
package main

import (
"bufio"
"io"
"io/ioutil"
"net/http"
"os"
"path/filepath"
Expand Down Expand Up @@ -36,7 +37,15 @@ func downloadPath(url string) (string, error) {
return binDir + "/load.txt", nil
}

func readFile(filePath string) ([]string, error) {
func readFile(file string) ([]byte, error) {
fileContent, err := ioutil.ReadFile(file)
if err != nil {
return []byte{}, err
}
return fileContent, nil
}

func readLocalRemoteFile(filePath string) ([]string, error) {
var urlLines []string
var err error

Expand Down
86 changes: 86 additions & 0 deletions docs/LIBRARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@

## Using Cassowary as an Library

Cassowary can be imported and used as a module in your Go app. Start by fetching the dependency by using go mod:

```bash
$ go mod init test && go get github.com/rogerwelin/cassowary/pkg/client
```

**Example 1: Simple Load Test of an URL**

```go
package main

import (
"encoding/json"
"fmt"

cassowary "github.com/rogerwelin/cassowary/pkg/client"
)

func main() {
cass := &cassowary.Cassowary{
BaseURL: "http://www.example.com",
ConcurrencyLevel: 1,
Requests: 10,
DisableTerminalOutput: true,
}
metrics, err := cass.Coordinate()
if err != nil {
panic(err)
}

// print results
fmt.Printf("%+v\n", metrics)

// or print as json
jsonMetrics, err := json.Marshal(metrics)
if err != nil {
panic(err)
}

fmt.Println(string(jsonMetrics))
}
```

**Example 2: Load Test an URL across multiple URL paths**

The following code will make 30 requests across the 3 URL paths declared in the URLPaths field:

```go
package main

import (
"encoding/json"
"fmt"

cassowary "github.com/rogerwelin/cassowary/pkg/client"
)

func main() {
cass := &cassowary.Cassowary{
BaseURL: "http://www.example.com",
ConcurrencyLevel: 2,
Requests: 30,
FileMode: true,
URLPaths: []string{"/accounts", "/orders", "/customers"}
DisableTerminalOutput: true,
}
metrics, err := cass.Coordinate()
if err != nil {
panic(err)
}

// print results
fmt.Printf("%+v\n", metrics)

// or print as json
jsonMetrics, err := json.Marshal(metrics)
if err != nil {
panic(err)
}

fmt.Println(string(jsonMetrics))
}
```
20 changes: 6 additions & 14 deletions pkg/client/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,28 +145,20 @@ func (c *Cassowary) Coordinate() (ResultMetrics, error) {
}
c.IsTLS = tls

var urlSuffixes []string

c.Client = &http.Client{
Timeout: time.Second * time.Duration(c.Timeout),
Transport: &http.Transport{
//MaxIdleConns: 300,
MaxIdleConnsPerHost: 10000,
//MaxConnsPerHost: 300,
DisableCompression: false,
DisableKeepAlives: c.DisableKeepAlive,
DisableCompression: false,
DisableKeepAlives: c.DisableKeepAlive,
},
}

if c.FileMode {
urlSuffixes, err = readFile(c.InputFile)
if err != nil {
return ResultMetrics{}, err
}
if c.Requests > len(urlSuffixes) {
urlSuffixes = generateSuffixes(urlSuffixes, c.Requests)
if c.Requests > len(c.URLPaths) {
c.URLPaths = generateSuffixes(c.URLPaths, c.Requests)
}
c.Requests = len(urlSuffixes)
c.Requests = len(c.URLPaths)
}

c.Bar = progressbar.New(c.Requests)
Expand All @@ -191,7 +183,7 @@ func (c *Cassowary) Coordinate() (ResultMetrics, error) {
}

if c.FileMode {
for _, line := range urlSuffixes {
for _, line := range c.URLPaths {
workerChan <- line
}
} else {
Expand Down
37 changes: 36 additions & 1 deletion pkg/client/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
)

func TestLoadCoordinate(t *testing.T) {

srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte("ok"))
Expand Down Expand Up @@ -38,3 +37,39 @@ func TestLoadCoordinate(t *testing.T) {
t.Errorf("Wanted %d but got %d", 0, metrics.FailedRequests)
}
}

func TestLoadCoordinateURLPaths(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte("ok"))
}))
defer srv.Close()

cass := Cassowary{
BaseURL: srv.URL,
ConcurrencyLevel: 1,
Requests: 30,
FileMode: true,
URLPaths: []string{"/get_user", "/get_accounts", "/get_orders"},
DisableTerminalOutput: true,
}
metrics, err := cass.Coordinate()
if err != nil {
t.Error(err)
}
if metrics.BaseURL != srv.URL {
t.Errorf("Wanted %s but got %s", srv.URL, metrics.BaseURL)
}

if metrics.TotalRequests != 30 {
t.Errorf("Wanted %d but got %d", 1, metrics.TotalRequests)
}

if metrics.FailedRequests != 0 {
t.Errorf("Wanted %d but got %d", 0, metrics.FailedRequests)
}

if len(cass.URLPaths) != 30 {
t.Errorf("Wanted %d but got %d", 30, len(cass.URLPaths))
}
}
2 changes: 1 addition & 1 deletion pkg/client/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
type Cassowary struct {
FileMode bool
IsTLS bool
InputFile string
BaseURL string
ConcurrencyLevel int
Requests int
Expand All @@ -19,6 +18,7 @@ type Cassowary struct {
PromExport bool
PromURL string
RequestHeader []string
URLPaths []string
DisableTerminalOutput bool
DisableKeepAlive bool
Client *http.Client
Expand Down

0 comments on commit 28cb6f0

Please sign in to comment.