Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ __IMPORTANT NOTICE:__ The contents of this repository currectly reflect a __DRAF
1. [Event Structure](./eiffel-syntax-and-usage/event-structure.md)
1. [The Meta Object](./eiffel-syntax-and-usage/the-meta-object.md)
1. [The Links Object](./eiffel-syntax-and-usage/the-links-object.md)
1. User Examples
1. The Eiffel Vocabulary
1. [EiffelActivityQueuedEvent](./eiffel-vocabulary/EiffelActivityQueuedEvent.md)
1. [EiffelActivityDequeuedEvent](./eiffel-vocabulary/EiffelActivityDequeuedEvent.md)
Expand All @@ -37,6 +36,8 @@ __IMPORTANT NOTICE:__ The contents of this repository currectly reflect a __DRAF
1. EiffelTestExecutionRecipeCollectionCreated
1. EiffelAnnouncementEvent
1. EiffelConfigurationChangedEvent
1. Usage Examples
1. [Confidence Level Joining](./usage-examples/confidence-level-joining.md)
1. Implementations
1. [Event Persistence](./implementations/event-persistence.md)
1. [Event Aggregation and Analysis](./implementations/event-aggregation-and-analysis.md)
Expand Down
1 change: 1 addition & 0 deletions usage-examples/confidence-level-joining.gliffy

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions usage-examples/confidence-level-joining.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Confidence Level Joining Example
This example illustrates how [EiffelConfidenceLevelModifiedEvent](../eiffel-vocabulary/EiffelConfidenceLevelModifiedEvent.md) can be used to capture and summarize a larger body of lower level results, such as test suite verdicts, effectively _joining_ multiple flows in the continuous integration and delivery system.

A JSON array of all events used in this example can be found [here](https://github.com/Ericsson/eiffel-examples/blob/master/flows/confidence-level-join/events.json).

## Introduction
A common use case in continuous integration and delivery systems is to join many separate (and disparate) tests into a larger entity, providing a stamp of approval to the item under test. In Eiffel, such stamps are provided by [EiffelConfidenceLevelModifiedEvent](../eiffel-vocabulary/EiffelConfidenceLevelModifiedEvent.md). This not only serves the purpose of raising the level of abstraction, thereby facilitating analysis and release decisions, but also provides a pragmatic extension point of the production pipeline: an external listener (e.g. a product looking to integrate the item under test) is not interested in tracking individual test case results, particularly as they may well change over time or even from execution to execution, but simply wants to know "Is this artifact good enough for me to pick up?".

## Event Graph
![alt text](./confidence-level-joining.png "Event Graph of Confidence Level Joining Example")

## Event-by-Event Explanation
### ArtC1
The [EiffelArtifactCreatedEvent](../eiffel-vocabulary/EiffelArtifactCreatedEvent.md) is central in this example. It declares that a new artifact has been created, and (largely via links) documents how and from what it was built. At the time of this event we still know very little about the artifact: it has unique coordinates (its GAV), but where to fetch it or whether it is any good remains to be seen.

### CDef1
An [EiffelCompositionDefinedEvent](../eiffel-vocabulary/EiffelCompositionDefinedEvent.md) detailing a composition of items (such as source code revisions and other artifacts), from which the artifact declared by __ArtC1__ was built. The elements of the composition, the reason for defining the composition et cetera are excluded in this example.

### EDef1
An [EiffelEnvironmentDefinedEvent](../eiffel-vocabulary/EiffelEnvironmentDefinedEvent.md) describing the environment in which the artifact declared by __ArtC1__ was built.

### ArtP1
The [EiffelArtifactPublishedEvent](../eiffel-vocabulary/EiffelArtifactPublishedEvent.md) declaring that the created artifact now has been published, and consequently may be fetched. Since __ArtC1__ itself declares the GAV, the artifact _may_ be fetched using only that information (assuming a binary repository supporting this, such as Artifactory), but it is still recommended practice to explicitly declare when and where the artifact can be retrieved, in order to avoid outages or timing issues.

### ActT1, ActT2, ActS1, ActS2, ActF1, ActF2
A set of [EiffelActivityTriggeredEvent](../eiffel-vocabulary/EiffelActivityTriggeredEvent.md), [EiffelActivityStartedEvent](../eiffel-vocabulary/EiffelActivityStartedEvent.md), [EiffelActivityFinishedEvent](../eiffel-vocabulary/EiffelActivityFinishedEvent.md) reporting on the lifecycle of two independent activity executions being caused by the publication of the artifact. Note that the EiffelActivityStartedEvents and EiffelActivityFinishedEvents are "dead ends" in the graph: in this example, nothing occurs as a direct cause of the activity starting or finishing (although such a setup is, of course, entirely possible) and the work being done within the activity refers directly to the EiffelActivityTriggeredEvent as its context. This shows how, in one sense, this type of lifecycle events is superfluous: for the core functionality of this example it is perfectly possible to cut them out and let the EiffelTestCaseStartedEvents refer directly to __ArtP1__ as their cause. Activity events do provide important contextual information, however, as they allow monitoring of e.g. system performance, bottlenecks, queue times and execution durations. They also serve the purpose of clustering work; in this example, __ActT1__ and __ActT2__ may represent activities executed at wildly different times, at different locations and by different organizations.

### TCS1, TCS2, TCS3, TCS4
[EiffelTestCaseStartedEvents](../eiffel-vocabulary/EiffelTestCaseStartedEvent.md) declaring that, as part of their respective activities, test cases have been launched. In this example only a very small number of test cases are executed - in reality, these events tend to be very numerous. Note that the cause of the execution can be traced to __ArtC1__ via __links.context__ and __links.causes__. This is not enough to unambiguously identify the item under test, however: it is entirely conceivable that the immediate cause for executing the test is completely independent from the item under test. Consequently __links.iut__ is used to reference __ArtC1__ directly.

### TCF1, TCF2, TCF3, TCF4
[EiffelTestCaseFinishedEvents](../eiffel-vocabulary/EiffelTestCaseFinishedEvent.md) reporting the verdict of their respective test case executions.

### CLM1
The [EiffelConfidenceLevelModifiedEvent](../eiffel-vocabulary/EiffelConfidenceLevelModifiedEvent.md) that summarizes all of the test case executions under a single headline. Note that the algorithm for determining this confidence level may be simple or relatively complex, but an important point of the event is that this algorithm is evaluated close to those tests, affording separation of concerns for users (human or automated) who simply want to know whether the relevant tests worked, whichever those tests happened to be at that point in time. This way the nitty gritty details are abstracted away. It doesn't end there, however: while not included in this example, __CLM1__ may in turn be but a building block of subsequent, even higher level EiffelConfidenceLevelModifiedEvents.
Binary file added usage-examples/confidence-level-joining.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.