Skip to content

Commit

Permalink
Add xk6-redis as experimental redis js module
Browse files Browse the repository at this point in the history
This commit imports the latest state of xk6-redis into k6's core as
an experimental module importable as "k6/experimental/redis".

With it comes a single direct dependency, the `redis/v8` library, and
two indirect dependencies implied by the former `xxhash`
and `go-rendezvous`.

This commit's essential files are:
* `js/modules/k6/experimental/redis`: the files composing the module
itself
* `js/initcontext.go`: exposes the module as `k6/experimental/redis`
* `samples/redis.go`: presents an example of the redis module in
action

The rest of the files are essentially go module and vendoring plumbing.
  • Loading branch information
oleiade committed Aug 3, 2022
1 parent 4435e87 commit 7350f8c
Show file tree
Hide file tree
Showing 63 changed files with 18,656 additions and 20 deletions.
9 changes: 7 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/fatih/color v1.13.0
github.com/golang/protobuf v1.5.2
github.com/gorilla/websocket v1.5.0
github.com/grafana/xk6-redis v0.1.0
github.com/influxdata/influxdb1-client v0.0.0-20190402204710-8ff2fc3824fc
github.com/jhump/protoreflect v1.12.0
github.com/klauspost/compress v1.15.7
Expand Down Expand Up @@ -40,6 +41,12 @@ require (
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
)

require (
github.com/andybalholm/cascadia v1.3.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
Expand All @@ -48,8 +55,6 @@ require (
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mstoykov/envconfig v1.4.1-0.20220114105314-765c6d8c76f1
github.com/onsi/ginkgo v1.14.0 // indirect
github.com/onsi/gomega v1.10.1 // indirect
github.com/tidwall/match v1.1.1 // indirect
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
golang.org/x/text v0.3.7 // indirect
Expand Down
50 changes: 47 additions & 3 deletions go.sum

Large diffs are not rendered by default.

25 changes: 14 additions & 11 deletions js/initcontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ import (
"go.k6.io/k6/lib"
"go.k6.io/k6/lib/fsext"
"go.k6.io/k6/loader"

"github.com/grafana/xk6-redis/redis"
)

type programWithSource struct {
Expand Down Expand Up @@ -370,17 +372,18 @@ func (i *InitContext) allowOnlyOpenedFiles() {

func getInternalJSModules() map[string]interface{} {
return map[string]interface{}{
"k6": k6.New(),
"k6/crypto": crypto.New(),
"k6/crypto/x509": x509.New(),
"k6/data": data.New(),
"k6/encoding": encoding.New(),
"k6/execution": execution.New(),
"k6/net/grpc": grpc.New(),
"k6/html": html.New(),
"k6/http": http.New(),
"k6/metrics": metrics.New(),
"k6/ws": ws.New(),
"k6": k6.New(),
"k6/crypto": crypto.New(),
"k6/crypto/x509": x509.New(),
"k6/data": data.New(),
"k6/encoding": encoding.New(),
"k6/execution": execution.New(),
"k6/experimental/redis": redis.New(),
"k6/net/grpc": grpc.New(),
"k6/html": html.New(),
"k6/http": http.New(),
"k6/metrics": metrics.New(),
"k6/ws": ws.New(),
}
}

Expand Down
224 changes: 224 additions & 0 deletions js/modules/k6/experimental/README.md

Large diffs are not rendered by default.

96 changes: 96 additions & 0 deletions samples/redis.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { check } from "k6";
import http from "k6/http";
import redis from "k6/experimental/redis";
import exec from "k6/execution";
import { textSummary } from "https://jslib.k6.io/k6-summary/0.0.1/index.js";

export const options = {
scenarios: {
redisPerformance: {
executor: "shared-iterations",
vus: 10,
iterations: 200,
exec: "measureRedisPerformance",
},
usingRedisData: {
executor: "shared-iterations",
vus: 10,
iterations: 200,
exec: "measureUsingRedisData",
},
},
};

// Instantiate a new redis client
const redisClient = new redis.Client({
addrs: __ENV.REDIS_ADDRS.split(",") || new Array("localhost:6379"), // in the form of "host:port", separated by commas
password: __ENV.REDIS_PASSWORD || "",
});

// Prepare an array of crocodile ids for later use
// in the context of the measureUsingRedisData function.
const crocodileIDs = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

export function measureRedisPerformance() {
// VUs are executed in a parallel fashion,
// thus, to ensure that parallel VUs are not
// modifying the same key at the same time,
// we use keys indexed by the VU id.
const key = `foo-${exec.vu.idInTest}`;

redisClient
.set(`foo-${exec.vu.idInTest}`, 1)
.then(() => redisClient.get(`foo-${exec.vu.idInTest}`))
.then((value) => redisClient.incrBy(`foo-${exec.vu.idInTest}`, value))
.then((_) => redisClient.del(`foo-${exec.vu.idInTest}`))
.then((_) => redisClient.exists(`foo-${exec.vu.idInTest}`))
.then((exists) => {
if (exists !== 0) {
throw new Error("foo should have been deleted");
}
});
}

export function setup() {
redisClient.sadd("crocodile_ids", ...crocodileIDs);
}

export function measureUsingRedisData() {
// Pick a random crocodile id from the dedicated redis set,
// we have filled in setup().
redisClient
.srandmember("crocodile_ids")
.then((randomID) => {
const url = `https://test-api.k6.io/public/crocodiles/${randomID}`;
const res = http.get(url);

check(res, {
"status is 200": (r) => r.status === 200,
"content-type is application/json": (r) =>
r.headers["content-type"] === "application/json",
});

return url;
})
.then((url) => redisClient.hincrby("k6_crocodile_fetched", url, 1));
}

export function teardown() {
redisClient.del("crocodile_ids");
}

export function handleSummary(data) {
redisClient
.hgetall("k6_crocodile_fetched")
.then((fetched) =>
Object.assign(data, { k6_crocodile_fetched: fetched })
)
.then((data) =>
redisClient.set(`k6_report_${Date.now()}`, JSON.stringify(data))
)
.then(() => redisClient.del("k6_crocodile_fetched"));

return {
stdout: textSummary(data, { indent: " ", enableColors: true }),
};
}
22 changes: 22 additions & 0 deletions vendor/github.com/cespare/xxhash/v2/LICENSE.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

69 changes: 69 additions & 0 deletions vendor/github.com/cespare/xxhash/v2/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 7350f8c

Please sign in to comment.