Documentation ¶
Overview ¶
Package gorankusu is a library and HTTP service that provide web user interface to test HTTP service, similar to Postman, and for load testing.
For the load testing we use vegeta [1] as the backend.
Usage ¶
See the example package on how to programmatically use and create service using this module, or
- clone this repository,
- execute `make run`, and
- open http://127.0.0.1:8217.
Screen shots ¶
The following screenshot display the main interface to Run or Attack the registered HTTP service,
https://git.sr.ht/~shulhan/gorankusu/blob/main/_screenshots/gorankusu_example.png
The following screenshot display the result of attack in two forms, vegeta metrics and vegeta histogram,
https://git.sr.ht/~shulhan/gorankusu/blob/main/_screenshots/gorankusu_attack_result.png
Web user interface ¶
By default, the Gorankusu user interface can be viewed by opening in browser at http://127.0.0.1:8217. One can change address through Environment's ListenAddress.
File name format ¶
Each attack result is saved in Environment's ResultsDir with the following file name format,
<Target.ID> "." <HttpTarget.ID> "." <DateTime> "." <Rate> "x" <Duration> "." <ResultsSuffix>
The "DateTime" is in the following layout,
YearMonthDate "_" HourMinuteSeconds
The "ResultsSuffix" is the one that defined in Environment.
License ¶
Copyright 2021, Shulhan <ms@kilabit.info>. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
References ¶
Index ¶
- Constants
- type AttackOptions
- type AttackResult
- type Environment
- type Example
- type FormInput
- type FormInputKind
- type Gorankusu
- func (gorankusu *Gorankusu) AttackHTTP(req *RunRequest) (err error)
- func (gorankusu *Gorankusu) AttackHTTPCancel() (rr *RunRequest, err error)
- func (gorankusu *Gorankusu) RegisterNavLink(nav *NavLink) (err error)
- func (gorankusu *Gorankusu) RegisterTarget(target *Target) (err error)
- func (gorankusu *Gorankusu) RunHTTP(req *RunRequest) (res *RunResponse, err error)
- func (gorankusu *Gorankusu) Start() (err error)
- func (gorankusu *Gorankusu) Stop()
- type HTTPAttackHandler
- type HTTPParamsConverter
- type HTTPPreAttackHandler
- type HTTPRequestDumper
- type HTTPResponseDumper
- type HTTPRunHandler
- type HTTPTarget
- type KeyFormInput
- type NavLink
- type RunRequest
- type RunResponse
- type Target
- type WebSocketRunHandler
- type WebSocketTarget
Constants ¶
const ( // FormInputKindBoolean only used for convertion, for example // ToJSONObject. // In the WUI, it will be rendered as string. FormInputKindBoolean = `boolean` // FormInputKindFile define the input for uploading file. // This form will rendered as "<input type='file' ...>" on the web // user interface. // Once submitted, the file name, type, size, and lastModification // will be stored under [FormInput] Filename, Filetype, Filesize, // and Filemodms. FormInputKindFile = `file` FormInputKindNumber = `number` FormInputKindString = `string` )
List of valid value for field FormInput Kind.
const ( FormDataFilecontent = `filecontent` FormDataFilemodms = `filemodms` FormDataFilename = `filename` FormDataFilesize = `filesize` FormDataFiletype = `filetype` )
List of additional parameters to be generated and send if the FormInput Kind is FormInputKindFile.
Caller can changes the name by using FormInput FormDataName.
const DefaultAttackDuration = 10 * time.Second
DefaultAttackDuration define default attack duration per Target. This is default value for [AttackOptions.Duration].
const DefaultAttackRatePerSecond = 500
DefaultAttackRatePerSecond define default attack rate per second per Target. This is default value for [AttackOptions.RatePerSecond].
const DefaultAttackTimeout = 30 * time.Second
DefaultAttackTimeout define default timeout for each attack request. This is default value for [AttackOptions.Timeout].
const DefaultListenAddress = `127.0.0.1:8217`
DefaultListenAddress define default gorankusu server address.
const DefaultMaxAttackDuration = 30 * time.Second
DefaultMaxAttackDuration define maximum duration attack can run on all Target. This is default value for [Environment.MaxAttackDuration].
const DefaultMaxAttackRate = 3000
DefaultMaxAttackRate define maximum rate an attack can run. This is default value for [Environment.MaxAttackRate].
const Version = `0.6.1`
Version of gorankusu module.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AttackOptions ¶
type AttackOptions struct { // Duration define the duration for each attack to be executed, // in seconds. // For example, if the AttackRate is 500 and AttackDuration is 10 // seconds, the total of request for each target will be 5000 // requests. // This field is optional, default to DefaultAttackDuration if its // zero. Duration time.Duration // RatePerSecond define the number of request per second. // This field is optional, default to DefaultAttackRatePerSecond if // its zero. RatePerSecond int // Timeout define the overall time to run the attack on each target. // This field is optional, default to DefaultAttackTimeout if its // zero. Timeout time.Duration // contains filtered or unexported fields }
AttackOptions define the options for attacking HTTP endpoint.
type AttackResult ¶
type AttackResult struct { TargetID string // ID of Target. HTTPTargetID string // ID of HTTP target which own the result. Name string // Name of output file without path. TextReport []byte // TextReport the result reported as text. HistReport []byte // HistReport the result reported as histogram text. // contains filtered or unexported fields }
AttackResult represent the output from load testing.
type Environment ¶
type Environment struct { // AttackRunning will be set to non-nil if there is a load // testing currently running. AttackRunning *RunRequest // ListenAddress is the address and port where Gorankusu HTTP web // will run. // If its emtpy, it will set to DefaultListenAddress. ListenAddress string `ini:"gorankusu::listen_address"` // ResultsDir is the path where the output of load testing will be // stored. // This field is optional, if its empty it will be set to the working // directory where the program is running. ResultsDir string `ini:"gorankusu:results:dir"` // ResultsSuffix define custom string to add to the file name to // uniquely identify results on each run. ResultsSuffix string `ini:"gorankusu:result:suffix"` // MaxAttackRate define the maximum AttackRate can be set by client. // The purpose of this option is to prevent client to set attack rate // which may bring down the service to be tested. // This field is optional, default to DefaultMaxAttackRate if its // zero. MaxAttackRate int `ini:"gorankusu::max_attack_rate"` // MaxAttackDuration define the maximum duration for an attack to be // run on each target. // The purpose of this option is to prevent client to attack service // and bringing it down. // This field is optional, default to DefaultMaxAttackDuration if its // zero. MaxAttackDuration time.Duration `ini:"gorankusu::max_attack_duration"` // IsDevelopment if true run gorankusu in testing mode. IsDevelopment bool // contains filtered or unexported fields }
Environment contains global configuration for load testing.
type Example ¶ added in v0.6.0
type Example struct { *Gorankusu // contains filtered or unexported fields }
Example provide an example how to use the Gorankusu library from setting it up to creating targets.
To run the example, execute
$ go run ./internal/cmd/gorankusu
It will run a web user interface at http://127.0.0.1:8217 .
func NewExample ¶ added in v0.6.0
NewExample create, initialize, and setup an example of Gorankusu.
type FormInput ¶
type FormInput struct { // FormDataName define function to map FormInputKindFile name // into different name. // For example, instead of, // // Content-Disposition: form-data; name="filesize" // // One can change the "filesize" to "size" using this function, so // generated request body would be, // // Content-Disposition: form-data; name="size" FormDataName func(string) string `json:"-"` Label string `json:"label"` Hint string `json:"hint"` Kind FormInputKind `json:"kind"` Value string `json:"value"` // The name of file for FormInputKindFile. Filename string `json:"filename"` Filetype string `json:"filetype"` // The file size for FormInputKindFile. Filesize int64 `json:"filesize"` // The file modification in millisecond. Filemodms int64 `json:"filemodms"` Max float64 `json:"max,omitempty"` Min float64 `json:"min,omitempty"` }
FormInput provide the information to create an input component.
The Label field define the input text. The Hint field provide a description about the input. The Kind field describe the type of input (number, string, and so on). The Value field contains default value for input.
The Max and Min fields is optional, it only affect if the Kind is FormInputKindNumber.
If the Kind is FormInputKindFile, the Filename, Filetype, Filesize, and Filemodms will be filled by request based on the file name, type, size, and modification time.
type Gorankusu ¶
type Gorankusu struct { Env *Environment Httpd *libhttp.Server // contains filtered or unexported fields }
Gorankusu is the HTTP server with web user interface and APIs for running and load testing the registered HTTP endpoints.
func New ¶
func New(env *Environment) (gorankusu *Gorankusu, err error)
New create and initialize new Gorankusu service.
func (*Gorankusu) AttackHTTP ¶
func (gorankusu *Gorankusu) AttackHTTP(req *RunRequest) (err error)
AttackHTTP start attacking the HTTP target defined in req.
func (*Gorankusu) AttackHTTPCancel ¶
func (gorankusu *Gorankusu) AttackHTTPCancel() (rr *RunRequest, err error)
AttackHTTPCancel cancel any running attack. It will return an error if no attack is running.
func (*Gorankusu) RegisterNavLink ¶
RegisterNavLink register custom navigation link.
func (*Gorankusu) RegisterTarget ¶
RegisterTarget register Target to be attached to Gorankusu.
func (*Gorankusu) RunHTTP ¶
func (gorankusu *Gorankusu) RunHTTP(req *RunRequest) (res *RunResponse, err error)
RunHTTP send the HTTP request to the HTTP target defined in RunRequest with optional Headers and Parameters.
type HTTPAttackHandler ¶
type HTTPAttackHandler func(rr *RunRequest) vegeta.Targeter
HTTPAttackHandler define the function type that will be called when client send request to attack HTTP target.
func DefaultHTTPAttack ¶ added in v0.6.0
func DefaultHTTPAttack() HTTPAttackHandler
DefaultHTTPAttack define the default value for [HTTPTarget.Attack] handler that return vegeta.Targeter.
type HTTPParamsConverter ¶ added in v0.6.0
type HTTPParamsConverter func(target *HTTPTarget) (any, error)
HTTPParamsConverter is a handler that will be called inside the Run handler to convert the Params values to type that will be send as request.
func DefaultParamsConverter ¶ added in v0.6.0
func DefaultParamsConverter() HTTPParamsConverter
DefaultParamsConverter define default function to convert [HTTPTarget.Params] to its equivalent parameters in HTTP, either as query in URL or as stream of bytes in body.
type HTTPPreAttackHandler ¶
type HTTPPreAttackHandler func(rr *RunRequest)
HTTPPreAttackHandler define the function type that will be called before the actual Attack being called.
type HTTPRequestDumper ¶
HTTPRequestDumper define an handler to convert http.Request into RunResponse DumpRequest.
func DefaultRequestDumper ¶ added in v0.6.0
func DefaultRequestDumper() HTTPRequestDumper
DefaultRequestDumper define default HTTPRequestDumper that convert http.Request with its body to stream of bytes using httputil.DumpRequest.
The returned bytes have CRLF ("\r\n") replaced with single LF ("\n").
type HTTPResponseDumper ¶
HTTPResponseDumper define an handler to convert http.Response into RunResponse DumpResponse.
func DefaultResponseDumper ¶ added in v0.6.0
func DefaultResponseDumper() HTTPResponseDumper
DefaultResponseDumper define default HTTPResponseDumper that convert http.Response with its body to stream of bytes using httputil.DumpResponse.
The returned bytes have CRLF ("\r\n") replaced with single LF ("\n").
type HTTPRunHandler ¶
type HTTPRunHandler func(rr *RunRequest) (runres *RunResponse, err error)
HTTPRunHandler define the function type that will be called when client send request to run the HTTP target.
func DefaultHTTPRun ¶ added in v0.6.0
func DefaultHTTPRun() HTTPRunHandler
DefaultHTTPRun default [HTTPTarget.Run] handler that generate http.Request, send it to the target, and store and dump them into RunResponse.
type HTTPTarget ¶
type HTTPTarget struct { Params KeyFormInput // ParamsConverter define the custom function to convert the Params // into HTTP request. // This field is optional default to [DefaultParamsConverter]. ParamsConverter HTTPParamsConverter `json:"-"` Headers KeyFormInput // Run define the handler that will be called when request to run // HTTPTarget received from client (web user-interface). // This field is optional, default to [DefaultHTTPRun]. Run HTTPRunHandler `json:"-"` PreAttack HTTPPreAttackHandler `json:"-"` // Attack define custom handler to generate [vegeta.Attacker]. // This field is optional default to [DefaultAttack]. Attack HTTPAttackHandler `json:"-"` // RequestDumper define the handler to store [http.Request] after // Run into [RunRequest.DumpRequest]. // Default to [DefaultRequestDumper] if its nil. RequestDumper HTTPRequestDumper `json:"-"` // ResponseDumper define the handler to store [http.Response] after // Run into [RunRequest.DumpResponse]. // Default to [DefaultResponseDumper] if its nil. ResponseDumper HTTPResponseDumper `json:"-"` // ID of target, optional. // If its empty, it will generated using value from Name. ID string Name string // Name of target, required. Hint string // Description about what this HTTP target is doing. Path string Method libhttp.RequestMethod RequestType libhttp.RequestType // RawBody contains raw request body that is being read and // forwarded to target. // It will be used only WithRawBody is true. RawBody []byte Results []*AttackResult // Results contains list of load testing output. sync.Mutex `json:"-"` // Use this inside the Attack to lock resource. // AllowAttack if its true the "Attack" button will be showed on user // interface and client will be allowed to run load testing on this // HTTPTarget. AllowAttack bool // IsCustomizable allow client to modify the Method, Path, and // RequestType. IsCustomizable bool // WithRawBody if true the request is read and forwarded from Body // instead of from Params. WithRawBody bool }
HTTPTarget define the HTTP endpoint that can be attached to Gorankusu.
func (*HTTPTarget) String ¶
func (ht *HTTPTarget) String() string
type KeyFormInput ¶
KeyFormInput is the simplified type for getting and setting HTTP headers and request parameters (either in query or in the parameter body).
func (KeyFormInput) ToHTTPHeader ¶
func (kfi KeyFormInput) ToHTTPHeader() (headers http.Header)
ToHTTPHeader convert the KeyFormInputs to the standard http.Header.
func (KeyFormInput) ToJSONObject ¶
func (kfi KeyFormInput) ToJSONObject() (data map[string]interface{})
ToJSONObject convert the KeyFormInput into JSON object. FormInput with Kind is FormInputKindBoolean will be converted to true if the Value is either "true", "yes", or "1".
func (KeyFormInput) ToMultipartFormData ¶
func (kfi KeyFormInput) ToMultipartFormData() (data map[string][]byte)
ToMultipartFormData convert the KeyFormInput into map of string and raw bytes.
func (KeyFormInput) ToURLValues ¶
func (kfi KeyFormInput) ToURLValues() (vals url.Values)
ToURLValues convert the KeyFormInput to the standard url.Values.
type NavLink ¶
type NavLink struct { // will opened in new tab. OpenInIFrame bool }
NavLink contains the data for custom navigation link.
type RunRequest ¶
type RunRequest struct { WebSocketTarget WebSocketTarget HTTPTarget HTTPTarget Target Target // contains filtered or unexported fields }
RunRequest define the request to run HTTP or WebSocket target.
func (*RunRequest) String ¶
func (rr *RunRequest) String() string
type RunResponse ¶
type RunResponse struct { ResponseStatus string ResponseType string DumpRequest []byte DumpResponse []byte ResponseBody []byte ResponseStatusCode int }
RunResponse contains the raw request and response when running HTTP or WebSocket target.
func (*RunResponse) SetHTTPRequest ¶
func (rres *RunResponse) SetHTTPRequest(dumper HTTPRequestDumper, req *http.Request) (err error)
SetHTTPRequest dump the HTTP request including body into the DumpRequest field.
func (*RunResponse) SetHTTPResponse ¶
func (rres *RunResponse) SetHTTPResponse(dumper HTTPResponseDumper, res *http.Response) (err error)
SetHTTPResponse dump the HTTP response including body into the DumpResponse field.
type Target ¶
type Target struct { // HTTPClient that can be used for running HTTPTarget. HTTPClient *libhttp.Client `json:"-"` // Headers define global headers that will send on all HTTPTargets // or WebSocketTargets. // The same header can also be defined on HTTPTarget that override // the value in here. Headers KeyFormInput Vars KeyFormInput ID string Name string // BaseURL contains the target address that serve the service to // be tested. // This field is required. BaseURL string Hint string HTTPTargets []*HTTPTarget WebSocketTargets []*WebSocketTarget Opts AttackOptions }
Target contains group of HTTPTarget that can be tested by Gorankusu.
type WebSocketRunHandler ¶
type WebSocketRunHandler func(rr *RunRequest) (interface{}, error)
WebSocketRunHandler define a function type that will be called to run the WebSocket target.
type WebSocketTarget ¶
type WebSocketTarget struct { Headers KeyFormInput // Params contains additional parameters to be passed when running // the WebSocket handler. // It could be custom HTTP headers, query parameters, or arguments in // the body. Its up to the user on how to use the Params inside the // Run handler. // This field is optional. Params KeyFormInput Run WebSocketRunHandler `json:"-"` // ID of target, optional. // If its empty, it will generated by normalized the value of Name. ID string Name string // Name of target, required. Hint string // Description about what this WebSocket target is doing. }
WebSocketTarget define the target to test WebSocket service.
Source Files ¶
- attack_options.go
- attack_result.go
- common.go
- doc.go
- environment.go
- errors.go
- example.go
- form_input.go
- gorankusu.go
- http_attack_handler.go
- http_params_converter.go
- http_request_dumper.go
- http_response_dumper.go
- http_run_handler.go
- http_server.go
- http_target.go
- key_form_input.go
- memfs.go
- memfs_www_embed.go
- nav_link.go
- run_request.go
- run_response.go
- target.go
- websocket_target.go
Directories ¶
Path | Synopsis |
---|---|
internal
|
|
cmd/gorankusu
Program gorankusu provide an example how to use the Gorankusu module.
|
Program gorankusu provide an example how to use the Gorankusu module. |