Catch the Absence of Change

The early-warning mechanisms that we’ve discussed so far help us detect deviating patterns in the evolution of a codebase. But problems may also be introduced by the absence of a change. For example, one microservice may produce a new event but the expected receiver doesn’t implement code to handle it, or maybe we forget to add proper error handling in a higher layer as we let a lower layer raise a new type of exception.

Most examples of bugs by omission can be caught by proper tests, a decent type system, or a static analysis tool. However, those safety nets aren’t able to cope with surprises of the kind we dealt with in Chapter 3, Coupling in Time: A Heuristic for the Concept of Surprise. Copy-paste code where we forgot to update one of the clones? Too bad; the compiler won’t help, and chances are slim that we remember to test for our omission.

To prevent these situations we use change coupling to our advantage. The technique won’t deliver a complete guarantee of correctness, but it does help catch omissions. Let’s demonstrate how.

If you did the exercises in Chapter 3, Coupling in Time: A Heuristic for the Concept of Surprise, you’ve already come across the Roslyn codebase.[127] Roslyn is a compiler platform that also implements the C# and Visual Basic compilers. Since both compilers are bootstrapped, Roslyn contains an equal amount of Visual Basic and C# code, as shown in the next figure.[128]

images/ci/roslyn-spots.png

A corresponding change coupling analysis shows that there are strong logical dependencies across the language boundaries.[129] For example, the Visual Basic code in the file VisualBasicEESymbolProvider.vb changes together with the C# code in the CSharpEESymbolProvider.cs file in 100 percent of commits. This change coupling in Roslyn looks deliberate, and it’s likely to be a design goal to maintain a similar structure in the two compilers. This means we can use our knowledge of such expected change patterns to verify the principle.

We do that by performing a change coupling analysis as part of a continuous integration pipeline, and then verify each commit against that baseline. Ideally, that check is implemented as a Git precommit hook, which means Git fires off a script that you provide.[130] Here’s what’s needed in that script:

  1. Fetch the results of the last change coupling analysis and ignore everything below a (configurable) threshold, like 80 percent change coupling. The purpose of the threshold is again to avoid false positives.
  2. Check each modified file in the pending commit against the last change coupling results, and look for omissions where an expected change coupling is absent from the pending commits set.
  3. Inform the user and give her or him the option to cancel the commit. In a precommit hook, aborting a commit is as simple as returning a nonzero status from your script.
  4. If all expected change couplings are present, the script runs to completion and reports success, and the developer doing the commit won’t notice.

So if we have this mechanism in place and we make a mistake, we get a dialog like in the following session:

 adam$ ​​git​​ ​​status
 On branch develop
 Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
 
  modified: CSharpEESymbolProvider.cs
 
 adam$ ​​git​​ ​​commit​​ ​​-m​​ ​​"PR #123: Correct error handling for missing symbols"
 Pre-Commit Warning
 ==================
 Previous modifications of CSharpEESymbolProvider.cs also
 required a change to VisualBasicEESymbolProvider.vb
 
 Are you sure you want to continue? (yes/no)

The final lines of output are examples from a precommit script. It’s important to give the developer the choice to ignore the warning; otherwise we won’t be able to refactor and break unwanted change coupling. That choice also has the nice side effect of being a self-learning algorithm; if we keep ignoring the warning, it will result in a lower change coupling over time, and eventually the coupling will go below the threshold and the warning will disappear.

This usage of change coupling concludes the technical analyses in this book. Used wisely, this technique fills the role of a Minority Report pre-cog, but for software (albeit with fewer car chases than the movie). Also note that you could apply the same early-warning technique on any level, such as between logical components, separate microservices, or on the level of functions. With that covered, we move on to take a quick glance at some proactive usages of social analyses.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.175.7