<?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: Dan Gross</title>
    <description>The latest articles on DEV Community by Dan Gross (@dangross).</description>
    <link>https://dev.to/dangross</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%2F915389%2F453b0282-f954-4fbf-86ca-2d3fd56f4e8b.jpg</url>
      <title>DEV Community: Dan Gross</title>
      <link>https://dev.to/dangross</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dangross"/>
    <language>en</language>
    <item>
      <title>Dive into Mocking Your Microservice Dependencies with Skyramp</title>
      <dc:creator>Dan Gross</dc:creator>
      <pubDate>Thu, 14 Dec 2023 15:34:30 +0000</pubDate>
      <link>https://dev.to/dangross/dive-into-mocking-your-microservice-dependencies-with-skyramp-51bj</link>
      <guid>https://dev.to/dangross/dive-into-mocking-your-microservice-dependencies-with-skyramp-51bj</guid>
      <description>&lt;p&gt;Welcome back, fellow developers! In today's blog post, we're diving into the world of microservices and discussing a crucial aspect of their development and testing: mocking dependencies. Distributed applications built on microservices offer unparalleled flexibility and scalability, but they also bring challenges when it comes to managing dependencies during development and testing. &lt;/p&gt;

&lt;p&gt;Fear not! &lt;a href="https://www.skyramp.dev" rel="noopener noreferrer"&gt;Skyramp&lt;/a&gt; provides effective ways to mock your microservice dependencies, making your development process smoother and more efficient. This blog post will cover the necessary inputs and many choices you have at your disposal for mocking dependencies with Skyramp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mocking for the Uninitiated
&lt;/h2&gt;

&lt;p&gt;Mocking is a technique used in software development to simulate the behavior of certain components, usually external dependencies, during the testing phase. The purpose of mocking is to isolate the unit of code being tested and control the inputs and outputs of external dependencies. Instead of using the actual implementations of these dependencies, developers create "mock" objects or functions that mimic the expected behavior without executing the real logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Do Developers Mock Services?
&lt;/h3&gt;

&lt;p&gt;In a microservices architecture, where a system is composed of multiple independently deployable services, mocking becomes particularly important for several reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Isolation&lt;/strong&gt;: Microservices often rely on external services, databases, or APIs. When developers are testing a specific microservice, they want to isolate it from these external dependencies. Mocking allows them to simulate the behavior of these dependencies, focusing solely on the code under test.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consistency&lt;/strong&gt;: Given that microservices have dependencies on other microservices or third-party APIs, mocking enables developers to test each microservice without relying on the availability or consistency of external services. This is crucial for maintaining a fast and reliable testing pipeline.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Controlled Testing Environment&lt;/strong&gt;: Mocking provides control over the responses from external services, allowing developers to test different scenarios, error conditions, or edge cases that might be challenging to reproduce with real services. This helps uncover potential issues and improve the overall robustness of the microservices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Parallel Development&lt;/strong&gt;: In a microservices environment, different teams might be working on different services simultaneously. Mocking enables parallel development by allowing teams to develop and test their microservices independently, even if other services they depend on are still under development.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cost and Resource Efficiency&lt;/strong&gt;: Connecting to real services, especially external services, during every test can be resource-intensive and slow down the development and testing process. Mocking eliminates the need to make actual requests, improving the efficiency of the testing cycle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fault Injection&lt;/strong&gt;: Mocking allows developers to simulate error conditions or faults in external services, helping them assess how well their microservices handle failures or unexpected behaviors in the dependencies. This is crucial for building resilient microservices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Early Testing&lt;/strong&gt;: Mocking facilitates testing early in the development process when certain dependencies might not be fully implemented or available. It allows developers to start testing components even before all external services are ready for integration.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mocking microservice dependencies is a key practice in  developing distributed applications to ensure efficient and effective testing, isolate units of code, and streamline the development workflow in a distributed and complex architecture. Let's take a look at all the ways you can mock dependencies for your microservices with Skyramp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mocking with Skyramp
&lt;/h2&gt;

&lt;p&gt;Mocking dependencies with Skyramp all starts with Skyramp's &lt;a href="https://skyramp.dev/docs/docker/mocker/" rel="noopener noreferrer"&gt;Mocker&lt;/a&gt;. Mocker is a solution for creating mock API services which run in-cluster for either &lt;a href="https://https://kubernetes.io/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt; or &lt;a href="https://docs.docker.com/compose/" rel="noopener noreferrer"&gt;Docker Compose&lt;/a&gt;. In the &lt;a href="https://skyramp.dev/docs/docker/reference/architecture/" rel="noopener noreferrer"&gt;architecture diagram&lt;/a&gt; below, you can see how &lt;a href="https://www.skyramp.dev/docs/docker/mocker/mock-description/" rel="noopener noreferrer"&gt;mock descriptions&lt;/a&gt; can be applied to the Skyramp Worker to run the mocks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fgmg31xc5ijpcazjo83sn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fgmg31xc5ijpcazjo83sn.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Skyramp Clients
&lt;/h3&gt;

&lt;p&gt;Skyramp offers multiple interfaces for mocking dependencies depending on your preference or workflow. Your options include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;a href="https://skyramp.dev/docs/docker/reference/cli-commands/skyramp/" rel="noopener noreferrer"&gt;command-line interface&lt;/a&gt; (CLI) for using Skyramp in a terminal.&lt;/li&gt;
&lt;li&gt;The Visual Studio Code &lt;a href="https://marketplace.visualstudio.com/items?itemName=skyramp.mocker-vscode" rel="noopener noreferrer"&gt;extension&lt;/a&gt; for using Skyramp in VSCode.&lt;/li&gt;
&lt;li&gt;The Skyramp libraries for &lt;a href="https://pypi.org/project/skyramp/" rel="noopener noreferrer"&gt;Python&lt;/a&gt; or &lt;a href="https://www.npmjs.com/package/@skyramp/skyramp" rel="noopener noreferrer"&gt;JavaScript&lt;/a&gt; for making Skyramp calls from your own code.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Supported Environments
&lt;/h3&gt;

&lt;p&gt;To get started with mocking dependencies with Skyramp, your microservice must be running in one of these environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Docker Compose&lt;/strong&gt;: Docker Compose is used for defining and running multi-container Docker applications. You can configure your application's services in YAML and then start the services with a simple command.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Kubernetes&lt;/strong&gt;: Orchestrating and managing containerized distributed applications becomes more manageable with Kubernetes, providing scalability and resilience to your microservices.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Service Protocols
&lt;/h3&gt;

&lt;p&gt;Skyramp supports a number protocols for mocks to accommodate different microservices architectures. Some of the key protocols include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;gRPC&lt;/strong&gt;: If your microservices communicate using the gRPC protocol, Skyramp provides comprehensive mocking capabilities, ensuring a smooth testing experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;: For microservices adhering to a RESTful architecture, Skyramp supports robust mocking to facilitate thorough testing and development.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;JSON-RPC WebSocket&lt;/strong&gt;: Skyramp extends its support to JSON-RPC over WebSocket, enabling developers to mock dependencies in real-time communication scenarios.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;JSON-RPC HTTP&lt;/strong&gt;: When your microservices utilize JSON-RPC over HTTP for communication, Skyramp is equipped to support mocks for this protocol, offering flexibility in testing various scenarios.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Choices for Mocking
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Generate a mock from an API definition&lt;/strong&gt;&lt;br&gt;
Skyramp simplifies the process of mocking by allowing you to generate mocks directly from your API definitions, such as &lt;a href="https://www.openapis.org/" rel="noopener noreferrer"&gt;OpenAPI&lt;/a&gt; or &lt;a href="https://protobuf.dev/" rel="noopener noreferrer"&gt;Protobuf&lt;/a&gt;. This means you can easily create realistic mocks that mimic the behavior of your actual microservices. With the Skyramp CLI, it's as easy as running &lt;code&gt;skyramp mocker generate ...&lt;/code&gt; with the relevant inputs. See the &lt;a href="https://skyramp.dev/docs/docker/mocker/how-to-mock-services/#generate-a-mock-from-user-input" rel="noopener noreferrer"&gt;Skyramp Docs&lt;/a&gt; for which flags to use based on your protocol. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create a mock from scratch&lt;/strong&gt;&lt;br&gt;
For more control over your mocks, Skyramp enables you to create mocks from scratch. This is useful when you need to tailor your mocks to specific scenarios or edge cases that may not be fully covered by the API definitions.  With the Skyramp CLI, it's as easy as running &lt;code&gt;skyramp init mock ...&lt;/code&gt; and providing a protocol. See the &lt;a href="https://skyramp.dev/docs/docker/mocker/how-to-mock-services/#write-a-mock-from-scratch" rel="noopener noreferrer"&gt;Skyramp Docs&lt;/a&gt; for the specific sub-commands.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configure mocks with data&lt;/strong&gt;&lt;br&gt;
Mocking isn't just about mimicking endpoints, it's also about replicating real-world scenarios. With Skyramp, you can configure your mocks with realistic data, ensuring that your microservices are tested thoroughly under various conditions. See the &lt;a href="https://www.skyramp.dev/docs/kubernetes/mocker/how-to-mock-services/#response-configuration" rel="noopener noreferrer"&gt;Skyramp Docs&lt;/a&gt; on how to configure responses for your mocks.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What's in a Mock?
&lt;/h3&gt;

&lt;p&gt;At a fundamental level, a Skyramp mock consists of an &lt;a href="https://skyramp.dev/docs/docker/mocker/how-to-mock-services/#endpoint-configuration" rel="noopener noreferrer"&gt;endpoint&lt;/a&gt;, a &lt;a href="https://skyramp.dev/docs/docker/mocker/how-to-mock-services/#response-configuration" rel="noopener noreferrer"&gt;response&lt;/a&gt;, and a &lt;a href="https://skyramp.dev/docs/docker/mocker/how-to-mock-services/#mock-configuration" rel="noopener noreferrer"&gt;mock&lt;/a&gt; configuration. Below is a sample mock description file as an example. You can read more details about Skyramp &lt;a href="https://www.skyramp.dev/docs/docker/mocker/mock-description/" rel="noopener noreferrer"&gt;mock descriptions&lt;/a&gt; in the Skyramp Docs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;mock&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;routeguide&lt;/span&gt;
    &lt;span class="na"&gt;responses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;responseName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ListFeatures&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;responseName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;RecordRoute&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;responseName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;RouteChat&lt;/span&gt;
          &lt;span class="na"&gt;lossPercentage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;
          &lt;span class="na"&gt;delayConfig&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;minDelay&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;
              &lt;span class="na"&gt;maxDelay&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2000&lt;/span&gt;
    &lt;span class="na"&gt;proxies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;endpointName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;routeguide-svc-RouteGuide&lt;/span&gt;
          &lt;span class="na"&gt;methodName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GetFeature&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Getting our Feet Wet: A Simple Example
&lt;/h2&gt;

&lt;p&gt;Let's walk through a simple example to illustrate how easy it is to mock microservice dependencies with Skyramp. We will use a sandbox environment that already has Docker and the Skyramp CLI installed, so there is nothing you need to install locally. You may recognize elements of this example from &lt;a href="https://dev.to/dangross/jump-into-microservices-testing-with-docker-compose-and-skyramp-18o6"&gt;previous blog posts&lt;/a&gt;. Start by launching the sandbox environment in GitHub Codespaces:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codespaces.new/letsramp/sample-microservices/tree/docker-compose-demo?machine=standardLinux32gb" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/codespaces/badge.svg" alt="Open in GitHub Codespaces"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, we have microservices that communicate via REST, and we want to mock one of the dependent microservices for testing purposes. This particular distributed application is an e-commerce store and we want to mock the payment service for the checkout flow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fc38n01kj2eoub8fnnfhc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fc38n01kj2eoub8fnnfhc.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the Codespace launches, you will see a VSCode window in your browser as shown above. The repo source files are pre-loaded and a terminal pane is available. Let's start by changing directories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;skyramp/docker-compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's bring up the containers, which include the Skyramp Worker container and the application containers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that the application services are running, let's take a look at the mock we generated previously for our payment service. It is called &lt;code&gt;payment-service-k8s.yaml&lt;/code&gt; under the &lt;code&gt;mocks&lt;/code&gt; folder, which you can navigate to and open in VSCode. Notice the configuration parameters of the mock, including &lt;code&gt;services&lt;/code&gt;, &lt;code&gt;endpoints&lt;/code&gt;, and &lt;code&gt;responseValues&lt;/code&gt; as discussed earlier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkhoam23o5vbze3kh2wd0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fkhoam23o5vbze3kh2wd0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's apply the mock to the Skyramp Worker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp mocker apply payment-service-k8s &lt;span class="nt"&gt;--address&lt;/span&gt; localhost:35142
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we can verify the mock is running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp mocker status &lt;span class="nt"&gt;--address&lt;/span&gt; localhost:35142
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see output like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Applied mocks at the address &lt;span class="s1"&gt;'localhost:35142'&lt;/span&gt;: 
+----+-----------------+-----------------+----------+-------------+
| ID | ADDRESS         | SERVICE         | ENDPOINT | METHOD      |
+----+-----------------+-----------------+----------+-------------+
| 1  | localhost:35142 | payment-service | charge   | charge-POST |
+----+-----------------+-----------------+----------+-------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we can run a test against the mock with a checkout test that has been pre-defined:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp tester start checkout-test &lt;span class="nt"&gt;--address&lt;/span&gt; localhost:35142
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see that the test scenario passes because the mock payment service is in place and the dependency for the checkout functions as expected. If you want to see the test fail by not having the mock in place, you can delete the running mocks and try the test again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp mocker delete &lt;span class="nt"&gt;-a&lt;/span&gt; localhost:35142  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You are free to experiment with this scenario to introduce new configurations and then adapt them to your own environment.&lt;/p&gt;

&lt;p&gt;This simple example demonstrates how quickly you can set up a mock for your microservice dependencies using Skyramp. For more information, including advanced features of Mocker like &lt;a href="https://skyramp.dev/docs/docker/mocker/mock-description/#grpc-proxying" rel="noopener noreferrer"&gt;gRPC Proxying&lt;/a&gt; and &lt;a href="https://skyramp.dev/docs/docker/mocker/mock-description/#dynamic-responses" rel="noopener noreferrer"&gt;Dynamic Responses&lt;/a&gt;, be sure to visit the &lt;a href="https://skyramp.dev/docs/docker/mocker/" rel="noopener noreferrer"&gt;Skyramp Docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Swim
&lt;/h2&gt;

&lt;p&gt;In conclusion, Skyramp provides a robust solution for mocking microservice dependencies, offering flexibility, ease of use, and support for various environments and protocols. Whether you are generating mocks from API definitions or creating them from scratch, Skyramp empowers you to streamline your development and testing processes. &lt;/p&gt;

