mctester

package module
v0.0.0-...-49cf40c Latest Latest
Warning

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

Go to latest
Published: Mar 3, 2022 License: BSD-3-Clause Imports: 11 Imported by: 0

README

Load tester/fuzzer for memcached.


Goals:
  • Allow easy creation of programs to test specific load patterns for long-term stability evaluation.
  • Generally for testing against a single instance of memcached
  • High but not maximum performance. mc-crusher should instead be used for stress testing performance.
  • Can be used in combination with fault generating systems (ie; toxiproxy)

cd cmd/basic ; go build
./basic -h

create new load patterns by making new directories under cmd/


Kitchen-sink phobic.

Testing for a novel load pattern should be done by copying top level binaries (ie; cmd/basic) into a new directory and adding anything specific into the code. Add or remove command line options as necessary.

Common tricks should filter up into library code.

Server loader.

Under cmd/server is a load tester that runs as an HTTP server. It lets you start multiple types of workloads, update current workloads, and stop workloads.

By default it listens on port 11210 with HTTP

example:

cd cmd/server ; go build
# Print out usage and defaults
./server

# Starts the server, listening on default port
./server start

# start memcached somewhere else
memcached -m 256 -d

# Get a template JSON file for the basic loader
./server show --type basic

# modify the output to your liking, save as "foo.json"
# Set the name to "toast" inside foo.json

# Start a workload
./server set --file ./foo.json

# A persistent workload is now running.
# Edit the .json file slightly, but keep the name the same.
./server set --file ./foo.json

# The existing workload has been updated.
# Note: not all parameters can be updated at runtime.
# File a bug if something doesn't update and is important to you!

# Now, stop the workload.
./server delete --name "toast"

# Workload is now stopped

Once you have a workload tuned, keep a few json files around and write a shell script to execute your workload. This can be used to emulate multiple types of clients running against the same server, peak/antipeak, fluctuations, mass spikes, and so on.

Documentation

Index

Constants

View Source
const (
	McCHECK_ERROR // bodge. guessing these should all be in err...
	McVA
	McOK
	McEN
	McME
	McNS
	McEX
	McNF
	McMN
	McSE
	McER
	McCL
	McHIT
	McMISS
	McSTORED
	McNOT_STORED
	McSERVER_ERROR
	McDELETED
	McNOT_FOUND
	McERROR
)
View Source
const (
	McOP_GET        = 0x00
	McOP_SET        = 0x01
	McOP_ADD        = 0x02
	McOP_REPLACE    = 0x03
	McOP_DELETE     = 0x04
	McOP_INCREMENT  = 0x05
	McOP_DECREMENT  = 0x06
	McOP_QUIT       = 0x07
	McOP_FLUSH      = 0x08
	McOP_GETQ       = 0x09
	McOP_NOOP       = 0x0a
	McOP_VERSION    = 0x0b
	McOP_GETK       = 0x0c
	McOP_GETKQ      = 0x0d
	McOP_APPEND     = 0x0e
	McOP_PREPEND    = 0x0f
	McOP_STAT       = 0x10
	McOP_SETQ       = 0x11
	McOP_ADDQ       = 0x12
	McOP_REPLACEQ   = 0x13
	McOP_DELETEQ    = 0x14
	McOP_INCREMENTQ = 0x15
	McOP_DECREMENTQ = 0x16
	McOP_QUITQ      = 0x17
	McOP_FLUSHQ     = 0x18
	McOP_APPENDQ    = 0x19
	McOP_PREPENDQ   = 0x1a
	McOP_TOUCH      = 0x1c
)

Variables

View Source
var (
	ErrCorruptValue       = errors.New("corrupt value in response")
	ErrUnknownStatus      = errors.New("unknown status code in response")
	ErrKeyTooLong         = errors.New("key is too long")
	ErrKeyDoesNotMatch    = errors.New("response key does not match request key")
	ErrUnexpectedResponse = errors.New("unexpected response from server")
	ErrServerError        = errors.New("SERVER_ERROR received")
)

