|
1 |
| -import { check } from "k6"; |
2 |
| -import http from "k6/http"; |
3 |
| -import redis from "k6/experimental/redis"; |
4 |
| -import exec from "k6/execution"; |
5 |
| -import { textSummary } from "https://jslib.k6.io/k6-summary/0.0.1/index.js"; |
| 1 | +import { check } from 'k6'; |
| 2 | +import http from 'k6/http'; |
| 3 | +import redis from 'k6/experimental/redis'; |
| 4 | +import exec from 'k6/execution'; |
| 5 | +import { textSummary } from 'https://jslib.k6.io/k6-summary/0.0.2/index.js'; |
| 6 | + |
6 | 7 | export const options = {
|
7 | 8 | scenarios: {
|
8 | 9 | redisPerformance: {
|
9 |
| - executor: "shared-iterations", |
| 10 | + executor: 'shared-iterations', |
10 | 11 | vus: 10,
|
11 | 12 | iterations: 200,
|
12 |
| - exec: "measureRedisPerformance", |
| 13 | + exec: 'measureRedisPerformance', |
13 | 14 | },
|
14 | 15 | usingRedisData: {
|
15 |
| - executor: "shared-iterations", |
| 16 | + executor: 'shared-iterations', |
16 | 17 | vus: 10,
|
17 | 18 | iterations: 200,
|
18 |
| - exec: "measureUsingRedisData", |
| 19 | + exec: 'measureUsingRedisData', |
19 | 20 | },
|
20 | 21 | },
|
21 | 22 | };
|
22 |
| -// Get the redis instance(s) address and password from the environment |
23 |
| -const redis_addrs = __ENV.REDIS_ADDRS || ""; |
24 |
| -const redis_password = __ENV.REDIS_PASSWORD || ""; |
| 23 | + |
25 | 24 | // Instantiate a new redis client
|
26 |
| -const redisClient = new redis.Client({ |
27 |
| - addrs: redis_addrs.split(",") || new Array("localhost:6379"), // in the form of 'host:port', separated by commas |
28 |
| - password: redis_password, |
29 |
| -}); |
30 |
| -// Prepare an array of crocodile ids for later use |
| 25 | +const redisClient = new redis.Client(`redis://localhost:6379`); |
| 26 | + |
| 27 | +// Prepare an array of rating ids for later use |
31 | 28 | // in the context of the measureUsingRedisData function.
|
32 |
| -const crocodileIDs = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); |
33 |
| -export function measureRedisPerformance() { |
| 29 | +const ratingIDs = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); |
| 30 | + |
| 31 | +export async function measureRedisPerformance() { |
34 | 32 | // VUs are executed in a parallel fashion,
|
35 | 33 | // thus, to ensure that parallel VUs are not
|
36 | 34 | // modifying the same key at the same time,
|
37 | 35 | // we use keys indexed by the VU id.
|
38 | 36 | const key = `foo-${exec.vu.idInTest}`;
|
39 |
| - redisClient |
40 |
| - .set(`foo-${exec.vu.idInTest}`, 1) |
41 |
| - .then(() => redisClient.get(`foo-${exec.vu.idInTest}`)) |
42 |
| - .then((value) => redisClient.incrBy(`foo-${exec.vu.idInTest}`, value)) |
43 |
| - .then((_) => redisClient.del(`foo-${exec.vu.idInTest}`)) |
44 |
| - .then((_) => redisClient.exists(`foo-${exec.vu.idInTest}`)) |
45 |
| - .then((exists) => { |
46 |
| - if (exists !== 0) { |
47 |
| - throw new Error("foo should have been deleted"); |
48 |
| - } |
49 |
| - }); |
| 37 | + |
| 38 | + await redisClient.set(key, 1); |
| 39 | + await redisClient.incrBy(key, 10); |
| 40 | + const value = await redisClient.get(key); |
| 41 | + if (value !== '11') { |
| 42 | + throw new Error('foo should have been incremented to 11'); |
| 43 | + } |
| 44 | + |
| 45 | + await redisClient.del(key); |
| 46 | + if ((await redisClient.exists(key)) !== 0) { |
| 47 | + throw new Error('foo should have been deleted'); |
| 48 | + } |
50 | 49 | }
|
51 |
| -export function setup() { |
52 |
| - redisClient.sadd("crocodile_ids", ...crocodileIDs); |
| 50 | + |
| 51 | +export async function setup() { |
| 52 | + await redisClient.sadd('rating_ids', ...ratingIDs); |
53 | 53 | }
|
54 |
| -export function measureUsingRedisData() { |
55 |
| - // Pick a random crocodile id from the dedicated redis set, |
| 54 | + |
| 55 | +export async function measureUsingRedisData() { |
| 56 | + // Pick a random rating id from the dedicated redis set, |
56 | 57 | // we have filled in setup().
|
57 |
| - redisClient |
58 |
| - .srandmember("crocodile_ids") |
59 |
| - .then((randomID) => { |
60 |
| - const url = `https://test-api.k6.io/public/crocodiles/${randomID}`; |
61 |
| - const res = http.get(url); |
62 |
| - check(res, { |
63 |
| - "status is 200": (r) => r.status === 200, |
64 |
| - "content-type is application/json": (r) => |
65 |
| - r.headers["content-type"] === "application/json", |
66 |
| - }); |
67 |
| - return url; |
68 |
| - }) |
69 |
| - .then((url) => redisClient.hincrby("k6_crocodile_fetched", url, 1)); |
| 58 | + const randomID = await redisClient.srandmember('rating_ids'); |
| 59 | + const url = `https://quickpizza.grafana.com/api/ratings/${randomID}`; |
| 60 | + const res = await http.asyncRequest('GET', url, { |
| 61 | + headers: { Authorization: 'token abcdef0123456789' }, |
| 62 | + }); |
| 63 | + |
| 64 | + check(res, { 'status is 200': (r) => r.status === 200 }); |
| 65 | + |
| 66 | + await redisClient.hincrby('k6_rating_fetched', url, 1); |
70 | 67 | }
|
71 |
| -export function teardown() { |
72 |
| - redisClient.del("crocodile_ids"); |
| 68 | + |
| 69 | +export async function teardown() { |
| 70 | + await redisClient.del('rating_ids'); |
73 | 71 | }
|
| 72 | + |
74 | 73 | export function handleSummary(data) {
|
75 | 74 | redisClient
|
76 |
| - .hgetall("k6_crocodile_fetched") |
77 |
| - .then((fetched) => |
78 |
| - Object.assign(data, { k6_crocodile_fetched: fetched }) |
79 |
| - ) |
80 |
| - .then((data) => |
81 |
| - redisClient.set(`k6_report_${Date.now()}`, JSON.stringify(data)) |
82 |
| - ) |
83 |
| - .then(() => redisClient.del("k6_crocodile_fetched")); |
| 75 | + .hgetall('k6_rating_fetched') |
| 76 | + .then((fetched) => Object.assign(data, { k6_rating_fetched: fetched })) |
| 77 | + .then((data) => redisClient.set(`k6_report_${Date.now()}`, JSON.stringify(data))) |
| 78 | + .then(() => redisClient.del('k6_rating_fetched')); |
| 79 | + |
84 | 80 | return {
|
85 |
| - stdout: textSummary(data, { indent: " ", enableColors: true }), |
| 81 | + stdout: textSummary(data, { indent: ' ', enableColors: true }), |
86 | 82 | };
|
87 | 83 | }
|
0 commit comments