&lt;p&gt;We encourage you to please join the &lt;a href="https://discord.gg/qBnEZM6JTb" rel="noopener noreferrer"&gt;Skyramp Community Discord&lt;/a&gt; for any questions, comments, or feedback. &lt;/p&gt;

&lt;p&gt;Happy mocking!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>microservices</category>
      <category>api</category>
      <category>devops</category>
    </item>
    <item>
      <title>Jump into Microservices Testing with Docker Compose and Skyramp</title>
      <dc:creator>Dan Gross</dc:creator>
      <pubDate>Thu, 30 Nov 2023 17:21:29 +0000</pubDate>
      <link>https://dev.to/dangross/jump-into-microservices-testing-with-docker-compose-and-skyramp-18o6</link>
      <guid>https://dev.to/dangross/jump-into-microservices-testing-with-docker-compose-and-skyramp-18o6</guid>
      <description>&lt;p&gt;Distributed applications leveraging microservices have become a predominant approach for building scalable and maintainable software systems. As developers embrace the microservices paradigm, the need for effective testing solutions becomes increasingly vital. &lt;a href="https://skyramp.dev" rel="noopener noreferrer"&gt;Skyramp&lt;/a&gt;, a powerful testing tool designed specifically for distributed systems, offers a robust solution to automate the testing of applications built on microservices. &lt;/p&gt;

&lt;p&gt;My &lt;a href="https://dev.to/search?q=skyramp%20kubernetes%20dan%20gross"&gt;previous blog posts&lt;/a&gt; have focused on the array of options Skyramp provides for testing distributed applications deployed to Kubernetes clusters. However, Kubernetes is not required to reap the benefits of using Skyramp for test automation. You can also setup and deploy your system-under-test using &lt;a href="https://docs.docker.com/compose/" rel="noopener noreferrer"&gt;Docker Compose&lt;/a&gt;. In this article, we'll explore how you can leverage Skyramp in conjunction with Docker Compose to streamline your microservices testing process.&lt;/p&gt;

&lt;p&gt;For a quick overview on all the points this article will cover, you can check out this short video, "Skyramp &amp;amp; GitHub Codespaces with Docker," as a reference:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  A Fly-By of Skyramp and Docker Compose
&lt;/h2&gt;

&lt;p&gt;Before diving into the details, let's briefly introduce Skyramp and Docker Compose.&lt;/p&gt;

&lt;h3&gt;
  
  
  Skyramp: A Testing Powerhouse for Microservices
&lt;/h3&gt;

&lt;p&gt;Skyramp is a testing tool specifically tailored for distributed systems built on microservices architecture. It provides a comprehensive set of features for automating the testing of various components within a microservices ecosystem. This includes: test generation, functional integration and performance testing, mocking services, hot code reload, and an integrated dashboard. While previous posts have centered around Kubernetes integration, it's important to note that Skyramp is versatile and can be employed with Docker Compose in place of Kubernetes.&lt;/p&gt;

&lt;p&gt;Below is an &lt;a href="https://skyramp.dev/docs/docker/reference/architecture/" rel="noopener noreferrer"&gt;architecture diagram&lt;/a&gt; showing where the Skyramp components fit in a Docker Compose setup for conducting automated testing:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fg16ypcopvp39b6fhw69u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fg16ypcopvp39b6fhw69u.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker Compose: Simplifying Orchestration
&lt;/h3&gt;

&lt;p&gt;Docker Compose is a tool for defining and running multi-container Docker applications. It allows developers to define a multi-container environment in a single file, making it easy to set up and manage complex microservices architectures. Docker Compose is an excellent choice for local development and testing, providing a lightweight alternative to full-scale orchestration solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting the Stage
&lt;/h2&gt;

&lt;p&gt;To set some context before jumping into the walkthrough, let's first look at a few key concepts:&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Repo from Skyramp
&lt;/h3&gt;

&lt;p&gt;Skyramp provides a sample project, &lt;a href="https://github.com/letsramp/sample-microservices/tree/docker-compose-demo" rel="noopener noreferrer"&gt;sample-microservices&lt;/a&gt;, which serves as an excellent starting point for demonstrating testing and mocking with a full-featured distributed application. The application is based on Google's &lt;a href="https://github.com/GoogleCloudPlatform/microservices-demo" rel="noopener noreferrer"&gt;Online Boutique&lt;/a&gt; repo, which is an e-commerce store consisting of 11 different microservices.  The &lt;code&gt;docker-compose-demo&lt;/code&gt; branch referenced above showcases how Skyramp can be seamlessly integrated with Docker Compose for testing microservices with no local setup required. You can also clone the repository and explore the structure of the microservices setup for your own purposes. &lt;/p&gt;

&lt;h3&gt;
  
  
  Mocks for Simulating Dependencies
&lt;/h3&gt;

&lt;p&gt;One powerful aspect of Skyramp is its ability to handle dependencies and external services through &lt;a href="https://skyramp.dev/docs/docker/mocker/how-to-mock-services/" rel="noopener noreferrer"&gt;mocks&lt;/a&gt;. Define mocked services with a &lt;a href="https://skyramp.dev/docs/docker/mocker/mock-description/" rel="noopener noreferrer"&gt;mock description&lt;/a&gt; for Skyramp's Mocker to simulate the behavior of external dependencies. This allows you to isolate and test individual microservices in a controlled environment. &lt;/p&gt;

&lt;h3&gt;
  
  
  Dashboard for Test Results
&lt;/h3&gt;

&lt;p&gt;Skyramp includes a &lt;a href="https://skyramp.dev/docs/docker/reference/dashboard/" rel="noopener noreferrer"&gt;dashboard&lt;/a&gt; for organization and analysis of your test results. Integrate the Skyramp dashboard into your testing setup to gain insights into tests, performance metrics, and potential issues. The dashboard enhances visibility, making it easier to identify and address issues in your microservices deployment. To spin up the dashboard for Docker locally with the &lt;a href="https://skyramp.dev/docs/docker/reference/cli-commands/dashboard/up/" rel="noopener noreferrer"&gt;CLI&lt;/a&gt;, simply run &lt;code&gt;skyramp dashboard up --docker&lt;/code&gt; from your terminal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker-Specific Docs
&lt;/h3&gt;

&lt;p&gt;Because Docker Compose is markedly different than Kubernetes in terms of setup and certain behaviors, the Skyramp docs have been tailored to provide &lt;a href="https://skyramp.dev/docs/docker/" rel="noopener noreferrer"&gt;Docker-specific&lt;/a&gt; instructions. There you can discover the many ways Skyramp can help you with your testing strategy for Docker Compose deployments.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Simple Walkthrough
&lt;/h2&gt;

&lt;p&gt;As mentioned above, we will use the Online Boutique distributed application for our example system-under-test. We can easily create a running test environment using &lt;a href="https://docs.github.com/en/codespaces" rel="noopener noreferrer"&gt;GitHub Codespaces&lt;/a&gt;. To launch your own environment so that you may follow along, simply click the link below and then click "Create codespace."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codespaces.new/letsramp/sample-microservices/tree/docker-compose-demo?machine=standardLinux32gb" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/codespaces/badge.svg" alt="Open in GitHub Codespaces"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bringing Up Services
&lt;/h3&gt;

&lt;p&gt;Once the Codespace launches, you will see a VSCode window in your browser. The repo source files are pre-loaded and a terminal pane is available. In the root folder of the repo, you will see a shell script called &lt;code&gt;workflow-1.sh&lt;/code&gt;. Executing this script will bring up the system-under-test using a pre-configured &lt;code&gt;docker-compose.yml&lt;/code&gt; file under the &lt;code&gt;skyramp/docker-compose&lt;/code&gt; folder. Go ahead and give it a spin from the command line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh workflow-1.sh &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point you should see a screen similar to this one, which shows the output from the running docker containers:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ff0rsidopfhblv99xn7fg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ff0rsidopfhblv99xn7fg.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The system-under-test deployment is comprised of the services we need to conduct a test of the checkout process, namely the product catalog, cart, payment, and checkout services.&lt;/p&gt;

&lt;p&gt;Our pre-defined test scenario in this case will aim to test the checkout flow. First, change directories in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;skyramp/docker-compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's go ahead and run our test. The test itself is defined under &lt;code&gt;tests&lt;/code&gt; as &lt;code&gt;checkout-test.yml&lt;/code&gt;, which you can review in the VSCode window from the codespace or by navigating &lt;a href="https://github.com/letsramp/sample-microservices/blob/docker-compose-demo/skyramp/docker-compose/tests/checkout-test.yaml" rel="noopener noreferrer"&gt;here&lt;/a&gt;. To run, execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp tester start checkout-test &lt;span class="nt"&gt;--address&lt;/span&gt; localhost:35142
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uh-oh, it looks like the test failed because the checkout process could not connect to the payment service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F92g32tnscsjjdcxu9u14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F92g32tnscsjjdcxu9u14.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Truth be told, we did that on purpose. This allows us to demonstrate how we can bring up a mock of the payment service using &lt;a href="https://www.skyramp.dev/docs/docker/mocker/" rel="noopener noreferrer"&gt;Skyramp Mocker&lt;/a&gt;. Simply run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp mocker apply &lt;span class="nt"&gt;--address&lt;/span&gt; localhost:35142
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mock is defined under &lt;code&gt;mocks&lt;/code&gt; as &lt;code&gt;payment-service-k8s.yaml&lt;/code&gt;, which you can review in the VSCode window from the codespace or by navigating &lt;a href="https://github.com/letsramp/sample-microservices/blob/docker-compose-demo/skyramp/docker-compose/mocks/payment-service-k8s.yaml" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With the payment service mock in place, let's re-run our checkout test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp tester start checkout-test &lt;span class="nt"&gt;--address&lt;/span&gt; localhost:35142
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we see the test scenario passes, so we have successfully tested our checkout components in concert to validate that the microservices are behaving as expected in the flow. Great work, give yourself a pat on the back.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F42u6cexjrv1chjbqu9sq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F42u6cexjrv1chjbqu9sq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Incorporating Skyramp with Docker Compose offers a seamless and efficient approach to testing microservices locally. By leveraging Docker Compose's simplicity for setting up multi-container environments and Skyramp's comprehensive testing capabilities, developers can ensure the reliability and performance of their microservices architectures. Whether you're new to microservices testing or looking to enhance your existing workflows, the combination of Skyramp and Docker Compose provides a powerful solution for robust and automated testing. As always, happy testing. &lt;/p&gt;

&lt;p&gt;Finally, please &lt;a href="https://discord.gg/qBnEZM6JTb" rel="noopener noreferrer"&gt;join our Discord&lt;/a&gt; for any questions, comments, or feedback. &lt;/p&gt;

</description>
      <category>microservices</category>
      <category>docker</category>
      <category>github</category>
      <category>testing</category>
    </item>
    <item>
      <title>Observe This: One Step from Trace to Test with Skyramp</title>
      <dc:creator>Dan Gross</dc:creator>
      <pubDate>Thu, 16 Nov 2023 14:44:34 +0000</pubDate>
      <link>https://dev.to/dangross/observability-traces-to-tests-in-one-step-with-skyramp-mnp</link>
      <guid>https://dev.to/dangross/observability-traces-to-tests-in-one-step-with-skyramp-mnp</guid>
      <description>&lt;p&gt;&lt;a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/"&gt;KubeCon North America 2023&lt;/a&gt; in Chicago last week was a barrage of technology and innovation all aimed at running distributed applications at scale with &lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt;. In particular, the &lt;strong&gt;observability&lt;/strong&gt; topic featured prominently in technical sessions, vendor booths, and in hallway conversations. &lt;/p&gt;

&lt;p&gt;Observability plays a key role in gaining insights about a system's behavior in order to ensure the reliability and performance of deployed applications. Because of the complex nature of distributed applications leveraging microservices, an important aspect of observability is tracing. In this blog, we'll explore how you can harness observability tracing to create effective test scenarios easily with &lt;a href="https://www.skyramp.dev"&gt;Skyramp&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Anatomy of Tracing
&lt;/h2&gt;

&lt;p&gt;Observability tracing involves capturing and analyzing the flow of requests as they traverse through the different components of a distributed system. Tools like &lt;a href="https://www.jaegertracing.io/"&gt;Jaeger&lt;/a&gt;, &lt;a href="https://opentelemetry.io/"&gt;OpenTelemetry&lt;/a&gt;, and &lt;a href="https://px.dev/"&gt;Pixie&lt;/a&gt; can be used in Kubernetes environments to trace the execution of requests across microservices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two Key Components of Tracing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Spans&lt;/strong&gt;: Spans represent individual units of work or operations within a distributed system. Spans will include metadata such as the operation name, start and end timestamps, and contextual information like tags and logs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Traces&lt;/strong&gt;: Traces consist of a collection of spans, forming a sequence that traces the journey of a request. Often, spans are collected and assembled into traces based on their shared trace ID. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Traces Versus Logs
&lt;/h3&gt;

&lt;p&gt;Traditional logging is still valuable from an observability standpoint. Logs offer detailed information about individual events within an application based on time, aiding in debugging and troubleshooting. However, if you've combed through the logs produced from a distributed application, you know it can be difficult to gain end-to-end visibility of a request. Observability tracing focuses on providing a higher-level view of the flow of requests through a distributed system, aiding in performance analysis and system optimization. Think of traces like enhanced logs. Both can and should be used in tandem for your observability strategy in Kubernetes.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Sample Trace
&lt;/h3&gt;

&lt;p&gt;Below is an short excerpt from a sample trace file, which can be found &lt;a href="https://github.com/letsramp/sample-microservices/blob/main/skyramp/rest-demo/trace/trace.json"&gt;here&lt;/a&gt; in Skyramp's public repo, &lt;code&gt;sample-microservices&lt;/code&gt;.&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="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;"Source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"px-operator/93bc2253481b44a32e04a523286b130a01e7a6e2168db1be5c02993f1978q75"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product-catalog-service"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"RequestBody"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ResponseBody"&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;"categories"&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;"accessories"&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;"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;"Add a modern touch to your outfits with these sleek aviator sunglasses."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"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;"OLJCESPC7Z"&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;"Sunglasses"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"picture"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/static/img/products/sunglasses.jpg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"priceUsd"&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;"currencyCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nanos"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;990000000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"units"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;19&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;"Headers"&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;"Accept-Encoding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gzip"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product-catalog-service:60000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"User-Agent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Go-http-client/1.1"&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="s2"&gt;"GET"&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;"/get-product?product_id=OLJCESPC7Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Status"&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;"ResponseMsg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"Port"&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="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The excerpt above represents one request in a series of requests in the &lt;code&gt;trace.json&lt;/code&gt; file. You can see quite a bit of extended information in the form of metadata about this request operation as made available from a span.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating Tests from Traces
&lt;/h2&gt;

