If code-quality is one of your concerns, you must be aware of code smells and design smells. Similarly, code written in configuration management systems such as Puppet and Chef is also prone to such maintainability smells.
Recently, we (myself, Prof. Diomidis Spinellis, and Marios Fragkoulis) have worked on configuration smells and a paper summarizing the research has been accepted in the Mining Software Repositories conference (2016). The paper defines configuration smells and introduces a catalog of configuration smells that I am presenting below. Interested readers may take a look at the preprint of the paper.
We define configuration smells as follows:
Configuration smells are the characteristics of a configuration program or script that violate the recommended best practices and potentially affect the program’s quality in a negative way.
Implementation Configuration Smells
Implementation configuration smells are quality issues such as naming convention, style, formatting, and indentation in configuration code.
1. Missing Default Case (IMD)
A default case is missing in a case or selector statement.
2. Inconsistent Naming Convention (INC)
The used naming convention deviates from the recommended naming convention.
3. Complex Expression (ICE)
A program contains a difficult to understand complex expression.
4. Duplicate Entity (IDE)
Duplicate hash keys or duplicate parameters present in the configuration code.
5. Misplaced Attribute (IMA)
Attribute placement within a resource or a class has not followed a recommended order (for example, mandatory attributes should be specified before the optional attributes).
6. Improper Alignment (IIA)
The code is not properly aligned (such as all the arrows in a resource declaration) or tabulation characters are used.
7. Invalid Property Value (IPV)
An invalid value of a property or attribute is used (such as a file mode specified using 3-digit octal value rather than 4-digit).
8. Incomplete Tasks (IIT)
The code has “FIXME” and “TODO” tags indicating incomplete tasks.
9. Deprecated Statement Usage (IDS)
The configuration code uses one of the deprecated statements (such as “import”).
10. Improper Quote Usage (IQU)
Single and double quotes are not used properly. For example, boolean values should not be quoted and variable names should not be used in single quoted strings.
11. Long Statement (ILS)
The code contains long statements (that typically do not fit in a screen).
12. Incomplete Conditional (IIC)
An “if..elsif” construct used without a terminating “else” clause.
13. Unguarded Variable (IUV)
A variable is not enclosed in braces when being interpolated in a string.
Design Configuration Smells
Design configuration smells reveal quality issues in the module design or structure of a configuration project.
1. Multifaceted Abstraction (DMF)
Each abstraction (e.g. a resource, class, ‘define’, or module) should be designed to specify the properties of a single piece of software. In other words, each abstraction should follow single responsibility principle. An abstraction suffers from multifaceted abstraction when the elements of the abstraction are not cohesive.
The smell may occur in the following two forms:
- a resource (file, package, or service) declaration specifies attributes of more than one physical resources, or
- all the language elements declared in a class, ‘define’, or a module are not cohesive.
2. Unnecessary Abstraction (DUA)
A class, ‘define’, or module must contain declarations or statements specifying the properties of a desired system. An empty class, ‘define’, or module shows the presence of unnecessary abstraction smell and thus must be removed.
3. Imperative Abstraction (DIA)
Puppet is declarative in nature. The presence of imperative statements (such as “exec”) defies the purpose of the language. An abstraction containing numerous imperative statements suffers from imperative abstraction smell.
4. Missing Abstraction (DMA)
Resource declarations and statements are easy to use and reuse when they are encapsulated in an abstraction such as a class or ‘define’. A module suffers from the missing abstraction smell when resources and language elements are declared and used without encapsulating them in an abstraction.
5. Insufficient Modularization (DIM)
An abstraction suffers from this smell when it is large or complex and thus can be modularized further. This smell arises in following forms:
- if a file contains a declaration of more than one class or ‘define’, or
- if the size of a class declaration is large crossing a certain threshold, or
- the complexity of a class or ‘define’ is high.
6. Duplicate Block (DDB)
A duplicate block of statements more than a threshold indicates that probably a suitable abstraction definition is missing. Thus, a module containing such a duplicate block suffers from duplicate block smell.
7. Broken Hierarchy (DBH)
The use of inheritance must be limited to the same module. The smell occurs when the inheritance is used across namespaces (“is-a” relationship is not followed).
8. Unstructured Module (DUM)
Each module in a configuration repository must have a well-defined and consistent module structure. A recommended structure for a module is the following.
- <Module name>
An ad-hoc structure of a repository suffers from unstructured module smell that impacts understandability and predictability of the repository.
9. Dense Structure (DDS)
This smell arises when a configuration code repository has excessive and dense dependencies without any particular structure.
10. Deficient Encapsulation (DDE)
This smell arises when a node definition or ENC (External Node Classifier) declares a set of global variables to be picked up by the included classes in the definition.
11. Weakened Modularity (DWM)
Each module must strive for high cohesion and low coupling. This smell arises when a module exhibits high coupling and low cohesion.