trunks

package module
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 11, 2023 License: GPL-3.0 Imports: 22 Imported by: 0

README

Trunks

Trunks is a Go library that provide HTTP service with web user interface to test HTTP and/or WebSocket endpoints and for load testing HTTP endpoints.

For testing HTTP endpoints it use the lib/http package as the client, a wrapper for standard Go HTTP package. For testing WebSocket endpoints it use the lib/websocket package as the client. For the load testing we use vegeta as the backend.

Go documentation

Usage

See the example package on how to programmatically use and create service using this module, or,

Screenshots

The following screenshot display the main interface to Run or Attack the registered HTTP service,

Main interface

The following screenshot display the result of attack in two forms, vegeta metrics and vegeta histogram,

Attack result

Web user interface (WUI)

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.

Development

Repository:: Link to the source code.

Mailing list:: Link to discussion and where to send patches.

Issues:: Link to report for bug or feature.

Credits

The Trunks icon and image is provided by https://www.spriters-resource.com/.

License

Copyright (C) 2021 M. Shulhan ms@kilabit.info

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.

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

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

[1] https://github.com/tsenart/vegeta

Index

Constants

View Source
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.

View Source
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.

View Source
const EnvDevelopment = "TRUNKS_DEV"

EnvDevelopment setting this environment variable will enable trunks development mode.

View Source
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 FormInputKind

type FormInputKind string

FormInputKind define type for form input.

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

type KeyFormInput map[string]FormInput

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 struct {
	ID   string // Unique ID for this navigation, auto generated from Text.
	Text string // Text to display on navigation. Default to Href if its empty.
	Href string // The URL for navigation.

	// If true, the Href will be opened inside an iframe, otherwise it
	// 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 *Trunks) RegisterNavLink(nav *NavLink) (err error)

RegisterNavLink register custom navigation link.

func (*Trunks) RegisterTarget

func (trunks *Trunks) RegisterTarget(target *Target) (err error)

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.

func (*Trunks) Start

func (trunks *Trunks) Start() (err error)

Start the Trunks HTTP server that provide user interface for running and load testing registered Targets.

func (*Trunks) Stop

func (trunks *Trunks) Stop()

Stop the Trunks HTTP server.

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.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL