<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: mikotian</title>
    <description>The latest articles on DEV Community by mikotian (@mikotian).</description>
    <link>https://dev.to/mikotian</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F109537%2F94befa6d-baf8-41bd-9c0b-e4713969a02b.jpeg</url>
      <title>DEV Community: mikotian</title>
      <link>https://dev.to/mikotian</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mikotian"/>
    <language>en</language>
    <item>
      <title>Making a server believe you're from somewhere else</title>
      <dc:creator>mikotian</dc:creator>
      <pubDate>Sun, 22 Jun 2025 18:00:00 +0000</pubDate>
      <link>https://dev.to/mikotian/making-a-server-believe-youre-from-somewhere-else-4n0h</link>
      <guid>https://dev.to/mikotian/making-a-server-believe-youre-from-somewhere-else-4n0h</guid>
      <description>&lt;p&gt;Recently I had to test a scenario where the laravel application detects which region a request is coming from and based on that chooses the correct payment gateway (domestic/international) to effect the payment. This was tricky for the following reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We were testing on servers which were in a VPN enclosed environment. And the VPN gateway always shows a United States IP.&lt;/li&gt;
&lt;li&gt;All gateways available to us were US based only. Using a different VPN wasn't possible as its against company policy (and also unsafe).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now normally, when such systems are built, they are usually built on the basis of geolocation (invasive, think of your browser asking you to share your location) or on the basis of IP Ranges (non-invasive, you can find these on many websites that tell you that you are from such and such country). We were going with IP Ranges, so spoofing geolocation using chrome, playwright etc was out of the question.&lt;/p&gt;

&lt;p&gt;The Solution:&lt;/p&gt;

&lt;p&gt;We're using an Apache Server as our web server. One of the features of the apache web server is the modules you can load onto it that helps you do things before requests hit the hosted applications. One such module is the mod_headers, which can be used to add/modify basically any header one may need.&lt;/p&gt;

&lt;p&gt;So we added the module, enabled it and wrote in a rule that would replace the RemoteIPHeader with whatever IP we fedinto each request in the X-Forwarded-For header.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ sudo a2enmod mod_headers&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ sudo a2enmod headers&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Restart apache2&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo systemctl restart apache2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add the following to virtualhost config for application site&lt;/p&gt;

&lt;p&gt;&lt;code&gt;RemoteIPHeader X-Forwarded-For&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That is the configuration needed at the server side.&lt;/p&gt;

&lt;p&gt;At the client side, we need to ensure that the X-Forwarded-For header is added/modified for each request. Since this is a web application and not an API, it needs some extra helping to do this.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a chrome extension to modify each request to add the required X-Forwarded-For&lt;/li&gt;
&lt;li&gt;Use a proxy that does the above.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We used a proxy. More to the point, we used Burp Suite Community Edition to do the same.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fraco706ykjqpi3t9zaf1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fraco706ykjqpi3t9zaf1.png" alt="Burp Proxy Settings" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Burp has a built in browser that will use the configured proxy. Browse the application with this browser and voila! You have fooled your application that you are from Berlin when in truth you sit in Baramati!&lt;/p&gt;

&lt;p&gt;The process in a nutshell:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fej1hivnqtzmifuy7g4pu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fej1hivnqtzmifuy7g4pu.png" alt="Flowchart showing modification of IP via Proxy" width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ipspoofing</category>
      <category>testing</category>
    </item>
    <item>
      <title>Running a simple chaos toolkit experiment</title>
      <dc:creator>mikotian</dc:creator>
      <pubDate>Sun, 11 Jul 2021 20:02:46 +0000</pubDate>
      <link>https://dev.to/mikotian/running-a-simple-chaos-toolkit-experiment-a5a</link>
      <guid>https://dev.to/mikotian/running-a-simple-chaos-toolkit-experiment-a5a</guid>
      <description>&lt;p&gt;Install Chaos Toolkit &amp;amp; required drivers as mentioned here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Setting up ChaosToolkit Execution Environment&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Make sure the virtual environment is activated.&lt;/p&gt;

