May 26, 2022 / by Zsolt Soczó

Optimizing a build pipeline

The topic of this blog entry is not a traditional code optimization where I make .NET code faster or tune SQL Server queries. This one is about making the Continuous Integration Build pipeline faster.

Last week I worked on the performance of a Continuous Integration Build for a company. They use an on-premise DevOps server. There are more than a thousand integration tests we wanted to run in less than an hour. For deterministic tests, I introduced SQL Server snapshot technology to revert the database before each test. However, it takes 5-10 seconds to restore the database. The actual restore is fast, but killing open connections before restoring needs 5-10 seconds.

To speed up the tests, we needed a parallel test runner pipeline. We needed four databases because these are integration tests that use databases heavily. Besides, we had to manage that the tests connect to the appropriate databases.

(Check the next article on how I shrank the databases to half).

The key idea for parallel test running is using multiple jobs in the DevOps server. You cannot run tasks parallel in one job, but you can run multiple jobs simultaneously.

The first job builds the source and copies the compiled assemblies and other relevant data to a temporary location. Then the Publish Build Artifacts task copies it to a new location.

Four more tasks wait to complete the build task. Then they start running parallel. Each uses the Download Build Artifacts task to get the test files from the build step. Each of them must use a separate location for the downloaded files. Why? We had to patch the config files, rewrite the connection strings, and snapshot location data, so the test runners in the jobs could use the appropriate databases.

A small PowerShell script handled the config string replacement. Using a single location for all jobs would trump the data of each other because I replaced strings in all configs in the test directory.

Overall, using 4 test jobs, I decreased the test run duration from 3.5 hours to 1 hour. This way, the team has faster feedback about the potential bugs after a commit.

Here are two pictures of the edit view and the pipeline run.

Edit view of the pipeline
Pipeline after a successful run

LEAVE A COMMENT

Your email address will not be published.

1 COMMENTS