mirror of https://github.com/hashicorp/terraform
The external api provided here is simply dag.Graph.SetDebugWriter(io.Writer). When a writer is provided to a Graph, it will immediately encode itself to the stream, and subsequently encode any additional transformations to the graph. This will allow easier logging of graph transformations without writing complete graphs to the logs at every step. Since the marshalGraph can also be dot encoded, this will allow translation from the JSON logs to dot graphs.pull/10030/head
parent
6f347ebb3a
commit
82b1a2abc2
@ -0,0 +1,175 @@
|
||||
package dag
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGraphDot_empty(t *testing.T) {
|
||||
var g Graph
|
||||
g.Add(1)
|
||||
g.Add(2)
|
||||
g.Add(3)
|
||||
|
||||
actual := strings.TrimSpace(string(g.Dot(nil)))
|
||||
expected := strings.TrimSpace(testGraphDotEmptyStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad: %s", actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGraphDot_basic(t *testing.T) {
|
||||
var g Graph
|
||||
g.Add(1)
|
||||
g.Add(2)
|
||||
g.Add(3)
|
||||
g.Connect(BasicEdge(1, 3))
|
||||
|
||||
actual := strings.TrimSpace(string(g.Dot(nil)))
|
||||
expected := strings.TrimSpace(testGraphDotBasicStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad: %s", actual)
|
||||
}
|
||||
}
|
||||
|
||||
const testGraphDotBasicStr = `digraph {
|
||||
compound = "true"
|
||||
newrank = "true"
|
||||
subgraph "root" {
|
||||
"[root] 1" -> "[root] 3"
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const testGraphDotEmptyStr = `digraph {
|
||||
compound = "true"
|
||||
newrank = "true"
|
||||
subgraph "root" {
|
||||
}
|
||||
}`
|
||||
|
||||
func TestGraphJSON_empty(t *testing.T) {
|
||||
var g Graph
|
||||
g.Add(1)
|
||||
g.Add(2)
|
||||
g.Add(3)
|
||||
|
||||
js, err := g.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
actual := strings.TrimSpace(string(js))
|
||||
expected := strings.TrimSpace(testGraphJSONEmptyStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad: %s", actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGraphJSON_basic(t *testing.T) {
|
||||
var g Graph
|
||||
g.Add(1)
|
||||
g.Add(2)
|
||||
g.Add(3)
|
||||
g.Connect(BasicEdge(1, 3))
|
||||
|
||||
js, err := g.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
actual := strings.TrimSpace(string(js))
|
||||
expected := strings.TrimSpace(testGraphJSONBasicStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad: %s", actual)
|
||||
}
|
||||
}
|
||||
|
||||
// record some graph transformations, and make sure we get the same graph when
|
||||
// they're replayed
|
||||
func TestGraphJSON_basicRecord(t *testing.T) {
|
||||
var g Graph
|
||||
var buf bytes.Buffer
|
||||
g.SetDebugWriter(&buf)
|
||||
|
||||
g.Add(1)
|
||||
g.Add(2)
|
||||
g.Add(3)
|
||||
g.Connect(BasicEdge(1, 2))
|
||||
g.Connect(BasicEdge(1, 3))
|
||||
g.Connect(BasicEdge(2, 3))
|
||||
(&AcyclicGraph{g}).TransitiveReduction()
|
||||
|
||||
recorded := buf.Bytes()
|
||||
// the Walk doesn't happen in a determined order, so just count operations
|
||||
// for now to make sure we wrote stuff out.
|
||||
if len(bytes.Split(recorded, []byte{'\n'})) != 17 {
|
||||
t.Fatalf("bad: %s", recorded)
|
||||
}
|
||||
|
||||
original, err := g.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// replay the logs, and marshal the graph back out again
|
||||
m, err := decodeGraph(bytes.NewReader(buf.Bytes()))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
replayed, err := json.MarshalIndent(m, "", " ")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(original, replayed) {
|
||||
t.Fatalf("\noriginal: %s\nreplayed: %s", original, replayed)
|
||||
}
|
||||
}
|
||||
|
||||
const testGraphJSONEmptyStr = `{
|
||||
"Type": "Graph",
|
||||
"Name": "root",
|
||||
"Vertices": [
|
||||
{
|
||||
"ID": "1",
|
||||
"Name": "1"
|
||||
},
|
||||
{
|
||||
"ID": "2",
|
||||
"Name": "2"
|
||||
},
|
||||
{
|
||||
"ID": "3",
|
||||
"Name": "3"
|
||||
}
|
||||
]
|
||||
}`
|
||||
|
||||
const testGraphJSONBasicStr = `{
|
||||
"Type": "Graph",
|
||||
"Name": "root",
|
||||
"Vertices": [
|
||||
{
|
||||
"ID": "1",
|
||||
"Name": "1"
|
||||
},
|
||||
{
|
||||
"ID": "2",
|
||||
"Name": "2"
|
||||
},
|
||||
{
|
||||
"ID": "3",
|
||||
"Name": "3"
|
||||
}
|
||||
],
|
||||
"Edges": [
|
||||
{
|
||||
"Name": "1|3",
|
||||
"Source": "1",
|
||||
"Target": "3"
|
||||
}
|
||||
]
|
||||
}`
|
||||
Loading…
Reference in new issue