// Mgmt // Copyright (C) 2013-2016+ James Shubin and the project contributors // Written by James Shubin and the project contributors // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // NOTE: this is pgraph, a pointer graph package main import ( "reflect" "testing" ) func TestPgraphT1(t *testing.T) { G := NewGraph("g1") if i := G.NumVertices(); i != 0 { t.Errorf("Should have 0 vertices instead of: %d.", i) } if i := G.NumEdges(); i != 0 { t.Errorf("Should have 0 edges instead of: %d.", i) } v1 := NewVertex(NewNoopRes("v1")) v2 := NewVertex(NewNoopRes("v2")) e1 := NewEdge("e1") G.AddEdge(v1, v2, e1) if i := G.NumVertices(); i != 2 { t.Errorf("Should have 2 vertices instead of: %d.", i) } if i := G.NumEdges(); i != 1 { t.Errorf("Should have 1 edges instead of: %d.", i) } } func TestPgraphT2(t *testing.T) { G := NewGraph("g2") v1 := NewVertex(NewNoopRes("v1")) v2 := NewVertex(NewNoopRes("v2")) v3 := NewVertex(NewNoopRes("v3")) v4 := NewVertex(NewNoopRes("v4")) v5 := NewVertex(NewNoopRes("v5")) v6 := NewVertex(NewNoopRes("v6")) e1 := NewEdge("e1") e2 := NewEdge("e2") e3 := NewEdge("e3") e4 := NewEdge("e4") e5 := NewEdge("e5") //e6 := NewEdge("e6") G.AddEdge(v1, v2, e1) G.AddEdge(v2, v3, e2) G.AddEdge(v3, v1, e3) G.AddEdge(v4, v5, e4) G.AddEdge(v5, v6, e5) if i := G.NumVertices(); i != 6 { t.Errorf("Should have 6 vertices instead of: %d.", i) } } func TestPgraphT3(t *testing.T) { G := NewGraph("g3") v1 := NewVertex(NewNoopRes("v1")) v2 := NewVertex(NewNoopRes("v2")) v3 := NewVertex(NewNoopRes("v3")) v4 := NewVertex(NewNoopRes("v4")) v5 := NewVertex(NewNoopRes("v5")) v6 := NewVertex(NewNoopRes("v6")) e1 := NewEdge("e1") e2 := NewEdge("e2") e3 := NewEdge("e3") e4 := NewEdge("e4") e5 := NewEdge("e5") //e6 := NewEdge("e6") G.AddEdge(v1, v2, e1) G.AddEdge(v2, v3, e2) G.AddEdge(v3, v1, e3) G.AddEdge(v4, v5, e4) G.AddEdge(v5, v6, e5) //G.AddEdge(v6, v4, e6) out1 := G.DFS(v1) if i := len(out1); i != 3 { t.Errorf("Should have 3 vertices instead of: %d.", i) t.Errorf("Found: %v", out1) for _, v := range out1 { t.Errorf("Value: %v", v.GetName()) } } out2 := G.DFS(v4) if i := len(out2); i != 3 { t.Errorf("Should have 3 vertices instead of: %d.", i) t.Errorf("Found: %v", out1) for _, v := range out1 { t.Errorf("Value: %v", v.GetName()) } } } func TestPgraphT4(t *testing.T) { G := NewGraph("g4") v1 := NewVertex(NewNoopRes("v1")) v2 := NewVertex(NewNoopRes("v2")) v3 := NewVertex(NewNoopRes("v3")) e1 := NewEdge("e1") e2 := NewEdge("e2") e3 := NewEdge("e3") G.AddEdge(v1, v2, e1) G.AddEdge(v2, v3, e2) G.AddEdge(v3, v1, e3) out := G.DFS(v1) if i := len(out); i != 3 { t.Errorf("Should have 3 vertices instead of: %d.", i) t.Errorf("Found: %v", out) for _, v := range out { t.Errorf("Value: %v", v.GetName()) } } } func TestPgraphT5(t *testing.T) { G := NewGraph("g5") v1 := NewVertex(NewNoopRes("v1")) v2 := NewVertex(NewNoopRes("v2")) v3 := NewVertex(NewNoopRes("v3")) v4 := NewVertex(NewNoopRes("v4")) v5 := NewVertex(NewNoopRes("v5")) v6 := NewVertex(NewNoopRes("v6")) e1 := NewEdge("e1") e2 := NewEdge("e2") e3 := NewEdge("e3") e4 := NewEdge("e4") e5 := NewEdge("e5") //e6 := NewEdge("e6") G.AddEdge(v1, v2, e1) G.AddEdge(v2, v3, e2) G.AddEdge(v3, v1, e3) G.AddEdge(v4, v5, e4) G.AddEdge(v5, v6, e5) //G.AddEdge(v6, v4, e6) save := []*Vertex{v1, v2, v3} out := G.FilterGraph("new g5", save) if i := out.NumVertices(); i != 3 { t.Errorf("Should have 3 vertices instead of: %d.", i) } } func TestPgraphT6(t *testing.T) { G := NewGraph("g6") v1 := NewVertex(NewNoopRes("v1")) v2 := NewVertex(NewNoopRes("v2")) v3 := NewVertex(NewNoopRes("v3")) v4 := NewVertex(NewNoopRes("v4")) v5 := NewVertex(NewNoopRes("v5")) v6 := NewVertex(NewNoopRes("v6")) e1 := NewEdge("e1") e2 := NewEdge("e2") e3 := NewEdge("e3") e4 := NewEdge("e4") e5 := NewEdge("e5") //e6 := NewEdge("e6") G.AddEdge(v1, v2, e1) G.AddEdge(v2, v3, e2) G.AddEdge(v3, v1, e3) G.AddEdge(v4, v5, e4) G.AddEdge(v5, v6, e5) //G.AddEdge(v6, v4, e6) graphs := G.GetDisconnectedGraphs() HeisenbergGraphCount := func(ch chan *Graph) int { c := 0 for x := range ch { _ = x c++ } return c } if i := HeisenbergGraphCount(graphs); i != 2 { t.Errorf("Should have 2 graphs instead of: %d.", i) } } func TestPgraphT7(t *testing.T) { G := NewGraph("g7") v1 := NewVertex(NewNoopRes("v1")) v2 := NewVertex(NewNoopRes("v2")) v3 := NewVertex(NewNoopRes("v3")) e1 := NewEdge("e1") e2 := NewEdge("e2") e3 := NewEdge("e3") G.AddEdge(v1, v2, e1) G.AddEdge(v2, v3, e2) G.AddEdge(v3, v1, e3) if i := G.NumVertices(); i != 3 { t.Errorf("Should have 3 vertices instead of: %d.", i) } G.DeleteVertex(v2) if i := G.NumVertices(); i != 2 { t.Errorf("Should have 2 vertices instead of: %d.", i) } G.DeleteVertex(v1) if i := G.NumVertices(); i != 1 { t.Errorf("Should have 1 vertices instead of: %d.", i) } G.DeleteVertex(v3) if i := G.NumVertices(); i != 0 { t.Errorf("Should have 0 vertices instead of: %d.", i) } G.DeleteVertex(v2) // duplicate deletes don't error... if i := G.NumVertices(); i != 0 { t.Errorf("Should have 0 vertices instead of: %d.", i) } } func TestPgraphT8(t *testing.T) { v1 := NewVertex(NewNoopRes("v1")) v2 := NewVertex(NewNoopRes("v2")) v3 := NewVertex(NewNoopRes("v3")) if HasVertex(v1, []*Vertex{v1, v2, v3}) != true { t.Errorf("Should be true instead of false.") } v4 := NewVertex(NewNoopRes("v4")) v5 := NewVertex(NewNoopRes("v5")) v6 := NewVertex(NewNoopRes("v6")) if HasVertex(v4, []*Vertex{v5, v6}) != false { t.Errorf("Should be false instead of true.") } v7 := NewVertex(NewNoopRes("v7")) v8 := NewVertex(NewNoopRes("v8")) v9 := NewVertex(NewNoopRes("v9")) if HasVertex(v8, []*Vertex{v7, v8, v9}) != true { t.Errorf("Should be true instead of false.") } v1b := NewVertex(NewNoopRes("v1")) // same value, different objects if HasVertex(v1b, []*Vertex{v1, v2, v3}) != false { t.Errorf("Should be false instead of true.") } } func TestPgraphT9(t *testing.T) { G := NewGraph("g9") v1 := NewVertex(NewNoopRes("v1")) v2 := NewVertex(NewNoopRes("v2")) v3 := NewVertex(NewNoopRes("v3")) v4 := NewVertex(NewNoopRes("v4")) v5 := NewVertex(NewNoopRes("v5")) v6 := NewVertex(NewNoopRes("v6")) e1 := NewEdge("e1") e2 := NewEdge("e2") e3 := NewEdge("e3") e4 := NewEdge("e4") e5 := NewEdge("e5") e6 := NewEdge("e6") G.AddEdge(v1, v2, e1) G.AddEdge(v1, v3, e2) G.AddEdge(v2, v4, e3) G.AddEdge(v3, v4, e4) G.AddEdge(v4, v5, e5) G.AddEdge(v5, v6, e6) indegree := G.InDegree() // map[*Vertex]int if i := indegree[v1]; i != 0 { t.Errorf("Indegree of v1 should be 0 instead of: %d.", i) } if i := indegree[v2]; i != 1 { t.Errorf("Indegree of v2 should be 1 instead of: %d.", i) } if i := indegree[v3]; i != 1 { t.Errorf("Indegree of v3 should be 1 instead of: %d.", i) } if i := indegree[v4]; i != 2 { t.Errorf("Indegree of v4 should be 2 instead of: %d.", i) } if i := indegree[v5]; i != 1 { t.Errorf("Indegree of v5 should be 1 instead of: %d.", i) } if i := indegree[v6]; i != 1 { t.Errorf("Indegree of v6 should be 1 instead of: %d.", i) } outdegree := G.OutDegree() // map[*Vertex]int if i := outdegree[v1]; i != 2 { t.Errorf("Outdegree of v1 should be 2 instead of: %d.", i) } if i := outdegree[v2]; i != 1 { t.Errorf("Outdegree of v2 should be 1 instead of: %d.", i) } if i := outdegree[v3]; i != 1 { t.Errorf("Outdegree of v3 should be 1 instead of: %d.", i) } if i := outdegree[v4]; i != 1 { t.Errorf("Outdegree of v4 should be 1 instead of: %d.", i) } if i := outdegree[v5]; i != 1 { t.Errorf("Outdegree of v5 should be 1 instead of: %d.", i) } if i := outdegree[v6]; i != 0 { t.Errorf("Outdegree of v6 should be 0 instead of: %d.", i) } s, ok := G.TopologicalSort() // either possibility is a valid toposort match := reflect.DeepEqual(s, []*Vertex{v1, v2, v3, v4, v5, v6}) || reflect.DeepEqual(s, []*Vertex{v1, v3, v2, v4, v5, v6}) if !ok || !match { t.Errorf("Topological sort failed, status: %v.", ok) str := "Found:" for _, v := range s { str += " " + v.Res.GetName() } t.Errorf(str) } } func TestPgraphT10(t *testing.T) { G := NewGraph("g10") v1 := NewVertex(NewNoopRes("v1")) v2 := NewVertex(NewNoopRes("v2")) v3 := NewVertex(NewNoopRes("v3")) v4 := NewVertex(NewNoopRes("v4")) v5 := NewVertex(NewNoopRes("v5")) v6 := NewVertex(NewNoopRes("v6")) e1 := NewEdge("e1") e2 := NewEdge("e2") e3 := NewEdge("e3") e4 := NewEdge("e4") e5 := NewEdge("e5") e6 := NewEdge("e6") G.AddEdge(v1, v2, e1) G.AddEdge(v2, v3, e2) G.AddEdge(v3, v4, e3) G.AddEdge(v4, v5, e4) G.AddEdge(v5, v6, e5) G.AddEdge(v4, v2, e6) // cycle if _, ok := G.TopologicalSort(); ok { t.Errorf("Topological sort passed, but graph is cyclic.") } } func TestPgraphT11(t *testing.T) { v1 := NewVertex(NewNoopRes("v1")) v2 := NewVertex(NewNoopRes("v2")) v3 := NewVertex(NewNoopRes("v3")) v4 := NewVertex(NewNoopRes("v4")) v5 := NewVertex(NewNoopRes("v5")) v6 := NewVertex(NewNoopRes("v6")) if rev := Reverse([]*Vertex{}); !reflect.DeepEqual(rev, []*Vertex{}) { t.Errorf("Reverse of vertex slice failed.") } if rev := Reverse([]*Vertex{v1}); !reflect.DeepEqual(rev, []*Vertex{v1}) { t.Errorf("Reverse of vertex slice failed.") } if rev := Reverse([]*Vertex{v1, v2, v3, v4, v5, v6}); !reflect.DeepEqual(rev, []*Vertex{v6, v5, v4, v3, v2, v1}) { t.Errorf("Reverse of vertex slice failed.") } if rev := Reverse([]*Vertex{v6, v5, v4, v3, v2, v1}); !reflect.DeepEqual(rev, []*Vertex{v1, v2, v3, v4, v5, v6}) { t.Errorf("Reverse of vertex slice failed.") } }