Skip to content

Commit 9040dce

Browse files
chore: fix broken links and bring changes from #1393 (#1448)
* chore: bring in changes from #1393 to next * chore: backport to v0.48 * chore: remove test services * chore: backport to v0.48 * chore: backport to v0.47
1 parent f9d6bff commit 9040dce

File tree

36 files changed

+678
-103
lines changed

36 files changed

+678
-103
lines changed

docs/sources/next/examples/oauth-authentication.md

Lines changed: 209 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,207 @@ export function authenticateUsingAzure(tenantId, clientId, clientSecret, scope,
6161

6262
{{< /code >}}
6363

64+
### Azure B2C
65+
66+
The following example shows how you can authenticate with Azure B2C using the [Client Credentials Flow](https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-reference-oauth-code#client-credentials-flow).
67+
68+
This example is based on a JMeter example found at the [azure-ad-b2c/load-tests](https://github.com/azure-ad-b2c/load-tests) repository.
69+
70+
To use this script, you need to:
71+
72+
1. [Set up your own Azure B2C tenant](https://learn.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-tenant)
73+
- Copy the tenant name, it will be used in your test script.
74+
1. [Register a web application](https://learn.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications?tabs=app-reg-ga)
75+
- Register a single page application with the redirect URL of: https://jwt.ms. That's needed for the flow to receive a token.
76+
- After the creation, you can get the Application (client) ID, and the Directory (tenant) ID. Copy both of them, they'll be used in your test script.
77+
1. [Create a user flow so that you can sign up and create a user](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows)
78+
- Create a new user, and copy the username and password. They'll be used in the test script.
79+
80+
You can find the settings in the B2C settings in the Azure portal if you need to refer to them later on. Make sure to fill out all the variables for the `B2CGraphSettings` object, as well as replace `USERNAME` and `PASSWORD` in `export default function`.
81+
82+
{{< code >}}
83+
84+
```javascript
85+
import http from 'k6/http';
86+
import crypto from 'k6/crypto';
87+
import { randomString } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';
88+
89+
const B2CGraphSettings = {
90+
B2C: {
91+
client_id: '', // Application ID in Azure
92+
user_flow_name: '',
93+
tenant_id: '', // Directory ID in Azure
94+
tenant_name: '',
95+
scope: 'openid',
96+
redirect_url: 'https://jwt.ms',
97+
},
98+
};
99+
100+
/**
101+
* Authenticate using OAuth against Azure B2C
102+
* @function
103+
* @param {string} username - Username of the user to authenticate
104+
* @param {string} password
105+
* @return {string} id_token
106+
*/
107+
export function GetB2cIdToken(username, password) {
108+
const state = GetState();
109+
SelfAsserted(state, username, password);
110+
const code = CombinedSigninAndSignup(state);
111+
return GetToken(code, state.codeVerifier);
112+
}
113+
114+
/**
115+
* @typedef {object} b2cStateProperties
116+
* @property {string} csrfToken
117+
* @property {string} stateProperty
118+
* @property {string} codeVerifier
119+
*
120+
*/
121+
122+
/**
123+
* Get the id token from Azure B2C
124+
* @function
125+
* @param {string} code
126+
* @returns {string} id_token
127+
*/
128+
const GetToken = (code, codeVerifier) => {
129+
const url =
130+
`https://${B2CGraphSettings.B2C.tenant_name}.b2clogin.com/${B2CGraphSettings.B2C.tenant_id}` +
131+
`/oauth2/v2.0/token` +
132+
`?p=${B2CGraphSettings.B2C.user_flow_name}` +
133+
`&client_id=${B2CGraphSettings.B2C.client_id}` +
134+
`&grant_type=authorization_code` +
135+
`&scope=${B2CGraphSettings.B2C.scope}` +
136+
`&code=${code}` +
137+
`&redirect_uri=${B2CGraphSettings.B2C.redirect_url}` +
138+
`&code_verifier=${codeVerifier}`;
139+
140+
const response = http.post(url, '', {
141+
tags: {
142+
b2c_login: 'GetToken',
143+
},
144+
});
145+
146+
return JSON.parse(response.body).id_token;
147+
};
148+
149+
/**
150+
* Signs in the user using the CombinedSigninAndSignup policy
151+
* extraqct B2C code from response
152+
* @function
153+
* @param {b2cStateProperties} state
154+
* @returns {string} code
155+
*/
156+
const CombinedSigninAndSignup = (state) => {
157+
const url =
158+
`https://${B2CGraphSettings.B2C.tenant_name}.b2clogin.com/${B2CGraphSettings.B2C.tenant_name}.onmicrosoft.com` +
159+
`/${B2CGraphSettings.B2C.user_flow_name}/api/CombinedSigninAndSignup/confirmed` +
160+
`?csrf_token=${state.csrfToken}` +
161+
`&rememberMe=false` +
162+
`&tx=StateProperties=${state.stateProperty}` +
163+
`&p=${B2CGraphSettings.B2C.user_flow_name}`;
164+
165+
const response = http.get(url, '', {
166+
tags: {
167+
b2c_login: 'CombinedSigninAndSignup',
168+
},
169+
});
170+
const codeRegex = '.*code=([^"]*)';
171+
return response.url.match(codeRegex)[1];
172+
};
173+
174+
/**
175+
* Signs in the user using the SelfAsserted policy
176+
* @function
177+
* @param {b2cStateProperties} state
178+
* @param {string} username
179+
* @param {string} password
180+
*/
181+
const SelfAsserted = (state, username, password) => {
182+
const url =
183+
`https://${B2CGraphSettings.B2C.tenant_name}.b2clogin.com/${B2CGraphSettings.B2C.tenant_id}` +
184+
`/${B2CGraphSettings.B2C.user_flow_name}/SelfAsserted` +
185+
`?tx=StateProperties=${state.stateProperty}` +
186+
`&p=${B2CGraphSettings.B2C.user_flow_name}` +
187+
`&request_type=RESPONSE` +
188+
`&email=${username}` +
189+
`&password=${password}`;
190+
191+
const params = {
192+
headers: {
193+
'X-CSRF-TOKEN': `${state.csrfToken}`,
194+
},
195+
tags: {
196+
b2c_login: 'SelfAsserted',
197+
},
198+
};
199+
http.post(url, '', params);
200+
};
201+
202+
/**
203+
* Calls the B2C login page to get the state property
204+
* @function
205+
* @returns {b2cStateProperties} b2cState
206+
*/
207+
const GetState = () => {
208+
const nonce = randomString(50);
209+
const challenge = crypto.sha256(nonce.toString(), 'base64rawurl');
210+
211+
const url =
212+
`https://${B2CGraphSettings.B2C.tenant_name}.b2clogin.com` +
213+
`/${B2CGraphSettings.B2C.tenant_id}/oauth2/v2.0/authorize?` +
214+
`p=${B2CGraphSettings.B2C.user_flow_name}` +
215+
`&client_id=${B2CGraphSettings.B2C.client_id}` +
216+
`&nonce=${nonce}` +
217+
`&redirect_uri=${B2CGraphSettings.B2C.redirect_url}` +
218+
`&scope=${B2CGraphSettings.B2C.scope}` +
219+
`&response_type=code` +
220+
`&prompt=login` +
221+
`&code_challenge_method=S256` +
222+
`&code_challenge=${challenge}` +
223+
`&response_mode=fragment`;
224+
225+
const response = http.get(url, '', {
226+
tags: {
227+
b2c_login: 'GetCookyAndState',
228+
},
229+
});
230+
231+
const vuJar = http.cookieJar();
232+
const responseCookies = vuJar.cookiesForURL(response.url);
233+
234+
const b2cState = {};
235+
b2cState.codeVerifier = nonce;
236+
b2cState.csrfToken = responseCookies['x-ms-cpim-csrf'][0];
237+
b2cState.stateProperty = response.body.match('.*StateProperties=([^"]*)')[1];
238+
return b2cState;
239+
};
240+
241+
/**
242+
* Helper function to get the authorization header for a user
243+
* @param {user} user
244+
* @returns {object} httpsOptions
245+
*/
246+
export const GetAuthorizationHeaderForUser = (user) => {
247+
const token = GetB2cIdToken(user.username, user.password);
248+
249+
return {
250+
headers: {
251+
'Content-Type': 'application/json',
252+
'Authorization': 'Bearer ' + token,
253+
},
254+
};
255+
};
256+
257+
export default function () {
258+
const token = GetB2cIdToken('USERNAME', 'PASSWORD');
259+
console.log(token);
260+
}
261+
```
262+
263+
{{< /code >}}
264+
64265
### Okta
65266

66267
{{< code >}}
@@ -79,7 +280,14 @@ import encoding from 'k6/encoding';
79280
* @param {string} scope - Space-separated list of scopes
80281
* @param {string|object} resource - Either a resource ID (as string) or an object containing username and password
81282
*/
82-
export function authenticateUsingOkta(oktaDomain, authServerId, clientId, clientSecret, scope, resource) {
283+
export function authenticateUsingOkta(
284+
oktaDomain,
285+
authServerId,
286+
clientId,
287+
clientSecret,
288+
scope,
289+
resource
290+
) {
83291
if (authServerId === 'undefined' || authServerId == '') {
84292
authServerId = 'default';
85293
}

docs/sources/next/get-started/resources.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ If you need a place to learn k6 and test your scripts, you can use these playgro
3232

3333
- [pizza.grafana.fun](https://pizza.grafana.fun/). A simple demo webapp. [grafana/quickpizza](https://github.com/grafana/quickpizza)
3434
- [k6-http.grafana.fun](https://k6-http.grafana.fun). A simple HTTP Request & Response Service. [grafana/httpbin](https://github.com/grafana/httpbin)
35-
- [k6-php.grafana.fun](https://k6-php.grafana.fun). A simple PHP website. [grafana/test.k6.io](https://github.com/grafana/test.k6.io)
36-
- [test-api.k6.io](https://test-api.k6.io). A demo HTTP REST API with some WebSocket support. [grafana/test-api.k6.io](https://github.com/grafana/test-api.k6.io)
3735
- [grpcbin.test.k6.io](https://grpcbin.test.k6.io/). A simple gRPC Request & Response Service. [grafana/k6-grpcbin](https://github.com/grafana/k6-grpcbin)
3836

3937
Note that these are shared testing environments - please avoid high-load tests. Alternatively, you can deploy and host them on your infrastructure and run the examples in the repository.
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
---
22
title: 'Faults'
33
excerpt: 'xk6-disruptor: Fault Description'
4-
weight: 01
4+
weight: 100
55
---
66

77
# Faults
88

99
A fault is as an abnormal condition that affects a system component and which may lead to a failure.
1010

11-
| Fault type | Description |
12-
| ------------------------------------------------------------------------------------ | ------------------------------------------- |
13-
| [gRPC Fault](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/grpc) | Fault affecting gRPC requests from a target |
14-
| [HTTP Fault](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/http) | Fault affecting HTTP requests from a target |
11+
| Fault type | Description |
12+
| --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
13+
| [gRPC Fault](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/grpc) | Fault affecting gRPC requests from a target |
14+
| [HTTP Fault](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/http) | Fault affecting HTTP requests from a target |
15+
| [Pod Termination Fault](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/pod-termination) | Fault terminating a number of target Pods |
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
title: 'Pod Termination'
3+
description: 'xk6-disruptor: Pod Termination Fault attributes'
4+
weight: 03
5+
---
6+
7+
# Pod Termination
8+
9+
A Pod Termination Fault allows terminating either a fixed number or a percentage of the pods that matching a selector or back a service.
10+
11+
A Pod Termination fault is defined by the following attributes:
12+
13+
| Attribute | Type | Description |
14+
| --------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
15+
| count | integer or percentage | the number of pods to be terminated. It can be specified as a integer number or as a percentage, for example `30%`, that defines the fraction of target pods to be terminated |
16+
17+
{{% admonition type="note" %}}
18+
19+
If the count is a percentage and there are no enough elements in the target pod list, the number is rounded up.
20+
For example '25%' of a list of 2 target pods will terminate one pod.
21+
If the list of target pods is not empty, at least one pod is always terminated.
22+
23+
{{% /admonition %}}
24+
25+
## Example
26+
27+
This example defines a PorTermination fault that will terminate `30%` of target pods
28+
29+
```javascript
30+
const fault = {
31+
count: '30%',
32+
};
33+
```

docs/sources/next/javascript-api/xk6-disruptor/get-started/_index.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
title: 'Get started'
33
excerpt: 'xk6-disruptor is an extension that adds fault injection capabilities to k6. Start here to learn the basics and how to use the disruptor'
44
weight: 01
5-
weight: 01
65
---
76

87
# Get started

docs/sources/next/javascript-api/xk6-disruptor/poddisruptor/_index.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: 'PodDisruptor'
33
excerpt: 'xk6-disruptor: PodDisruptor class'
4-
weight: 02
4+
weight: 200
55
---
66

77
# PodDisruptor
@@ -12,11 +12,12 @@ To construct a `PodDisruptor`, use the [PodDisruptor() constructor](https://graf
1212

1313
## Methods
1414

15-
| Method | Description |
16-
| --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
17-
| [PodDisruptor.injectGrpcFaults()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/poddisruptor/injectgrpcfaults) | Inject [gRPC faults](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/grpc) in the target Pods |
18-
| [PodDisruptor.injectHTTPFaults()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/poddisruptor/injecthttpfaults) | Inject [HTTP faults](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/http) in the target Pods |
19-
| PodDisruptor.targets() | Returns the list of target Pods of the PodDisruptor |
15+
| Method | Description |
16+
| -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
17+
| [PodDisruptor.injectGrpcFaults()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/poddisruptor/injectgrpcfaults) | Inject [gRPC faults](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/grpc) in the target Pods |
18+
| [PodDisruptor.injectHTTPFaults()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/poddisruptor/injecthttpfaults) | Inject [HTTP faults](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/http) in the target Pods |
19+
| PodDisruptor.targets() | Returns the list of target Pods of the PodDisruptor |
20+
| [PodDisruptor.terminatePods()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/poddisruptor/terminate-pods) | executes a [Pod Termination fault](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/pod-termination) in the target Pods |
2021

2122
## Example
2223

@@ -59,4 +60,4 @@ $ kubectl run nginx --image=nginx
5960

6061
You can also use the [xk6-kubernetes](https://github.com/grafana/xk6-kubernetes) extension for creating these resources from your test script.
6162

62-
{{% /admonition %}}
63+
{{% /admonition %}}

docs/sources/next/javascript-api/xk6-disruptor/poddisruptor/constructor.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: 'Constructor'
33
excerpt: 'xk6-disruptor: PodDisruptor constructor'
4-
weight: 01
4+
weight: 100
55
---
66

77
# Constructor

docs/sources/next/javascript-api/xk6-disruptor/poddisruptor/injectgrpcfaults.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
---
22
title: 'injectGrpcFaults()'
33
excerpt: 'xk6-disruptor: PodDisruptor.injectGrpcFaults method'
4-
weight: 02
4+
weight: 200
55
---
66

77
# injectGrpcFaults()
88

99
injectGrpcFaults injects gRPC faults in the requests served by a target Pod.
1010

11-
| Parameter | Type | Description |
12-
| ------------------ | ------ | ---------------------------------------------------------------------------------------------------------------------- |
11+
| Parameter | Type | Description |
12+
| ------------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
1313
| fault | object | description of the [gRPC faults](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/grpc) to be injected |
14-
| duration | string | duration of the disruption |
15-
| options (optional) | object | [options](#options) that control the injection of the fault |
14+
| duration | string | duration of the disruption |
15+
| options (optional) | object | [options](#options) that control the injection of the fault |
1616

1717
## options
1818

docs/sources/next/javascript-api/xk6-disruptor/poddisruptor/injecthttpfaults.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
---
22
title: 'injectHTTPFaults()'
33
excerpt: 'xk6-disruptor: PodDisruptor.injectHTTPFaults method'
4-
weight: 03
4+
weight: 300
55
---
66

77
# injectHTTPFaults()
88

99
injectHTTPFaults injects HTTP faults in the requests served by a target Pod.
1010

11-
| Parameter | Type | Description |
12-
| ------------------ | ------ | ---------------------------------------------------------------------------------------------------------------------- |
11+
| Parameter | Type | Description |
12+
| ------------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
1313
| fault | object | description of the [http faults](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/http) to be injected |
14-
| duration | string | duration of the disruption |
15-
| options (optional) | object | [options](#options) that control the injection of the fault |
14+
| duration | string | duration of the disruption |
15+
| options (optional) | object | [options](#options) that control the injection of the fault |
1616

1717
## options
1818

@@ -30,7 +30,7 @@ WARN\[0035\] Request Failed error="read tcp 172.18.0.1:43564->172.18.255.200:80:
3030

3131
This is normal and means that one request was "in transit" at the time the faults were injected, causing the request to fail from a network connection reset.
3232

33-
{{% /admonition %}}
33+
{{% /admonition %}}
3434

3535
## Example
3636

0 commit comments

Comments
 (0)