Conf42 Golang 2021 - Online

Using Arch-Go to continuously test the quality of our architecture

Video size:

Abstract

In every product, we start by defining architectural guidelines and code conventions, but the hard part is to check if the code adheres to these definitions over the time. Arch-Go is a testing tool that can be included as part of the CI pipeline to continuously verify our architectural guidelines.

Most authors defines software architecture as a set of important decisions which are hard to change. If we are working in a software artifact, then these decisions are represented as architectural guideline, because of that it’s very common to talk about some unwritten rules like “Don’t call repository components from components in the presentation packages”, or “prefer the use of structs over too many parameters or return values in functions/methods”. We can check this kind of rules as part of a code review process, but as this is manual, is errors-prone, then is possible to pass this quality-gate and push code into our master branch that breaks our guidelines, so we need a way to automatically check if our code adheres to these rules.

This talk is about Arch-Go, a testing tool which provides a simple way to document the architectural guidelines and checks if our Go code complies with those rules as part of a continuous integration pipeline. We will review why we need to check architecture quality and how Arch-Go can help us to automate it.

Summary

  • Archgo is a very simple testing tool strongly inspired in Arc unit, a testing framework for Java language. Francisco defines will talk about Archgo and how we can use it to continuously test the quality of our architectures.
  • Architectural guidelines are important decisions that we take along the development of a product or a project. If you are thinking in publishing your architectural guidelines in systems like confluence or an internal wiki, you have to take care of an important risk. And finally, metrics. It's always about metrics.
  • Art go offers a simple way to describe architectural guidelines in a more readable way. The rules description process starts when we have created the Jammer file and described all our architectural guidelines inside this file. Just run Archgo with the describe option and the output will be the description.
  • Archgo supports five types of rules, dependency rules, content rules, function rules, naming rules and cycles rules. The rules evaluation process starts when we have created the Jammer file. Archgo will consolidate all the different evaluation results.
  • Archgo generates a simple verification report that shows the result of the verification process. Architecture tests are supported by Archgo. Do you want to contribute with Archgo? You just need to download these tool, use it, and create some pull requests.
  • This is the ideas backlog. There are many ideas in the backlog. I'm very interested to know what do you think about them? And of course, if you have new ideas, you are welcome. I invite you to participate in the rest of the sessions of this conference.

Transcript

