News & Events

Architecture testing for performance

Architecture testing for performance - how to guarantee a highly efficient system?

Architecture testing can be a daunting task – especially for devs who aren’t in the habit of testing architecture from the very beginning and continuing to do so as their deadline approaches. We’re here to tell you that it’s really worth the effort and save you a ton of time and tears in your next project!

When you’ve worked as a Quality Assurance Expert for a while, you might believe to yourself, “OK, I’m very good at it!” Nothing can surprise me anymore because I have the requisite skill set and a lot of experience.” Then you’re requested to do some architecture testing.

It was like my worst nightmare come true for a QA like myself who specialised in manual testing. My first assumption was that it was some sort of retaliation for continually attempting to persuade everyone that quality assurance should be a part of every project from the start.

With a little support from my coworker, I was able to run architecture tests, learn new skills, and even have a little fun while doing it. We’ll tell you about the project, which was both a challenge and an architecture testing learning experience, with the help of Bartek, our PHP developer who was also on the team.

You’ll see both of our unique points of view as well as a conclusion we got to. I hope you appreciate it and that you will apply what you’ve learned to make your own architecture testing voyage more enjoyable.

Why is it necessary to test the architecture? Here are six primary reasons:

To begin, keep in mind that strong and smart architecture is the first step toward developing amazing software. In a nutshell, architecture specifies the software components and their interdependencies. It describes the working environment and provides a path for creating and developing the programme you desire.

  • System extensibility
  • System flexibility
  • System performance
  • System reusability 
  • Readability and understandability of the code
  • System testability

As you probably know, you create descriptions, UML diagrams, prototypes, and use cases while developing an architecture concept.

ALL of these things can be put to the test. There are many different sorts of architecture tests, but the most important one for our project was performance testing.

In practise, how does architectural testing look?

It’s the same as if you were taking an application test! You can develop tests based on the documentation you have (I mean all materials created during the “architecture phase”) to specify both the initial and final conditions for the process.

If this isn’t achievable, consider it a first indication that the architecture isn’t as cohesive as you’d like it to be. It’s safe to assume that if you can’t test the architecture, you won’t be able to test the solution once it’s been delivered. Although test scenarios are often simple, they might act as a catalyst for uncovering business difficulties and scenarios that aren’t addressed by the design.

To tell you the truth, I noticed that testing architecture isn’t that dissimilar from previous projects. But when I first got told that I was about to test a tool that will be used by programmers to configure other systems, I was worried that I wouldn’t be able to do it.

Let us begin with some background information about the project.

Before starting to talk about architecture tests, we should start with some basic information on how this system works. The client wanted to have a highly available and reliable data bus. The data bus’s main job is propagating messages between systems. 

Producers can send the messages to the data bus without knowing who the receiver is. The data bus accepts them and propagates them to previously defined receivers based on settings and configuration.  Take a look at the diagram below for a better perspective:

This is, of course, a simplified main flow. The entire system is more difficult because many secondary characteristics are dependent on the data bus’s setup or message structure. The main premise, however, is sufficient to comprehend how we went about building the solution and performing architecture testing.

Non-functional requirements

The client has outlined the most essential non-functional criteria prior to the start of the data bus implementation. They had a significant influence on the proposed solution we devised.

  • The initial requirement was that the entire project be written in PHP and the Symfony framework. The key reason for this was that the client was the one who had the greatest familiarity with these technologies. It is easier to maintain projects built with technology we are familiar with – this is something we try to remember at all times.
  • The second requirement was strictly related to the data bus performance. It needed to accept no less than 1000 messages per second for 20 minutes – that’s at least 1,200,000 messages! We also received the specifications of the server on which the project would ultimately be launched. That requirement is what we decided to focus the most on in the beginning. 

Furthermore, cloud-based options were ruled out. Simple solutions were required by the client. The data bus had to be simple to install on any Linux server.

First step – proof of concept!

We began the project by implementing the data bus’s most basic use case: message reception. Error handling and data bus configuration were not included in the design. The only thing we wanted to do was see if the efficiency goal could be met on this particular system. So we spent the first few weeks proving the notion.

We chose a few auxiliary technologies for the project from the beginning. For storing messages, we went with a relational database. The key reason for this was the data’s long-term viability. We couldn’t afford to have any messages go unnoticed.

That cannot be guaranteed by a NoSQL method, which is thought to be faster for single write and read operations. These databases first store data in a RAM buffer before writing it to disc on a regular basis. We couldn’t ensure that an already received message would be saved in the event of a power loss, thus PostgreSQL was our first choice.

REST API is used to communicate between producers and the data bus. As previously stated, the data bus must accept a large number of messages each second. As a result, we had to ensure that the request was handled as quickly as possible and that the communication was not lost. The rest of the work, such as sending messages to recipients, can be done asynchronously.

Proof of concept completed – time for some architecture tests

It’s time to think about testing our data bus now that the first version is complete. After all, that’s why we made it in the first place!

In a nutshell, it enables you to generate virtual users who make HTTP requests for modelling purposes using a simple JavaScript script. And this is precisely what we were after.

We performed few tests:

  • Endurance testing –That was our primary goal. When testing the application’s behavior over a lengthy period of time with an expected load, endurance testing can be used.
  • Stress testing –This is used to test our application’s major breaking points. It answers the question of how large a load may be before our system becomes ineffective.
  • Load testing – with the purpose of identifying bottlenecks in our architecture and application When we load test our systems, we keep an eye on the architecture components.

We wanted to see what the data bus’s maximum load capacity was at first. As a result, we created a simple K6 script that randomly selects a message from the prepared pool and sends it to the data bus. It’s also worth noting that our initial tests were conducted on a machine that was roughly four times as bad as the intended environment.

You might wonder why. I believe that developing your architecture on a less powerful system is a viable option. Because you have fewer computer resources, it helps you uncover more items that are lowering performance.

Conclusion

We fulfilled our objective and met the client’s performance requirements. As you can see, there are numerous approaches to boost your application’s performance:

  1. Profiler can be used to find any bottlenecks in your application.
  2. Check the libraries and packages you’ve included in your project. Make certain you’ll require all of them.
  3. Examine your architecture and components. Perhaps there are more effective alternatives.
  4. Examine the links between your application’s components.
  5. Perform performance tests on a regular basis. A seemingly insignificant modification in your code can sometimes have a significant impact on performance.