Deep-dive into Mockintosh - an Open Source Microservice Mocking
Tags: testing, webperf, performance, tutorial
Published: 2021-03-15 14:43:32

<!-- wp:paragraph -->
<p>Recently I stumbled upon <a href="https://github.com/up9inc/mockintosh" target="_blank" rel="noreferrer noopener">Mockintosh</a> repo in GitHub from my <a href="https://www.linkedin.com/in/naveenkumarn/" target="_blank" rel="noreferrer noopener">LinkedIn</a> feed. Then I started exploring on my own, for couple days by going through the documentation and the code. This blog article will deep-dive into Mockintosh, how you can get started, how it will be useful from performance testing perspective and more.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-what-is-mock-service">What is Mock Service?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>From my experience, couple of times I used mock services during the performance testing the web applications. Assume that you are performance testing real estate listing website. In each listing, there will be contact details of the agent with their name, office address, contact number, email ID etc. Agent's office address will be displayed using the commercial map APIs (it could be Google or Bing). </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>When you run a load test against the agent's page, you are consuming the map credits. If you are running high volume load test, you will consume more billing from the map API provider. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Instead of making real map API calls, your development team can mock the map API. Whenever you load the page, it will display the dummy coordinates. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>By mocking the map API, you can do performance testing by saving the budget. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Another use case of mocking the service is, when you shift-left the testing, instead of waiting for the complete implementation, for the time being, you can mock the relevant services. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In microservice world, mocking the service there are gaps which are mentioned in this blog <a href="https://up9.com/open-source-microservice-mocking-introducing-mockintosh" target="_blank" rel="noreferrer noopener nofollow">article</a>. This artcile will focus on the implementation part. Let's get started.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-what-is-mockintosh">What is Mockintosh?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>From the GitHub repo</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Mockintosh aims to provide usual HTTP mock service functionality with small resource footprint, making it friendly for microservice applications. You can have tens of mocks at once, inside moderate laptop or single Docker container. Also, we have some additional ideas on how to make mocks simple and useful.</p></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p>The selling points of Mockintosh are small memory footprint, based on Python, YAML (or JSON) configuration and easy to get started. Also, you can mock a service within 30 seconds (including installation time).</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-prerequisites">Prerequisites </h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This demo uses Windows 10 Pro operating system. But the instructions are similar to other OS.</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>Python (latest version)</li><li>PIP (latest version)</li></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>I am using Python 3.9.2 and PIP 21.0.1 in my Windows. For the editor, I am using Pycharm Community Edition 2020.3.3. You can use your own favorite editor. I am not imposing.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-installation">Installation</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Installing Mockintosh is pretty straight forward. Create a new project n Pycharm or virtual environment, and issue the below command in the terminal.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>pip3 install mockintosh</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>To validate the installation of Mockintosh, issue the below command.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>mockintosh --help</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Above command will list out all the help commands.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If you want to leverage Docker, you can install the below command (assuming Docker is installed).</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>docker run -it -p 8000-8005:8000-8005 -v `pwd`:/tmp testrio/mockintosh /tmp/config.json</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>This will run Mockintosh in the inside the docker container using the default <code>config.json</code> file.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-hello-world">Hello World</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To run the Hello World mock, just issue the below command.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>mockintosh</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>This will launch the mock server at the default port 8001. Here is the output.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>(venv) C:\Users\..\PycharmProjects\MockintoshTest&gt;mockintosh
&#91;2021-03-12 20:07:38,886 root INFO] Mockintosh v0.7 is starting...
&#91;2021-03-12 20:07:38,890 root INFO] Configuration file is valid according to the JSON schema.
&#91;2021-03-12 20:07:38,899 root INFO] Serving at http://localhost:8001 the mock for 'Default Mock Service Config'
&#91;2021-03-12 20:07:38,899 root INFO] Mock server is ready!
</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Congratulations! You just mocked it :)</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Launch the localhost:8001 in your favorite browser, you could see the response 'hello world'.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>After you hit the URL, if you go back to the terminal, you can see the log info.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>&#91;2021-03-12 20:07:44,357 tornado.access INFO] 200 GET / (127.0.0.1) 7.00ms
&#91;2021-03-12 20:07:44,589 tornado.access WARNING] 404 GET /favicon.ico (127.0.0.1) 1.00ms
</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Yes, Mockintosh uses <a href="https://github.com/tornadoweb/tornado" target="_blank" rel="noreferrer noopener">Tornado</a> - a Python web framework.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If you would like to log detailed info, use the flag <code>--verbose</code>. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>To terminate the mock server, press Ctrl + C in the terminal. Now let us create our own mock service.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-creating-your-first-mock-service">Creating your first mock service</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Mock service can be created using YAML or JSON notation. I am going to use YAML notation in Pycharm. Create a new YAML file in PyCharm by right clicking on the project folder &gt; New &gt; File. Enter the name as <code>app.yaml</code> and hit enter.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Copy and paste the below YAML into your <code>app.yaml</code>.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>services:
- name: First Mock Service
  hostname: localhost
  port: 8001
  endpoints:
  - path: "/"
    method: GET</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>In the above YAML, we create a mock service named 'First Mock Service' in <code>localhost</code> at port <code>8001</code> where the endpoint is <code>/</code> for the HTTP method GET.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If you hit the localhost:8001 from the browser or some tool, you will get success HTTP status code.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Start the mockintosh in the terminal by issuing the below command.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>mockintosh app.yaml</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Here is the result of http://localhost:8001 in JMeter.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":8253,"sizeSlug":"large","linkDestination":"media"} -->
