Documentation ¶
Overview ¶
Package trunks 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/trunks/blob/main/_screenshots/trunks_example.png
The following screenshot display the result of attack in two forms, vegeta metrics and vegeta histogram,
https://git.sr.ht/~shulhan/trunks/blob/main/_screenshots/trunks_attack_result.png
Web user interface ¶
By default, the Trunks 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 FormInput
- type FormInputKind
- type HttpAttackHandler
- type HttpConvertParams
- type HttpPreAttackHandler
- type HttpRunHandler
- type HttpTarget
- type KeyFormInput
- type NavLink
- type RunRequest
- type RunResponse
- type Target
- type Trunks
- func (trunks *Trunks) AttackHttp(req *RunRequest) (err error)
- func (trunks *Trunks) AttackHttpCancel() (rr *RunRequest, err error)
- func (trunks *Trunks) RegisterNavLink(nav *NavLink) (err error)
- func (trunks *Trunks) RegisterTarget(target *Target) (err error)
- func (trunks *Trunks) RunHttp(req *RunRequest) (res *RunResponse, err error)
- func (trunks *Trunks) Start() (err error)
- func (trunks *Trunks) Stop()
- 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` FormInputKindNumber = `number` FormInputKindString = `string` )
List of valid value for field FormInput.Kind.
const ( DefaultAttackDuration = 10 * time.Second DefaultAttackRatePerSecond = 500 DefaultAttackTimeout = 30 * time.Second DefaultMaxAttackDuration = 30 * time.Second DefaultMaxAttackRate = 3000 DefaultListenAddress = `127.0.0.1:8217` )
List of default values.
const EnvDevelopment = "TRUNKS_DEV"
EnvDevelopment setting this environment variable will enable trunks development mode.
const Version = `0.4.1`
Version of trunks 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 Trunks HTTP web // will run. // If its emtpy, it will set to DefaultListenAddress. ListenAddress string `ini:"trunks::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:"trunks:results:dir"` // ResultsSuffix define custom string to add to the file name to // uniquely identify results on each run. ResultsSuffix string `ini:"trunks: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:"trunks::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:"trunks::max_attack_duration"` // contains filtered or unexported fields }
Environment contains global configuration for load testing.
type FormInput ¶
type FormInput struct { Label string `json:"label"` Hint string `json:"hint"` Kind FormInputKind `json:"kind"` Value string `json:"value"` 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), and the Value field contains default value for input.
The Max and Min fields is optional, it only affect if the Kind is FormInputKindNumber.
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.
type HttpConvertParams ¶
type HttpConvertParams func(target *HttpTarget) (interface{}, error)
HttpConvertParams is a handler that will be called inside the Run handler to convert the Params values to type that will be send as request.
type HttpPreAttackHandler ¶
type HttpPreAttackHandler func(rr *RunRequest)
HttpPreAttackHandler define the function type that will be called before the actual Attack being called.
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.
type HttpTarget ¶
type HttpTarget struct { Params KeyFormInput ConvertParams HttpConvertParams `json:"-"` Headers KeyFormInput Run HttpRunHandler `json:"-"` PreAttack HttpPreAttackHandler `json:"-"` Attack HttpAttackHandler `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 Results []*AttackResult // Results contains list of load testing output. RequestType libhttp.RequestType Method libhttp.RequestMethod 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 }
HttpTarget define the HTTP endpoint that can be attached to Trunks.
func (*HttpTarget) String ¶ added in v0.3.0
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 { Target Target WebSocketTarget WebSocketTarget HttpTarget HttpTarget // 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(req *http.Request) (err error)
SetHttpRequest dump the HTTP request including body into the DumpRequest field.
func (*RunResponse) SetHttpResponse ¶
func (rres *RunResponse) SetHttpResponse(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:"-"` Opts *AttackOptions 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 }
Target contains group of HttpTarget that can be tested by Trunks.
type Trunks ¶
type Trunks struct { Env *Environment Httpd *libhttp.Server // contains filtered or unexported fields }
Trunks 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) (trunks *Trunks, err error)
New create and initialize new Trunks service.
func (*Trunks) AttackHttp ¶
func (trunks *Trunks) AttackHttp(req *RunRequest) (err error)
AttackHttp start attacking the HTTP target defined in req.
func (*Trunks) AttackHttpCancel ¶
func (trunks *Trunks) AttackHttpCancel() (rr *RunRequest, err error)
AttackHttpCancel cancel any running attack. It will return an error if no attack is running.
func (*Trunks) RegisterNavLink ¶
RegisterNavLink register custom navigation link.
func (*Trunks) RegisterTarget ¶
RegisterTarget register Target to be attached to Trunks.
func (*Trunks) RunHttp ¶
func (trunks *Trunks) 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 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 ¶
Directories ¶
Path | Synopsis |
---|---|
Package example provide an example how to use the Trunks library from setting it up to creating targets.
|
Package example provide an example how to use the Trunks library from setting it up to creating targets. |
internal
|
|
cmd/trunks
Program trunks provide an example how to use the Trunks module.
|
Program trunks provide an example how to use the Trunks module. |