summaryrefslogtreecommitdiff
path: root/libpod/container_graph.go
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@gmail.com>2018-03-27 13:23:23 -0400
committerAtomic Bot <atomic-devel@projectatomic.io>2018-03-29 02:18:45 +0000
commitb1dfee50e826bb3e4a699c89fabdb3bfcdaae86b (patch)
tree4258f39aa67bbcbc220d3533cf3bc2ec86df7fd1 /libpod/container_graph.go
parent120520af349bd6f23133fcf2e7f3b6efa0f7a7ad (diff)
downloadpodman-b1dfee50e826bb3e4a699c89fabdb3bfcdaae86b.tar.gz
podman-b1dfee50e826bb3e4a699c89fabdb3bfcdaae86b.tar.bz2
podman-b1dfee50e826bb3e4a699c89fabdb3bfcdaae86b.zip
Add tests for container graphs
Signed-off-by: Matthew Heon <matthew.heon@gmail.com> Closes: #557 Approved by: rhatdan
Diffstat (limited to 'libpod/container_graph.go')
-rw-r--r--libpod/container_graph.go19
1 files changed, 18 insertions, 1 deletions
diff --git a/libpod/container_graph.go b/libpod/container_graph.go
index 67b0e3ac2..214f1b245 100644
--- a/libpod/container_graph.go
+++ b/libpod/container_graph.go
@@ -2,6 +2,7 @@ package libpod
import (
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
type containerNode struct {
@@ -73,7 +74,8 @@ func buildContainerGraph(ctrs []*Container) (*containerGraph, error) {
return graph, nil
}
-// Detect cycles in a container graph
+// Detect cycles in a container graph using Tarjan's strongly connected
+// components algorithm
// Return true if a cycle is found, false otherwise
func detectCycles(graph *containerGraph) (bool, error) {
type nodeInfo struct {
@@ -89,6 +91,8 @@ func detectCycles(graph *containerGraph) (bool, error) {
var strongConnect func(*containerNode) (bool, error)
strongConnect = func(node *containerNode) (bool, error) {
+ logrus.Debugf("Strongconnecting node %s", node.id)
+
info := new(nodeInfo)
info.index = index
info.lowLink = index
@@ -100,9 +104,13 @@ func detectCycles(graph *containerGraph) (bool, error) {
info.onStack = true
+ logrus.Debugf("Pushed %s onto stack", node.id)
+
// Work through all nodes we point to
for _, successor := range node.dependsOn {
if _, ok := nodes[successor.id]; !ok {
+ logrus.Debugf("Recursing to successor node %s", successor.id)
+
cycle, err := strongConnect(successor)
if err != nil {
return false, err
@@ -132,6 +140,15 @@ func detectCycles(graph *containerGraph) (bool, error) {
topOfStack := stack[l-1]
stack = stack[:l-1]
+ // Popped item is no longer on the stack, mark as such
+ topInfo, ok := nodes[topOfStack.id]
+ if !ok {
+ return false, errors.Wrapf(ErrInternal, "error finding node info for %s", topOfStack.id)
+ }
+ topInfo.onStack = false
+
+ logrus.Debugf("Finishing node %s. Popped %s off stack", node.id, topOfStack.id)
+
// If the top of the stack is not us, we have found a
// cycle
if topOfStack.id != node.id {