<div class="wp-block-image"><figure class="aligncenter size-large"><a href="https://qainsights.com/wp-content/uploads/2021/03/image-1.png"><img src="https://qainsights.com/wp-content/uploads/2021/03/image-1.png" alt="Deep-dive into Mockintosh - an Open Source Microservice Mocking" class="wp-image-8253"/></a><figcaption>Deep-dive into Mockintosh - an Open Source Microservice Mocking</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p><strong>Response header</strong></p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>HTTP/1.1 200 OK
Server: Mockintosh/0.7
Content-Type: text/html; charset=UTF-8
Date: Sat, 13 Mar 2021 01:22:02 GMT
Etag: "da39a3ee5e6b4b0d3255bfef95601890afd80709"
Content-Length: 0</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2 id="h-multiple-endpoints">Multiple Endpoints</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To create multiple endpoints, you just add it under the <code>endpoints</code> array as shown below. Below <code>Search Service</code> has two methods: GET and POST. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>GET will mock the home page and POST will pass the search string and return the mock response.</p>
<!-- /wp:paragraph -->

```
<pre class="wp-block-code"><code>services:
- name: Search Service
  hostname: localhost
  port: 8001
  endpoints:
  - path: "/"
    method: GET
  - path: "/search?q={{keyword}}"
    method: POST
    body:
      urlencoded:
        q: '{{keyword}}'
    response: 'You queried about {{keyword}}. Here are the results:'
```

<!-- wp:paragraph -->
<p>Here is the JMeter request/response snapshot.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":8254,"sizeSlug":"large","linkDestination":"media"} -->
<div class="wp-block-image"><figure class="aligncenter size-large"><a href="https://qainsights.com/wp-content/uploads/2021/03/image-2.png"><img src="https://qainsights.com/wp-content/uploads/2021/03/image-2.png" alt="" class="wp-image-8254"/></a><figcaption>GET and POST Mock Service</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:heading -->
<h2 id="h-multiple-services">Multiple Services</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Let us create multiple services in the same YAML. Just add the service under <code>services</code> array by creating new entry as shown below.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Below auth service will generate a random token for auth service. Dynamic string can be generated using <a href="https://handlebarsjs.com/guide/" target="_blank" rel="noreferrer noopener nofollow">Handlebars </a>which is a templated language.</p>
<!-- /wp:paragraph -->

```
<pre class="wp-block-code"><code>services:
- name: Search Service
  hostname: localhost
  port: 8001
  endpoints:
  - path: "/"
    method: GET
  - path: "/search?q={{keyword}}"
    method: POST
    body:
      urlencoded:
        q: '{{keyword}}'
    response: 'You queried about {{keyword}}. Here are the results:'

- name: Auth Service
  hostname: localhost
  port: 8002
  endpoints:
  - path: "/generateToken"
    method: GET
    response: 'Generated Token: {{random.uuid4}}'</code></pre>
```

