<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>xk6-disruptor examples on Grafana Labs</title><link>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/</link><description>Recent content in xk6-disruptor examples on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/index.xml" rel="self" type="application/rss+xml"/><item><title>Inject gRPC faults into Service</title><link>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/inject-grpc-faults-into-service/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/inject-grpc-faults-into-service/</guid><content><![CDATA[&lt;h1 id=&#34;inject-grpc-faults-into-service&#34;&gt;Inject gRPC faults into Service&lt;/h1&gt;
&lt;p&gt;This example shows a way to use the 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/servicedisruptor/&#34;&gt;ServiceDisruptor&lt;/a&gt; to test the effect of faults injected in the gRPC requests served by a service.&lt;/p&gt;
&lt;p&gt;The complete &lt;a href=&#34;#source-code&#34;&gt;source code&lt;/a&gt; is at the end of this document. The next sections examine the code in detail.&lt;/p&gt;
&lt;p&gt;The example uses &lt;a href=&#34;https://github.com/moul/grpcbin&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;grpcpbin&lt;/a&gt;, a simple request/response application that offers endpoints for testing different gRPC requests.&lt;/p&gt;
&lt;p&gt;The test requires &lt;code&gt;grpcpbin&lt;/code&gt; to be deployed in a cluster in the namespace &lt;code&gt;grpcbin&lt;/code&gt; and exposed with an external IP. The IP address is expected in the environment variable &lt;code&gt;GRPC_HOST&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For the Kubernetes manifests and the instructions on how to deploy it to a cluster, refer to the &lt;a href=&#34;#test-setup&#34;&gt;test setup&lt;/a&gt; section at the end of this document. To learn more about how to get the external IP address, refer to 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/expose--your-application/&#34;&gt;Expose your application&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;initialization&#34;&gt;Initialization&lt;/h2&gt;
&lt;p&gt;The initialization code imports the external dependencies required by the test. The 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/servicedisruptor/&#34;&gt;ServiceDisruptor&lt;/a&gt; class imported from the &lt;code&gt;xk6-disruptor&lt;/code&gt; extension provides functions for injecting faults in services. The 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-net-grpc/&#34;&gt;k6/net/grpc&lt;/a&gt; module provides functions for executing gRPC requests. The 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/checks/&#34;&gt;check&lt;/a&gt; function verifies the results from the requests.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { ServiceDisruptor } from &amp;#39;k6/x/disruptor&amp;#39;;
import grpc from &amp;#39;k6/net/grpc&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We also create a grpc client and load the protobufs definitions for the &lt;a href=&#34;https://github.com/moul/pb/blob/master/hello/hello.proto&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;HelloService&lt;/a&gt; service.&lt;/p&gt;
&lt;!-- eslint-disable no-undef  --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;const client = new grpc.Client();
client.load([&amp;#39;pb&amp;#39;], &amp;#39;hello.proto&amp;#39;);&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- eslint-enable no-undef  --&gt;
&lt;h2 id=&#34;test-load&#34;&gt;Test Load&lt;/h2&gt;
&lt;p&gt;The test load is generated by the &lt;code&gt;default&lt;/code&gt; function, which connects to the &lt;code&gt;grpcbin&lt;/code&gt; service using the IP and port obtained from the environment variable &lt;code&gt;GRPC_HOST&lt;/code&gt; and invokes the &lt;code&gt;SayHello&lt;/code&gt; method of the &lt;code&gt;hello.HelloService&lt;/code&gt; service. Finally, The status code of the response is checked. When faults are injected, this check should fail.&lt;/p&gt;
&lt;!-- eslint-disable no-undef  --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;export default function () {
  client.connect(__ENV.GRPC_HOST, {
    plaintext: true,
    timeout: &amp;#39;1s&amp;#39;,
  });

  const data = { greeting: &amp;#39;Bert&amp;#39; };
  const response = client.invoke(&amp;#39;hello.HelloService/SayHello&amp;#39;, data, {
    timeout: &amp;#39;1s&amp;#39;,
  });
  client.close();

  check(response, {
    &amp;#39;status is OK&amp;#39;: (r) =&amp;gt; r &amp;amp;&amp;amp; r.status === grpc.StatusOK,
  });
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- eslint-enable no-undef  --&gt;
&lt;h2 id=&#34;fault-injection&#34;&gt;Fault injection&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;disrupt&lt;/code&gt; function creates a &lt;code&gt;ServiceDisruptor&lt;/code&gt; for the &lt;code&gt;grpcbin&lt;/code&gt; service in the namespace &lt;code&gt;grpcbin&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The gRPC faults are injected by calling the 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/servicedisruptor/injectgrpcfaults/&#34;&gt;ServiceDisruptor.injectGrpcFaults&lt;/a&gt; method using a fault definition that introduces a delay of &lt;code&gt;300ms&lt;/code&gt; on each request and an error with status code &lt;code&gt;13&lt;/code&gt; (&amp;ldquo;Internal error&amp;rdquo;) in &lt;code&gt;10%&lt;/code&gt; of the requests.&lt;/p&gt;
&lt;!-- eslint-disable no-undef  --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;export function disrupt() {
  if (__ENV.SKIP_FAULTS == &amp;#39;1&amp;#39;) {
    return;
  }

  const fault = {
    averageDelay: &amp;#39;300ms&amp;#39;,
    statusCode: grpc.StatusInternal,
    errorRate: 0.1,
    port: 9000,
  };
  const disruptor = new ServiceDisruptor(&amp;#39;grpcbin&amp;#39;, &amp;#39;grpcbin&amp;#39;);
  disruptor.injectGrpcFaults(fault, &amp;#39;30s&amp;#39;);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- eslint-enable no-undef  --&gt;
&lt;p&gt;Notice the following code snippet in the &lt;code&gt;injectFaults&lt;/code&gt; function above:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;export function disrupt() {
  if (__ENV.SKIP_FAULTS == &amp;#39;1&amp;#39;) {
    return;
  }
  //...
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This code makes the function return without injecting faults if the &lt;code&gt;SKIP_FAULTS&lt;/code&gt; environment variable is passed to the execution of the test with a value of &amp;ldquo;1&amp;rdquo;. We will use this option to obtain a &lt;a href=&#34;#baseline-execution&#34;&gt;baseline execution&lt;/a&gt; without faults.&lt;/p&gt;
&lt;h2 id=&#34;scenarios&#34;&gt;Scenarios&lt;/h2&gt;
&lt;p&gt;This test defines two 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/&#34;&gt;scenarios&lt;/a&gt; to be executed. The &lt;code&gt;load&lt;/code&gt; scenario applies the test load to the &lt;code&gt;grpcpbin&lt;/code&gt; application for &lt;code&gt;30s&lt;/code&gt; invoking the &lt;code&gt;default&lt;/code&gt; function. The &lt;code&gt;disrupt&lt;/code&gt; scenario invokes the &lt;code&gt;disrupt&lt;/code&gt; function to inject a fault in the gRPC requests to the target application.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;export const options = {
  scenarios: {
    load: {
      executor: &amp;#39;constant-arrival-rate&amp;#39;,
      rate: 100,
      preAllocatedVUs: 10,
      maxVUs: 100,
      exec: &amp;#39;default&amp;#39;,
      startTime: &amp;#39;0s&amp;#39;,
      duration: &amp;#39;30s&amp;#39;,
    },
    disrupt: {
      executor: &amp;#39;shared-iterations&amp;#39;,
      iterations: 1,
      vus: 1,
      exec: &amp;#39;disrupt&amp;#39;,
      startTime: &amp;#39;0s&amp;#39;,
    },
  },
};&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;The &lt;code&gt;disrupt&lt;/code&gt; scenario uses a &lt;code&gt;shared-iterations&lt;/code&gt; executor with one iteration and one &lt;code&gt;VU&lt;/code&gt;. This setting ensures the &lt;code&gt;disrupt&lt;/code&gt; function is executed only once. Executing this function multiples times concurrently may have unpredictable results.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;executions&#34;&gt;Executions&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;The commands in this section assume the &lt;code&gt;xk6-disruptor&lt;/code&gt; binary is available in your current directory. This location can change depending on the installation process and the platform. Refer to 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/installation/&#34;&gt;Installation&lt;/a&gt; for details on how to install it in your environment.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h3 id=&#34;baseline-execution&#34;&gt;Baseline execution&lt;/h3&gt;
&lt;p&gt;We will first execute the test without introducing faults to have an baseline using the following command:&lt;/p&gt;



  

  






  

  



  &lt;div class=&#34;code&#34; x-data=&#34;app_code([&amp;#34;bash&amp;#34;,&amp;#34;windows-powershell&amp;#34;], false)&#34; x-init=&#34;init()&#34; data-codetoggle=&#34;true&#34;&gt;
    &lt;div class=&#34;toggle-toolbar &#34;&gt;
      &lt;div&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;bash&#39; }&#34; @click=&#34;$store.code.language = &#39;bash&#39;&#34;&gt;
              &lt;span&gt;Bash&lt;/span&gt;
            &lt;/button&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;windows-powershell&#39; }&#34; @click=&#34;$store.code.language = &#39;windows-powershell&#39;&#34;&gt;
              &lt;span&gt;windows-powershell&lt;/span&gt;
            &lt;/button&gt;&lt;/div&gt;
      &lt;div class=&#34;d-flex&#34;&gt;&lt;span class=&#34;code-clipboard&#34; x-ref=&#34;tooltip&#34;&gt;
          &lt;button @click=&#34;copy()&#34;&gt;
            &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
            &lt;span&gt;Copy&lt;/span&gt;
          &lt;/button&gt;
        &lt;/span&gt;
      &lt;/div&gt;
      &lt;div class=&#34;toggle-toolbar__border&#34;&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&#34;code-rendered&#34; &gt;
      
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;xk6-disruptor --env SKIP_FAULTS=1 --env GRPC_HOST=$GRPC_HOST run grpc-faults.js&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;windows-powershell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-windows-powershell&#34;&gt;xk6-disruptor --env SKIP_FAULTS=1 --env &amp;#34;GRPC_HOST=$Env:GRPC_HOST&amp;#34; run grpc-faults.js&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

    &lt;/div&gt;
  &lt;/div&gt;


&lt;p&gt;Notice the argument &lt;code&gt;--env SKIP_FAULT=1&lt;/code&gt;, which makes the &lt;code&gt;disrupt&lt;/code&gt; function return without injecting any fault as explained in the &lt;a href=&#34;#fault-injection&#34;&gt;fault injection&lt;/a&gt; section. Also notice the &lt;code&gt;--env GRPC_HOST&lt;/code&gt; argument, which passes the external IP used to access the &lt;code&gt;grpcbin&lt;/code&gt; application.&lt;/p&gt;
&lt;p&gt;You should get an output similar to the following (use the &lt;code&gt;Expand&lt;/code&gt; button to see all output).&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;         /\      Grafana   /‾‾/
    /\  /  \     |\  __   /  /
   /  \/    \    | |/ /  /   ‾‾\
  /          \   |   (  |  (‾)  |
 / __________ \  |_|\_\  \_____/

  execution: local
     script: scripts/grpc-faults.js
     output: -

  scenarios: (100.00%) 2 scenarios, 101 max VUs, 10m30s max duration (incl. graceful stop):
           * disrupt: 1 iterations shared among 1 VUs (maxDuration: 10m0s, exec: disrupt, gracefulStop: 30s)
           * load: 100.00 iterations/s for 30s (maxVUs: 10-100, exec: default, gracefulStop: 30s)


running (00m30.0s), 000/011 VUs, 3001 complete and 0 interrupted iterations
disrupt ✓ [======================================] 1 VUs        00m00.0s/10m0s  1/1 shared iters
load    ✓ [======================================] 000/010 VUs  30s             100.00 iters/s

  █ TOTAL RESULTS

    checks_total.......................: 3000    100.03/s
    checks_succeeded...................: 100.00% 3000 out of 3000
    checks_failed......................: 0.00%   0 out of 3000

    ✓ status is OK

    GRPC
    grpc_req_duration..................: avg=1.36ms min=512.43µs med=1.25ms max=26.62ms p(90)=1.75ms p(95)=2.09ms

    EXECUTION
    iteration_duration.................: avg=4.4ms  min=52.86µs  med=4.01ms max=66.26ms p(90)=5.32ms p(95)=6.35ms
    iterations.........................: 3001    100.03/s
    vus................................: 10      min=10       max=10
    vus_max............................: 11      min=11       max=11

    NETWORK
    data_received......................: 416 kB  14 kB/s
    data_sent..........................: 630 kB  21 kB/s&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;fault-injection-1&#34;&gt;Fault injection&lt;/h3&gt;
&lt;p&gt;We repeat the execution injecting the faults. Notice we have removed the &lt;code&gt;--env SKIP_FAULTS=1&lt;/code&gt; argument.&lt;/p&gt;



  

  






  

  



  &lt;div class=&#34;code&#34; x-data=&#34;app_code([&amp;#34;bash&amp;#34;,&amp;#34;windows-powershell&amp;#34;], false)&#34; x-init=&#34;init()&#34; data-codetoggle=&#34;true&#34;&gt;
    &lt;div class=&#34;toggle-toolbar &#34;&gt;
      &lt;div&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;bash&#39; }&#34; @click=&#34;$store.code.language = &#39;bash&#39;&#34;&gt;
              &lt;span&gt;Bash&lt;/span&gt;
            &lt;/button&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;windows-powershell&#39; }&#34; @click=&#34;$store.code.language = &#39;windows-powershell&#39;&#34;&gt;
              &lt;span&gt;windows-powershell&lt;/span&gt;
            &lt;/button&gt;&lt;/div&gt;
      &lt;div class=&#34;d-flex&#34;&gt;&lt;span class=&#34;code-clipboard&#34; x-ref=&#34;tooltip&#34;&gt;
          &lt;button @click=&#34;copy()&#34;&gt;
            &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
            &lt;span&gt;Copy&lt;/span&gt;
          &lt;/button&gt;
        &lt;/span&gt;
      &lt;/div&gt;
      &lt;div class=&#34;toggle-toolbar__border&#34;&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&#34;code-rendered&#34; &gt;
      
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;xk6-disruptor --env GRPC_HOST=$GRPC_HOST run grpc-faults.js&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;windows-powershell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-windows-powershell&#34;&gt;xk6-disruptor --env &amp;#34;GRPC_HOST=$Env:GRPC_HOST&amp;#34; run grpc-faults.js&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

    &lt;/div&gt;
  &lt;/div&gt;



&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;         /\      Grafana   /‾‾/
    /\  /  \     |\  __   /  /
   /  \/    \    | |/ /  /   ‾‾\
  /          \   |   (  |  (‾)  |
 / __________ \  |_|\_\  \_____/

  execution: local
     script: scripts/grpc-faults.js
     output: -

  scenarios: (100.00%) 2 scenarios, 101 max VUs, 10m30s max duration (incl. graceful stop):
           * disrupt: 1 iterations shared among 1 VUs (maxDuration: 10m0s, exec: disrupt, gracefulStop: 30s)
           * load: 100.00 iterations/s for 30s (maxVUs: 10-100, exec: default, gracefulStop: 30s)


running (00m50.6s), 000/033 VUs, 2975 complete and 0 interrupted iterations
disrupt ✓ [======================================] 1 VUs        00m50.6s/10m0s  1/1 shared iters
load    ✓ [======================================] 000/032 VUs  30s             100.00 iters/s

  █ TOTAL RESULTS

    checks_total.......................: 2974    58.77/s
    checks_succeeded...................: 89.71%  2668 out of 2974
    checks_failed......................: 10.29%  306 out of 2974

    ✗ status is OK
     ↳  89% — ✓ 2668 / ✗ 306

    GRPC
    grpc_req_duration..................: avg=270.51ms min=502.12µs med=302.34ms max=310.48ms p(90)=303.25ms p(95)=303.57ms

    EXECUTION
    dropped_iterations.................: 26     0.51/s
    iteration_duration.................: avg=290.05ms min=1.96ms   med=304.86ms max=50.61s   p(90)=306.36ms p(95)=306.89ms
    iterations.........................: 2975   58.77/s
    vus................................: 1      min=1        max=33
    vus_max............................: 33     min=25       max=33

    NETWORK
    data_received......................: 405 kB 8.0 kB/s
    data_sent..........................: 615 kB 12 kB/s&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;comparison&#34;&gt;Comparison&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s take a closer look at the results for the requests on each scenario. We can observe that in the &lt;code&gt;base&lt;/code&gt; scenario requests duration has an percentile 95 of &lt;code&gt;2.09ms&lt;/code&gt; and &lt;code&gt;100%&lt;/code&gt; of requests pass the check. The &lt;code&gt;faults&lt;/code&gt; scenario has a percentile 96 of &lt;code&gt;303.57ms&lt;/code&gt; and only &lt;code&gt;89%&lt;/code&gt; of requests pass the check (or put in another way, &lt;code&gt;11%&lt;/code&gt; of requests failed), closely matching the fault definition.&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Execution&lt;/th&gt;
              &lt;th&gt;P95 Req. Duration&lt;/th&gt;
              &lt;th&gt;Passed Checks&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;Baseline&lt;/td&gt;
              &lt;td&gt;2.09ms&lt;/td&gt;
              &lt;td&gt;100%&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Fault injection&lt;/td&gt;
              &lt;td&gt;303.57ms&lt;/td&gt;
              &lt;td&gt;89%&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;source-code&#34;&gt;Source Code&lt;/h2&gt;
&lt;div class=&#34;collapse&#34; x-data=&#34;app_collapse()&#34;&gt;
  &lt;button class=&#34;collapse-trigger&#34; @click=&#34;toggle()&#34;&gt;
    &lt;span class=&#34;body-large&#34;&gt;grpc-faults.js&lt;/span&gt;
    &lt;span class=&#34;collapse-trigger__icon&#34; :class=&#34;{ &#39;collapse-trigger__icon-open&#39; : open }&#34;&gt;
      
  &lt;svg width=&#34;27&#34; height=&#34;26&#34; viewBox=&#34;0 0 27 26&#34; fill=&#34;none&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
&lt;path opacity=&#34;0.2&#34; d=&#34;M1.73047 12.8359C1.73047 19.4634 7.10305 24.8359 13.7305 24.8359C20.3579 24.8359 25.7305 19.4634 25.7305 12.8359C25.7305 6.20852 20.3579 0.835937 13.7305 0.835937C7.10305 0.835937 1.73047 6.20852 1.73047 12.8359Z&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M18.2344 12.8359L9.23438 12.8359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M13.7344 8.33594L13.7344 17.3359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;/svg&gt;


    &lt;/span&gt;
  &lt;/button&gt;
  &lt;div class=&#34;collapse-content&#34; x-ref=&#34;content&#34; hidden=&#34;until-found&#34;&gt;
    &lt;div class=&#34;collapse-content__inner&#34; x-ref=&#34;content-inner&#34;&gt;
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { ServiceDisruptor } from &amp;#39;k6/x/disruptor&amp;#39;;
import grpc from &amp;#39;k6/net/grpc&amp;#39;;
import { check } from &amp;#39;k6&amp;#39;;

const client = new grpc.Client();
client.load([&amp;#39;pb&amp;#39;], &amp;#39;hello.proto&amp;#39;);

export default function () {
  client.connect(__ENV.GRPC_HOST, {
    plaintext: true,
    timeout: &amp;#39;1s&amp;#39;,
  });

  const data = { greeting: &amp;#39;Bert&amp;#39; };
  const response = client.invoke(&amp;#39;hello.HelloService/SayHello&amp;#39;, data, {
    timeout: &amp;#39;1s&amp;#39;,
  });
  client.close();

  check(response, {
    &amp;#39;status is OK&amp;#39;: (r) =&amp;gt; r &amp;amp;&amp;amp; r.status === grpc.StatusOK,
  });
}

export function disrupt() {
  if (__ENV.SKIP_FAULTS == &amp;#39;1&amp;#39;) {
    return;
  }

  const disruptor = new ServiceDisruptor(&amp;#39;grpcbin&amp;#39;, &amp;#39;grpcbin&amp;#39;);

  // inject errors in requests
  const fault = {
    averageDelay: &amp;#39;300ms&amp;#39;,
    statusCode: grpc.StatusInternal,
    errorRate: 0.1,
    port: 9000,
  };
  disruptor.injectGrpcFaults(fault, &amp;#39;30s&amp;#39;);
}

export const options = {
  scenarios: {
    load: {
      executor: &amp;#39;constant-arrival-rate&amp;#39;,
      rate: 100,
      preAllocatedVUs: 10,
      maxVUs: 100,
      exec: &amp;#39;default&amp;#39;,
      startTime: &amp;#39;0s&amp;#39;,
      duration: &amp;#39;30s&amp;#39;,
    },
    disrupt: {
      executor: &amp;#39;shared-iterations&amp;#39;,
      iterations: 1,
      vus: 1,
      exec: &amp;#39;disrupt&amp;#39;,
      startTime: &amp;#39;0s&amp;#39;,
    },
  },
};&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;collapse&#34; x-data=&#34;app_collapse()&#34;&gt;
  &lt;button class=&#34;collapse-trigger&#34; @click=&#34;toggle()&#34;&gt;
    &lt;span class=&#34;body-large&#34;&gt;pb/hello.proto&lt;/span&gt;
    &lt;span class=&#34;collapse-trigger__icon&#34; :class=&#34;{ &#39;collapse-trigger__icon-open&#39; : open }&#34;&gt;
      
  &lt;svg width=&#34;27&#34; height=&#34;26&#34; viewBox=&#34;0 0 27 26&#34; fill=&#34;none&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
&lt;path opacity=&#34;0.2&#34; d=&#34;M1.73047 12.8359C1.73047 19.4634 7.10305 24.8359 13.7305 24.8359C20.3579 24.8359 25.7305 19.4634 25.7305 12.8359C25.7305 6.20852 20.3579 0.835937 13.7305 0.835937C7.10305 0.835937 1.73047 6.20852 1.73047 12.8359Z&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M18.2344 12.8359L9.23438 12.8359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M13.7344 8.33594L13.7344 17.3359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;/svg&gt;


    &lt;/span&gt;
  &lt;/button&gt;
  &lt;div class=&#34;collapse-content&#34; x-ref=&#34;content&#34; hidden=&#34;until-found&#34;&gt;
    &lt;div class=&#34;collapse-content__inner&#34; x-ref=&#34;content-inner&#34;&gt;
&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;syntax = &amp;#34;proto2&amp;#34;;

package hello;

service HelloService {
  rpc SayHello(HelloRequest) returns (HelloResponse);
  rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
  rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
  rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
}

message HelloRequest {
  optional string greeting = 1;
}

message HelloResponse {
  required string reply = 1;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h2 id=&#34;test-setup&#34;&gt;Test setup&lt;/h2&gt;
&lt;p&gt;The tests requires the deployment of the &lt;code&gt;grpcbin&lt;/code&gt; application. The application must also be accessible using an external IP available in the &lt;code&gt;GRPC_HOST&lt;/code&gt; environment variable.&lt;/p&gt;
&lt;p&gt;The following &lt;a href=&#34;#manifests&#34;&gt;manifests&lt;/a&gt; define the resources required for deploying the application and exposing it as a LoadBalancer service.&lt;/p&gt;
&lt;p&gt;You can deploy the application using the following commands:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;# Create Namespace
kubectl apply -f namespace.yaml
namespace/grpcbin created

# Deploy Pod
kubectl apply -f pod.yaml
pod/grpcbin created

# Expose Pod as a Service
kubectl apply -f service.yaml
service/grpcbin created&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You must set the environment variable &lt;code&gt;GRPC_HOST&lt;/code&gt; with the external IP address and port used to access the &lt;code&gt;grpcbin&lt;/code&gt; service from the test script.&lt;/p&gt;
&lt;p&gt;Learn more about how to get the external IP address in the 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/expose--your-application/&#34;&gt;Expose your application&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;manifests&#34;&gt;Manifests&lt;/h3&gt;
&lt;div class=&#34;collapse&#34; x-data=&#34;app_collapse()&#34;&gt;
  &lt;button class=&#34;collapse-trigger&#34; @click=&#34;toggle()&#34;&gt;
    &lt;span class=&#34;body-large&#34;&gt;namespace.yaml&lt;/span&gt;
    &lt;span class=&#34;collapse-trigger__icon&#34; :class=&#34;{ &#39;collapse-trigger__icon-open&#39; : open }&#34;&gt;
      
  &lt;svg width=&#34;27&#34; height=&#34;26&#34; viewBox=&#34;0 0 27 26&#34; fill=&#34;none&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
&lt;path opacity=&#34;0.2&#34; d=&#34;M1.73047 12.8359C1.73047 19.4634 7.10305 24.8359 13.7305 24.8359C20.3579 24.8359 25.7305 19.4634 25.7305 12.8359C25.7305 6.20852 20.3579 0.835937 13.7305 0.835937C7.10305 0.835937 1.73047 6.20852 1.73047 12.8359Z&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M18.2344 12.8359L9.23438 12.8359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M13.7344 8.33594L13.7344 17.3359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;/svg&gt;


    &lt;/span&gt;
  &lt;/button&gt;
  &lt;div class=&#34;collapse-content&#34; x-ref=&#34;content&#34; hidden=&#34;until-found&#34;&gt;
    &lt;div class=&#34;collapse-content__inner&#34; x-ref=&#34;content-inner&#34;&gt;
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: &amp;#39;v1&amp;#39;
kind: Namespace
metadata:
  name: grpcbin&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;collapse&#34; x-data=&#34;app_collapse()&#34;&gt;
  &lt;button class=&#34;collapse-trigger&#34; @click=&#34;toggle()&#34;&gt;
    &lt;span class=&#34;body-large&#34;&gt;pod.yaml&lt;/span&gt;
    &lt;span class=&#34;collapse-trigger__icon&#34; :class=&#34;{ &#39;collapse-trigger__icon-open&#39; : open }&#34;&gt;
      
  &lt;svg width=&#34;27&#34; height=&#34;26&#34; viewBox=&#34;0 0 27 26&#34; fill=&#34;none&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
&lt;path opacity=&#34;0.2&#34; d=&#34;M1.73047 12.8359C1.73047 19.4634 7.10305 24.8359 13.7305 24.8359C20.3579 24.8359 25.7305 19.4634 25.7305 12.8359C25.7305 6.20852 20.3579 0.835937 13.7305 0.835937C7.10305 0.835937 1.73047 6.20852 1.73047 12.8359Z&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M18.2344 12.8359L9.23438 12.8359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M13.7344 8.33594L13.7344 17.3359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;/svg&gt;


    &lt;/span&gt;
  &lt;/button&gt;
  &lt;div class=&#34;collapse-content&#34; x-ref=&#34;content&#34; hidden=&#34;until-found&#34;&gt;
    &lt;div class=&#34;collapse-content__inner&#34; x-ref=&#34;content-inner&#34;&gt;
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;kind: &amp;#39;Pod&amp;#39;
apiVersion: &amp;#39;v1&amp;#39;
metadata:
  name: grpcbin
  namespace: grpcbin
  labels:
    app: grpcbin
spec:
  containers:
    - name: grpcbin
      image: moul/grpcbin
      ports:
        - name: http
          containerPort: 9000&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;collapse&#34; x-data=&#34;app_collapse()&#34;&gt;
  &lt;button class=&#34;collapse-trigger&#34; @click=&#34;toggle()&#34;&gt;
    &lt;span class=&#34;body-large&#34;&gt;service.yaml&lt;/span&gt;
    &lt;span class=&#34;collapse-trigger__icon&#34; :class=&#34;{ &#39;collapse-trigger__icon-open&#39; : open }&#34;&gt;
      
  &lt;svg width=&#34;27&#34; height=&#34;26&#34; viewBox=&#34;0 0 27 26&#34; fill=&#34;none&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
&lt;path opacity=&#34;0.2&#34; d=&#34;M1.73047 12.8359C1.73047 19.4634 7.10305 24.8359 13.7305 24.8359C20.3579 24.8359 25.7305 19.4634 25.7305 12.8359C25.7305 6.20852 20.3579 0.835937 13.7305 0.835937C7.10305 0.835937 1.73047 6.20852 1.73047 12.8359Z&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M18.2344 12.8359L9.23438 12.8359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M13.7344 8.33594L13.7344 17.3359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;/svg&gt;


    &lt;/span&gt;
  &lt;/button&gt;
  &lt;div class=&#34;collapse-content&#34; x-ref=&#34;content&#34; hidden=&#34;until-found&#34;&gt;
    &lt;div class=&#34;collapse-content__inner&#34; x-ref=&#34;content-inner&#34;&gt;
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: &amp;#39;v1&amp;#39;
kind: &amp;#39;Service&amp;#39;
metadata:
  name: grpcbin
  namespace: grpcbin
spec:
  selector:
    app: grpcbin
  type: &amp;#39;NodePort&amp;#39;
  ports:
    - port: 9000
      targetPort: 9000&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;!-- md-k6:skipall --&gt;
]]></content><description>&lt;h1 id="inject-grpc-faults-into-service">Inject gRPC faults into Service&lt;/h1>
&lt;p>This example shows a way to use the
&lt;a href="/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/servicedisruptor/">ServiceDisruptor&lt;/a> to test the effect of faults injected in the gRPC requests served by a service.&lt;/p></description></item><item><title>Inject HTTP faults into Pod</title><link>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/inject-http-faults-into-pod/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/inject-http-faults-into-pod/</guid><content><![CDATA[&lt;h1 id=&#34;inject-http-faults-into-pod&#34;&gt;Inject HTTP faults into Pod&lt;/h1&gt;
&lt;p&gt;This example shows how 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/poddisruptor/&#34;&gt;PodDisruptor&lt;/a&gt; can be used for testing the effect of faults injected in the HTTP requests served by a pod.&lt;/p&gt;
&lt;p&gt;You will find the complete &lt;a href=&#34;#source-code&#34;&gt;source code&lt;/a&gt; at the end of this document. Next sections examine the code in detail.&lt;/p&gt;
&lt;p&gt;The example uses &lt;a href=&#34;https://httpbin.org&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;httpbin&lt;/a&gt;, a simple request/response application that offers endpoints for testing different HTTP requests.&lt;/p&gt;
&lt;p&gt;The test requires &lt;code&gt;httpbin&lt;/code&gt; to be deployed in a cluster in the namespace &lt;code&gt;httpbin&lt;/code&gt; and exposed with an external IP. the IP address is expected in the environment variable &lt;code&gt;SVC_IP&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You will find the Kubernetes manifests and the instructions of how to deploy it to a cluster in the &lt;a href=&#34;#test-setup&#34;&gt;test setup&lt;/a&gt; section at the end of this document. You can learn more about how to get the external IP address in the 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/expose--your-application/&#34;&gt;expose your application&lt;/a&gt; section.&lt;/p&gt;
&lt;h2 id=&#34;initialization&#34;&gt;Initialization&lt;/h2&gt;
&lt;p&gt;The initialization code imports the external dependencies required by the test. The &lt;code&gt;PodDisruptor&lt;/code&gt; class imported from the &lt;code&gt;xk6-disruptor&lt;/code&gt; extension provides functions for injecting faults in pods. The 
    &lt;a href=&#34;/docs/k6/v2.3.x/javascript-api/k6-http/&#34;&gt;k6/http&lt;/a&gt; module provides functions for executing HTTP requests.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { PodDisruptor } from &amp;#39;k6/x/disruptor&amp;#39;;
import http from &amp;#39;k6/http&amp;#39;;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;test-load&#34;&gt;Test Load&lt;/h2&gt;
&lt;p&gt;The test load is generated by the &lt;code&gt;default&lt;/code&gt; function, which executes a request to the &lt;code&gt;httpbin&lt;/code&gt; pod using the IP obtained from the environment variable &lt;code&gt;SVC_IP&lt;/code&gt;. The test makes requests to the endpoint &lt;code&gt;delay/0.1&lt;/code&gt; which will return after &lt;code&gt;0.1&lt;/code&gt; seconds (&lt;code&gt;100ms&lt;/code&gt;).&lt;/p&gt;
&lt;!-- eslint-disable no-undef  --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;export default function (data) {
  http.get(`http://${data.SVC_IP}/delay/0.1`);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- eslint-enable no-undef  --&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;The test uses the &lt;code&gt;delay&lt;/code&gt; endpoint which return after the requested delay. It requests a &lt;code&gt;0.1s&lt;/code&gt; (&lt;code&gt;100ms&lt;/code&gt;) delay to ensure the baseline scenario (see scenarios below) has meaningful statistics for the request duration. If we were simply calling a locally deployed http server (for example &lt;code&gt;nginx&lt;/code&gt;), the response time would exhibit a large variation between a few microseconds to a few milliseconds. Having &lt;code&gt;100ms&lt;/code&gt; as baseline response time has proved to offer more consistent results.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;fault-injection&#34;&gt;Fault injection&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;disrupt&lt;/code&gt; function creates a &lt;code&gt;PodDisruptor&lt;/code&gt; using a selector that matches pods in the namespace &lt;code&gt;httpbin&lt;/code&gt; with the label &lt;code&gt;app: httpbin&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The http faults are injected by calling the 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/poddisruptor/injecthttpfaults/&#34;&gt;PodDisruptor.injectHTTPFaults&lt;/a&gt; method using a fault definition that introduces a delay of &lt;code&gt;50ms&lt;/code&gt; on each request and an error code &lt;code&gt;500&lt;/code&gt; in &lt;code&gt;10%&lt;/code&gt; of the requests.&lt;/p&gt;
&lt;!-- eslint-disable no-undef  --&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;export function disrupt(data) {
  if (__ENV.SKIP_FAULTS == &amp;#39;1&amp;#39;) {
    return;
  }
  const selector = {
    namespace: namespace,
    select: {
      labels: {
        app: &amp;#39;httpbin&amp;#39;,
      },
    },
  };
  const podDisruptor = new PodDisruptor(selector);
  // delay traffic from one random replica of the deployment
  const fault = {
    averageDelay: &amp;#39;50ms&amp;#39;,
    errorCode: 500,
    errorRate: 0.1,
  };
  podDisruptor.injectHTTPFaults(fault, &amp;#39;30s&amp;#39;);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- eslint-enable no-undef  --&gt;
&lt;p&gt;Notice the following code snippet in the &lt;code&gt;injectFaults&lt;/code&gt; function above:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;export function disrupt(data) {
  if (__ENV.SKIP_FAULTS == &amp;#39;1&amp;#39;) {
    return;
  }
  //...
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This code makes the function return without injecting faults if the &lt;code&gt;SKIP_FAULTS&lt;/code&gt; environment variable is passed to the execution of the test with a value of &amp;ldquo;1&amp;rdquo;. We will use this option to obtain a &lt;a href=&#34;#baseline-execution&#34;&gt;baseline execution&lt;/a&gt; without faults.&lt;/p&gt;
&lt;h2 id=&#34;scenarios&#34;&gt;Scenarios&lt;/h2&gt;
&lt;p&gt;This test defines two 
    &lt;a href=&#34;/docs/k6/v2.3.x/using-k6/scenarios/&#34;&gt;scenarios&lt;/a&gt; to be executed. The &lt;code&gt;load&lt;/code&gt; scenario applies the test load to the &lt;code&gt;httpbin&lt;/code&gt; application for &lt;code&gt;30s&lt;/code&gt; invoking the &lt;code&gt;default&lt;/code&gt; function. The &lt;code&gt;disrupt&lt;/code&gt; scenario invokes the &lt;code&gt;disrupt&lt;/code&gt; function to inject a fault in the HTTP requests of the target application.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;export const options = {
  scenarios: {
    load: {
      executor: &amp;#39;constant-arrival-rate&amp;#39;,
      rate: 100,
      preAllocatedVUs: 10,
      maxVUs: 100,
      exec: &amp;#39;default&amp;#39;,
      startTime: &amp;#39;0s&amp;#39;,
      duration: &amp;#39;30s&amp;#39;,
    },
    disrupt: {
      executor: &amp;#39;shared-iterations&amp;#39;,
      iterations: 1,
      vus: 1,
      exec: &amp;#39;disrupt&amp;#39;,
      startTime: &amp;#39;0s&amp;#39;,
    },
  },
};&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Notice that the &lt;code&gt;disrupt&lt;/code&gt; scenario uses a &lt;code&gt;shared-iterations&lt;/code&gt; executor with one iteration and one &lt;code&gt;VU&lt;/code&gt;. This setting ensures the &lt;code&gt;disrupt&lt;/code&gt; function is executed only once. Executing this function multiples times concurrently may have unpredictable results.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;executions&#34;&gt;Executions&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;The commands in this section assume the &lt;code&gt;xk6-disruptor&lt;/code&gt; binary is available in your current directory. This location can change depending on the installation process and the platform. Refer to the 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/installation/&#34;&gt;installation section&lt;/a&gt; for details on how to install it in your environment.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h3 id=&#34;baseline-execution&#34;&gt;Baseline execution&lt;/h3&gt;
&lt;p&gt;We will first execute the test without introducing faults to have an baseline using the following command:&lt;/p&gt;



  

  






  

  



  &lt;div class=&#34;code&#34; x-data=&#34;app_code([&amp;#34;bash&amp;#34;,&amp;#34;windows-powershell&amp;#34;], false)&#34; x-init=&#34;init()&#34; data-codetoggle=&#34;true&#34;&gt;
    &lt;div class=&#34;toggle-toolbar &#34;&gt;
      &lt;div&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;bash&#39; }&#34; @click=&#34;$store.code.language = &#39;bash&#39;&#34;&gt;
              &lt;span&gt;Bash&lt;/span&gt;
            &lt;/button&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;windows-powershell&#39; }&#34; @click=&#34;$store.code.language = &#39;windows-powershell&#39;&#34;&gt;
              &lt;span&gt;windows-powershell&lt;/span&gt;
            &lt;/button&gt;&lt;/div&gt;
      &lt;div class=&#34;d-flex&#34;&gt;&lt;span class=&#34;code-clipboard&#34; x-ref=&#34;tooltip&#34;&gt;
          &lt;button @click=&#34;copy()&#34;&gt;
            &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
            &lt;span&gt;Copy&lt;/span&gt;
          &lt;/button&gt;
        &lt;/span&gt;
      &lt;/div&gt;
      &lt;div class=&#34;toggle-toolbar__border&#34;&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&#34;code-rendered&#34; &gt;
      
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;xk6-disruptor run --env SKIP_FAULTS=1 --env SVC_IP=$SVC_IP disrupt-pod.js&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;windows-powershell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-windows-powershell&#34;&gt;xk6-disruptor run --env SKIP_FAULTS=1 --env &amp;#34;SVC_IP=$Env:SVC_IP&amp;#34; disrupt-pod.js&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

    &lt;/div&gt;
  &lt;/div&gt;


&lt;p&gt;Notice the argument &lt;code&gt;--env SKIP_FAULT=1&lt;/code&gt;, which makes the &lt;code&gt;disrupt&lt;/code&gt; function return without injecting any fault as explained in the &lt;a href=&#34;#fault-injection&#34;&gt;fault injection&lt;/a&gt; section. Also notice the &lt;code&gt;--env SVC_IP&lt;/code&gt; argument, which passes the external IP used to access the &lt;code&gt;httpbin&lt;/code&gt; application.&lt;/p&gt;
&lt;p&gt;You should get an output similar to the one shown below (click &lt;code&gt;Expand&lt;/code&gt; button to see all output).&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;         /\      Grafana   /‾‾/
    /\  /  \     |\  __   /  /
   /  \/    \    | |/ /  /   ‾‾\
  /          \   |   (  |  (‾)  |
 / __________ \  |_|\_\  \_____/

  execution: local
     script: test.js
     output: -

  scenarios: (100.00%) 2 scenarios, 101 max VUs, 10m30s max duration (incl. graceful stop):
           * disrupt: 1 iterations shared among 1 VUs (maxDuration: 10m0s, exec: disrupt, gracefulStop: 30s)
           * load: 100.00 iterations/s for 30s (maxVUs: 10-100, exec: default, gracefulStop: 30s)


running (00m30.1s), 000/014 VUs, 2998 complete and 0 interrupted iterations
disrupt ✓ [======================================] 1 VUs        00m00.0s/10m0s  1/1 shared iters
load    ✓ [======================================] 000/013 VUs  30s             100.00 iters/s

     data_received..................: 1.4 MB 46 kB/s
     data_sent......................: 267 kB 8.9 kB/s
     dropped_iterations.............: 4      0.132766/s
     http_req_blocked...............: avg=8.08µs   min=2.36µs   med=5.8µs    max=543.79µs p(90)=8.68µs   p(95)=10.5µs
     http_req_connecting............: avg=1.25µs   min=0s       med=0s       max=418.63µs p(90)=0s       p(95)=0s
     http_req_duration..............: avg=103.22ms min=101.65ms med=103.13ms max=121.7ms  p(90)=104.01ms p(95)=104.4ms
       { expected_response:true }...: avg=103.22ms min=101.65ms med=103.13ms max=121.7ms  p(90)=104.01ms p(95)=104.4ms
     http_req_failed................: 0.00%  ✓ 0         ✗ 2997
     http_req_receiving.............: avg=133.5µs  min=45.06µs  med=131.23µs max=879.43µs p(90)=193.48µs p(95)=223.04µs
     http_req_sending...............: avg=31.14µs  min=11.46µs  med=29.37µs  max=171.68µs p(90)=40.48µs  p(95)=47.53µs
     http_req_tls_handshaking.......: avg=0s       min=0s       med=0s       max=0s       p(90)=0s       p(95)=0s
     http_req_waiting...............: avg=103.05ms min=101.54ms med=102.98ms max=121.56ms p(90)=103.82ms p(95)=104.2ms
     http_reqs......................: 2997   99.474844/s
     iteration_duration.............: avg=103.34ms min=109.86µs med=103.28ms max=121.92ms p(90)=104.19ms p(95)=104.63ms
     iterations.....................: 2998   99.508035/s
     vus............................: 13     min=11      max=13
     vus_max........................: 14     min=12      max=14&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;fault-injection-1&#34;&gt;Fault injection&lt;/h3&gt;
&lt;p&gt;We repeat the execution injecting the faults. Notice we have removed the &lt;code&gt;--env SKIP_FAULTS=1&lt;/code&gt; argument.&lt;/p&gt;



  

  






  

  



  &lt;div class=&#34;code&#34; x-data=&#34;app_code([&amp;#34;bash&amp;#34;,&amp;#34;windows-powershell&amp;#34;], false)&#34; x-init=&#34;init()&#34; data-codetoggle=&#34;true&#34;&gt;
    &lt;div class=&#34;toggle-toolbar &#34;&gt;
      &lt;div&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;bash&#39; }&#34; @click=&#34;$store.code.language = &#39;bash&#39;&#34;&gt;
              &lt;span&gt;Bash&lt;/span&gt;
            &lt;/button&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;windows-powershell&#39; }&#34; @click=&#34;$store.code.language = &#39;windows-powershell&#39;&#34;&gt;
              &lt;span&gt;windows-powershell&lt;/span&gt;
            &lt;/button&gt;&lt;/div&gt;
      &lt;div class=&#34;d-flex&#34;&gt;&lt;span class=&#34;code-clipboard&#34; x-ref=&#34;tooltip&#34;&gt;
          &lt;button @click=&#34;copy()&#34;&gt;
            &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
            &lt;span&gt;Copy&lt;/span&gt;
          &lt;/button&gt;
        &lt;/span&gt;
      &lt;/div&gt;
      &lt;div class=&#34;toggle-toolbar__border&#34;&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&#34;code-rendered&#34; &gt;
      
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;xk6-disruptor run --env SVC_IP=$SVC_IP disrupt-pod.js&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;windows-powershell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-windows-powershell&#34;&gt;xk6-disruptor run --env &amp;#34;SVC_IP=$Env:SVC_IP&amp;#34; disrupt-pod.js&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

    &lt;/div&gt;
  &lt;/div&gt;



&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;         /\      Grafana   /‾‾/
    /\  /  \     |\  __   /  /
   /  \/    \    | |/ /  /   ‾‾\
  /          \   |   (  |  (‾)  |
 / __________ \  |_|\_\  \_____/

  execution: local
     script: disrupt-pod.js
     output: -

  scenarios: (100.00%) 2 scenarios, 101 max VUs, 10m30s max duration (incl. graceful stop):
           * disrupt: 1 iterations shared among 1 VUs (maxDuration: 10m0s, exec: disrupt, gracefulStop: 30s)
           * load: 100.00 iterations/s for 30s (maxVUs: 10-100, exec: default, gracefulStop: 30s)


running (00m31.1s), 000/018 VUs, 2995 complete and 0 interrupted iterations
disrupt ✓ [======================================] 1 VUs        00m31.1s/10m0s  1/1 shared iters
load    ✓ [======================================] 000/017 VUs  30s             100.00 iters/s

     data_received..................: 1.1 MB 34 kB/s
     data_sent......................: 267 kB 8.6 kB/s
     dropped_iterations.............: 7      0.224798/s
     http_req_blocked...............: avg=9.81µs   min=2.59µs   med=5.93µs   max=489.67µs p(90)=7.88µs   p(95)=9.5µs
     http_req_connecting............: avg=2.48µs   min=0s       med=0s       max=367.63µs p(90)=0s       p(95)=0s
     http_req_duration..............: avg=142.15ms min=50.33ms  med=153.79ms max=165.85ms p(90)=154.8ms  p(95)=155.12ms
       { expected_response:true }...: avg=151.9ms  min=101.81ms med=153.9ms  max=165.85ms p(90)=154.86ms p(95)=155.17ms
     http_req_failed................: 9.65%  ✓ 289       ✗ 2705
     http_req_receiving.............: avg=80.92µs  min=28.32µs  med=77.33µs  max=352.19µs p(90)=105.09µs p(95)=123.68µs
     http_req_sending...............: avg=30.43µs  min=11.27µs  med=29.37µs  max=287.71µs p(90)=37.42µs  p(95)=41.84µs
     http_req_tls_handshaking.......: avg=0s       min=0s       med=0s       max=0s       p(90)=0s       p(95)=0s
     http_req_waiting...............: avg=142.04ms min=50.25ms  med=153.68ms max=165.76ms p(90)=154.69ms p(95)=155.01ms
     http_reqs......................: 2994   96.149356/s
     iteration_duration.............: avg=152.64ms min=50.43ms  med=153.93ms max=31.12s   p(90)=154.97ms p(95)=155.29ms
     iterations.....................: 2995   96.18147/s
     vus............................: 1      min=1       max=18
     vus_max........................: 18     min=12      max=18&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;comparison&#34;&gt;Comparison&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s take a closer look at the results for the requests on each scenario. We can observe that he &lt;code&gt;base&lt;/code&gt; scenario has an average of &lt;code&gt;103ms&lt;/code&gt; and an error rate of &lt;code&gt;0%&lt;/code&gt; while the &lt;code&gt;faults&lt;/code&gt; scenario has a median around &lt;code&gt;151.9ms&lt;/code&gt; and an error rate of nearly &lt;code&gt;10%&lt;/code&gt;, matching the definition of the faults defined in the disruptor.&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Execution&lt;/th&gt;
              &lt;th&gt;Avg. Response&lt;/th&gt;
              &lt;th&gt;Failed requests&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;Baseline&lt;/td&gt;
              &lt;td&gt;103.22ms&lt;/td&gt;
              &lt;td&gt;0.00%&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Fault injection&lt;/td&gt;
              &lt;td&gt;151.9 ms&lt;/td&gt;
              &lt;td&gt;9.65%&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;

&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Notice we have used the average response time reported as &lt;code&gt;expected_response:true&lt;/code&gt; because this metric only consider successful requests while &lt;code&gt;http_req_duration&lt;/code&gt; considers all requests, including those returning a fault.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;source-code&#34;&gt;Source Code&lt;/h2&gt;
&lt;div class=&#34;collapse&#34; x-data=&#34;app_collapse()&#34;&gt;
  &lt;button class=&#34;collapse-trigger&#34; @click=&#34;toggle()&#34;&gt;
    &lt;span class=&#34;body-large&#34;&gt;disrupt-pod.js&lt;/span&gt;
    &lt;span class=&#34;collapse-trigger__icon&#34; :class=&#34;{ &#39;collapse-trigger__icon-open&#39; : open }&#34;&gt;
      
  &lt;svg width=&#34;27&#34; height=&#34;26&#34; viewBox=&#34;0 0 27 26&#34; fill=&#34;none&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
&lt;path opacity=&#34;0.2&#34; d=&#34;M1.73047 12.8359C1.73047 19.4634 7.10305 24.8359 13.7305 24.8359C20.3579 24.8359 25.7305 19.4634 25.7305 12.8359C25.7305 6.20852 20.3579 0.835937 13.7305 0.835937C7.10305 0.835937 1.73047 6.20852 1.73047 12.8359Z&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M18.2344 12.8359L9.23438 12.8359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M13.7344 8.33594L13.7344 17.3359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;/svg&gt;


    &lt;/span&gt;
  &lt;/button&gt;
  &lt;div class=&#34;collapse-content&#34; x-ref=&#34;content&#34; hidden=&#34;until-found&#34;&gt;
    &lt;div class=&#34;collapse-content__inner&#34; x-ref=&#34;content-inner&#34;&gt;
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JavaScript&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-javascript&#34;&gt;import { PodDisruptor } from &amp;#39;k6/x/disruptor&amp;#39;;
import http from &amp;#39;k6/http&amp;#39;;

export default function (data) {
  http.get(`http://${__ENV.SVC_IP}/delay/0.1`);
}

export function disrupt(data) {
  if (__ENV.SKIP_FAULTS == &amp;#39;1&amp;#39;) {
    return;
  }

  const selector = {
    namespace: &amp;#39;httpbin&amp;#39;,
    select: {
      labels: {
        app: &amp;#39;httpbin&amp;#39;,
      },
    },
  };
  const podDisruptor = new PodDisruptor(selector);

  // delay traffic from one random replica of the deployment
  const fault = {
    averageDelay: &amp;#39;50ms&amp;#39;,
    errorCode: 500,
    errorRate: 0.1,
  };
  podDisruptor.injectHTTPFaults(fault, &amp;#39;30s&amp;#39;);
}

export const options = {
  scenarios: {
    load: {
      executor: &amp;#39;constant-arrival-rate&amp;#39;,
      rate: 100,
      preAllocatedVUs: 10,
      maxVUs: 100,
      exec: &amp;#39;default&amp;#39;,
      startTime: &amp;#39;0s&amp;#39;,
      duration: &amp;#39;30s&amp;#39;,
    },
    disrupt: {
      executor: &amp;#39;shared-iterations&amp;#39;,
      iterations: 1,
      vus: 1,
      exec: &amp;#39;disrupt&amp;#39;,
      startTime: &amp;#39;0s&amp;#39;,
    },
  },
};&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h2 id=&#34;test-setup&#34;&gt;Test setup&lt;/h2&gt;
&lt;p&gt;The tests requires the deployment of the &lt;code&gt;httpbin&lt;/code&gt; application. The application must also be accessible using an external IP available in the &lt;code&gt;SVC_IP&lt;/code&gt; environment variable.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;#manifests&#34;&gt;manifests&lt;/a&gt; below define the resources required for deploying the application and exposing it as a LoadBalancer service.&lt;/p&gt;
&lt;p&gt;You can deploy the application using the following commands:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;# Create Namespace
kubectl apply -f namespace.yaml
namespace/httpbin created

# Deploy Pod
kubectl apply -f pod.yaml
pod/httpbin created

# Expose Pod as a Service
kubectl apply -f service.yaml
service/httpbin created&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can retrieve the resources using the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl -n httpbin get all
NAME          READY   STATUS    RESTARTS   AGE
pod/httpbin   1/1     Running   0          1m

NAME              TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
service/httpbin   LoadBalancer   10.96.169.78   172.18.255.200   80:31224/TCP   1m&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You must set the environment variable &lt;code&gt;SVC_IP&lt;/code&gt; with the external IP address and port used to access the &lt;code&gt;httpbin&lt;/code&gt; service from the test script.&lt;/p&gt;
&lt;p&gt;You can learn more about how to get the external IP address in the 
    &lt;a href=&#34;/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/expose--your-application/&#34;&gt;expose your application&lt;/a&gt; section.&lt;/p&gt;
&lt;h3 id=&#34;manifests&#34;&gt;Manifests&lt;/h3&gt;
&lt;div class=&#34;collapse&#34; x-data=&#34;app_collapse()&#34;&gt;
  &lt;button class=&#34;collapse-trigger&#34; @click=&#34;toggle()&#34;&gt;
    &lt;span class=&#34;body-large&#34;&gt;namespace.yaml&lt;/span&gt;
    &lt;span class=&#34;collapse-trigger__icon&#34; :class=&#34;{ &#39;collapse-trigger__icon-open&#39; : open }&#34;&gt;
      
  &lt;svg width=&#34;27&#34; height=&#34;26&#34; viewBox=&#34;0 0 27 26&#34; fill=&#34;none&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
&lt;path opacity=&#34;0.2&#34; d=&#34;M1.73047 12.8359C1.73047 19.4634 7.10305 24.8359 13.7305 24.8359C20.3579 24.8359 25.7305 19.4634 25.7305 12.8359C25.7305 6.20852 20.3579 0.835937 13.7305 0.835937C7.10305 0.835937 1.73047 6.20852 1.73047 12.8359Z&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M18.2344 12.8359L9.23438 12.8359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M13.7344 8.33594L13.7344 17.3359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;/svg&gt;


    &lt;/span&gt;
  &lt;/button&gt;
  &lt;div class=&#34;collapse-content&#34; x-ref=&#34;content&#34; hidden=&#34;until-found&#34;&gt;
    &lt;div class=&#34;collapse-content__inner&#34; x-ref=&#34;content-inner&#34;&gt;
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: &amp;#39;v1&amp;#39;
kind: Namespace
metadata:
  name: httpbin&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;collapse&#34; x-data=&#34;app_collapse()&#34;&gt;
  &lt;button class=&#34;collapse-trigger&#34; @click=&#34;toggle()&#34;&gt;
    &lt;span class=&#34;body-large&#34;&gt;pod.yaml&lt;/span&gt;
    &lt;span class=&#34;collapse-trigger__icon&#34; :class=&#34;{ &#39;collapse-trigger__icon-open&#39; : open }&#34;&gt;
      
  &lt;svg width=&#34;27&#34; height=&#34;26&#34; viewBox=&#34;0 0 27 26&#34; fill=&#34;none&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
&lt;path opacity=&#34;0.2&#34; d=&#34;M1.73047 12.8359C1.73047 19.4634 7.10305 24.8359 13.7305 24.8359C20.3579 24.8359 25.7305 19.4634 25.7305 12.8359C25.7305 6.20852 20.3579 0.835937 13.7305 0.835937C7.10305 0.835937 1.73047 6.20852 1.73047 12.8359Z&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M18.2344 12.8359L9.23438 12.8359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M13.7344 8.33594L13.7344 17.3359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;/svg&gt;


    &lt;/span&gt;
  &lt;/button&gt;
  &lt;div class=&#34;collapse-content&#34; x-ref=&#34;content&#34; hidden=&#34;until-found&#34;&gt;
    &lt;div class=&#34;collapse-content__inner&#34; x-ref=&#34;content-inner&#34;&gt;
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;kind: &amp;#39;Pod&amp;#39;
apiVersion: &amp;#39;v1&amp;#39;
metadata:
  name: httpbin
  namespace: httpbin
  labels:
    app: httpbin
spec:
  containers:
    - name: httpbin
      image: kennethreitz/httpbin
      ports:
        - name: http
          containerPort: 80&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;collapse&#34; x-data=&#34;app_collapse()&#34;&gt;
  &lt;button class=&#34;collapse-trigger&#34; @click=&#34;toggle()&#34;&gt;
    &lt;span class=&#34;body-large&#34;&gt;service.yaml&lt;/span&gt;
    &lt;span class=&#34;collapse-trigger__icon&#34; :class=&#34;{ &#39;collapse-trigger__icon-open&#39; : open }&#34;&gt;
      
  &lt;svg width=&#34;27&#34; height=&#34;26&#34; viewBox=&#34;0 0 27 26&#34; fill=&#34;none&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
&lt;path opacity=&#34;0.2&#34; d=&#34;M1.73047 12.8359C1.73047 19.4634 7.10305 24.8359 13.7305 24.8359C20.3579 24.8359 25.7305 19.4634 25.7305 12.8359C25.7305 6.20852 20.3579 0.835937 13.7305 0.835937C7.10305 0.835937 1.73047 6.20852 1.73047 12.8359Z&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M18.2344 12.8359L9.23438 12.8359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M13.7344 8.33594L13.7344 17.3359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;/svg&gt;


    &lt;/span&gt;
  &lt;/button&gt;
  &lt;div class=&#34;collapse-content&#34; x-ref=&#34;content&#34; hidden=&#34;until-found&#34;&gt;
    &lt;div class=&#34;collapse-content__inner&#34; x-ref=&#34;content-inner&#34;&gt;
&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: &amp;#39;v1&amp;#39;
kind: &amp;#39;Service&amp;#39;
metadata:
  name: httpbin
  namespace: httpbin
spec:
  selector:
    app: httpbin
  type: &amp;#39;LoadBalancer&amp;#39;
  ports:
    - port: 80
      targetPort: 80&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;!-- md-k6:skipall --&gt;
]]></content><description>&lt;h1 id="inject-http-faults-into-pod">Inject HTTP faults into Pod&lt;/h1>
&lt;p>This example shows how
&lt;a href="/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/xk6-disruptor/poddisruptor/">PodDisruptor&lt;/a> can be used for testing the effect of faults injected in the HTTP requests served by a pod.&lt;/p></description></item><item><title>Interactive demo</title><link>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/demo-environment/</link><pubDate>Mon, 21 Sep 2026 15:16:28 +0000</pubDate><guid>https://grafana.com/docs/k6/v2.3.x/testing-guides/injecting-faults-with-xk6-disruptor/examples/demo-environment/</guid><content><![CDATA[&lt;h1 id=&#34;interactive-demo&#34;&gt;Interactive demo&lt;/h1&gt;
&lt;p&gt;Visit the &lt;a href=&#34;https://killercoda.com/grafana-xk6-disruptor/scenario/killercoda&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;interactive demo environment in Killercoda&lt;/a&gt; and try the disruptor in a demo application without having to do any setup.&lt;/p&gt;
]]></content><description>&lt;h1 id="interactive-demo">Interactive demo&lt;/h1>
&lt;p>Visit the &lt;a href="https://killercoda.com/grafana-xk6-disruptor/scenario/killercoda" target="_blank" rel="noopener noreferrer">interactive demo environment in Killercoda&lt;/a> and try the disruptor in a demo application without having to do any setup.&lt;/p></description></item></channel></rss>