&lt;p&gt;Observability traces can give us valuable insights into the behavior of our distributed applications for troubleshooting and optimization. So, can we also use traces for generating test scenarios? With Skyramp, you can! Creating tests based on observability traces provides several advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Realistic Scenarios&lt;/strong&gt;: Traces capture real interactions between microservices, allowing you to recreate realistic scenarios for testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance Analysis&lt;/strong&gt;: Identify performance bottlenecks and latency issues by analyzing trace data during test executions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Error Detection&lt;/strong&gt;: Leverage traces to detect errors and exceptions, facilitating the creation of robust test cases to handle various failure scenarios.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Regression Testing&lt;/strong&gt;: Use trace data to establish a baseline for application behavior, enabling effective regression testing as your application evolves.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Early Detection&lt;/strong&gt;: Catching issues early before deploying to production saves time and money. Using traces a basis for test scenarios helps avoid "testing in prod."&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Furthermore, these kinds of functional integration tests, known as service tests or component tests, are often overlooked and yet an important layer in the test pyramid. This is also the area of testing where Skyramp shines.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gDUaUZ80--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdttgw07pvvhm15h1ldd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gDUaUZ80--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdttgw07pvvhm15h1ldd.png" alt="Image description" width="466" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The above image is from an article related to testing on &lt;a href="https://martinfowler.com/articles/practical-test-pyramid.html#TheTestPyramid"&gt;martinfowler.com&lt;/a&gt;.&lt;/em&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Skyramp on the Scene
&lt;/h2&gt;

&lt;p&gt;Skyramp provides an array of features to help developers and platform engineers create, manage, and run test scenarios for microservices in Kubernetes clusters. &lt;/p&gt;

&lt;p&gt;Previous blog posts have shown how to generate tests based on API schema definitions with OpenAPI or Protocol Buffers. For example, this blog covers test generation with OpenAPI: &lt;a href="https://dev.to/dangross/test-generation-for-distributed-apps-made-easy-with-skyramp-1fei"&gt;Test Generation for Distributed Apps Made Easy with Skyramp&lt;/a&gt;. However, there are many options available for generating tests, as you can see from the flag options in the &lt;a href="https://skyramp.dev/docs/kubernetes/reference/cli-commands/tester/generate/"&gt;Skyramp CLI&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp tester generate &amp;lt;flags&amp;gt;
      &lt;span class="nt"&gt;--address&lt;/span&gt; string              destination address of tests
      &lt;span class="nt"&gt;--alias&lt;/span&gt; string                Kubernetes service / Docker &lt;span class="nb"&gt;alias &lt;/span&gt;name
      &lt;span class="nt"&gt;--api-schema&lt;/span&gt; string           path to API schema file, or URL &lt;span class="o"&gt;(&lt;/span&gt;URL support &lt;span class="k"&gt;for &lt;/span&gt;OpenAPI 3.x only&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="nt"&gt;--cluster-id&lt;/span&gt; string           cluster &lt;span class="nb"&gt;id &lt;/span&gt;from telemetry provider
  &lt;span class="nt"&gt;-n&lt;/span&gt;, &lt;span class="nt"&gt;--namespace&lt;/span&gt; string            Kubernetes namespace where Skyramp worker resides
      &lt;span class="nt"&gt;--openai&lt;/span&gt;                      &lt;span class="o"&gt;(&lt;/span&gt;experimental&lt;span class="o"&gt;)&lt;/span&gt; use OpenAI to generate &lt;span class="nb"&gt;test &lt;/span&gt;values &lt;span class="o"&gt;(&lt;/span&gt;the &lt;span class="s1"&gt;'OPENAI_API_KEY'&lt;/span&gt; environment variable must be &lt;span class="nb"&gt;set &lt;/span&gt;with an OpenAI API token&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="nt"&gt;--openai-model&lt;/span&gt; string         &lt;span class="o"&gt;(&lt;/span&gt;experimental&lt;span class="o"&gt;)&lt;/span&gt; Optional, GPT model to use &lt;span class="k"&gt;for &lt;/span&gt;OpenAI &lt;span class="o"&gt;(&lt;/span&gt;one of &lt;span class="o"&gt;[&lt;/span&gt;gpt-3.5-turbo gpt-4]&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; Note that some models may not accesible based on the API token &lt;span class="o"&gt;(&lt;/span&gt;default &lt;span class="s2"&gt;"gpt-3.5-turbo"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="nt"&gt;--openapi-tag&lt;/span&gt; string          tag to filter on &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;openapi protocol&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="nt"&gt;--output-prefix&lt;/span&gt; string        prefix &lt;span class="k"&gt;for &lt;/span&gt;generated files
      &lt;span class="nt"&gt;--port&lt;/span&gt; int                    port number &lt;span class="k"&gt;for &lt;/span&gt;the service
      &lt;span class="nt"&gt;--proto-service&lt;/span&gt; string        proto service to utilize &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;protobuf protocol&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="nt"&gt;--protocol&lt;/span&gt; string             protocol to use &lt;span class="k"&gt;for &lt;/span&gt;the &lt;span class="nb"&gt;test &lt;/span&gt;configuration &lt;span class="o"&gt;(&lt;/span&gt;one of &lt;span class="o"&gt;[&lt;/span&gt;grpc rest]&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="nt"&gt;--start-time&lt;/span&gt; string           start &lt;span class="nb"&gt;time &lt;/span&gt;to retrieve traces from
      &lt;span class="nt"&gt;--telemetry-provider&lt;/span&gt; string   telemetry provider, currently only pixie is supported
      &lt;span class="nt"&gt;--trace-file&lt;/span&gt; string           trace file path
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this blog, we will focus on generating tests from observability traces. You can accomplish this based on trace data captured directly from a telemetry provider or using an exported trace file as the input.&lt;/p&gt;

&lt;h3&gt;
  
  
  One Step Generation
&lt;/h3&gt;

&lt;p&gt;You will see in the &lt;code&gt;skyramp/rest-demo&lt;/code&gt; folder from the &lt;code&gt;sample-microservices&lt;/code&gt; repo &lt;a href="https://github.com/letsramp/sample-microservices/blob/main/skyramp/rest-demo/"&gt;referenced above&lt;/a&gt; that there is a &lt;code&gt;trace&lt;/code&gt; folder containing an &lt;a href="https://github.com/letsramp/sample-microservices/blob/main/skyramp/rest-demo/trace/trace.json"&gt;example trace file&lt;/a&gt; discussed earlier. This particular trace file was created by calling the running system in the cluster with &lt;code&gt;curl&lt;/code&gt; commands and exporting the resulting trace.&lt;/p&gt;

&lt;p&gt;Furthermore, the &lt;code&gt;tests/test-trace-bOl4.yaml&lt;/code&gt; demo test description as well as the &lt;code&gt;scenarios/scenario-trace-bOl4.yaml&lt;/code&gt; file were automatically generated from the example trace file using Skyramp. To illustrate, this how to generate the same test scenario with the Skyramp CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp tester generate &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--trace-file&lt;/span&gt; trace/trace.json &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--protocol&lt;/span&gt; rest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Successfully created/updated the &lt;span class="nb"&gt;test &lt;/span&gt;description configuration files: 
        scenarios/scenario-trace-XI0m.yaml
        tests/test-trace-XI0m.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It really is that easy!&lt;/p&gt;

&lt;p&gt;Another way to capture traces for generating test scnearios is by passing in a telemetry provider to &lt;code&gt;skyramp generate&lt;/code&gt;. In the following example, we are using &lt;a href="https://px.dev"&gt;Pixie&lt;/a&gt; as the provider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp tester generate &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--telemetry-provider&lt;/span&gt; pixie &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--cluster-id&lt;/span&gt; cid1 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--namespace&lt;/span&gt; ns1 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--start-time&lt;/span&gt; &lt;span class="s2"&gt;"-5m"&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whichever way you choose, generating tests with Skyramp is just one step.&lt;/p&gt;

&lt;h3&gt;
  
  
  Executing the Tests
&lt;/h3&gt;

&lt;p&gt;Once the test scenarios are generated from observability traces, we can easily execute them to playback the sequence in the trace with Skyramp. Here, we run the test that we generated above against our system-under-test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp tester start test-trace-bOl4 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we get our results of the test run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Starting tests
Tester finished
Test trace-test------
 &lt;span class="o"&gt;[&lt;/span&gt;Status: finished] &lt;span class="o"&gt;[&lt;/span&gt;Started at: 2023-11-15 15:46:00 PST] &lt;span class="o"&gt;[&lt;/span&gt;End: 2023-11-15 15:46:00 PST] &lt;span class="o"&gt;[&lt;/span&gt;Duration: 0s]
  - pattern0.scenario_x2Dk
    &lt;span class="o"&gt;[&lt;/span&gt;Status: finished] &lt;span class="o"&gt;[&lt;/span&gt;Started at: 2023-11-15 15:46:00 PST] &lt;span class="o"&gt;[&lt;/span&gt;Duration: 0s]
  - pattern0.scenario_x2Dk.0.POST_q9FJ
    &lt;span class="o"&gt;[&lt;/span&gt;Status: finished] &lt;span class="o"&gt;[&lt;/span&gt;Started at: 2023-11-15 15:46:00 PST] &lt;span class="o"&gt;[&lt;/span&gt;Duration: 0s]
    Executed: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;:&lt;span class="s2"&gt;"200 OK"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
  - pattern0.scenario_x2Dk.1.assert
    &lt;span class="o"&gt;[&lt;/span&gt;Status: finished] &lt;span class="o"&gt;[&lt;/span&gt;Started at: N/A]
    Assert: requests.POST_q9FJ.code &lt;span class="o"&gt;==&lt;/span&gt; 200
    Passed: &lt;span class="nb"&gt;true&lt;/span&gt;
  - pattern0.scenario_x2Dk.2.GET_D0WG
    &lt;span class="o"&gt;[&lt;/span&gt;Status: finished] &lt;span class="o"&gt;[&lt;/span&gt;Started at: 2023-11-15 15:46:00 PST] &lt;span class="o"&gt;[&lt;/span&gt;Duration: 0s]
    Executed: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"user_id"&lt;/span&gt;:&lt;span class="s2"&gt;"eeeee"&lt;/span&gt;,&lt;span class="s2"&gt;"items"&lt;/span&gt;:[&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"product_id"&lt;/span&gt;:&lt;span class="s2"&gt;"OLJCESPC7Z"&lt;/span&gt;,&lt;span class="s2"&gt;"quantity"&lt;/span&gt;:2&lt;span class="o"&gt;}]}&lt;/span&gt;
  - pattern0.scenario_x2Dk.3.assert
    &lt;span class="o"&gt;[&lt;/span&gt;Status: finished] &lt;span class="o"&gt;[&lt;/span&gt;Started at: N/A]
    Assert: requests.GET_D0WG.code &lt;span class="o"&gt;==&lt;/span&gt; 200
    Passed: &lt;span class="nb"&gt;true&lt;/span&gt;
  - pattern0.scenario_x2Dk.4.POST_qwWE
    &lt;span class="o"&gt;[&lt;/span&gt;Status: finished] &lt;span class="o"&gt;[&lt;/span&gt;Started at: 2023-11-15 15:46:00 PST] &lt;span class="o"&gt;[&lt;/span&gt;Duration: 0s]
    Executed: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"order_id"&lt;/span&gt;:&lt;span class="s2"&gt;"149bbe85-c41c-443a-b273-53551c1b52f3"&lt;/span&gt;,&lt;span class="s2"&gt;"shipping_tracking_id"&lt;/span&gt;:&lt;span class="s2"&gt;"00be572e-02d4-41a5-b1ac-f50c87c2cc8a"&lt;/span&gt;,&lt;span class="s2"&gt;"shipping_cost"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"currency_code"&lt;/span&gt;:&lt;span class="s2"&gt;"USD"&lt;/span&gt;,&lt;span class="s2"&gt;"units"&lt;/span&gt;:10,&lt;span class="s2"&gt;"nanos"&lt;/span&gt;:100&lt;span class="o"&gt;}&lt;/span&gt;,&lt;span class="s2"&gt;"shipping_address"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"street_address"&lt;/span&gt;:&lt;span class="s2"&gt;"1600 Amp street"&lt;/span&gt;,&lt;span class="s2"&gt;"city"&lt;/span&gt;:&lt;span class="s2"&gt;"Mountain View"&lt;/span&gt;,&lt;span class="s2"&gt;"state"&lt;/span&gt;:&lt;span class="s2"&gt;"CA"&lt;/span&gt;,&lt;span class="s2"&gt;"country"&lt;/span&gt;:&lt;span class="s2"&gt;"USA"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;,&lt;span class="s2"&gt;"items"&lt;/span&gt;:[&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"item"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"product_id"&lt;/span&gt;:&lt;span class="s2"&gt;"OLJCESPC7Z"&lt;/span&gt;,&lt;span class="s2"&gt;"quantity"&lt;/span&gt;:2&lt;span class="o"&gt;}}]}&lt;/span&gt;
  - pattern0.scenario_x2Dk.5.assert
    &lt;span class="o"&gt;[&lt;/span&gt;Status: finished] &lt;span class="o"&gt;[&lt;/span&gt;Started at: N/A]
    Assert: requests.POST_qwWE.code &lt;span class="o"&gt;==&lt;/span&gt; 200
    Passed: &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the tests passed, so this was a successful test run. Of course, you can modify the test scenarios manually if you choose. You can introduce new steps or inject alternative data. Modifications can be valuable for troubleshooting behavior of the microservices in the system-under-test.&lt;/p&gt;

&lt;p&gt;All of the examples above are available for you to try for yourself. Simply follow the links provided or visit the &lt;a href="https://skyramp.dev/docs/"&gt;Skyramp Docs&lt;/a&gt; for additional guidance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leaving with a Trace
&lt;/h2&gt;

&lt;p&gt;Observability tracing is a powerful mechanism for understanding the intricacies of distributed systems. By leveraging traces to create test scenarios in Kubernetes clusters, you can enhance the robustness and reliability of your applications. As we demonstrated, generating tests with Skyramp based on traces is easy. This proactive approach to testing ensures that your system not only meets current requirements but is also well-prepared for future challenges. &lt;/p&gt;

&lt;p&gt;Embrace observability tracing as a fundamental aspect of your testing strategy with Skyramp, and watch as your Kubernetes applications become more resilient and performant in the face of evolving demands. Keep exploring and remember the sky's the limit. Happy tracing!&lt;/p&gt;

&lt;p&gt;P.S. Please join the &lt;a href="https://discord.gg/qBnEZM6JTb"&gt;Skyramp Community Discord&lt;/a&gt; for any questions, comments, or feedback. &lt;/p&gt;

