Skip to content

Commit

Permalink
Add support for annotations in visualization
Browse files Browse the repository at this point in the history
  • Loading branch information
anishathalye committed Nov 21, 2024
1 parent afb340d commit 12c3848
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 34 deletions.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,13 @@ the case of a non-linearizable history). The result is an HTML page that draws
an interactive visualization using JavaScript. The output looks like this:

<p align="center">
<a href="https://anishathalye.github.io/porcupine/demo.html">
<img src="https://raw.githubusercontent.com/anishathalye/assets/master/porcupine/demo.png" width="735" alt="Visualization demo">
<a href="https://anishathalye.github.io/porcupine/demo-annotations.html">
<img src="https://raw.githubusercontent.com/anishathalye/assets/master/porcupine/demo-annotations.png" width="1021" alt="Visualization demo">
</a>
</p>

You can see the full interactive version
[here](https://anishathalye.github.io/porcupine/demo.html).
[here](https://anishathalye.github.io/porcupine/demo-annotations.html).

The visualization is by partition: all partitions are essentially independent,
so with the key-value store example above, operations related to each unique
Expand Down Expand Up @@ -221,8 +221,14 @@ it's useful to fill out the `DescribeOperation` and `DescribeState` fields of
the model. See [`visualization_test.go`](visualization_test.go) for an
end-to-end example of how to visualize a history using Porcupine.

You can also add custom annotations to visualizations, as shown in the example
above. This can be helpful for attaching debugging information, for example,
from servers or the test framework. You can do this using the
[`AddAnnotations`][AddAnnotations] method.

[CheckOperationsVerbose]: https://pkg.go.dev/github.com/anishathalye/porcupine#CheckOperationsVerbose
[CheckEventsVerbose]: https://pkg.go.dev/github.com/anishathalye/porcupine#CheckEventsVerbose
[AddAnnotations]: https://pkg.go.dev/github.com/anishathalye/porcupine#LinearizationInfo.AddAnnotations

## Notes

Expand Down
1 change: 1 addition & 0 deletions checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type entry struct {
type LinearizationInfo struct {
history [][]entry // for each partition, a list of entries
partialLinearizations [][][]int // for each partition, a set of histories (list of ids)
annotations []annotation
}

// PartialLinearizations returns partial linearizations found during the
Expand Down
82 changes: 79 additions & 3 deletions visualization.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ type historyElement struct {
Description string
}

type annotation struct {
ClientId int
Tag string
Start int64
End int64
Description string
Details string
Annotation bool // always true
TextColor string
BackgroundColor string
}

type linearizationStep struct {
Index int
StateDescription string
Expand All @@ -29,11 +41,63 @@ type partitionVisualizationData struct {
Largest map[int]int
}

type visualizationData = []partitionVisualizationData
type visualizationData struct {
Partitions []partitionVisualizationData
Annotations []annotation
}

// Annotations to add to histories.
//
// Either a ClientId or Tag must be supplied. The End is optional, for "point
// in time" annotations. If the end is left unspecified, the framework
// interprets it as Start. The text given in Description is shown in the main
// visualization, and the text given in Details (optional) is shown in the
// tooltip for the annotation. TextColor and BackgroundColor are both optional;
// if specified, they should be valid CSS colors, e.g., "#efaefc".
//
// To attach annotations to a visualization, use
// [LinearizationInfo.AddAnnotations].
type Annotation struct {
ClientId int
Tag string
Start int64
End int64
Description string
Details string
TextColor string
BackgroundColor string
}

// AddAnnotations adds extra annotations to a visualization.
//
// This can be used to add extra client operations or it can be used to add
// standalone annotations with arbitrary tags, e.g., associated with "servers"
// rather than clients, or even a "test framework".
//
// See documentation on [Annotation] for what kind of annotations you can add.
func (li *LinearizationInfo) AddAnnotations(annotations []Annotation) {
for _, elem := range annotations {
end := elem.End
if end < elem.Start {
end = elem.Start
}
li.annotations = append(li.annotations, annotation{
ClientId: elem.ClientId,
Tag: elem.Tag,
Start: elem.Start,
End: end,
Description: elem.Description,
Details: elem.Details,
Annotation: true,
TextColor: elem.TextColor,
BackgroundColor: elem.BackgroundColor,
})
}
}

func computeVisualizationData(model Model, info LinearizationInfo) visualizationData {
model = fillDefault(model)
data := make(visualizationData, len(info.history))
partitions := make([]partitionVisualizationData, len(info.history))
for partition := 0; partition < len(info.history); partition++ {
// history
n := len(info.history[partition]) / 2
Expand All @@ -51,6 +115,9 @@ func computeVisualizationData(model Model, info LinearizationInfo) visualization
history[elem.id].Description = model.DescribeOperation(callValue[elem.id], elem.value)
returnValue[elem.id] = elem.value
}
// historyElement.Annotation defaults to false, so we
// don't need to explicitly set it here; all of these
// are non-annotation elements
}
// partial linearizations
largestIndex := make(map[int]int)
Expand Down Expand Up @@ -78,12 +145,21 @@ func computeVisualizationData(model Model, info LinearizationInfo) visualization
}
linearizations[i] = linearization
}
data[partition] = partitionVisualizationData{
partitions[partition] = partitionVisualizationData{
History: history,
PartialLinearizations: linearizations,
Largest: largestIndex,
}
}
annotations := info.annotations
if annotations == nil {
annotations = make([]annotation, 0)
}
data := visualizationData{
Partitions: partitions,
Annotations: annotations,
}

return data
}

Expand Down
6 changes: 6 additions & 0 deletions visualization/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ text {
fill: #42d1f5;
}

.client-annotation-rect {
stroke: #888;
stroke-width: 1;
fill: #e0e0e0;
}

.link {
fill: #206475;
cursor: pointer;
Expand Down
Loading

0 comments on commit 12c3848

Please sign in to comment.