<!-- wp:heading -->
<h2 id="h-what-s-in-it-for-performance-testers">What's in it for performance testers?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Above examples are more into functional mock services. Would Mockintosh help from performance engineers perspective? Yes. Mockintosh has a feature called Performance/Chaos Profile where you can set a rule(s) to simulate the delay (think time), fault injection, performance profile injection etc.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>To set a performance profile for a service, just add the below YAML which splits the response code 200 and 500 with 50% probability along with the delay of 0.1 seconds.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Performance profile declared at the top and referenced into each service. You can also set the profile globally using <code>globals</code> key.</p>
<!-- /wp:paragraph -->

```
performanceProfiles:
  loadprofile:
    ratio: 0.5
    delay: 0.1
    faults:
      '200': 0.5
      '500': 0.5

services:
- name: Search Service
  performanceProfile: loadprofile
  hostname: localhost
  port: 8001
  endpoints:
  - path: "/"
    method: GET
  - path: "/search?q={{keyword}}"
    method: POST
    body:
      urlencoded:
        q: '{{keyword}}'
    response: 'You queried about {{keyword}}. Here are the results:'

- name: Auth Service
  performanceProfile: loadprofile
  hostname: localhost
  port: 8002
  endpoints:
  - path: "/generateToken"
    method: GET
    response: 'Generated Token: {{random.uuid4}}'

```

<!-- wp:heading -->
<h2 id="h-remote-management">Remote Management</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Another interesting feature of Mockintosh is Remote Management which helps us to manage the mock server via REST interface (Swagger). To enable this feature, you have to add the <code>management</code> key in the yaml.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Below YAML opens another port 8000 for management.</p>
<!-- /wp:paragraph -->

```
management:
  port: 8000

performanceProfiles:
  loadprofile:
    ratio: 0.5
    delay: 0.1
    faults:
      '200': 0.5
      '500': 0.5

services:
- name: Search Service
  performanceProfile: loadprofile
  hostname: localhost
  port: 8001
  endpoints:
  - path: "/"
    method: GET
  - path: "/search?q={{keyword}}"
    method: POST
    body:
      urlencoded:
        q: '{{keyword}}'
    response: 'You queried about {{keyword}}. Here are the results:'

- name: Auth Service
  performanceProfile: loadprofile
  hostname: localhost
  port: 8002
  endpoints:
  - path: "/generateToken"
    method: GET
    response: 'Generated Token: {{random.uuid4}}'

```