&lt;p&gt;Create the following file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"random website testing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Just checking the chaostoolkit base stuff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"steady-state-hypothesis"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Website is OK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"probes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"probe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"website-must-be-up"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"tolerance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"timeout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://httpbin.org/forms/post"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GET"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"probe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"website-must-return-202"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tolerance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;202&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://httpbin.org/status/202"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"probe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"response should be json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tolerance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jsonpath"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$.slideshow.author"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"expect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="s2"&gt;"failed"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"body"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://httpbin.org/json"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rollbacks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running the experiment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chaos run SimpleExperiment.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ScreenGrab:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/qJy20m2GT4M"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The same can be run in a Jenkins Pipeline:&lt;/p&gt;

&lt;p&gt;The jenkins pipeline script is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pipeline {
    agent any

    stages {
        stage('Deploy') {
            steps {
                // Get some code from a GitHub repository
                git 'https://github.com/mikotian/resilientchaos.git'

            }

            post {
                success {
                    echo 'Hello World'
                }
            }
        }
        stage('Run Chaos Script') {
            steps {

                sh ". /home/mithun/.venvs/chaostk/bin/activate &amp;amp;&amp;amp; chaos run SimpleExperiment.json"
            }

            post {
                success {
                    echo 'Success'
                }
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The execution looks like this:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/VJoiFlIHL7E"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>resiliency</category>
      <category>chaos</category>
      <category>toolkit</category>
    </item>
    <item>
      <title>Setting up ChaosToolkit Execution Environment</title>
      <dc:creator>mikotian</dc:creator>
      <pubDate>Sun, 11 Jul 2021 20:01:32 +0000</pubDate>
      <link>https://dev.to/mikotian/setting-up-chaostoolkit-execution-environment-2hm6</link>
      <guid>https://dev.to/mikotian/setting-up-chaostoolkit-execution-environment-2hm6</guid>
      <description>&lt;p&gt;&lt;strong&gt;Base Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install Python 3.5 on your execution machine.&lt;/p&gt;

&lt;p&gt;Windows : Download the &lt;a href="https://www.python.org/downloads/windows/" rel="noopener noreferrer"&gt;latest binary installer&lt;/a&gt; from the Python website.&lt;/p&gt;

&lt;p&gt;Linux: &lt;a href="https://www.python.org/download/other/" rel="noopener noreferrer"&gt;https://www.python.org/download/other/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a virtual environment. Virtual environments help us encapsulate our changes away from the larger system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python3 -m venv ~/.venvs/resilient

source ~/.venvs/resilient/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install chaostoolkit&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install chaostoolkit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify version&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chaos --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will install the base version of chaostoolkit with its inbuilt probes, tolerances &amp;amp; actions.&lt;/p&gt;

&lt;p&gt;Install AWS Drivers&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install -U chaostoolkit-aws
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Passing Credentials to ChaosToolkit.&lt;/p&gt;

&lt;p&gt;For AWS actions/probes to work as expected we need to place a credentials file like below in the following location. ~/.aws&lt;/p&gt;

&lt;p&gt;The credentials can be added in the experiment itself, like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"secrets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"aws"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"aws_access_key_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"aws_secret_access_key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"access key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"aws_session_token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"token"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thats it, you're all set to run AWS Chaos/resiliency experiments!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install Toxiproxy Drivers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install Toxiproxy Server from here: (&lt;a href="https://github.com/Shopify/toxiproxy/releases" rel="noopener noreferrer"&gt;https://github.com/Shopify/toxiproxy/releases&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Install the toxiproxy CLI (&lt;a href="https://github.com/Shopify/toxiproxy/releases" rel="noopener noreferrer"&gt;https://github.com/Shopify/toxiproxy/releases&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;These are required in order to make the network changes work.&lt;/p&gt;

&lt;p&gt;Install the chaos toolkit drivers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install -U chaostoolkit-toxiproxy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following configuration to your experiment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"configuration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"toxiproxy_host"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"10.124.23.183"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"some_environment_variable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"environment"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ENVIRONMENT_VARIABLE"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start the toxiproxy server.&lt;/p&gt;

&lt;p&gt;Now you are ready to run the experiment.&lt;/p&gt;

</description>
      <category>chaos</category>
      <category>toolkit</category>
      <category>resiliency</category>
    </item>
    <item>
      <title>ChaosToolkit Basics</title>
      <dc:creator>mikotian</dc:creator>
      <pubDate>Sun, 11 Jul 2021 19:58:49 +0000</pubDate>
      <link>https://dev.to/mikotian/chaostoolkit-basics-o54</link>
      <guid>https://dev.to/mikotian/chaostoolkit-basics-o54</guid>
      <description>&lt;p&gt;The major aim of Resiliency Experiments is always the same -&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;To observe a steady state
Do something that attempts to disrupt that steady state
Observe if we still have a steady state
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;These three steps are always constant in any resiliency experiment.&lt;/p&gt;

&lt;p&gt;What changes are the ways we measure or cause these steps to happen.&lt;/p&gt;

&lt;p&gt;For instance,&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;To see if a service is up we can have multiple methods viz. Health Checks, Monitoring Checks or Request Checks.
To simulate a service downtime, we can shutdown the machine or the specific process (each has its own case)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In order to correctly perform the experiment when automated and to maintain the sameness for the tests, we needed to implement a tool that would provide a homogeneous way of doing this.&lt;/p&gt;

&lt;p&gt;We evaluated Gremlin and Chaos Toolkit for these experiments.&lt;/p&gt;

&lt;p&gt;This document describes the working of Chaos Toolkit, keeping in mind what is listed above.&lt;br&gt;
Chaos Toolkit is a declarative framework for Chaos Engineering experiments which can be extended for any system by using drivers. It has open source drivers for most major systems.&lt;/p&gt;

&lt;p&gt;We will take a look at the declarative framework and its basics:&lt;/p&gt;

&lt;p&gt;Each Experiment will have the following sections:&lt;/p&gt;

&lt;p&gt;Description Section:&lt;/p&gt;

&lt;p&gt;This is just meta data for the test. Version, Title &amp;amp; Description mention specifics of the experiment. The tags mention what the system being tested is composed of or what the test tags are. There can be multiple tags but only singular version, title &amp;amp; description.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx7igx08msfxemhevyzb2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx7igx08msfxemhevyzb2.png" alt="Description Section" width="473" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Steady State Hypothesis Section:&lt;/p&gt;

&lt;p&gt;This is the heart of the experiment. This section is executed when the experiment is started and after the "method" section is executed. The first time execution is to ensure that steady state hypothesis is met before we do any action. If it is not, then the experiment is failed. The Steady State&lt;/p&gt;

&lt;p&gt;The way to verify a state or hypothesis is by using a probe. ChaosToolkit provides a set of probes that can be used to check on services or URLs. Each probe has a provider which mentions the type of the probe and arguments, if applicable. Each probe is different and may have multiple arguments or none at all.&lt;/p&gt;

&lt;p&gt;In the example below, there are two probes.&lt;/p&gt;

&lt;p&gt;The first one is a python function that returns a boolean. This is verified in the "tolerance" parameter.&lt;/p&gt;

&lt;p&gt;The second one is a built in http probe that checks a url and verifies if the response code is 200&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Writing a good steady state hypothesis is essential to get your resiliency tests be repeatable and accurate. Too simple and you risk missing issues. Too complex and you risk false negatives.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foljg6ic9gvyjom5uydyf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foljg6ic9gvyjom5uydyf.png" alt="Steady State Hypothesis" width="471" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"Action" Section:&lt;/p&gt;

&lt;p&gt;This section is where we perform our "disruptions"&lt;/p&gt;

&lt;p&gt;Depending on the drivers, we can have many types of disruptions, for e.g:&lt;/p&gt;

&lt;p&gt;The AWS driver can shutdown instances, random machines in availability zones etc.&lt;/p&gt;

&lt;p&gt;Kubernetes drivers have the ability to kill random pods.&lt;/p&gt;

&lt;p&gt;In the example below, we can see that the action is terminating a pod based on a random name from a given pattern. After the action is performed, we can pause execution for a provided value in seconds to let the system stabilize and then proceed to  probe for our expected values. In this case we are probing by reference of a probe that has already been defined earlier in the experiment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9u2a55uhc6vl41ovwtos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9u2a55uhc6vl41ovwtos.png" alt="Action Section" width="479" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see the other probes defined as well. Just as there can be multiple probes, there can be multiple actions within the "methods" section.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;It might be better to keep the action itself brief and limited so that we can objectively identify what that action does to our system. If there are multiple actions, determining what caused the failure might be difficult.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;This is not always true though as many issues will come up because of multiple actions performed simultaneously. In short, YMMV.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2mmu6i2p6hm0nb1qyn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2mmu6i2p6hm0nb1qyn8.png" alt="snippet" width="433" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rollback Section:&lt;/p&gt;

&lt;p&gt;This section is to undo any permanent change to the system we may have caused during the course of the experiment. For example, we could start an instance that we shut down in the experiment.&lt;/p&gt;

&lt;p&gt;Overall, an experiment descriptor file looks like below:&lt;/p&gt;

&lt;p&gt;
  Simple ChaosToolkit Experiment
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Stop an instance"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"it should stop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"stop"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"steady-state-hypothesis"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Application responds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"probes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"count-instances"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"probe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"tolerance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"func"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"count_instances"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"arguments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="nl"&gt;"filters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"chaosaws.ec2.probes"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stop-an-ec2-instance"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"chaosaws.ec2.actions"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"func"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stop_instance"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"arguments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"instance_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"i-0e1f0c1d97589b5e9"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pauses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"after"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"count-instances"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"probe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"tolerance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"func"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"count_instances"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"arguments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"filters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"chaosaws.ec2.probes"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"probe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"healthcheck-service-must-still-respond"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:8080/healthcheck"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

</description>
      <category>chaos</category>
      <category>toolkit</category>
      <category>resiliency</category>
    </item>
    <item>
      <title>Resiliency</title>
      <dc:creator>mikotian</dc:creator>
      <pubDate>Sun, 11 Jul 2021 19:56:43 +0000</pubDate>
      <link>https://dev.to/mikotian/resiliency-1d68</link>
      <guid>https://dev.to/mikotian/resiliency-1d68</guid>
      <description>&lt;p&gt;In a complex setup where hundreds of microservices talk to and depend on each other to function properly, things can always go wrong. Especially when multiple teams are involved in making changes. Sometimes multiple teams are involved in making changes on the same microservice! This is a sure shot recipe for issues that will crop up at stages starting from integration to weird production issues that may have no functional basis at all. Some issues are purely related to improper error handling, dependency management or infrastructure glitches causing cascading issues. It is this problem that Resiliency Testing tries to solve. While these need not be automated all the time, but having these automated (for a mature product) is most likely to be beneficial.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core Aim of Resiliency Tests:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify Resiliency Issues with the Application Under Test&lt;/li&gt;
&lt;li&gt;Help the team identify markers of issues that may otherwise take multiple hours to decode in a production environment&lt;/li&gt;
&lt;li&gt;Make a more observable system by introducing errors that will expose the need for more logging and tracing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The two main areas for inducing uncertainty in a system are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure&lt;/strong&gt;: Randomly shutting down instances and other infrastructure parts&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Application&lt;/strong&gt;: Introduce failures during runtime at a component level (e.g. endpoint/request level)&lt;/p&gt;

&lt;p&gt;You then enable uncertainty randomly or intentionally via experiments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Randomly (Chaos)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More suitable for ‘disposable’ infrastructure (e.g. ec2 instances)&lt;/li&gt;
&lt;li&gt;Tests redundant infrastructure for impact on end-users&lt;/li&gt;
&lt;li&gt;Used when impact is well-understood&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Experiments (Resilience)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accurately measure impact&lt;/li&gt;
&lt;li&gt;Control over experimental parameters&lt;/li&gt;
&lt;li&gt;Suitable for complex failures (e.g. latency) when impact is not well understood&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Finally, you can categorize failure modes as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resource&lt;/strong&gt;: CPU, memory, IO, disk&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Network&lt;/strong&gt;: Blackhole, latency, packet loss, DNS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;State&lt;/strong&gt;: Shutdown, time, process killer&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many of these modes can be applied or simulated at the infrastructure or application level:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzd9a2o4l49kd1qy0puxi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzd9a2o4l49kd1qy0puxi.jpg" alt="Resiliency Areas" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After running an experiment, there are typically two potential outcomes. Either the system is found to be resilient to the introduced failure, or a problem is identified that may needed to be fixed. Both of these are good outcomes. In the first case, the confidence in the system and its behaviour is enhanced. In the other case, a problem has been found before it causes an outage.&lt;/p&gt;

&lt;p&gt;By proactively testing and validating our system’s failure modes we can reduce operational burden, increase resiliency, and will eventually lead to reduced palpitations at the time of production issues.&lt;/p&gt;

</description>
      <category>resiliency</category>
    </item>
    <item>
      <title>To kill a MockingBird...</title>
      <dc:creator>mikotian</dc:creator>
      <pubDate>Mon, 09 Mar 2020 14:02:09 +0000</pubDate>
      <link>https://dev.to/mikotian/to-kill-a-mockingbird-5c2j</link>
      <guid>https://dev.to/mikotian/to-kill-a-mockingbird-5c2j</guid>
      <description>&lt;p&gt;In the previous posts of the series I recounted why the need for MockingBird arose and what we did to implement it.&lt;/p&gt;

&lt;p&gt;To recap, it was implemented using Flask and Python and was started on the machine using the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;python mockingbird.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This meant that Flask was running in its default mode - development, on its own server and was running a single process - ideally with a single thread but I have read conflicting documents that mention that flask is multi-threaded by default currently (i.e Threaded=true is the default way now).&lt;/p&gt;

&lt;p&gt;If a single thread is around, then flask will serve only one request at a time. This combined with the 0.5s sleep we applied would mean that we were able to serve only 2 requests per second. Which is not ideal.&lt;/p&gt;

&lt;p&gt;My target was 1200 requests per minute at the bare minimum.&lt;/p&gt;

&lt;p&gt;My tests initially went well, we were able to handle the load thrown at the MockingBird pretty well (probably because of the aforementioned threading) for short test durations and low load. But I noticed something weird in the logs of my tests when I applied the full load.&lt;/p&gt;

&lt;p&gt;Timeouts, lots of them.&lt;/p&gt;

&lt;p&gt;The timeout in the originating MS was set at 60s. And Mockingbird was unable to send responses to a majority of the requests (&amp;gt;60%) in that time. &lt;/p&gt;

&lt;p&gt;And that was how I killed the MockingBird.&lt;/p&gt;

&lt;p&gt;Looking at the logs I started cursing at myself for not thinking the solution through. Redoing the whole thing would mean loss of time. And time is something we cannot afford at my current organization.&lt;/p&gt;

&lt;p&gt;So off I went to read the flask documentation(great resource btw) which mentioned that the inbuilt webserver was not ideal for production loads (which I had thrown at it). It might have worked if I didn't have the blocking sleep call but that was needed. So what else could work?&lt;/p&gt;

&lt;p&gt;I decided to take a look at some recommended servers. One I liked in particular was &lt;a href="https://gunicorn.org/" rel="noopener noreferrer"&gt;Gunicorn&lt;/a&gt;, with its support for different types of workers.&lt;/p&gt;

&lt;p&gt;A worker is to put it simply, a copy of your code that is run in parallel to other workers. Read the &lt;a href="http://docs.gunicorn.org/en/stable/design.html" rel="noopener noreferrer"&gt;design doc&lt;/a&gt; for more info.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install gunicorn&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;is how to install gunicorn on your system&lt;/p&gt;

&lt;p&gt;I also decided to use the gevent worker for gunicorn to handle multiple requests. This decision was made since we needed a AsyncIO worker to optimize for our forced IO wait times. For more information I suggest reading the documentation linked above.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install gevent&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;is how to install gevent.&lt;/p&gt;

&lt;p&gt;After doing these two things, it is a matter of just issuing the proper command (no code changes needed to existing files!) to start the application.&lt;/p&gt;

&lt;p&gt;All that is needed is one extra file in the root directory of your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from flaskapi import api

if __name__ == "__main__":
    api.run()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Name it whatever you want. I named it wsgi.py&lt;/p&gt;

&lt;p&gt;The command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gunicorn --worker-class gevent -w 4 flaskapi:api --bind 0.0.0.0:5000 --daemon&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;0.0.0.0 is important if you want intranet access to your API/server&lt;/li&gt;
&lt;li&gt;-w 4 means 4 workers : ideal value should be number of processors + 1&lt;/li&gt;
&lt;li&gt;--daemon means that processes will be spawned in the background&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkswed4nhgzgj9ky5jiht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkswed4nhgzgj9ky5jiht.png" alt="Command Line Screenshot" width="800" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This can be seen to start 5 processes on the server, one master and 4 workers each serving multiple requests per second. This worked sorta fine for the load we were throwing at it, but we had to eventually upgrade our puny server (CPU was hitting 100% at peak load) to land consistent results, even under prolonged peak load.&lt;/p&gt;

&lt;p&gt;And thus the MockingBird lives to sing another day.&lt;/p&gt;

&lt;p&gt;So this brings to an end the MockingBird series of posts. One hopes it has been informative!      &lt;/p&gt;

</description>
      <category>python</category>
      <category>coroutine</category>
      <category>gevent</category>
    </item>
    <item>
      <title>To make a MockingBird</title>
      <dc:creator>mikotian</dc:creator>
      <pubDate>Sat, 08 Feb 2020 11:11:22 +0000</pubDate>
      <link>https://dev.to/mikotian/to-make-a-mockingbird-1f8j</link>
      <guid>https://dev.to/mikotian/to-make-a-mockingbird-1f8j</guid>
      <description>&lt;p&gt;Prologue &lt;a href="https://dev.to/mikotian/to-birth-a-mockingbird-ep8"&gt;https://dev.to/mikotian/to-birth-a-mockingbird-ep8&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I began researching mocking tools and found one that seemed quick enough for my needs.&lt;/p&gt;

&lt;p&gt;Mockoon[&lt;a href="https://mockoon.com/" rel="noopener noreferrer"&gt;https://mockoon.com/&lt;/a&gt;] was a nice little gui based tool that I had heard of before and without giving it much thought, I started implementing my little mockingbird.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The good part about Mockoon:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;*Its fairly simple to start with. Anybody who has used Postman will find this to be intuitive and easy to understand.&lt;br&gt;
*You can have multiple apis running in parallel on your chosen ports&lt;br&gt;
the ability to define multiple responses based on what is the incoming payload&lt;br&gt;
*https support out of the box, if you need it&lt;br&gt;
*Very very good templating support (e.g. generating unique ids for fields)&lt;br&gt;
*Latency Simulation (this was the number 1 requirement I had)&lt;br&gt;
*latency simulation on a per endpoint basis as well (this is cumulative over base path latency)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The dealbreaker(s):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;*It is a localhost only application (so no intranet exposure, at least I wasn't able to get that to work)&lt;br&gt;
*No commandline or gui-less invocation, so would not work on no-desktop environments without major tinkering (one way could be x11 forwarding, perhaps)&lt;/p&gt;

&lt;p&gt;Some Screenshots from my experiment&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb2jqglvk9rub99kun0ia.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb2jqglvk9rub99kun0ia.png" alt="1" width="800" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnrvevcnyskvp57sp8jou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnrvevcnyskvp57sp8jou.png" alt="2" width="800" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I could simulate every API endpoint I wanted to mock and it worked flawlessly for me, except for the intranet part. Might be interesting for Devs who want to mock complex API behavior.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So I had to think of something else.&lt;/p&gt;

&lt;p&gt;Having worked on Python for a while, and had always wanted to write an API using it. I had researched a bit on flask back in the day but had never quite got around to using it. This was my chance.&lt;/p&gt;

&lt;p&gt;And it turned out to be quite easy.&lt;/p&gt;

&lt;p&gt;I used the standard python installation on an AWS installation to run the following code:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;It is pretty boilerplate stuff except for a few things:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;*In order to introduce some latency in the responses, I used time.sleep() before sending the response&lt;br&gt;
*Used the inbuilt support for json to manipulate json objects.&lt;br&gt;
*Used uuid to generate a couple of different types of guids (learnt about the library too along the way!)&lt;/p&gt;

&lt;p&gt;The instance I used to host this was a AWS t2.micro instance with 1 vCPU and 1 GB of RAM.&lt;/p&gt;

&lt;p&gt;It was exposed on the standard 5000 port that flask uses and I decided not to use https since that would have increased setup time on the many instances of the producing microservice.&lt;/p&gt;

&lt;p&gt;In order to expose it to the internal network, I used 0.0.0.0 as the address which means that the program will listen to all binded IPs for the machine.&lt;/p&gt;

&lt;p&gt;There is good support for debugging in flask as well and that requires us to set the debug flag while starting the service/application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flzmow50zcejgm2qihf4q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flzmow50zcejgm2qihf4q.png" alt="debug flag" width="400" height="50"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The command I used to start the application was a fairly straightforward one:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;python mockingbird.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The application worked wonderfully for our purposes. It was giving the correct responses with the desired latency and it looked like it was absorbing all the load as well. A couple of load tests went well with parameters showing to be on expected lines.&lt;/p&gt;

&lt;p&gt;But as it is in the world of Software Development (and especially in the world of Software Testing), the first version is never quite the finished project.&lt;/p&gt;

&lt;p&gt;In the next post, I'll recount/explain how i killed the mockingbird (and what I did to fix it)&lt;/p&gt;

</description>
      <category>mockoon</category>
      <category>python</category>
      <category>flask</category>
      <category>perftesting</category>
    </item>
    <item>
      <title>To need a MockingBird</title>
      <dc:creator>mikotian</dc:creator>
      <pubDate>Sat, 01 Feb 2020 12:09:35 +0000</pubDate>
      <link>https://dev.to/mikotian/to-birth-a-mockingbird-ep8</link>
      <guid>https://dev.to/mikotian/to-birth-a-mockingbird-ep8</guid>
      <description>&lt;p&gt;Weird title, but it'll get clear by the end of the post, I promise!&lt;/p&gt;

&lt;p&gt;Mocking is something that is associated with developers more than it is with testers, especially if one is dealing with Unit Tests.&lt;/p&gt;

&lt;p&gt;That is not to say that testers don't use it. Mocking is helpful when testers have API specifications but don't have the actual API itself and they have to develop API Automation (because Agile).&lt;/p&gt;

&lt;p&gt;In my current project, we are migrating over a legacy ticketing platform (standard .NET stuff &amp;amp; a lot of confused applications) to a new platform comprised of a SaaS based Incident Management system that is supported by multiple "new" microservices with every new age technology stuffed into the architecture somehow (I could fill up a couple of blog posts with snark aimed at the overall thinking in doing something like this, but I digress. Maybe later).&lt;/p&gt;

&lt;p&gt;So, the overall system when tested for performance (by yours truly) was doing extremely poor in terms of the lofty expectations set by people who were good at setting expectations :) &lt;/p&gt;

&lt;p&gt;So a few "war" rooms with much yelling and panicky reactions, the performance issue was narrowed down to some faulty API calls that were setting databases on fire in the third party ticketing system (imagine 30-40 second response times on good calls and 62 seconds about 70% of the times, where the expected value was sub-second). Perfectly legal, good API calls, mind you. This in turn dragged down the performance of our "victim" microservice to abysmal levels.  &lt;/p&gt;

&lt;p&gt;After much wringing of hands, late night builds &amp;amp; some more panicked conference calls, we ran performance tests that absolved the Third Party SaaS Incident Management System of any wrongdoing. This caused a lot of frayed tempers to be soothed and the hand-wringing moved down to just twitching of fingers. What it did though was give us pause to think. &lt;/p&gt;

&lt;p&gt;What was the actual throughput of our "victim" service? &lt;/p&gt;

&lt;p&gt;Now that we knew that the service's performance was tied to how the SaaS API performed, will we ever know its true performance given how flaky the API was turning out to be?&lt;/p&gt;

&lt;p&gt;We decided to setup a performance lab, abstract out the rest of the stuff and just keep the microservice, its common infra and have a mock do the work of the SaaS API.&lt;/p&gt;

&lt;p&gt;And that is how we gave birth to our MockingBird - thats what I call the mock API that I built.&lt;/p&gt;

&lt;p&gt;The next post will be about how exactly that was accomplished.&lt;/p&gt;

</description>
      <category>mock</category>
      <category>perftesting</category>
    </item>
  </channel>
</rss>
