Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test coverage to xk6-redis #5

Merged
merged 5 commits into from
Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# v1.43.0
# v1.47.2
# Please don't remove the first line. It uses in CI to determine the golangci version
run:
deadline: 5m
Expand Down Expand Up @@ -29,6 +29,9 @@ issues:
text: "does not use range value in test Run"

linters-settings:
nolintlint:
# Disable to ensure that nolint directives don't have a leading space. Default is true.
allow-leading-space: false
exhaustive:
default-signifies-exhaustive: true
govet:
Expand All @@ -45,6 +48,13 @@ linters-settings:
funlen:
lines: 80
statements: 60
goheader:
template-path: ".license-template"
values:
const:
year: "2022"
regexp:
year-range: (\d\d\d\d|{{year}})

linters:
enable-all: true
Expand All @@ -68,7 +78,14 @@ linters:
- scopelint # deprecated, replaced by exportloopref
- wrapcheck # a little bit too much for k6, maybe after https://github.com/tomarrell/wrapcheck/issues/2 is fixed
- golint # this linter is deprecated
- varnamelen # disabled before the final decision in (https://github.com/grafana/k6/pull/2323)
- varnamelen
- ireturn
- tagliatelle
- exhaustruct
- execinquery
- maintidx
- grouper
- decorder
- nonamedreturns
- nosnakecase
fast: false
85 changes: 71 additions & 14 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ type Client struct {
}

// Set the given key with the given value.
//
// If the provided value is not a supported type, the promise is rejected with an error.
//
// The value for `expiration` is interpreted as seconds.
func (c *Client) Set(key string, value interface{}, expiration int) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand Down Expand Up @@ -46,6 +50,10 @@ func (c *Client) Set(key string, value interface{}, expiration int) *goja.Promis
}

// Get returns the value for the given key.
//
// If the key does not exist, the promise is rejected with an error.
//
// If the key does not exist, the promise is rejected with an error.
func (c *Client) Get(key string) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand All @@ -68,6 +76,8 @@ func (c *Client) Get(key string) *goja.Promise {
}

// GetSet sets the value of key to value and returns the old value stored
//
// If the provided value is not a supported type, the promise is rejected with an error.
func (c *Client) GetSet(key string, value interface{}) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand Down Expand Up @@ -117,6 +127,8 @@ func (c *Client) Del(keys ...string) *goja.Promise {
}

// GetDel gets the value of key and deletes the key.
//
// If the key does not exist, the promise is rejected with an error.
func (c *Client) GetDel(key string) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand Down Expand Up @@ -263,6 +275,8 @@ func (c *Client) DecrBy(key string, decrement int64) *goja.Promise {
}

// RandomKey returns a random key.
//
// If the database is empty, the promise is rejected with an error.
func (c *Client) RandomKey() *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand Down Expand Up @@ -332,7 +346,7 @@ func (c *Client) Expire(key string, seconds int) *goja.Promise {
}

// Ttl returns the remaining time to live of a key that has a timeout.
// nolint:stylecheck,revive
//nolint:revive,stylecheck
func (c *Client) Ttl(key string) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand Down Expand Up @@ -436,7 +450,10 @@ func (c *Client) Rpush(key string, values ...interface{}) *goja.Promise {
}

