Posts

  • Integration tests with Docker Compose and Azure Service Containers

    In a previous blog post, I demonstrated how to implement integration tests in a .NET application using Testcontainers.

    If you prefer not to manage Docker containers within the test code, it is advisable to start and stop the containers independently of the test execution. Docker Compose and the Azure DevOps feature Service Containers are good alternatives for this.

    Read more
  • Integration tests in .NET with Testcontainers

    In software development, it is essential to sufficiently test the written code. In addition to Unit Tests, which individually test single components, integration tests examine the interaction between multiple components. However, when there are external dependencies such as a database or a message broker, testing becomes more complex.

    To ensure that external systems are reproducibly and predictably available in integration tests, they can be run in Docker containers. A simple setup of such service containers is enabled by the library Testcontainers.

    Read more
  • Lightweight Architecture Documentation with ADRs

    When a software application reaches a certain size, documentation of the individual components and their interactions makes sense. Recording architectural decisions is also important to be able to understand why a particular solution was chosen even months or years later. Future colleagues and your future self will thank you for it.

    A lightweight method for documenting architectural decisions is through Architectural Decision Records, ADRs.

    Read more
  • Architecture Refactoring with ArchUnitNET

    Besides the functional requirements of a software product, which can be ensured through unit and integration tests, there are also a number of non-functional requirements. Aspects of security or the performance of an application can be covered by end-to-end tests. To ensure the maintainability and extensibility of software, in addition to static code analysis, automated architecture tests can be used. These tests can verify dependencies between components or the adherence to naming conventions.

    Even when refactoring existing code, such architecture tests can prove to be meaningful.

    With ArchUnitNET, architecture rules can be defined as code and tested automatically.

    Read more
  • Uptime Kuma in Azure Web App for Containers

    Uptime Kuma is a self-hosted monitoring system that allows you to monitor the availability of various services. It offers a variety of monitoring types, including those for different types of HTTP endpoints such as websites or REST APIs.

    As it is also available as a ready-made Docker image, you can easily deploy it as an Azure App Service. For rolling it out using Terraform, a simple configuration is sufficient.

    Read more
  • Refactor to Purity

    Pure Functions are program methods that can be executed without causing side effects. In functional programming, they are more of a rule than an exception. However, in most object-oriented languages, you encounter them less often, or at least they are not frequently considered the preferred approach. In the dotnet environment, much emphasis is placed on Dependency Injection and more or less extensive abstractions using interfaces.

    The following article will demonstrate how to transition from a codebase with many such indirections to a simpler version that removes a lot of unnecessary complexity.

    Read more
  • Simple test setup with dummy factories

    Meaningful software verification involves comprehensive testing. A recurring task is writing source code that generates or describes test data. Depending on the volume of data, this can be tedious and slow down the development process, and in the worst case, lead to the complete omission of testing. An elegant way to generate test data easily and quickly is by using dummy factories.

    Read more
  • Docker Scale-to-Zero with Traefik and Sablier

    When operating web applications or services that are only used sporadically, it can be useful to start them only when there is a specific need. In the context of Docker containers and Kubernetes, the concept of “Scale-to-Zero” exists for such use cases, which means scaling down workloads to zero.

    For HTTP services in conjunction with a reverse proxy, Sablier offers a simple way to implement Scale-to-Zero in your own infrastructure.

    Read more
  • Automating DNS with DNSControl

    Configuration of DNS zones is a necessary part of most (web) software projects. Whether during the initial setup or over time, domains need to be registered, and DNS records need to be set up or adjusted. While this can often be done manually through the web interface of the corresponding provider, it’s error-prone, hard to track, and not easy to automate.

    If you use Infrastructure-as-Code (IaC) tools like Terraform for provisioning your cloud infrastructure, you can also manage DNS configuration through it. However, this approach often restricts you to the major hyperscale cloud providers for DNS services.

    DNSControl provides a simpler and less configuration-intensive way to define DNS configuration for dozens of large and small providers using JavaScript code. This allows you to set up and manage your DNS environment in an automated and reproducible manner. The configuration is versioned in a Git repository and can undergo code reviews, seamlessly integrating the process into the DevOps toolchain.

    Read more
  • Property-based testing in C# with FsCheck

    As part of the toolkit for software development, writing (meaningful) automated tests is essential. Through unit, integration, and end-to-end tests, the proper functionality of our code is ensured, and we gain confidence that when implementing new requirements and refactoring existing code, we won’t break any existing functionality. Michael Feathers even defines legacy software as code that lacks tests.

    legacy code is code without tests

    Michael Feathers

    In addition to common approaches like example-based testing or snapshot testing, there are other methods that help us verify the correctness of our code. One of these approaches is property-based testing.

    Property-based testing doesn’t check individual values for equality; rather, it aims to verify properties that our implementation must exhibit. For example, in mathematical addition, commutativity is a property that we can check without looking at specific numbers. For the addition of two numbers a and b, the commutative property always holds:

    a + b = b + a
    
    Read more
  • Devcontainer with Visual Studio Code

    For running applications, especially in the cloud environment, the use of containers has become established. With the advent of Docker, it became easy to execute software in a defined environment that can be easily reproduced. All runtime dependencies are packaged into a container image and can be run on a different system effortlessly. The disparity between different stages in the development process (Development, Testing, Production) is reduced, and “works on my machine” is no longer a valid excuse.

    To make not only the runtime but also the development environment reproducible and portable, Development Containers are a suitable solution.

    Read more
  • Static code analysis for terraform

    Static code analysis is a crucial component of quality assurance for software projects. It allows errors to be detected early in a short feedback loop and addressed promptly. Source code is examined against defined rules to identify errors and potential vulnerabilities, and depending on the tool used, possible solutions are often suggested.

    With the emergence of “Infrastructure as Code” approaches, infrastructure descriptions are increasingly being stored in the form of code or at least structured text files. This enables the advantages of static code analysis to be applied to infrastructure definitions as well.

    Read more
  • AKS Kubernetes Update

    Kubernetes is the de facto standard for container orchestration. If you don’t want to manage the operations yourself, you can opt for a managed solution like Microsoft’s Azure Kubernetes Service (AKS). With AKS, many operational aspects are handled for you. Even the updates to newer Kubernetes version can be entirely managed by Azure. You can learn how to configure auto-upgrades in AKS from this article.

    However, if you want to determine the version and timing of a cluster upgrade yourself, you can achieve this using the Azure CLI or even better, through Terraform. Of course, this assumes that you have provisioned your Kubernetes infrastructure using Terraform.

    Read more
  • Mailgraph Docker Container

    Postfix is probably still one of the most widely used free SMTP servers. For those who self-host an email server and want to keep track of the volume of incoming and outgoing emails, they quickly come across the tool Mailgraph by David Schweikert. Mailgraph consists of a Perl script that analyzes the log files of Postfix, populates an RRDtool database, and a CGI script that presents the data in the form of graphics in a clear manner in the browser.

    Read more