This transcript was autogenerated. To make changes, submit a PR.
Hello everyone, welcome to a new session of the deeptype track. In this conference today I'm going to talk about Archgo and how we can use it to continuously test the quality of our architectures. Archgo is a very simple testing tool strongly inspired in Arc unit, a testing framework for Java language. To start, I'm going to introduce myself. My name is Francisco defines, but most of the people call me Dino. I am a software developer and I'm working in Walmart, Chile in the artificial intelligence and data exploitation department. I have worked in many industries, in many business models, playing different roles and working with different languages as Java, C, Javascript, Python per Ruby and others. Since last year I'm working with Golang and today I consider myself a gopher because I'm really impressed about its simplicity. You can find me in social media with the user fdaimas, in GitHub, LinkedIn, Twitter, and of course you got my email. Okay, the first topic that we are going to talk about is what are the architectural guidelines and why we should know but them architectural guidelines in a very brief way are these important decisions that we take along the development of a product or a project mostly in the first moment. But of course we can make changes to these definitions as the project moves forward. A very common example of architectural guidelines is when we have to choose the package model we want to follow in our code base in the project. For example, if we have to create a simple rest service, maybe we can choose a layered architecture model because it's a very simple approach. In this approach we will have some layers and each layer can have one or more packages. And not only this. Also we have rules about how the packages in one layer can interact with packages in another layer. For example, looking at the diagram below, packages that are contained inside the presentation layer can only interact with packages in the same layer or packages in the business logic layer. Other example is that packages inside the persistence layer cannot interact with packages in any other layer. This image shows us the clean architecture model proposed by Robert Simarti. If we want to follow this architecture model, we can implement an onion architecture packages model in our code base. But the case is very similar to the previous one. We have packages and we have to decide in what layers those packages can be located and how these packages can interact with the other packages. This set of rules and definitions about packages and their interactions are part of the architectural guidelines. Of course, the packages model is not the only important decisions that we can take. There are many other agreements, for example, how to create functions if we want to require some properties that these functions must comply with. Or maybe if we want to have a naming convention, or if we want to restrict what kind of items can be placed in certain packages. Of course, if we want to restrict or allow some interactions between packages. Now we are going to look at some issues related to architectural guidelines. These first one is defining. Today it's very common to heard about evolutionary architectures, the approach proposed by Grepa, Caparsons, Nielford and Pat Gua. By the way, it's a very interesting approach. I strongly recommend to read this book. So if we think that our architecture can evolve, we must provide a way to make and record changes to our guidelines. It's just common sense. The next one is about outdated guidelines. If you are thinking in publishing your architectural guidelines in systems like confluence or an internal wiki, you have to take care of an important risk. Those systems are far from code. In a daily basis we work with the code base, not with the confluence system. So there is a risk that these developers forget to update the document in confluence. And after a couple of months we will end with an architectural guidelines that does not represent what we are applying in the code base. These next issue is about software quality degradation. Even if we apply some powerful techniques in our teams, like code reviews or pair programming, we are humans, so we made mistakes, and it's fine to make mistakes. For example, if we have a lot of rules as part of our architectural guidelines, maybe a couple of developers forgot to check some of them in a certain pull request. And after a couple of months, our code base does not comply with our architectural guidelines. But the worst part is that we are not seeing it, so we have no way to take care of this situation. And finally, metrics. It's always about metrics. If we want to know if there is a relation between the compliance level that our code has against the architectural guidelines and other metrics like lead time or change values, or another kind of metrics, the only way that we have is to measure the compliance level. There is no other way. So we need a way to know if our code complies with our architectural guidelines. Now we are ready to know about Archgo and see how we can use this tool to represent our architectural guidelines and checks if our project complies with them. The best way to understand and introduce ArG Go is looking at the execution flow. The process starts when the team members complies with a set of architectural guidelines and represents them in a YAML file. This JAML file must comply with these Archgo schema and has to be included as part of the code base in the root directory of the project. Then we need to download Archgo, for example using the Goget command. And finally we just run Archgo in the console and Argo makes his magic and do all the verifications and the output of ArchGo will be succeeded or rejected. And of course the console output has all the detailed information. An alternative way to execute and run Archgo is passing an optional argument that generates an HTML report in cases that we want to publish this report in another system. Now that we know a typical execution process of Archgo, let's see what features are included in this tool. Archgo contains three features. The first one is the rules description. As our architectural guidelines are represented in a jammer file, Archgo offers a simple way to represented those rules in a more readable way. The second feature is the core feature of Archgo, the rules evaluation. It checks if our project complies with all of the architectural guidelines described in this JAML file. And finally the HTML report. It creates an HTML report with the result of all the evaluation process. So let's go deeper in the first feature, the rules description at first time, the rules description feature does not look very attractive because we think we are representing our architectural guidelines in a JAML file, and YAMl format is very readable and easy to understand. But the problem with YAML format is that we have many ways to represent exactly the same document. As we can see, those two files represent exactly the same rules. And of course, both of these jammer configurations complies with the same schema. That's the reason why art go offer a simple way to describe this rule in a more readable way. The rules description process starts when we have created the Jammer file and described all our architectural guidelines inside this file. Then we just run Archgo with the describe option and the output will be the description, in a very readable way of all the rules contained in this jammer file. So this format is very easy to understand, and we can share this output with other teams, with other members, and maybe with other rules, like a product owner or a business analyst. We can continue with the core feature of Archgo, the rules evaluation. The rules evaluation process starts when we have created the Jammer file and described all our architectural guidelines inside this file. Of course, the Jammer file has to be included as part of our code base. Archgo will gather all the packages from our application and base it on. The rules described in the Jammer file will resolve which rules will be evaluated. ArchGo supports five types of rules, dependency rules, content rules, function rules, naming rules and cycles rules. Finally, Archgo will consolidate all the different evaluation results and resolve what will be the global result of the evaluation process that can be succeeded or rejected. The first rule type is dependency rules. Those rule are about the allowed and the restricted relations between different packages. For example, the green arrows represented allowed dependencies. So package a can depends on package c and the red arrows represented restricted and not allowed dependencies. So if any file in package b depends on anything that's declared on package d, the evaluation process will reject this rule. But not only this. Also, ArchGo offers a way to allow and restrict dependency with external packages. For example, in this case, package d can depends on goSql driver, mySql package, but cannot depends in the Fdynas go mySql package. All of these dependency rules can be modeled in archgo. As we can see, it's very simple to represent those rules in the JAML file, we have to declare a package using a pattern and these the keywords that can be should only depends on, should not depends on, and should only depends on external. The next type is content rules. Those rules are about which content are allowed as part of a certain package. For example, package b allows only interface definitions and package c allows only functions definitions. So if a developer create an structs inside packages b, the evaluation process will fail. In the case of package a, it accepts declarations of structures functions methods, but does not allow interfaces definitions. All of these cases can be modeled in archgo. As we can see, it's very simple to model. We have two main forms to model these content rules. We have the should only contain and these item type that can be functions, methods, interfaces and structs and these opposite that is should not contain and the item type. The next one are the function rules. Those rules are about some properties that the functions must comply with. For example, we can restrict how many parameters the functions can receive because we prefer, for example, using structures to encapsulate those parameters. A similar case is for the return values. We can restrict how many return values the functions can declare, and also we can define a maximum quantity of lines of code that the function implementations has to comply. And finally, how many functions we accept inside a single file. All of these properties can be modeled in Archgo and as we can see in this example, it's very natural to represent those rules. We define a package and all the packages that complies with this pattern require the functions to comply with these max quantity of parameters. The max return values, these max public functions per file, and the definitions must comply with these maximum lines of code. The next rule type is naming rule. Those rules are about naming conventions. Example above shows an interface which is implemented by three structs. So it's a common sense that these structs have a naming convention, a common pattern to comply with, because sometimes makes sense to comply with a naming rules. More. Even in Golang, where we have an implicit interface implementation, we don't have explicit one, but in another case, like the one in the right, it doesn't make sense. We are implementing two interfaces, so we are free to use the name that we want in this structure. For the first case, we can model this case in Archgo, and it's very simple too. We have an interface implementation naming rules attribute, and inside them we can define what's the pattern for the interface, and then what's the pattern that the structs must comply with. The last one are these cycles rules? Those rules are about cycles in the dependency graph, this diagram represents a cycle between package b, package c and package d. The truth is that as Golan compiler does not allow import cycles, this feature is evaluated and maybe it will be deprecated in future releases. If you want to know how to model this rule in the YAML file, there is an example. In this example we configure that all the packages that complies with this pattern should not contain cycles. Now we have reached the last feature of Archgo, the HTML report generation. This feature generates a very simple verification report that shows the result of the verification process. This report is strongly inspired on Pytest coverage report Pytest is a mutation testing tool for Java language. This feature is in work in progress status, so we will be added more interactions in future releases. At this moment I'm sure that you are asking yourself, what about the continuously part in the title of this session? Well, let's talk about automation. A generic CI CD pipeline contains several steps. The process starts when the developers write the code and push it to a virtual control repository. This event triggers some automatic steps as running these unit test or running the integration test, and then we can continue with the deployment part of the pipeline. Looking at this process, it's natural to think in including architecture tests as part of the CI CD pipeline for Golang. Architecture tests are supported by Archgo. As we've seen before, running ArcGo is very simple. We just need to run Archgo command, so include Argo in different guidelines are very simple too. Here are examples for GitHub actions Circleci and bitbacket guidelines. Of course we can run Archgo inside a docker container. Do you want to contribute with Archgo? These is these project repository URL. So you just need to download these tool, use it, and create some pull requests. This is the ideas backlog. There are many ideas in the backlog. I'm very interested to know what do you think about them? And of course, if you have new ideas, you are welcome. And that's all. We have reached the end of this session. I have to thank you for being here and invite you to participate in the rest of the sessions of this conference. And finally, if you like what Archgo offers, please promote the use of this tool in the community. Thank you very much and see you another time.
...

Francisco Daines

Senior Software Developer @ Walmart

Francisco Daines's LinkedIn account Francisco Daines's twitter account



Awesome tech events for

Priority access to all content

Video hallway track

Community chat

Exclusive promotions and giveaways