</description>
      <category>observability</category>
      <category>kubernetes</category>
      <category>monitoring</category>
      <category>microservices</category>
    </item>
    <item>
      <title>3 Tools to Improve Your Code Quality: GitHub Codespaces, Kubernetes, and Skyramp</title>
      <dc:creator>Dan Gross</dc:creator>
      <pubDate>Thu, 02 Nov 2023 13:46:01 +0000</pubDate>
      <link>https://dev.to/dangross/3-tools-to-improve-your-code-quality-github-codespaces-kubernetes-and-skyramp-51h1</link>
      <guid>https://dev.to/dangross/3-tools-to-improve-your-code-quality-github-codespaces-kubernetes-and-skyramp-51h1</guid>
      <description>&lt;p&gt;In the world of developing distributed applications with microservices, code quality is paramount. It can make the difference between a well-functioning application, and one that's prone to bugs and vulnerabilities. To help you maintain and improve your code quality, we'll explore three powerful tools in this blog: &lt;a href="https://docs.github.com/codespaces" rel="noopener noreferrer"&gt;GitHub Codespaces&lt;/a&gt;, &lt;a href="https://kubernetes.io/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;, and &lt;a href="https://www.skyramp.dev" rel="noopener noreferrer"&gt;Skyramp&lt;/a&gt;. You’ll be able to try this combo for yourself with an instant dev environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting the Pieces Together
&lt;/h2&gt;

&lt;p&gt;In previous blog posts, we covered using &lt;a href="https://dev.to/dangross/turbocharge-your-debugging-with-skyramps-hot-code-reload-2ckm"&gt;GitHub Codespaces for debugging&lt;/a&gt;, &lt;a href="https://dev.to/dangross/test-generation-for-distributed-apps-made-easy-with-skyramp-1fei"&gt;generating tests in a Kubernetes cluster&lt;/a&gt;, and running &lt;a href="https://dev.to/dangross/all-your-tests-and-mocks-in-one-place-with-skyramp-dashboard-pjf"&gt;Skyramp's built-in dashboard&lt;/a&gt; to manage test results. In this blog, we’ll bring the pieces together to show how you can use all these tools to construct and run test scenarios for your system-under-test.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Word about Component Testing
&lt;/h2&gt;

&lt;p&gt;Within the space beyond unit testing and prior to end-to-end testing, there is a critical stage known as component testing. &lt;a href="https://martinfowler.com/articles/microservice-testing/#testing-component-introduction" rel="noopener noreferrer"&gt;This infodeck&lt;/a&gt; on Martin Fowler's &lt;a href="http://martinfowler.com" rel="noopener noreferrer"&gt;website&lt;/a&gt; covering testing strategies for microservices describes component testing this way: &lt;/p&gt;

&lt;p&gt;&lt;em&gt;"In a microservice architecture, the components are the services themselves. By writing tests at this granularity, the contract of the API is driven through tests from the perspective of a consumer."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you're developing a distributed application with microservices, it's essential to ensure that each component functions correctly, both in isolation as well as when integrated with other components. Component testing is the key to ensuring this, and Skyramp is here to assist you in this endeavor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instant Dev Environment
&lt;/h2&gt;

&lt;p&gt;GitHub Codespaces can be used to provide a cloud-based, integrated development environment that makes it easier to set up and run your tests with Skyramp. You can clone your repository, create a dedicated Codespace for your microservices, and then execute tests. A straightforward testing workflow is crucial to identify and fix issues early in the development process, saving you time and reducing headaches in the long run.&lt;/p&gt;

&lt;p&gt;Here are some benefits of using GitHub Codespaces for component testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;On-Demand Environments&lt;/strong&gt;: Easily spin up a development environment for your microservices project, reducing setup time and eliminating conflicts between dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consistency&lt;/strong&gt;: Ensure that all developers work in identical environments, reducing the "it works on my machine" problem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Collaboration&lt;/strong&gt;: Multiple developers can collaborate on the same project without worrying about where to setup and run environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easy Test and Debug&lt;/strong&gt;: Run tests and debug seamlessly within the Codespace environment using a familiar VSCode interface.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We've prepared a GitHub Codespace from a &lt;a href="https://github.com/letsramp/sample-microservices/tree/devcontainer-dashboard" rel="noopener noreferrer"&gt;branch&lt;/a&gt; of the Skyramp &lt;code&gt;sample-microservices&lt;/code&gt; repo on GitHub. This branch is based on the &lt;a href="https://github.com/GoogleCloudPlatform/microservices-demo" rel="noopener noreferrer"&gt;Online Boutique&lt;/a&gt; demo project from Google Cloud. The project is a web-based e-commerce store that consists of an 11-tier microservices application. Skyramp added support for REST, which we will use for the example in this blog.&lt;/p&gt;

&lt;p&gt;The GitHub Codespace can be launched from the link below and then clicking "Create Codespace".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codespaces.new/letsramp/sample-microservices/tree/devcontainer-dashboard?machine=standardLinux32gb" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/codespaces/badge.svg" alt="Open in GitHub Codespaces"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That will setup a VSCode environment within the browser that looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fcz0qdkowfoywvtc6rmgb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fcz0qdkowfoywvtc6rmgb.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Kubernetes Clusters in GitHub Codespaces
&lt;/h2&gt;

&lt;p&gt;For microservices to function as a cohesive system, you need a way to test their interaction in a realistic environment. This is where Kubernetes comes into play. Kubernetes allows you to manage containerized applications in clusters, making it a perfect fit for deploying and testing microservices.&lt;/p&gt;

&lt;p&gt;We will be using the Online Boutique application mentioned earlier for our example, which is built around Kubernetes. Skyramp can then be utilized to easily deploy and test the distributed app consisting of various microservices. We have created tests in the repo for testing 4 primary components of the application - Product Catalog, Cart, Payment, and Checkout.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fzeic5vua8v2ejalw9qxg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fzeic5vua8v2ejalw9qxg.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's get started by changing the directory in the terminal of the Codespace to &lt;code&gt;skyramp/rest-demo&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;skyramp/rest-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we'll create a new Kubernetes cluster with the Skyramp CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp cluster create &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Creating &lt;span class="nb"&gt;local &lt;/span&gt;cluster     &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="c"&gt;##############################################################] 100 %&lt;/span&gt;
Successfully created &lt;span class="nb"&gt;local &lt;/span&gt;cluster.
Starting/restarting Resolver     &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="c"&gt;##############################################################] 100 %&lt;/span&gt;
Resolver manages DNS changes needed to access the cluster and needs &lt;span class="nb"&gt;sudo &lt;/span&gt;access.
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; updating file /etc/resolv.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's bring up the system using Skyramp Deployer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp deployer up rest-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;email-service-745ddcd9c4-6zf8s                 ready
frontend-6f8fc574f7-w6hgb                      ready
product-catalog-service-5467566c8f-5n86m       ready
skyramp-worker-6c8bfdf587-bpf9m                ready
cart-service-56cd75c447-kshpg                  ready
currency-service-5b966cbfb8-tffff              ready
ad-service-7cb787976d-ldjm7                    ready
payment-service-5f9b47cfd4-26r9d               ready
redis-6fc54f68c4-fwg75                         ready
recommendation-service-6f8cd558b8-6cppj        ready
checkout-service-c5546db56-vdxld               ready
shipping-service-599947db74-flqhq              ready
All pods are ready.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system-under-test is now up and running. We have prepared several test scenarios which will be easy to run and then review the results with Skyramp.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Complement of Tests
&lt;/h2&gt;

&lt;p&gt;Quality assurance is not limited to early unit tests and final end-to-end tests. You need a comprehensive suite of tests, which include functional integration and performance tests, as well as the component tests highlighted earlier. This is where Skyramp completes the picture. Skyramp is an automated testing platform that can help you create and manage a wide range of tests for this stage of development. &lt;/p&gt;

&lt;p&gt;Skyramp takes a modular approach to testing, as illustrated below with examples taken from the testing scenario we used for this blog. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Endpoints&lt;/strong&gt;: Skyramp will use endpoint definitions for networking details of services used in tests as shown in this endpoint YAML file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-catalog-service&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;60000&lt;/span&gt;
      &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-catalog-service&lt;/span&gt;
      &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rest&lt;/span&gt;
&lt;span class="na"&gt;endpoints&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-catalog-service-get-products&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/get-products"&lt;/span&gt;
    &lt;span class="na"&gt;serviceName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-catalog-service&lt;/span&gt;
    &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GET'&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;get-products&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scenarios&lt;/strong&gt;: Skyramp uses scenario definitions for request behavior of service methods or chains of requests, and specific asserts within test scenarios:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;scenarios&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scenario_123&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;requestName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;listProductsRequest&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;asserts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;requests.listProductsRequest.res[0].id == "OLJCESPC7Z"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;requestName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;addCartRequest&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;asserts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;requests.addCartRequest.res.success == "200 OK"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;requestName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;getCartRequest&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;asserts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;requests.getCartRequest.res.user_id == "abcde"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;requestName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chargeRequest&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;asserts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;requests.chargeRequest.res.transaction_id != &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;requestName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;checkoutRequest&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;asserts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;requests.checkoutRequest.res.items[0].item.product_id == "OLJCESPC7Z"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tests&lt;/strong&gt;: Skyramp uses test definitions as a starting point to execute the proper behavior of tests:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[REST]&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Checkout&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;load&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;test&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;testcase"&lt;/span&gt;
  &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rest-app&lt;/span&gt;
  &lt;span class="na"&gt;testPattern&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;startAt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1s&lt;/span&gt;
      &lt;span class="na"&gt;atOnce&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
      &lt;span class="na"&gt;scenarioName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scenario1&lt;/span&gt;
      &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Running the Test, Checking the Results
&lt;/h2&gt;

&lt;p&gt;We’ve found it incredibly valuable to have a central dashboard that aggregates and visualizes the results of your tests so you can get the most out of these tools, and ensure that your code quality is continually improving. Skyramp provides just that, and it can be run in GitHub Codespaces! Let's fire up the Skyramp Dashboard and run our test scenario against the services in the cluster.&lt;/p&gt;

&lt;p&gt;Back to the Codespaces terminal, run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp dashboard up &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.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%2F3yfm7u4f9cfpt067ebda.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F3yfm7u4f9cfpt067ebda.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click "Open in Browser" from the dialog box popup regarding port forwarding and you will see the Skyramp Dashboard interface in a new browser tab. Click on "Tests". There will be no tests yet to display, but we can change that. Back to the Codespace tab, run Skyramp Tester in the terminal to execute our &lt;code&gt;full-system&lt;/code&gt; test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp tester start full-system &lt;span class="nt"&gt;-n&lt;/span&gt; test-rest-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now back to the Skyramp Dashboard tab in the browser and you will see the results of the test run there:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fydvs2geo63ginlhwmzp7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fydvs2geo63ginlhwmzp7.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looks like a passing grade! Notice the cells in the table can be expanded to view details of the test results.&lt;/p&gt;

&lt;p&gt;You can explore further and even tweak the tests by checking out the YAML files in the &lt;code&gt;endpoints&lt;/code&gt;, &lt;code&gt;scenarios&lt;/code&gt;, and &lt;code&gt;tests&lt;/code&gt; folders under &lt;code&gt;skyramp/rest-demo&lt;/code&gt;. Also, visit the &lt;a href="https://www.skyramp.dev/docs/" rel="noopener noreferrer"&gt;Skyramp Docs&lt;/a&gt; to learn more about all the functionality available for testing with Skyramp.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Power of 3
&lt;/h2&gt;

&lt;p&gt;By combining GitHub Codespaces, Kubernetes, and Skyramp, especially with a robust testing dashboard, you can ensure that your code quality remains high throughout the development lifecycle. As a result, your applications will be more reliable, ultimately leading to greater user satisfaction and a stronger competitive edge in the landscape of microservices-based distributed apps. As always, happy testing! &lt;/p&gt;

&lt;p&gt;For more info, visit: &lt;a href="https://www.skyramp.dev" rel="noopener noreferrer"&gt;Skyramp.dev&lt;/a&gt; &amp;amp; Join the &lt;a href="https://discord.com/invite/qBnEZM6JTb" rel="noopener noreferrer"&gt;Skyramp Community Discord&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>kubernetes</category>
      <category>testing</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Test Generation for Distributed Apps Made Easy with Skyramp</title>
      <dc:creator>Dan Gross</dc:creator>
      <pubDate>Fri, 27 Oct 2023 20:05:25 +0000</pubDate>
      <link>https://dev.to/dangross/test-generation-for-distributed-apps-made-easy-with-skyramp-1fei</link>
      <guid>https://dev.to/dangross/test-generation-for-distributed-apps-made-easy-with-skyramp-1fei</guid>
      <description>&lt;p&gt;In the ever-evolving world of software development, the importance of testing to ensure quality cannot be overstated. This rings especially true when it comes to distributed applications with loosely coupled microservices. These kinds of distributed applications bring a host of complexities that require a thoughtful approach to testing. With the advent of testing tools provided by &lt;a href="https://www.skyramp.dev/" rel="noopener noreferrer"&gt;Skyramp&lt;/a&gt;, combined with technology building blocks like &lt;a href="https://kubernetes.io/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt; and &lt;a href="https://www.openapis.org/" rel="noopener noreferrer"&gt;OpenAPI&lt;/a&gt;, test generation for distributed apps is easier and more efficient than ever before. This blog will dive into the process of generating tests for your distributed applications by showing a step-by-step example using Skyramp and the aforementioned standards.&lt;/p&gt;

&lt;h2&gt;
  
  
  Talking About Test Generation
&lt;/h2&gt;

&lt;p&gt;Before we delve into the step-by-step walkthrough of generating tests, let's first understand why test generation is beneficial for distributed applications. Distributed applications, most often composed of various microservices, can be particularly intricate in terms of communication, dependencies, and data flow. Manually writing tests for each component can be time-consuming and prone to human error. Automated test generation can streamline this process, ensuring comprehensive coverage and robust testing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fh0oqxp0h9urgb8x8m2e2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fh0oqxp0h9urgb8x8m2e2.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OpenAPI, formerly known as Swagger, is a set of specifications that defines a standard, language-agnostic interface to RESTful APIs. It's often used to document and describe the capabilities of a microservice, including the available endpoints, input/output parameters, and response formats. This can act as the foundation for automated test generation by providing a clear and structured definition of a service.&lt;/p&gt;

&lt;p&gt;Leveraging OpenAPI, Skyramp can analyze your microservices and automatically create test cases based on your API specifications and service dependencies. This allows you to verify that the various components of your distributed application work seamlessly together, saving you time. It should be noted that Skyramp supports other protocols for test generation like gRPC and Protocol Buffers, but we'll save that for another day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating Tests: A Step-By-Step Walkthrough
&lt;/h2&gt;

&lt;p&gt;Now, let's get into the nitty-gritty of how to generate tests for your distributed applications using Skyramp. We will use our tried and true &lt;a href="https://github.com/letsramp/sample-microservices" rel="noopener noreferrer"&gt;sample-microservices repo on GitHub&lt;/a&gt;, which is an 11-tier distributed app with REST support already configured for deployment to a Kubernetes cluster. The app itself is a complete web-based e-commerce store created by Google, known as Online Boutique.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F82vmbiofu9n6wm49ojny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F82vmbiofu9n6wm49ojny.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below is the step-by-step walkthrough to guide you along the journey. These steps were tested on Mac, but should work on Linux or Windows with a bash shell.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Install the Skyramp CLI
&lt;/h3&gt;