<!-- wp:paragraph -->
<p>Here is the Mockintosh Management interface screenshot.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":8255,"sizeSlug":"large","linkDestination":"media"} -->
<figure class="wp-block-image size-large"><a href="https://qainsights.com/wp-content/uploads/2021/03/image-3.png"><img src="https://qainsights.com/wp-content/uploads/2021/03/image-3-1024x523.png" alt="Mockintosh Management" class="wp-image-8255"/></a><figcaption>Mockintosh Management</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Management app has four tabs: Query APIs, Statistics, Configuration and Unhandled Requests.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Query APIs</strong> tab helps you to smoke test the mock APIs and test automation.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Statistics </strong>tab displays the stats of mock APIs e.g. response time, status code distribution, services' details etc. You can refresh the stats and reset it.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":8256,"sizeSlug":"large","linkDestination":"media"} -->
<div class="wp-block-image"><figure class="aligncenter size-large"><a href="https://qainsights.com/wp-content/uploads/2021/03/image-4.png"><img src="https://qainsights.com/wp-content/uploads/2021/03/image-4.png" alt="" class="wp-image-8256"/></a><figcaption>Legacy UI</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Here is the latest UI of Statistics.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":8260,"sizeSlug":"large","linkDestination":"media"} -->
<div class="wp-block-image"><figure class="aligncenter size-large"><a href="https://qainsights.com/wp-content/uploads/2021/03/image-7.png"><img src="https://qainsights.com/wp-content/uploads/2021/03/image-7-1024x321.png" alt="Latest UI" class="wp-image-8260"/></a><figcaption>Latest UI</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p><strong>Configuration</strong> tab helps to get and set the config yaml. You can modify the config and apply the changes or you can read the config by clicking on <strong>Load </strong>button.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":8257,"sizeSlug":"large","linkDestination":"media"} -->
<div class="wp-block-image"><figure class="aligncenter size-large"><a href="https://qainsights.com/wp-content/uploads/2021/03/image-5.png"><img src="https://qainsights.com/wp-content/uploads/2021/03/image-5.png" alt="Configuration tab" class="wp-image-8257"/></a><figcaption>Configuration tab</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p><strong>Unhandled Requests</strong> tab displays the requests which are not handled by the mock server. E.g. if you hit http://localhost:8001/not-exists, (this path doesn't exist in our yaml) it will get recorded and displayed it in <strong>Unhandled Requests</strong>.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":8258,"sizeSlug":"large","linkDestination":"media"} -->
<div class="wp-block-image"><figure class="aligncenter size-large"><a href="https://qainsights.com/wp-content/uploads/2021/03/image-6.png"><img src="https://qainsights.com/wp-content/uploads/2021/03/image-6.png" alt="Unhandled Requests" class="wp-image-8258"/></a><figcaption><strong>Unhandled Requests</strong></figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:heading -->
<h2 id="h-traffic-log">Traffic Log</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Traffic Log enables to record all the requests which hits the mock server. To enable traffic log, go to Trafic Log tab (available in the latest version) and check <strong>Enable Traffic Log.</strong></p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":8261,"sizeSlug":"large","linkDestination":"media"} -->
<figure class="wp-block-image size-large"><a href="https://qainsights.com/wp-content/uploads/2021/03/image-8.png"><img src="https://qainsights.com/wp-content/uploads/2021/03/image-8-1024x456.png" alt="Traffic Log" class="wp-image-8261"/></a><figcaption>Traffic Log</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>To delete the log, uncheck Enable Traffic Log checkbox which will not record the traffic.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-request-matching">Request Matching</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Apart from the above features, Mockintosh comes with Request Matching where you can embed the regular expressions in the requests.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Below regex will look out for 6 digits in the requests and display it in the response.</p>
<!-- /wp:paragraph -->

```
  - path: "/getorder/{{regEx '(&#91;0-9]{6})' 'ordernumber'}}"
    response: 'Here is your order details for : {{ordernumber}}'
```

<!-- wp:image {"align":"center","id":8263,"sizeSlug":"large","linkDestination":"media"} -->
<div class="wp-block-image"><figure class="aligncenter size-large"><a href="https://qainsights.com/wp-content/uploads/2021/03/image-10.png"><img src="https://qainsights.com/wp-content/uploads/2021/03/image-10.png" alt="Request Matching" class="wp-image-8263"/></a><figcaption>Request Matching</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:heading -->
<h2 id="h-response-templating">Response Templating</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>You can mock the response headers, status, body etc using dynamic values using Handlerbars and Jinja2. You can leverage faker library to mock the data.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>- name: Customer Service
  hostname: localhost
  port: 8003
  endpoints:
  - path: "/customer"
    response:
      headers:
        Content-Type: "application/json; charset=UTF-8"
      body: "@response/customerdetails.json.hbs"</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Above yaml, will generate fake data in the response using the <strong>customerdetails.json.hbs</strong> file.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>{
    "useragent": " Mozilla\/5.0 (X11; Linux i686; rv:1.9.5.20) Gecko\/2015-11-08 00:26:50 Firefox\/8.0",
    "creditcard": "Diners Club \/ Carte Blanche\nKatherine Graves\n30301229452350 06\/24\nCVC: 336\n",
    "ssn": "031-26-2812"
}</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>JSON Template</p>
<!-- /wp:paragraph -->

```
{
  "creditcard": "{{ fake.credit_card_full }}",
  "ssn": "{{ fake.ssn }}",
  "useragent": " {{ fake.user_agent }}"
}
```

<!-- wp:heading -->
<h2 id="h-conclusion">Conclusion</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Whatever features we have seen till now is just a little drop of Mockintosh capabilities. If you are looking for advanced usage, how it works, sample yaml config etc, I suggest you to check the <a href="https://github.com/up9inc/mockintosh" target="_blank" rel="noreferrer noopener">GitHub repo</a>. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>All the above examples which I used is available in <a href="https://github.com/QAInsights/Mockintosh-Samples" target="_blank" rel="noreferrer noopener">here</a>. </p>
<!-- /wp:paragraph -->