Introduction

DICTŌ ("I prescribe" in latin) is a simple declarative language for specifying architectural constraints. Once specified, constraints can be automatically verified using the most appropriate dedicated tool.

Motivation

After interviewing over a dozen architects, we discovered that architecture is often described in terms of constraints. Some examples of constraint are:

  • Dependencies (Component A cannot invoke method X of component B)
  • Response time (The system is time-critical and has to answer each request within 10 ms)
  • Naming conventions (Java bean classes end with the suffix "Bean")
  • Meta-annotations (Attributes of type DateTime must be annotated with @Date(format = "d-m-Y"))
  • Authorization (Access to the service is restricted to users having role A or being part of group B)
Testing these constraints is a costly (and therefore mostly avoided) task. Existing analysis tools are typically not well-known, can be hard to use (poor documentation, obscure API, etc.) and often require you to specify constraints in a too technical form (i.e. Java or XML code that needs to be kept in sync with equivalent natural language statements contained in a document).

In order to make architectural testing cheaper and more accessible, architects need a simple declarative language for writing rules that are easy to maintain, read and test. For this reason we are proposing a new solution called DICTŌ. DICTŌ is a tool-agnostic and extensible language that can be used to specify architectural constraints and test for implementation compliance. Other than typical architectural DSLs, DICTŌ is not backed by a specific analysis engine but relies on a series of pluggable third-party analysis providers. Each constraint specified by the user can be accepted by one or more analysis providers or might even be rejected by all of them. This makes the language very flexible and independent from the actual underlying analysis infrastructure while still making it useful and effective for testing.

How to use it

Let’s suppose we have the following constraint:

In a Java system, packages org.app.syntax and org.app.core can only depend on org.app.parser and cannot contain “@PublicAPI”


With DICTŌ, the constraint can be expressed as follows:

Syntax = Package with name:"org.app.Syntax"
Core = Package with name:"org.app.Core"
Parser = Package with name:"org.app.Parser"

Syntax, Core can only depend on Parser
Syntax, Core cannot contain text “@PublicAPI"

The constraint is concise and self-explanatory. It can easily be embedded in a guideline document and presented to less technical stakeholder. Our testing framework will automatically search for the most appropriate analysis tool to be employed for testing. All the user need do is write a valid specification and the tool will take care of the rest.

A constraint consists of a statements conforming to one of the following formats:

SUBJECTS must PREDICATES
SUBJECTS cannot PREDICATES
only SUBJECTS can PREDICATES
SUBJECTS can only PREDICATES
Subjects and entities used as predicate arguments are defined as follows:

NAME = [all] TYPE with SPECIFIER:VALUE, SPECIFIER:VALUE

SonarQube

Dicto results can currently be exported to Sonarqube.
Each violation are transformed into issues which can be discussed and assigned to users.


Comparison

Architectural testing can be achieved through the following strategies:


Tools: Ad-hoc technical solution Certain constraints can be verified by running dedicated tools. Structural anomalies, such as illegal dependencies or dependency cycles can be checked with tools like Dependometer, JDepend, SAVE, Lattix LDM, Sonargraph, Structure 101. Performance issues can be discovered with JMeter. Code quality can be analyzed using Moose, checkstyle and findbugs.

These tools are powerful and mostly reliable but are very different one from the other. They differ in terms of offered functionality and foundamental conceptual assumptions on which they are based. Test conditions might be specified using a Java API, written in an XML file or drawn through a GUI. All this makes tool discovery and constraint formalization error-prone and expensive.

  • Pro: powerful analysis.
  • Contra: tool discovery, tool understanding, specification mainstainance.


Adapting source code: Embedding architecture in code Architectural constraints can be enforced by specifying desirable properties directly in the source code (using domain specific constructs which are not part of the host PL) and checking their validity at compile-time or run-time. ArchFace and ArchJava both offer such a solution.

  • Pro: Low risk of divergence between constraint specification and implementation.
  • Contra: Breaks tool support, no link to architectural documents.


ADLs: Model checking ADLs (Architecture description languages) allow architects to define a formal model of their architecture. Models can be enriched with properties that can be evaluated against specified constraints. Proposed languages (e.g. AADL, xADL, ACME, Darwin, Rapide, OCL/UML) do not provide analysis tools for testing constraints on a concrete implementation. ADLs also don’t allow partial descriptions and require a full specification of the architecture (in terms of components and connections).

  • Pro: useful for formal proving of structural and behavioral properties (e.g. dependencies, scheduling, performance).
  • Contra: constraints are not tested on the implementation but just on a model.


DSLs for Architectural constraints: A convenient testing solution To address the limitations of ADLs researchers came up with other more concrete DSLs (Soul, DCL, inCode.Rules) specifically designed to support the definition of implementation related constraints. These languages are typically backed up by a static analyzer used for testing the constraints. The expressivity of the language is obviously limited by the capability of the backing tool.

  • Pro: very simple way to express constraints, can be embedded in architectural documents.
  • Contra: DSLs typically support only a very limited number of constraint types (mostly component dependencies).


DICTŌ: A tool-agnostic extensible testing solution DICTŌ is simple DSL designed for specifying architectural constraints. Other then typical architectural DSLs, DICTŌ is not backed by a specific analysis engine. For testing purposes, DICTŌ relies on a series of pluggable third-party analysis providers. Each specified constraint can be accepted by one or more analysis providers or might even be rejected by all of them. This makes the language very flexible and independent from the actual underlying analysis infrastructure.

  • Pro: very simple way to express constraints; can be embedded in architectural documents; language expressivity is not limited by testing capabilities.
  • Contra: constraints can only be tested if a suitable tool adapter is present.

Publications

A Unified Approach to Architecture Conformance Checking.
In Proceedings of the 12th Working IEEE/IFIP Conference on Software Architecture (WICSA), ACM Press, 2015.

A Unified Approach to Automatic Testing of Architectural Constraints.
In Proceedings of ICSE 2015 (37st International Conference on Software Engineering), Doctoral Symposium, ACM Press, 2015.

Dicto: A Unified DSL for Testing Architectural Rules.
In Proceedings of the 2014 European Conference on Software Architecture Workshops, ECSAW '14.

Dicto: Keeping Software Architecture Under Control.
In ERCIM News 99, October 2014.

Future Work

We are currently developing a web-based text editor with auto-completion and syntax error highlighting. This will help users to write proper rules based on the accepted grammars of all currently supported adapters.


If you want to suggest possible future research directions, please contact the authors.