&lt;p&gt;The first step is to install the Skyramp Command Line Interface (CLI). See the &lt;a href="https://www.skyramp.dev/docs/" rel="noopener noreferrer"&gt;Skyramp Docs&lt;/a&gt; for specifics, or you can run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://skyramp.dev/installer.sh&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NOTE: You will also need &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; installed to continue.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Clone the Repository
&lt;/h3&gt;

&lt;p&gt;Next, clone the sample repository discussed above. This contains the code and configuration files necessary for your distributed application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/letsramp/sample-microservices.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Create a Cluster
&lt;/h3&gt;

&lt;p&gt;Now, create a cluster using the Skyramp CLI. This cluster will serve as the environment in which your microservices will be deployed and tested.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp cluster create &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Change to the Demo Directory
&lt;/h3&gt;

&lt;p&gt;Navigate to the directory containing the prepared REST demo project under "rest-demo".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;sample-microservices/skyramp/rest-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Deploy the Cluster with Skyramp Deployer
&lt;/h3&gt;

&lt;p&gt;Use the Skyramp Deployer to bring up the microservices within the cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp deployer up rest-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ad-service-7cb787976d-l49n5                    ready
currency-service-5b966cbfb8-q7dvf              ready
email-service-745ddcd9c4-7wdvq                 ready
cart-service-56cd75c447-xzdlk                  ready
checkout-service-c5546db56-lsdtm               ready
product-catalog-service-5467566c8f-sl6wb       ready
skyramp-worker-6c8bfdf587-jr2tq                ready
payment-service-5f9b47cfd4-cw4j2               ready
recommendation-service-6f8cd558b8-dmvh8        ready
shipping-service-599947db74-8dtkn              ready
frontend-6f8fc574f7-nv76g                      ready
redis-6fc54f68c4-v6mqb                         ready
All pods are ready.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: OpenAPI Configuration
&lt;/h3&gt;

&lt;p&gt;In this project, there is a pre-defined OpenAPI specification file (demo.yaml). This file describes the API endpoints and their expected behavior. Take a peek at the contents of this file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;openapi/demo.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that the definition centers around charging a credit card. We can use this definition to test the payment service running in our cluster.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7: Generate a Test
&lt;/h3&gt;

&lt;p&gt;Now comes the fun part - generating a test using the Skyramp CLI. You can specify the protocol, API schema, alias, and port for your test. Run the command below to see how this works.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp tester generate &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--protocol&lt;/span&gt; openapi &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--api-schema&lt;/span&gt; openapi/demo.yaml &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--alias&lt;/span&gt; test-rest-demo &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--port&lt;/span&gt; 60000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will automatically generate test cases for your distributed application based on the provided OpenAPI schema.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 8: Tune Your Test
&lt;/h3&gt;

&lt;p&gt;Upon running the test generation command from the step above, Skyramp will create three files that contain your test cases and configuration. You can review and customize these files to fit your specific testing needs. The output will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Creating &lt;span class="nb"&gt;test &lt;/span&gt;files     &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="c"&gt;##############################################################] 100 %&lt;/span&gt;
Successfully created/updated the &lt;span class="nb"&gt;test &lt;/span&gt;description configuration files:
    endpoints/test-rest-demo-tDPT.yaml
    scenarios/scenario-test-rest-demo-tDPT.yaml
    tests/test-test-rest-demo-tDPT.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's make a few edits to the files that were generated.&lt;/p&gt;