// Lpop removes and returns the first element of the list stored at `key`.
//
// If the list does not exist, this command rejects the promise with an error.
func (c *Client) Lpop(key string) *goja.Promise {
// TODO: redis supports indicating the amount of values to pop
promise, resolve, reject := c.makeHandledPromise()

if err := c.connect(); err != nil {
Expand All @@ -458,7 +475,10 @@ func (c *Client) Lpop(key string) *goja.Promise {
}

// Rpop removes and returns the last element of the list stored at `key`.
//
// If the list does not exist, this command rejects the promise with an error.
func (c *Client) Rpop(key string) *goja.Promise {
// TODO: redis supports indicating the amount of values to pop
promise, resolve, reject := c.makeHandledPromise()

if err := c.connect(); err != nil {
Expand Down Expand Up @@ -507,6 +527,8 @@ func (c *Client) Lrange(key string, start, stop int64) *goja.Promise {
// Lindex returns the specified element of the list stored at `key`.
// The index is zero-based. Negative indices can be used to designate
// elements starting at the tail of the list.
//
// If the list does not exist, this command rejects the promise with an error.
func (c *Client) Lindex(key string, index int64) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand All @@ -529,6 +551,8 @@ func (c *Client) Lindex(key string, index int64) *goja.Promise {
}

// Lset sets the list element at `index` to `element`.
//
// If the list does not exist, this command rejects the promise with an error.
func (c *Client) Lset(key string, index int64, element string) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand All @@ -554,6 +578,8 @@ func (c *Client) Lset(key string, index int64, element string) *goja.Promise {
// at `key`. If `count` is positive, elements are removed from the beginning of the list.
// If `count` is negative, elements are removed from the end of the list.
// If `count` is zero, all elements matching `value` are removed.
//
// If the list does not exist, this command rejects the promise with an error.
func (c *Client) Lrem(key string, count int64, value string) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand All @@ -577,6 +603,8 @@ func (c *Client) Lrem(key string, count int64, value string) *goja.Promise {

// Llen returns the length of the list stored at `key`. If `key`
// does not exist, it is interpreted as an empty list and 0 is returned.
//
// If the list does not exist, this command rejects the promise with an error.
func (c *Client) Llen(key string) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand All @@ -601,6 +629,8 @@ func (c *Client) Llen(key string) *goja.Promise {
// Hset sets the specified field in the hash stored at `key` to `value`.
// If the `key` does not exist, a new key holding a hash is created.
// If `field` already exists in the hash, it is overwritten.
//
// If the hash does not exist, this command rejects the promise with an error.
func (c *Client) Hset(key string, field string, value interface{}) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand Down Expand Up @@ -653,6 +683,8 @@ func (c *Client) Hsetnx(key, field, value string) *goja.Promise {
}

// Hget returns the value associated with `field` in the hash stored at `key`.
//
// If the hash does not exist, this command rejects the promise with an error.
func (c *Client) Hget(key, field string) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand Down Expand Up @@ -697,6 +729,8 @@ func (c *Client) Hdel(key string, fields ...string) *goja.Promise {
}

// Hgetall returns all fields and values of the hash stored at `key`.
//
// If the hash does not exist, this command rejects the promise with an error.
func (c *Client) Hgetall(key string) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand All @@ -719,6 +753,8 @@ func (c *Client) Hgetall(key string) *goja.Promise {
}

// Hkeys returns all fields of the hash stored at `key`.
//
// If the hash does not exist, this command rejects the promise with an error.
func (c *Client) Hkeys(key string) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand All @@ -741,6 +777,8 @@ func (c *Client) Hkeys(key string) *goja.Promise {
}

// Hvals returns all values of the hash stored at `key`.
//
// If the hash does not exist, this command rejects the promise with an error.
func (c *Client) Hvals(key string) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand All @@ -763,6 +801,8 @@ func (c *Client) Hvals(key string) *goja.Promise {
}

// Hlen returns the number of fields in the hash stored at `key`.
//
// If the hash does not exist, this command rejects the promise with an error.
func (c *Client) Hlen(key string) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand Down Expand Up @@ -917,6 +957,8 @@ func (c *Client) Smembers(key string) *goja.Promise {
}

// Srandmember returns a random element from the set value stored at key.
//
// If the set does not exist, the promise is rejected with an error.
func (c *Client) Srandmember(key string) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand All @@ -939,6 +981,8 @@ func (c *Client) Srandmember(key string) *goja.Promise {
}

// Spop removes and returns a random element from the set value stored at key.
//
// If the set does not exist, the promise is rejected with an error.
func (c *Client) Spop(key string) *goja.Promise {
promise, resolve, reject := c.makeHandledPromise()

Expand Down Expand Up @@ -1026,23 +1070,34 @@ func (c *Client) connect() error {
return common.NewInitContextError("connecting to a redis server in the init context is not supported")
}

if c.redisClient == nil {
// If k6 has a TLSConfig set in its state, use
// it has redis' client TLSConfig too.
if vuState.TLSConfig != nil {
c.redisOptions.TLSConfig = vuState.TLSConfig
}

// use k6's lib.DialerContexter function has redis'
// client Dialer
c.redisOptions.Dialer = vuState.Dialer.DialContext
// If the redisClient is already instantiated, it is safe
// to assume that the connection is already established.
if c.redisClient != nil {
return nil
}

c.redisClient = redis.NewUniversalClient(c.redisOptions)
// If k6 has a TLSConfig set in its state, use
// it has redis' client TLSConfig too.
if vuState.TLSConfig != nil {
c.redisOptions.TLSConfig = vuState.TLSConfig
}

// use k6's lib.DialerContexter function has redis'
// client Dialer
c.redisOptions.Dialer = vuState.Dialer.DialContext

// Replace the internal redis client instance with a new
// one using our custom options.
c.redisClient = redis.NewUniversalClient(c.redisOptions)

return nil
}

// IsConnected returns true if the client is connected to redis.
func (c *Client) IsConnected() bool {
return c.redisClient != nil
}

// isSupportedType returns whether the provided arguments are of a type
// supported by the redis client.
//
Expand All @@ -1060,9 +1115,11 @@ func (c *Client) isSupportedType(offset int, args ...interface{}) error {
for idx, arg := range args {
switch arg.(type) {
case string, int, int64, float64, bool:
return nil
continue
default:
return fmt.Errorf("unsupported type: %T for argument at index: %d", arg, idx+offset)
return fmt.Errorf(
"unsupported type provided for argument at index %d, "+
"supported types are string, number, and boolean", idx+offset)
}
}

Expand Down
Loading