Define errors here to allow comparison.

View Source
var (
	// ErrItemNotFound indicates the item was not found when command is cas/delete/incr/decr
	ErrItemNotFound = errors.New("item is not found")
	// ErrItemExists indicates the item has stored where command is cas
	ErrItemExists = errors.New("item exists")
	// ErrItemNotStored indicates the data not stored where command is add
	ErrItemNotStored = errors.New("item is not stored")
)

Functions

func ParseUint

func ParseUint(part []byte) (n uint64, i int)

no overflow/anything testing. numerics from memcached should make sense unless corrupted.

func RandBytes

func RandBytes(src rand.Source, n int) []byte

randomized values! FIXME: take a buffer.

func RandString

func RandString(src rand.Source, n int) string

randomized keys! TODO: is sb reusable?

Types

type Client

type Client struct {
	ConnectTimeout time.Duration
	// read or write timeout
	NetTimeout time.Duration
	Host       string

	WBufSize int
	RBufSize int
	// contains filtered or unexported fields
}

func NewClient

func NewClient(host string) (client *Client)

func (*Client) BinCorrupt

func (c *Client) BinCorrupt() (opaque uint32, err error)

sends a corrupt/bad/evil packet in some form.

func (*Client) BinFlush

func (c *Client) BinFlush() (err error)

This _could_ just be Flush() and shared, but there might be reasons to hook something protocol specific in here.

func (*Client) BinGet

func (c *Client) BinGet(key string) (opaque uint32, err error)

TODO: opaque.

func (*Client) BinQuit

func (c *Client) BinQuit() (opaque uint32, err error)

func (*Client) BinQuitQ

func (c *Client) BinQuitQ() (opaque uint32, err error)

func (*Client) BinReceive

func (c *Client) BinReceive(item *Item) (opcode uint8, code McCode, err error)

don't run this without anything in the queue :P

func (*Client) BinSet

func (c *Client) BinSet(item *Item) (opaque uint32, err error)

func (*Client) BinTouch

func (c *Client) BinTouch(item *Item) (opaque uint32, err error)

func (*Client) Decr

func (c *Client) Decr(key string, delta uint64) (result uint64, code McCode, err error)

func (*Client) Delete

func (c *Client) Delete(key string) (code McCode, err error)

func (*Client) Get

func (c *Client) Get(key string) (flags uint64, value []byte, code McCode, err error)

func (*Client) Incr

func (c *Client) Incr(key string, delta uint64) (result uint64, code McCode, err error)

func (*Client) MetaDebug

func (c *Client) MetaDebug(key string) (err error)

TODO: helper func for chopping up result?

func (*Client) MetaDelete

func (c *Client) MetaDelete(key string, flags string) (err error)

func (*Client) MetaFlush

func (c *Client) MetaFlush() (err error)

func (*Client) MetaGet

func (c *Client) MetaGet(key string, flags string) (err error)

func (*Client) MetaNoop

func (c *Client) MetaNoop() (err error)

func (*Client) MetaReceive

func (c *Client) MetaReceive() (rflags []byte, value []byte, code McCode, err error)

Note: User should stop pulling when they know no more responses will happen, else this will wait forever.

func (*Client) MetaSet

func (c *Client) MetaSet(key string, flags string, value []byte) (err error)

func (*Client) ParseMetaResponse

func (c *Client) ParseMetaResponse() (rflags []byte, value []byte, code McCode, err error)

func (*Client) Set

func (c *Client) Set(key string, flags uint32, expiration uint32, value []byte) (code McCode, err error)

type Item

type Item struct {
	Key        string
	Value      []byte
	Expiration uint32
	Flags      uint32
	CAS        uint64
	Opaque     uint32
}

Debating if the other interfaces should use these structs... they should be passed in rather than generated internally. Also; should we be using a static byte buffer for key? not much to be done about the garbage generated by value, we can slice into what's generated by receiving data at least.

func (*Item) Reset

func (it *Item) Reset()

type McCode

type McCode int

TODO: write out the full code?

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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