&lt;p&gt;1) Change the &lt;code&gt;serviceName&lt;/code&gt; value in the generated "endpoint" file to use the payment service running in the cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;serviceName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payment-service&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Change the &lt;code&gt;requestName&lt;/code&gt; parameter in the generated "test" file to &lt;code&gt;scenarioName&lt;/code&gt; and assign the value "scenario_123".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;scenarioName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scenario_123&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Modify the generated "scenario" file to include a &lt;code&gt;scenarios&lt;/code&gt; section at the end of the file that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;scenarios&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scenario_123&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;requestName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chargeRequest&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;asserts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;requests.chargeRequest.res.transaction_id != &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Also modify generated parameters and values in the "scenario" file under the &lt;code&gt;requests&lt;/code&gt; section as shown below. Many of the parameters will be auto-generated based on the OpenAPI definition, but we can improve the values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chargeRequest&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json"&lt;/span&gt;
      &lt;span class="na"&gt;blob&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|-&lt;/span&gt;
        &lt;span class="s"&gt;{&lt;/span&gt;
          &lt;span class="s"&gt;"amount": {&lt;/span&gt;
            &lt;span class="s"&gt;"currency_code": "USD",&lt;/span&gt;
            &lt;span class="s"&gt;"units": 100&lt;/span&gt;
          &lt;span class="s"&gt;},&lt;/span&gt;
          &lt;span class="s"&gt;"credit_card": {&lt;/span&gt;
            &lt;span class="s"&gt;"credit_card_cvv": 100,&lt;/span&gt;
            &lt;span class="s"&gt;"credit_card_expiration_month": 10,&lt;/span&gt;
            &lt;span class="s"&gt;"credit_card_expiration_year": 2030,&lt;/span&gt;
            &lt;span class="s"&gt;"credit_card_number": "4432-8015-6152-0454"&lt;/span&gt;
          &lt;span class="s"&gt;}&lt;/span&gt;
        &lt;span class="s"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 9: Run and Refine
&lt;/h3&gt;

&lt;p&gt;After completing the edits from above, we are ready to run our test against the payment service. Simply run Skyramp Tester to execute the test scenario we composed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp tester start test-test-rest-demo-2VHL &lt;span class="nt"&gt;-n&lt;/span&gt; test-rest-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output should indicate a passed test such as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Starting tests
Tester finished
Test test-rest-demo------
 &lt;span class="o"&gt;[&lt;/span&gt;Status: finished] &lt;span class="o"&gt;[&lt;/span&gt;Started at: 2023-10-26 09:32:56 PDT] &lt;span class="o"&gt;[&lt;/span&gt;End: 2023-10-26 09:32:57 PDT] &lt;span class="o"&gt;[&lt;/span&gt;Duration: 1s]
  - pattern0.scenario_123
    &lt;span class="o"&gt;[&lt;/span&gt;Status: finished] &lt;span class="o"&gt;[&lt;/span&gt;Started at: 2023-10-26 09:32:57 PDT] &lt;span class="o"&gt;[&lt;/span&gt;Duration: 0s]
  - pattern0.scenario_123.0.chargeRequest
    &lt;span class="o"&gt;[&lt;/span&gt;Status: finished] &lt;span class="o"&gt;[&lt;/span&gt;Started at: 2023-10-26 09:32:57 PDT] &lt;span class="o"&gt;[&lt;/span&gt;Duration: 0s]
    Executed: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"transaction_id"&lt;/span&gt;:&lt;span class="s2"&gt;"e740f1b8-3618-4253-94ae-9be0de082f68"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
  - pattern0.scenario_123.1.assert
    &lt;span class="o"&gt;[&lt;/span&gt;Status: finished] &lt;span class="o"&gt;[&lt;/span&gt;Started at: N/A]
    Assert: requests.chargeRequest.res.transaction_id &lt;span class="o"&gt;!=&lt;/span&gt; null
    Passed: &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can continue to fine-tune your tests by modifying the generated files. Working with these files, you can see the modular approach Skyramp takes to testing. Adjust the test cases, add custom scenarios, and configure test environments as needed to ensure comprehensive testing for your distributed applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  This Was Only a Test
&lt;/h2&gt;

&lt;p&gt;In conclusion, automated test generation with Skyramp simplifies the testing process for distributed applications. It enhances the efficiency and reliability of testing scenarios, ensuring that your microservices work harmoniously to deliver a robust and error-free application.&lt;/p&gt;

&lt;p&gt;By following the step-by-step walkthrough outlined in this blog, you can see how to effectively generate and customize tests for your distributed apps, saving time and ensuring the quality of your software. Happy testing with Skyramp!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>testing</category>
      <category>openapi</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Turbocharge Your Debugging with Skyramp's Hot Code Reload</title>
      <dc:creator>Dan Gross</dc:creator>
      <pubDate>Fri, 20 Oct 2023 15:06:42 +0000</pubDate>
      <link>https://dev.to/dangross/turbocharge-your-debugging-with-skyramps-hot-code-reload-2ckm</link>
      <guid>https://dev.to/dangross/turbocharge-your-debugging-with-skyramps-hot-code-reload-2ckm</guid>
      <description>&lt;p&gt;Are you tired of the traditional, cumbersome debugging process that requires re-deployments of microservices every time you want to test a code change? &lt;a href="https://www.skyramp.dev" rel="noopener noreferrer"&gt;Skyramp&lt;/a&gt; now offers a game-changing feature known as Hot Code Reload. With this feature, you can debug your services in real-time without the hassle of re-deploying your application. You can attach your debugger, step through code, and make changes while your service continues to run without interruption. &lt;/p&gt;

&lt;p&gt;In this blog post, we'll explore how to enable and use Skyramp's Hot Code Reload feature to turbocharge your development and debugging workflow for distributed applications. We'll first cover how to setup Hot Code Reload for any &lt;a href="https://kubernetes.io/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt; environment, then we'll step through a specific example that you can follow along using &lt;a href="https://github.com/features/codespaces" rel="noopener noreferrer"&gt;GitHub Codespaces&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In addition, we also have a YouTube video that walks through a quick summary of the Hot Code Reload feature from Skyramp:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  How to Setup Hot Code Reload
&lt;/h2&gt;

&lt;p&gt;The Hot Code Reload feature is available as a configuration option for the &lt;a href="https://www.skyramp.dev/docs/deployer/" rel="noopener noreferrer"&gt;Skyramp Deployer&lt;/a&gt; tool. By using Deployer to deploy services to your Kubernetes cluster, you can take advantage of this feature. &lt;/p&gt;

&lt;p&gt;To setup the Hot Code Reload feature, you need to include a 'debug' section in your &lt;a href="https://www.skyramp.dev/docs/deployer/target-description/" rel="noopener noreferrer"&gt;target description&lt;/a&gt; file under the 'containers' section. This 'debug' section should specify various parameters to configure the debugging process. Here's an example of what this looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment/my-service&lt;/span&gt;
    &lt;span class="na"&gt;runtimeType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;go&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myservice&lt;/span&gt;
    &lt;span class="na"&gt;debugPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;33333&lt;/span&gt;
    &lt;span class="na"&gt;mountPaths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/workspaces/myproject/src/myservice&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break down what each of these parameters means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;containerName&lt;/code&gt;: This is the name of the container you want to use in debug mode. You should specify the container associated with the service you wish to debug.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;runtimeType&lt;/code&gt;: Here, you specify the runtime type of your service, such as 'go,' 'node,' or 'python.' This information is crucial for Skyramp to set up the debugging environment correctly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;command&lt;/code&gt;: This parameter represents the application's entry point that will run in a loop. It should be relative to the first path specified in the 'mountPaths'. It is the core of the debugging process, allowing you to inject code changes without disrupting the service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;debugPort&lt;/code&gt;: The 'debugPort' is the local port of the running service that you want to debug. This port is where your debugger will connect to interact with your service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;mountPaths&lt;/code&gt;: You can specify one or more paths that should be mounted to the remote container. These paths are the locations where your code changes will be applied. It's essential to ensure that your code and any necessary dependencies are mounted correctly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The information above is also covered in the &lt;a href="https://www.skyramp.dev/docs/" rel="noopener noreferrer"&gt;Skyramp Docs&lt;/a&gt;, where you can learn more about how to utilize all the Skyramp capabilities for testing distributed applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking under the Hood
&lt;/h2&gt;

&lt;p&gt;Once you've configured the 'debug' section in your target description file, Skyramp's Hot Code Reload feature comes to life. Now, let's take a closer look at how it works:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-time Debugging&lt;/strong&gt;&lt;br&gt;
With Hot Code Reload, you can attach your debugger to the running service. This allows you to inspect the current state of your application and set breakpoints as needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Changes&lt;/strong&gt;&lt;br&gt;
As you debug your service, you can make code changes on the fly. These changes are instantly injected into the running application, giving you the flexibility to fix issues or implement new features without restarting the service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interactive Debugging&lt;/strong&gt;&lt;br&gt;
You can step through your code, inspect variables, and watch how your changes affect the behavior of your service. This interactive debugging experience greatly accelerates the troubleshooting and development process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Streamlined Workflow&lt;/strong&gt;&lt;br&gt;
Hot Code Reload streamlines your debugging process by eliminating the need for frequent re-deployments. It saves you time and effort, enabling faster iteration and more efficient debugging.&lt;/p&gt;
&lt;h2&gt;
  
  
  Give It a Spin with Codespaces
&lt;/h2&gt;

&lt;p&gt;In this section, we are going to step through an example of using Hot Code Reload to debug a sample application within a pre-configured deployment. Don't worry, though, no local setup is required because we are going to use GitHub Codespaces from a browser. &lt;/p&gt;

&lt;p&gt;For our scenario, let's say a problem was reported with the cart service in our distributed application. We will attempt to find and fix the issue by setting up a Codespace environment to test and debug the cart service using Skyramp.&lt;/p&gt;

&lt;p&gt;Note: the specific steps outlined below may be refined since the Skyramp product is rapidly evolving.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1 - Fire Up the Codespace
&lt;/h3&gt;

&lt;p&gt;Our starting point is the &lt;code&gt;hot-code-reload-demo&lt;/code&gt; branch in Skyramp's &lt;code&gt;letsramp/sample-microservices&lt;/code&gt; GitHub repo. You can use your browser to navigate to the correct branch in the repo &lt;a href="https://github.com/letsramp/sample-microservices/tree/hot-code-reload-demo" rel="noopener noreferrer"&gt;here&lt;/a&gt;. The &lt;code&gt;sample-microservices&lt;/code&gt; repo contains a demo project based on GCP's &lt;a href="https://github.com/GoogleCloudPlatform/microservices-demo" rel="noopener noreferrer"&gt;Online Boutique&lt;/a&gt; with added support for REST and Thrift APIs. This sample e-commerce application is perfect for demonstrating cloud-native development and testing, including debugging with Hot Code Reload with Skyramp.&lt;/p&gt;

&lt;p&gt;To launch the Codespace, click the "Open in GitHub Codespaces" link from the &lt;code&gt;README.md&lt;/code&gt;. You can also click the link below: &lt;a href="https://codespaces.new/letsramp/sample-microservices/tree/hot-code-reload-demo?machine=standardLinux32gb&amp;amp;geo=UsEast" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/codespaces/badge.svg" alt="Open in GitHub Codespaces"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the "Create a new codespace" page on GitHub, simply click "Create codespace". It will take a few moments to set up your Codespace. When the process finishes, you will see a VSCode environment like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F2v1gevzaxa0fq4c93fnb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F2v1gevzaxa0fq4c93fnb.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2 - Setup the Cluster and Deploy
&lt;/h3&gt;

&lt;p&gt;Next, we will use the Skyramp CLI to create a Kubernetes cluster in the Codespace, and then deploy the services we need in order to test and debug. &lt;/p&gt;

&lt;p&gt;Create a Kubernetes cluster from the Terminal in VSCode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp cluster create &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; ~/.skyramp/kind-cluster.kubeconfig ~/.kube/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For debug purposes, we will need to install this SMB driver with Helm into the Codespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add csi-driver-smb https://raw.githubusercontent.com/kubernetes-csi/csi-driver-smb/master/charts
helm &lt;span class="nb"&gt;install &lt;/span&gt;csi-driver-smb csi-driver-smb/csi-driver-smb &lt;span class="nt"&gt;--namespace&lt;/span&gt; kube-system &lt;span class="nt"&gt;--version&lt;/span&gt; v1.11.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also for debugging, the binary for the cart service needs to be built:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /workspaces/sample-microservices/src/cartservice
&lt;span class="nv"&gt;CGO_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 &lt;span class="nv"&gt;GOOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux &lt;span class="nv"&gt;GOARCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;amd64 go build &lt;span class="nt"&gt;-o&lt;/span&gt; cartservice &lt;span class="nt"&gt;-gcflags&lt;/span&gt; &lt;span class="s2"&gt;"all=-N -l"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we deploy the services to the cluster using Skyramp Deployer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /workspaces/sample-microservices/skyramp/rest-demo
skyramp deployer up checkout-system 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now see that all pods are ready.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fbmyqsfj6isxdwfccoxry.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fbmyqsfj6isxdwfccoxry.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 - Test and Debug
&lt;/h3&gt;

&lt;p&gt;We will be using a specific port for the debugger, so open the&lt;br&gt;
&lt;code&gt;src/cartservice/.vscode/launch.json&lt;/code&gt; file in the repo and change the &lt;code&gt;port&lt;/code&gt; parameter value to &lt;code&gt;2345&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fpe1pxwg0af2hybzaorb7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fpe1pxwg0af2hybzaorb7.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, create a second Terminal in VSCode using the drop down and selecting "bash". From there, we will start the debugger with the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;POD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; test-rest-demo | &lt;span class="nb"&gt;grep &lt;/span&gt;cart-service | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{ print $1}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nv"&gt;$POD&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; test-rest-demo &lt;span class="nt"&gt;--&lt;/span&gt; /mnt/debug/debuggers/dlv &lt;span class="nb"&gt;exec&lt;/span&gt; /mnt/debug/cart-service/cartservice/cartservice &lt;span class="nt"&gt;--wd&lt;/span&gt; /mnt/debug/cart-service/cartservice  &lt;span class="nt"&gt;--listen&lt;/span&gt; :2345 &lt;span class="nt"&gt;--log&lt;/span&gt; &lt;span class="nt"&gt;--api-version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2  &lt;span class="nt"&gt;--headless&lt;/span&gt; &lt;span class="nt"&gt;--continue&lt;/span&gt; &lt;span class="nt"&gt;--accept-multiclient&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can run our test scenario from the first Terminal window using Skyramp Tester:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp tester start checkout-test &lt;span class="nt"&gt;-n&lt;/span&gt; test-rest-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We see that there is a failed test. It looks like a problem with the user ID.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F8qeb4cy65rpbbgta4cxt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F8qeb4cy65rpbbgta4cxt.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a third Terminal to setup port forwarding for the debugger, and then execute the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;POD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; test-rest-demo | &lt;span class="nb"&gt;grep &lt;/span&gt;cart-service | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{ print $1}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
kubectl port-forward &lt;span class="nv"&gt;$POD&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; test-rest-demo 2345:2345
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can attach the debugger in VSCode to step through the code. Open the &lt;code&gt;src/cartservice/rest.go&lt;/code&gt; file and set breakpoint on line 33 at the &lt;code&gt;post&lt;/code&gt; function. Since the error was related to the user ID, there might be an issue in this function.&lt;/p&gt;

&lt;p&gt;Click the "Run and Debug" button on the left nav and then click the green play arrow to attach the debugger. You will see the status bar at the bottom of VSCode turn red. From the first Terminal, re-run the test as shown earlier. Execution will stop at line 33 where we set our breakpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fsk9y77oan55d1oyr6jok.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fsk9y77oan55d1oyr6jok.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using the debug controls to step over the code, we see that &lt;code&gt;user_id&lt;/code&gt; is not populated. It looks like the code is using &lt;code&gt;UserID&lt;/code&gt; instead of &lt;code&gt;user_id&lt;/code&gt; for the parameter. That's most likely the issue, so let's fix it. We can continue execution and then disconnect the debugger in VSCode using the debug controls. Also, we can kill the debugger by running the following command in the first Terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;POD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; test-rest-demo | &lt;span class="nb"&gt;grep &lt;/span&gt;cart-service | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{ print $1}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nv"&gt;$POD&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; test-rest-demo &lt;span class="nt"&gt;--&lt;/span&gt; killall dlv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4 - Fix and Validate
&lt;/h3&gt;

&lt;p&gt;Now on to the best part -- fixing the bug. First, update the code in &lt;code&gt;rest.go&lt;/code&gt; to use &lt;code&gt;user_id&lt;/code&gt; instead of &lt;code&gt;UserID&lt;/code&gt; on line 33. Then, rebuild the binary as we did earlier from the first Terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /workspaces/sample-microservices/src/cartservice
&lt;span class="nv"&gt;CGO_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 &lt;span class="nv"&gt;GOOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux &lt;span class="nv"&gt;GOARCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;amd64 go build &lt;span class="nt"&gt;-o&lt;/span&gt; cartservice &lt;span class="nt"&gt;-gcflags&lt;/span&gt; &lt;span class="s2"&gt;"all=-N -l"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we restart the debugger in the second Terminal as we did earlier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;POD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; test-rest-demo | &lt;span class="nb"&gt;grep &lt;/span&gt;cart-service | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{ print $1}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nv"&gt;$POD&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; test-rest-demo &lt;span class="nt"&gt;--&lt;/span&gt; /mnt/debug/debuggers/dlv &lt;span class="nb"&gt;exec&lt;/span&gt; /mnt/debug/cart-service/cartservice/cartservice &lt;span class="nt"&gt;--wd&lt;/span&gt; /mnt/debug/cart-service/cartservice  &lt;span class="nt"&gt;--listen&lt;/span&gt; :2345 &lt;span class="nt"&gt;--log&lt;/span&gt; &lt;span class="nt"&gt;--api-version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2  &lt;span class="nt"&gt;--headless&lt;/span&gt; &lt;span class="nt"&gt;--continue&lt;/span&gt; &lt;span class="nt"&gt;--accept-multiclient&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switching back to the first Terminal, we can re-run our test with Skyramp Tester:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /workspaces/sample-microservices/skyramp/rest-demo
skyramp tester start checkout-test &lt;span class="nt"&gt;-n&lt;/span&gt; test-rest-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at that, the previously failed test now passes!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F3003ny9r2xmsy53nwg8m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F3003ny9r2xmsy53nwg8m.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We found the bug, validated the fix, and did not have to re-deploy our cluster. Excellent work!&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Hot Code Reload
&lt;/h2&gt;

&lt;p&gt;Skyramp's Hot Code Reload feature brings several benefits to your development and debugging workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time Savings&lt;/strong&gt;&lt;br&gt;
Say goodbye to the time-consuming process of re-deploying your application every time you make a code change. Hot Code Reload lets you make changes on the fly, saving you valuable development time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enhanced Productivity&lt;/strong&gt;&lt;br&gt;
With real-time debugging and interactive code changes, you can identify and fix issues more efficiently. This increased productivity helps you deliver high-quality software faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reduced Downtime&lt;/strong&gt;&lt;br&gt;
Hot Code Reload minimizes service downtime for your system-under-test by allowing you to fix issues without restarting the entire application. This is particularly useful for services that must maintain continuous availability in a shared environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Improved Collaboration&lt;/strong&gt;&lt;br&gt;
Debugging is more accessible and collaborative with Hot Code Reload. Team members can work together to troubleshoot and enhance your services in real-time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flexible Testing&lt;/strong&gt;&lt;br&gt;
Quickly test new features or experiments by applying changes while your service is running. This flexibility encourages experimentation and innovation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summing It Up
&lt;/h2&gt;

&lt;p&gt;In conclusion, Skyramp's Hot Code Reload feature is a game-changer for developers. It empowers you to debug your services in real-time, eliminate the need for re-deployments, and significantly accelerate your development and testing workflow. Simply configuring Skyramp Deployer and following the steps outlined in this blog post, you can start using Hot Code Reload to turbocharge your debugging process for distributed applications today. Happy debugging!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>microservices</category>
      <category>kubernetes</category>
      <category>coding</category>
    </item>
    <item>
      <title>All your Tests and Mocks in One Place with Skyramp Dashboard</title>
      <dc:creator>Dan Gross</dc:creator>
      <pubDate>Tue, 10 Oct 2023 17:32:17 +0000</pubDate>
      <link>https://dev.to/dangross/all-your-tests-and-mocks-in-one-place-with-skyramp-dashboard-pjf</link>
      <guid>https://dev.to/dangross/all-your-tests-and-mocks-in-one-place-with-skyramp-dashboard-pjf</guid>
      <description>&lt;p&gt;&lt;a href="https://www.skyramp.dev"&gt;Skyramp&lt;/a&gt; gives you the tools you need to make integration and performance testing for distributed applications easier. One way Skyramp helps you save time and be more productive is with the &lt;a href="https://skyramp.dev/docs/reference/dashboard/"&gt;Skyramp Dashboard&lt;/a&gt;. The Skyramp Dashboard allows you to view the details of your test results, see your active mocks, and track all of your test runs.&lt;/p&gt;

&lt;p&gt;In this post, we will take a deep dive into using the Skyramp Dashboard for testing microservices in a Kubernetes cluster. If you're a developer or devops engineer looking to streamline your testing workflow for distributed applications, you've come to the right place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up
&lt;/h2&gt;

&lt;p&gt;Before we get started, let's make sure you have a suitable testing environment in place.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install the Skyramp CLI
&lt;/h3&gt;

&lt;p&gt;First things first, you need to have the Skyramp Terminal Client installed. If you haven't already done this, you can find the install steps &lt;a href="https://skyramp.dev/docs/get-started/install-client/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Register your Kubernetes Cluster
&lt;/h3&gt;

&lt;p&gt;Next, you will need to have a Kubernetes cluster registered with Skyramp. You have two choices. From the Skyramp CLI, you can either: (1) register an existing cluster with &lt;code&gt;skyramp cluster register&lt;/code&gt;, or (2) create a new cluster with &lt;code&gt;skyramp cluster create&lt;/code&gt;. More details about these Skyramp CLI Commands can be found &lt;a href="https://www.skyramp.dev/docs/reference/cli-commands/cluster/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: For an easy way to follow along with this post, you can create a local Kubernetes cluster by stepping through &lt;a href="https://skyramp.dev/docs/get-started/walkthrough/"&gt;this simple walkthrough&lt;/a&gt;. The tests and mocks referenced in this post will use the examples from the walkthrough. As shown in the steps from the walkthrough, we can create a local Kubernetes cluster from the sample project that is registered with Skyramp by running this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp cluster create &lt;span class="nt"&gt;--local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have a Kubernetes cluster registered with Skyramp, you can double-check the current cluster by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp cluster current
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will produce output like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;current: kind-cluster
kubeconfig: ~/.skyramp/kind-cluster.kubeconfig
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With your testing environment in place, let's move on to deploying the Skyramp Dashboard to the cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bringing Up the Dashboard
&lt;/h2&gt;

&lt;p&gt;To deploy the Skyramp Dashboard to your currently registered Kubernetes cluster, execute the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp dashboard up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command automatically creates the Kubernetes assets for the dashboard like the client, the server, and a MongoDB Kubernetes operator within the Skyramp namespace of your cluster. It also sets up port forwarding for local access to the dashboard.&lt;/p&gt;

&lt;p&gt;Once the dashboard is ready, the terminal client will provide you with a URL for access and then open the dashboard page in a new browser tab. The terminal output should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;The dashboard is accessible here: http://localhost:50326/testresults
Port forwarding is started &lt;span class="k"&gt;for &lt;/span&gt;the dashboard, hit Ctrl+c &lt;span class="o"&gt;(&lt;/span&gt;or Cmd+c&lt;span class="o"&gt;)&lt;/span&gt; to stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Browsing the Dashboard
&lt;/h2&gt;

&lt;p&gt;Using your browser to access the URL provided, you should see the Skyramp Dashboard main page. If you're starting from scratch without any test runs, you will just see an empty page with no tests. Once you run some tests, you will see a list of tests like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BaJkG6Xz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h1au1ycz8gshxga7o7yk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BaJkG6Xz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h1au1ycz8gshxga7o7yk.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, this list shows the start and stop times of the tests along with the status of the results. The tests in the list above were run from the examples in the walkthrough &lt;a href="https://skyramp.dev./docs/get-started/walkthrough/"&gt;referenced earlier&lt;/a&gt;. One such test from the walkthrough that we are using is a test of the checkout system, which can be run with &lt;a href="https://www.skyramp.dev/docs/tester/"&gt;Tester&lt;/a&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp tester start checkout-test 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try it yourself!&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing Individual Test Results
&lt;/h2&gt;

&lt;p&gt;Once you have a list of tests in the dashboard, you can click on each test to view the details, including the specific test results for that run of the test. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1uq3mbvH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nnddxhpkmhy3xq75dtai.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1uq3mbvH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nnddxhpkmhy3xq75dtai.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, we are viewing the test results from a checkout test run that passed. You can expand the output to review the details. Here, our second assert that checks the quantity matched the output from the service and so there is no error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing Load Tests
&lt;/h2&gt;

&lt;p&gt;You can also use the Skyramp Dashboard to view load test results, which have their own characteristics. Here is the test output from a load test we ran, again using an example from the walkthrough:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8n6YVfp6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tc3h0o39w88gvlmv24c0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8n6YVfp6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tc3h0o39w88gvlmv24c0.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For load tests, the results will show stats such as: latency numbers, error rates, requests per second (RPS), and service utilization. The graphs above are autogenerated based on the metrics from the test run. &lt;/p&gt;

&lt;h2&gt;
  
  
  See your Active Mocks
&lt;/h2&gt;

&lt;p&gt;Finally, the Skyramp Dashboard also displays any active mocks that have been applied by &lt;a href="https://www.skyramp.dev/docs/mocker/"&gt;Mocker&lt;/a&gt; in the cluster. If you mocked the payment service from the walkthrough, as an example, you will see that mock in place as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xDxnpCtg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftwux6uc4uzpzcwudqio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xDxnpCtg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftwux6uc4uzpzcwudqio.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have multiple mocks applied, you will see a list of all your active mocks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stopping the Dashboard
&lt;/h2&gt;

&lt;p&gt;To stop the Skyramp Dashboard and clean up resources, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp dashboard down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dashboard will then terminate. You can always bring the dashboard back with &lt;code&gt;skyramp dashboard up&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Congratulations! You are now equipped with the knowledge to  use the Skyramp Dashboard on your Kubernetes cluster, making testing easier and saving you time. Whether it's tracking test results or managing active mocks, Skyramp Dashboard simplifies the process, making your development workflow smoother than ever.&lt;/p&gt;

&lt;p&gt;If you have any questions or run into any issues, refer to the official Skyramp Dashboard &lt;a href="https://skyramp.dev/docs/reference/dashboard/"&gt;documentation&lt;/a&gt; for further assistance. Happy testing!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>testing</category>
      <category>devops</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Skyramp Feature Highlight: Using Dynamic Python for Tests and Mocks</title>
      <dc:creator>Dan Gross</dc:creator>
      <pubDate>Tue, 03 Oct 2023 17:15:31 +0000</pubDate>
      <link>https://dev.to/dangross/skyramp-feature-highlight-using-dynamic-python-for-tests-and-mocks-foo</link>
      <guid>https://dev.to/dangross/skyramp-feature-highlight-using-dynamic-python-for-tests-and-mocks-foo</guid>
      <description>&lt;p&gt;Python developers, rejoice! &lt;a href="https://www.skyramp.dev"&gt;Skyramp&lt;/a&gt; now supports Python code for dynamically testing and mocking your distributed applications. Previously, Skyramp supported only JavaScript for dynamic requests and responses within test and mock description files. In this blog post, we'll walk you through Skyramp's new capability of employing dynamic Python code in requests and responses for testing and mocking microservices, right from a running Kubernetes cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unpacking Skyramp Tests
&lt;/h2&gt;

&lt;p&gt;Before diving into the step-by-step example, let's first lay the foundation by understanding what constitutes a Skyramp test. At the heart of every Skyramp test is a test description file. This file can either be auto-generated using &lt;code&gt;skyramp tester generate&lt;/code&gt; or created manually as a &lt;code&gt;.yaml&lt;/code&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's Inside a Test Description?
&lt;/h3&gt;

&lt;p&gt;Within a Skyramp test description file, you define the essential components of your test. This includes the scenarios for testing, the services to be tested, the requests you'll make to them, the expected responses in the form of asserts, and any custom logic or handlers to process these interactions. Let's dissect the important elements.&lt;/p&gt;

&lt;p&gt;Here's a simple scenario in a test description:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;scenarios&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scenario1&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;request1&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;asserts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;requests.request1.res.message == "abc"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The scenario above simply tests if the message returned from a service is equal to "abc". Below is an example request to support the scenario above. We can assume this hypothetical service takes an &lt;code&gt;id&lt;/code&gt; and returns a &lt;code&gt;message&lt;/code&gt;. Both of these YAML sections are contained within a Skyramp test description file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;request1&lt;/span&gt;
    &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;our-service&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GetMessage&lt;/span&gt;
    &lt;span class="na"&gt;requestValue&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;blob&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"id": "123"&lt;/span&gt;
        &lt;span class="s"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the block under &lt;code&gt;requestValue&lt;/code&gt;. It is configured as a static &lt;code&gt;blob&lt;/code&gt; in this example, but it can also be configured as dynamic code that the Skyramp Worker will execute during a test. The language used in a dynamic handler had been limited to JavaScript, but now you can use Python! Let's look at how.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Hands-on Example: Testing with Python Code
&lt;/h2&gt;

&lt;p&gt;To illustrate how Python can now be harnessed in Skyramp tests, let's embark on a simple journey you can follow yourself. We'll clone a sample project from a Skyramp-provided repo on GitHub, which conveniently contains microservices that can be swiftly deployed to a Kubernetes cluster, all primed and ready for testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Paving the Way with the Skyramp CLI
&lt;/h3&gt;

&lt;p&gt;First, make sure you have the Skyramp CLI installed. The Skyramp CLI enables the &lt;a href="https://www.skyramp.dev/docs/deployer/"&gt;Deployer&lt;/a&gt;, &lt;a href="https://www.skyramp.dev/docs/mocker/"&gt;Mocker&lt;/a&gt;, and &lt;a href="https://www.skyramp.dev/docs/tester/"&gt;Tester&lt;/a&gt; tools. You can follow &lt;a href="https://www.skyramp.dev/docs/get-started/install-client/"&gt;these easy steps&lt;/a&gt; from the Skyramp Docs for installation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloning the Project
&lt;/h3&gt;

&lt;p&gt;Start with cloning Skyramp's &lt;code&gt;letsramp/sample-microservices&lt;/code&gt; repo, which is a sample e-commerce system that includes a number of microservices. See the &lt;a href="https://github.com/letsramp/sample-microservices"&gt;GitHub repo Readme&lt;/a&gt; for additional information. The Skyramp repo is based on Google Cloud's &lt;a href="https://github.com/GoogleCloudPlatform/microservices-demo"&gt;Online Boutique&lt;/a&gt;, adding test demos and support for REST and Thrift APIs.&lt;/p&gt;

&lt;p&gt;From a terminal, you can execute this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/letsramp/sample-microservices.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Start your Cluster
&lt;/h3&gt;

&lt;p&gt;Now that the project is in place, you can navigate to the &lt;code&gt;grpc-demo&lt;/code&gt; directory in your terminal and bring up a local cluster for testing by executing these three commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;sample-microservices/skyramp/grpc-demo
skyramp cluster create &lt;span class="nt"&gt;--local&lt;/span&gt;
skyramp deployer up checkout-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Putting Python to the Test
&lt;/h3&gt;

&lt;p&gt;With the system-under-test up and running, let's edit one of the tests to show where we can insert Python code that will be run dynamically during testing. The &lt;code&gt;tests/checkout-test.yaml&lt;/code&gt; test description file contains a &lt;code&gt;requests&lt;/code&gt; section with a static blob. Edit the section under &lt;code&gt;requestValue&lt;/code&gt; for &lt;code&gt;request1&lt;/code&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;request1&lt;/span&gt;
    &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cart-service&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AddItem&lt;/span&gt;
    &lt;span class="na"&gt;requestValue&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;python&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;def handler():&lt;/span&gt;
          &lt;span class="s"&gt;uid = "abcde"&lt;/span&gt;
          &lt;span class="s"&gt;qty = 5 * 5&lt;/span&gt;
          &lt;span class="s"&gt;pid = "OLJCE"&lt;/span&gt;
          &lt;span class="s"&gt;pid += "SPC7Z"&lt;/span&gt;
          &lt;span class="s"&gt;request_value = {&lt;/span&gt;
            &lt;span class="s"&gt;"userId": uid,&lt;/span&gt;
            &lt;span class="s"&gt;"item": {&lt;/span&gt;
                &lt;span class="s"&gt;"productId": pid,&lt;/span&gt;
                &lt;span class="s"&gt;"quantity": qty&lt;/span&gt;
            &lt;span class="s"&gt;}&lt;/span&gt;
          &lt;span class="s"&gt;}&lt;/span&gt;
          &lt;span class="s"&gt;return SkyrampValue(value=request_value)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see we replaced the &lt;code&gt;blob&lt;/code&gt; attribute with &lt;code&gt;python&lt;/code&gt; and are now creating the request values in code. To learn more about the specific details of how you can use Python in test descriptions, visit the Skyramp Docs that cover &lt;a href="https://www.skyramp.dev/docs/tester/test-description/#python-dynamic-requests"&gt;Python Dynamic Requests&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You will notice that the &lt;code&gt;tests/checkout-test.yaml&lt;/code&gt; test description file has two requests. The first request, shown above as &lt;code&gt;request1&lt;/code&gt;, adds an item to the cart. The second request, &lt;code&gt;request2&lt;/code&gt;, places an order. We will leave the &lt;code&gt;requestValue&lt;/code&gt; in &lt;code&gt;request2&lt;/code&gt; as a static &lt;code&gt;blob&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For our test scenario under &lt;code&gt;scenarios&lt;/code&gt;, we first make a request to &lt;code&gt;request1&lt;/code&gt; and then make a request to &lt;code&gt;request2&lt;/code&gt;. The existing assert checks that the &lt;code&gt;productId&lt;/code&gt; matches the first item returned in the response from &lt;code&gt;request2&lt;/code&gt;. Let's also add an &lt;code&gt;asserts&lt;/code&gt; line in the same file  to check the &lt;code&gt;quantity&lt;/code&gt; value returned. This should match the &lt;code&gt;quantity&lt;/code&gt; we set in &lt;code&gt;request1&lt;/code&gt;. Notice the type is a &lt;code&gt;number&lt;/code&gt; and not a &lt;code&gt;string&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;scenarios&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scenario1&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;request1&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;request2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;asserts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;requests.request2.res.order.items[0].item.productId == "OLJCESPC7Z"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;asserts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;requests.request2.res.order.items[0].item.quantity == &lt;/span&gt;&lt;span class="m"&gt;25&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are almost ready to run our new test scenario with Python, but we are missing one final piece. We know our checkout depends on the payment service, but it is not running in our system-under-test. Luckily, we have a mock for that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Yes, Mocks Too!
&lt;/h3&gt;

&lt;p&gt;Not only is Python available for dynamic requests in the test description, but Python is also available for dynamic responses in the mock description.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;mocks/payment-service-k8s.yaml&lt;/code&gt; for editing, which is also under the &lt;code&gt;skyramp/grpc-demo&lt;/code&gt; folder in the &lt;code&gt;letsramp/sample-microservices&lt;/code&gt; repo.&lt;/p&gt;

&lt;p&gt;Change the section under &lt;code&gt;responseValues&lt;/code&gt; to include the &lt;code&gt;python&lt;/code&gt; attribute and the code shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;responseValues&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ChargeResponse&lt;/span&gt;
      &lt;span class="na"&gt;python&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;def handler(req):&lt;/span&gt;
          &lt;span class="s"&gt;key = "transaction_id"&lt;/span&gt;
          &lt;span class="s"&gt;value = "default-string"&lt;/span&gt;
          &lt;span class="s"&gt;return SkyrampValue(value={key: value})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we now return values from Python-generated variables instead of a static &lt;code&gt;blob&lt;/code&gt; as before. To learn more about the specific details of how you can use Python in mock descriptions, visit the Skyramp Docs that cover &lt;br&gt;
&lt;a href="https://www.skyramp.dev/docs/mocker/mock-description/#python-dynamic-response"&gt;Python Dynamic Responses&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Mocking and Testing with Skyramp
&lt;/h3&gt;

&lt;p&gt;With our new test description and mock description updated to include dynamic Python, we can proceed with our test session. Skyramp makes running tests a breeze.&lt;/p&gt;

&lt;p&gt;First, apply the mock that was updated with Python code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp mocker apply &lt;span class="nt"&gt;-n&lt;/span&gt; test-grpc-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see this output in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Applying mock config     &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="c"&gt;##############################################################] 100 %&lt;/span&gt;
Successfully applied mock configurations.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, run the test that was updated with Python code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skyramp tester start checkout-test &lt;span class="nt"&gt;-n&lt;/span&gt; test-grpc-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The test results should produce the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; - pattern0.scenario1.2.assert
    &lt;span class="o"&gt;[&lt;/span&gt;Status: finished] &lt;span class="o"&gt;[&lt;/span&gt;Started at: N/A]
    Assert: requests.request2.res.order.items[0].item.productId &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"OLJCESPC7Z"&lt;/span&gt;
    Passed: &lt;span class="nb"&gt;true&lt;/span&gt;
  - pattern0.scenario1.3.assert
    &lt;span class="o"&gt;[&lt;/span&gt;Status: finished] &lt;span class="o"&gt;[&lt;/span&gt;Started at: N/A]
    Assert: requests.request2.res.order.items[0].item.quantity &lt;span class="o"&gt;==&lt;/span&gt; 25
    Passed: &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice job, you did it! This was just a simple taste to show how to use Python for tests and mocks, but there is much more to explore. Additional capabilities include: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Utilizing the &lt;code&gt;req&lt;/code&gt; parameter for incoming requests (&lt;a href="https://www.skyramp.dev/docs/tester/test-description/#python-dynamic-requests"&gt;see docs&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Using the &lt;code&gt;pythonPath&lt;/code&gt; attribute for external source code files (&lt;a href="https://www.skyramp.dev/docs/tester/test-description/#python-dynamic-requests"&gt;see docs&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.skyramp.dev/docs/tester/test-description/#installing-npm-based-packages"&gt;Installing NPM-based packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.skyramp.dev/docs/tester/test-description/#chaining-and-overrides"&gt;Chaining and Overrides&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;That concludes our exploration of using Python code in Skyramp tests and mocks. Now Python developers can leverage their skills to create comprehensive and robust testing scenarios. We hope you've enjoyed this glimpse into using Python for dynamic requests and responses in testing distributed applications with Skyramp.&lt;/p&gt;

&lt;p&gt;Stay tuned for more updates and enhancements as Skyramp continues to evolve, enabling developers to optimize their testing processes like never before. Happy testing!&lt;/p&gt;

</description>
      <category>python</category>
      <category>testing</category>
      <category>kubernetes</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Test Your Microservices with Skyramp in IntelliJ IDEA</title>
      <dc:creator>Dan Gross</dc:creator>
      <pubDate>Fri, 08 Sep 2023 19:42:10 +0000</pubDate>
      <link>https://dev.to/dangross/testing-microservices-with-skyramp-in-intellij-idea-2a2k</link>
      <guid>https://dev.to/dangross/testing-microservices-with-skyramp-in-intellij-idea-2a2k</guid>
      <description>&lt;p&gt;Hello devs! This is Dan from &lt;a href="https://www.skyramp.dev"&gt;Skyramp&lt;/a&gt;. When we say Skyramp meets devs in any workflow, we mean it. In this blog, we will demonstrate iterative testing and development for microservices in a local Kubernetes cluster performed directly from the IntelliJ IDEA with Skyramp. It’s as easy as 1, 2, 3.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are We Testing?
&lt;/h2&gt;

&lt;p&gt;This blog features the &lt;a href="https://github.com/letsramp/sample-microservices"&gt;Skyramp fork&lt;/a&gt; of Google’s popular cloud-native microservices demo app, &lt;a href="https://github.com/GoogleCloudPlatform/microservices-demo"&gt;Online Boutique&lt;/a&gt;. Online Boutique is a web-based e-commerce app containing microservices that mimic real-world services, such as a product catalog, shopping cart, ad service, recommendation service, payment service, and others. The services use gRPC APIs by default, but Skyramp has also added support for REST and Thrift APIs.&lt;/p&gt;

&lt;p&gt;This walkthrough will focus on the ad service component of the system to demonstrate how you can easily generate test descriptions and run tests during the development stage using Skyramp. The ad service is a microservice written in Java, so &lt;a href="https://www.jetbrains.com/idea/"&gt;IntelliJ IDEA&lt;/a&gt; is a perfect fit for our development environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-Flight Checklist
&lt;/h2&gt;

&lt;p&gt;Here’s what you need in order to follow along with this walkthrough:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install &lt;a href="https://www.docker.com/get-started/"&gt;Docker&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install the &lt;a href="https://www.skyramp.dev/docs/get-started/install-client/"&gt;Skyramp Terminal Client&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install &lt;a href="https://www.jetbrains.com/idea/"&gt;JetBrains IntelliJ IDEA&lt;/a&gt; and &lt;a href="https://www.jetbrains.com/idea/guide/tips/download-jdk/"&gt;download a JDK&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Clone the Skyramp project, &lt;code&gt;sample-microservices&lt;/code&gt;, to a folder of your choice. From a terminal, run:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/letsramp/sample-microservices.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Let’s Get Testing
&lt;/h2&gt;

&lt;p&gt;First, start the IntelliJ IDEA you installed and open the Skyramp &lt;code&gt;sample-microservices&lt;/code&gt; project from the local folder where it was cloned. Navigate to the &lt;code&gt;src/adservice/src/main/java/hipstershop&lt;/code&gt; folder and open the &lt;code&gt;AdService.java&lt;/code&gt; file to view the ad service source code.&lt;/p&gt;

&lt;p&gt;Next, open the Terminal pane in the IDE by clicking the Terminal button in the lower left corner. You can run all the skyramp commands from this Terminal. Change to the Skyramp demo directory for gRPC in the terminal and check your installed version of skyramp:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd skyramp/grpc-demo
skyramp version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, you should see something like this:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4yJcpsQX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kborfnfdbjix0jqwk0d0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4yJcpsQX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kborfnfdbjix0jqwk0d0.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;br&gt;
Next, we will create a local Kubernetes cluster for deploying and testing the microservices. This is easily done with the Skyramp client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;skyramp cluster create --local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ftgSadGw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/92k17qirh7wrstd54poj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ftgSadGw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/92k17qirh7wrstd54poj.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;br&gt;
Deploy all the services to the cluster that will make up our system under test using &lt;a href="https://www.skyramp.dev/docs/deployer"&gt;Skyramp Deployer&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;skyramp deployer up grpc-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the services are deployed, you can check the status of the services, also with Skyramp Deployer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;skyramp deployer status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H4CHEcgg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y0pn1nm7d5yp7roas74c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H4CHEcgg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y0pn1nm7d5yp7roas74c.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;br&gt;
Now we will generate a test description for the ad service using &lt;a href="https://www.skyramp.dev/docs/tester/"&gt;Skyramp Tester&lt;/a&gt;. This will allow us to execute tests against the running service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;skyramp tester generate --protocol protobuf \
--api-schema pb/demo.proto --alias ad-service \
--port 9555 --proto-service AdService
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How do you know what values to provide to Skyramp Tester in order to generate a test description? In this case, we know we will be using &lt;code&gt;protobuf&lt;/code&gt; as the &lt;code&gt;protocol&lt;/code&gt; for our distributed application. We already have a proto file defined in the repo at &lt;code&gt;pb/demo.proto&lt;/code&gt;, so we can utilize that for the &lt;code&gt;api-schema&lt;/code&gt; flag. The &lt;code&gt;AdService&lt;/code&gt; is specified in the proto file, which is the service we want to test, so that should be used for the &lt;code&gt;proto-service&lt;/code&gt; flag. The values for the &lt;code&gt;alias&lt;/code&gt; and &lt;code&gt;port&lt;/code&gt; flags are derived from the deployment status as seen in the screenshot above.&lt;/p&gt;

&lt;p&gt;Once you run the Skyramp Tester command above, the generated test description file will be under the &lt;code&gt;tests&lt;/code&gt; folder called &lt;code&gt;ad-service.yaml&lt;/code&gt;. Next, we simply need to define our specific scenario for testing.&lt;/p&gt;

&lt;p&gt;The ad service behavior we want to test is whether the service returns exactly two ads from its response payload, and if those ads are non-zero length. Furthermore, we want to test that the two ads are not the same, because we do not want duplicate ads returned. We can define all of this by adding a &lt;code&gt;scenarios&lt;/code&gt; section with &lt;code&gt;asserts&lt;/code&gt; in the file as seen below:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PEV9vqOy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sgw08r8qxfyuk6sx4ppk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PEV9vqOy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sgw08r8qxfyuk6sx4ppk.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;br&gt;
Here is the &lt;code&gt;scenario&lt;/code&gt; section with the &lt;code&gt;asserts&lt;/code&gt; to add to the YAML file if you would like to copy and paste:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;scenarios&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scenario1&lt;/span&gt;
   &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;EAdServiceMGetAds&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;asserts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;requests.EAdServiceMGetAds.res.ads.length == &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;asserts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;requests.EAdServiceMGetAds.res.ads[0].text.length &amp;gt;= &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;asserts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;requests.EAdServiceMGetAds.res.ads[1].text.length &amp;gt;= &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;asserts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;requests.EAdServiceMGetAds.res.ads[0].text != requests.EAdServiceMGetAds.res.ads[1].text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now save the file. Running the test is easy with Skyramp Tester. From the same &lt;code&gt;skyramp/grpc-demo&lt;/code&gt; directory, just execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;skyramp tester start ad-service -n test-grpc-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1J6nXSvY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6myprsfaxd51uhefqziq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1J6nXSvY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6myprsfaxd51uhefqziq.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;br&gt;
Notice from the test results that the first three asserts passed, but the last assert failed. We appear to be getting duplicate ads from our ad service. A side note: this failed test may take several tries to surface, since the ads returned are randomized and may not always be the same. &lt;/p&gt;

&lt;p&gt;If we navigate back to the source file and examine the code, we see that &lt;code&gt;getRandomAds()&lt;/code&gt; does not account for duplicates.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PKPoF9lv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z98n2n5tz69jlejuc5ru.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PKPoF9lv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z98n2n5tz69jlejuc5ru.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;br&gt;
We can fix that with a &lt;code&gt;LinkedHashSet&lt;/code&gt; to force uniqueness. Here is the new &lt;code&gt;getRandomAds()&lt;/code&gt; source with a few lines changed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Ad&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getRandomAds&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Ad&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="no"&gt;MAX_ADS_TO_SERVE&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nc"&gt;Collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Ad&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;allAds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;adsMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Ad&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LinkedHashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Ad&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;MAX_ADS_TO_SERVE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Iterables&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;allAds&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;allAds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;())));&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;ads&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ads&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We update the code in the editor and then rebuild the ad service from &lt;code&gt;src/adservice&lt;/code&gt; in a new terminal pane by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd src/adservice
./gradlew installDist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B4CBuTvN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j048ui8d4j2t6tkd65t6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B4CBuTvN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j048ui8d4j2t6tkd65t6.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;br&gt;
Once the ad service is rebuilt, simply bring all the services down and back up again with Skyramp Deployer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;skyramp deployer down grpc-app
skyramp deployer up grpc-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when you re-run the test with Skyramp Tester, all asserts will pass because the ad service no longer produces duplicate ads in the payload.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;skyramp tester start ad-service -n test-grpc-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OCVHVzT2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/74tejnf9ua3qpjr33e7n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OCVHVzT2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/74tejnf9ua3qpjr33e7n.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;br&gt;
Once you are finished with your test session, you can remove the test cluster completely with Skyramp:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;skyramp deployer down grpc-app 
skyramp cluster remove --local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;And there you have it. You can use this setup to explore more capabilities Skyramp provides with &lt;a href="https://www.skyramp.dev/docs/mocker"&gt;Mocker&lt;/a&gt;, &lt;a href="https://www.skyramp.dev/docs/tester"&gt;Tester&lt;/a&gt;, and &lt;a href="https://www.skyramp.dev/docs/deployer"&gt;Deployer&lt;/a&gt;. We give you all the tools you need to mock, test, and deploy your own microservices from IntelliJ IDEA easily with Skyramp.&lt;/p&gt;

&lt;p&gt;Happy testing!&lt;/p&gt;

&lt;p&gt;Have questions or comments? &lt;a href="https://discord.com/invite/qBnEZM6JTb"&gt;Join the Skyramp Community Discord&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Debugging FreeRTOS with QEMU in VSCode</title>
      <dc:creator>Dan Gross</dc:creator>
      <pubDate>Wed, 15 Feb 2023 23:06:15 +0000</pubDate>
      <link>https://dev.to/iotbuilders/debugging-freertos-with-qemu-in-vscode-4j52</link>
      <guid>https://dev.to/iotbuilders/debugging-freertos-with-qemu-in-vscode-4j52</guid>
      <description>&lt;p&gt;In this post, I will step through an example setup that shows how to debug a &lt;a href="https://freertos.org" rel="noopener noreferrer"&gt;FreeRTOS&lt;/a&gt; application in the Visual Studio Code (VSCode) editor using &lt;a href="https://www.qemu.org/" rel="noopener noreferrer"&gt;QEMU&lt;/a&gt; to emulate an Arm Cortex-M3 microcontroller. No actual hardware is required for this example, except a laptop or desktop as your development environment.&lt;/p&gt;

&lt;p&gt;First off, what is QEMU and why would we want to debug with it? QEMU is a machine emulator that allows you to virtualize hardware types, even across different architectures. This can be very helpful for embedded development because you can run applications against hardware targets that you may not have immediate access to. This might be because (a) you are still in the process of selecting a chipset for an embedded product design, (b) your boards are somewhere else like a lab, (c) you want to run automated tests without physical hardware, or (d) the real hardware is simply in short supply. If you recognize any of these constraints, and the software development must go on, then QEMU can help.&lt;/p&gt;

&lt;p&gt;QEMU supports many different hardware platforms, from x86 to ARM to RISC-V. FreeRTOS also supports many different hardware platforms. So, it is worth pointing out that the example I will cover below is not limited to just this hardware platform for FreeRTOS. You can adapt the same methods if you have a target other than the Arm Cortex-M3.&lt;/p&gt;

&lt;p&gt;With those considerations, how do we begin? There are a number of prerequisites and dependencies in order to get up and running with the example. I have laid these out in 7 steps below, which you can follow. The order is not that important except the last step should stay the last step. You may have some or all of these tools installed on your development machine already, so just double-check that they are up-to-date and present in your path if that is the case.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download and install VSCode &lt;a href="https://code.visualstudio.com/download" rel="noopener noreferrer"&gt;from here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download and install QEMU &lt;a href="https://www.qemu.org/download/" rel="noopener noreferrer"&gt;from here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download and install the Arm GNU Toolchain &lt;a href="https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain" rel="noopener noreferrer"&gt;from here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download and install CMake &lt;a href="https://cmake.org/download/" rel="noopener noreferrer"&gt;from here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For Windows, download and install Git (includes Bash terminal) &lt;a href="https://git-scm.com/downloads" rel="noopener noreferrer"&gt;from here&lt;/a&gt;. Git should already be installed on MacOS and Linux.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make sure 'make' is installed on your system. There are different ways to do this depending on your platform. &lt;/p&gt;

&lt;p&gt;a. On Windows, you can install 'make' using &lt;a href="https://chocolatey.org/" rel="noopener noreferrer"&gt;Chocolatey&lt;/a&gt; at the Command Prompt with this command: &lt;code&gt;&amp;gt; choco install make&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;b. On MacOS, you can install 'make' using &lt;a href="https://brew.sh/" rel="noopener noreferrer"&gt;Homebrew&lt;/a&gt; in the Terminal app with this command &lt;code&gt;$ brew install make&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;c. On Linux, you can install 'make' using the package manager from a terminal with this command: &lt;code&gt;$ sudo apt install build-essential&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the QEMU, Arm GNU Compiler, CMake, and 'make' installation paths to your PATH environment variable. OSes and environments have different ways to do this, so use the appropriate method for your system. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you have the prerequisite tools installed, proceed by cloning the source code we will be working with. From the command line, navigate to a folder where you would like to clone the &lt;a href="https://github.com/FreeRTOS/FreeRTOS" rel="noopener noreferrer"&gt;FreeRTOS repository with the demo code&lt;/a&gt;, such as &lt;code&gt;$ cd $HOME/Projects&lt;/code&gt; as an example. Then, go ahead and clone the FreeRTOS repository from GitHub like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git clone https://github.com/FreeRTOS/FreeRTOS.git --recurse-submodules&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
When cloning the repo has finished, launch VSCode. In VSCode, select 'File &amp;gt; Open Folder' in the menu. Navigate to the FreeRTOS repository you just cloned and select this subfolder: '.../FreeRTOS/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC'&lt;/p&gt;

&lt;p&gt;After VScode loads the demo folder, open '.vscode/launch.json' in the editor. Find the &lt;code&gt;miDebuggerPath&lt;/code&gt; parameter and change the value to the path where 'arm-none-eabi-gdb' is located on your machine.&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%2Foy3e4unot3kpgqrnkbm6.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%2Foy3e4unot3kpgqrnkbm6.jpg" alt="Screenshot" width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now open 'main.c' and make sure that &lt;code&gt;mainCREATE_SIMPLE_BLINKY_DEMO_ONLY&lt;/code&gt; is set to &lt;code&gt;1&lt;/code&gt;. This will generate only the simple blinky demo.&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%2Fiqj2hhy4ymzf9xjlnm9z.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%2Fiqj2hhy4ymzf9xjlnm9z.jpg" alt="Screenshot" width="739" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, press the 'Run and Debug' button from the left side panel in VSCode. Select 'Launch QEMU RTOSDemo' from the dropdown at the top and press the 'play' button. This will build the code, run the program, and attach the debugger.&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%2Fapbo7u7amw0xfyr2zh0u.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%2Fapbo7u7amw0xfyr2zh0u.jpg" alt="Screenshot" width="444" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From there, you can 'Continue', 'Step Over', 'Step Into', 'Step Out', and 'Stop' from the button bar. You can also add breakpoints in the code by right clicking next to the line number.&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%2Fnfip3trd52awe94wb4z7.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%2Fnfip3trd52awe94wb4z7.jpg" alt="Screenshot" width="645" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pressing the 'Continue' button will execute the code, which will produce output like this in the Terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;QEMU RTOSdemo started
Message received from task
Message received from task
Message received from task
Message received from task
Message received from task
Message received from task
Message received from task
Message received from task
Message received from task
Message received from software timer
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there you have it, debugging FreeRTOS with QEMU in VSCode.  You can use this example to play around and explore what is possible. Happy debugging!&lt;/p&gt;

</description>
      <category>motivation</category>
      <category>challenge</category>
    </item>
  </channel>
</rss>
