Added tests for graph.go

graph-rework
noah metz 2023-04-08 15:23:40 -06:00
parent 18cb18f6a7
commit 07c78387d8
2 changed files with 189 additions and 4 deletions

@ -137,7 +137,6 @@ type Resource interface {
type BaseResource struct { type BaseResource struct {
BaseNode BaseNode
update_channel chan error
parents []Resource parents []Resource
children []Resource children []Resource
} }
@ -153,7 +152,7 @@ func (resource * BaseResource) Parents() []Resource {
func (resource * BaseResource) AddParent(parent Resource) error { func (resource * BaseResource) AddParent(parent Resource) error {
// Don't add self as parent // Don't add self as parent
if parent.ID() == resource.ID() { if parent.ID() == resource.ID() {
error_str := fmt.Sprintf("Will not add %s as parent of itself", parent.ID) error_str := fmt.Sprintf("Will not add %s as parent of itself", parent.ID())
return errors.New(error_str) return errors.New(error_str)
} }
@ -190,7 +189,22 @@ type BaseEvent struct {
parent Event parent Event
} }
func NewBaseEvent(name string, description string, required_resources []Resource) * BaseEvent { func NewResource(name string, description string, children []Resource) * BaseResource {
resource := &BaseResource{
BaseNode: BaseNode{
name: name,
description: description,
id: gql_randid(),
listeners: []chan error{},
},
parents: []Resource{},
children: children,
}
return resource
}
func NewEvent(name string, description string, required_resources []Resource) * BaseEvent {
event := &BaseEvent{ event := &BaseEvent{
BaseNode: BaseNode{ BaseNode: BaseNode{
name: name, name: name,
@ -199,6 +213,7 @@ func NewBaseEvent(name string, description string, required_resources []Resource
listeners: []chan error{}, listeners: []chan error{},
}, },
parent: nil, parent: nil,
children: []Event{},
locked_resources: []Resource{}, locked_resources: []Resource{},
created_resources: []Resource{}, created_resources: []Resource{},
required_resources: required_resources, required_resources: required_resources,
@ -272,10 +287,25 @@ func NewEventManager() * EventManager {
return state; return state;
} }
func (manager * EventManager) FindResource(id graphql.ID) Resource {
resource, exists := manager.dag_nodes[id]
if exists == false {
return nil
}
return resource
}
func (manager * EventManager) FindEvent(id graphql.ID) Event {
event := manager.root_event.FindChild(id)
return event
}
func (manager * EventManager) AddResource(resource Resource) error { func (manager * EventManager) AddResource(resource Resource) error {
_, exists := manager.dag_nodes[resource.ID()] _, exists := manager.dag_nodes[resource.ID()]
if exists == true { if exists == true {
error_str := fmt.Sprintf("%s is already in the resource DAG, cannot add again") error_str := fmt.Sprintf("%s is already in the resource DAG, cannot add again", resource.ID())
return errors.New(error_str) return errors.New(error_str)
} }

@ -0,0 +1,155 @@
package main
import (
"testing"
"time"
)
type graph_tester testing.T
const listner_timeout = 100 * time.Millisecond
func (t * graph_tester) CheckForNil(listener chan error) {
timeout := time.After(listner_timeout)
select {
case msg := <-listener:
if msg == nil {
return
} else {
t.Fatal("non-nil message on channel")
}
case <-timeout:
t.Fatal("timeout waiting for message on channel")
}
}
func (t * graph_tester) CheckForNonNil(listener chan error) {
timeout := time.After(listner_timeout)
select {
case msg := <- listener:
if msg != nil {
return
} else {
t.Fatal("nil message on channel")
}
case <-timeout:
t.Fatal("timeout waiting for message on channel")
}
}
func (t * graph_tester) CheckForNone(listener chan error) {
timeout := time.After(listner_timeout)
select {
case <- listener:
t.Fatal("message on channel")
case <-timeout:
}
}
func TestNewResourceAdd(t *testing.T) {
name := "Test Resource"
description := "A resource for testing"
children := []Resource{}
test_resource := NewResource(name, description, children)
event_manager := NewEventManager()
event_manager.AddResource(test_resource)
res := event_manager.FindResource(test_resource.ID())
if res == nil {
t.Fatal("Failed to find Resource in EventManager after adding")
}
if res.Name() != name || res.Description() != description {
t.Fatal("Name/description of returned resource did not match added resource")
}
}
func TestDoubleResourceAdd(t * testing.T) {
test_resource := NewResource("", "", []Resource{})
event_manager := NewEventManager()
err_1 := event_manager.AddResource(test_resource)
err_2 := event_manager.AddResource(test_resource)
if err_1 != nil {
t.Fatalf("First AddResource returned error %s", err_1)
}
if err_2 == nil {
t.Fatal("Second AddResource returned nil")
}
}
func TestMissingResourceAdd(t * testing.T) {
r1 := NewResource("r1", "", []Resource{})
r2 := NewResource("r2", "", []Resource{r1})
event_manager := NewEventManager()
err := event_manager.AddResource(r2)
if err == nil {
t.Fatal("AddResource with missing child returned nil")
}
}
func TestTieredResourceAdd(t * testing.T) {
r1 := NewResource("r1", "", []Resource{})
r2 := NewResource("r2", "", []Resource{r1})
event_manager := NewEventManager()
err_1 := event_manager.AddResource(r1)
err_2 := event_manager.AddResource(r2)
if err_1 != nil || err_2 != nil {
t.Fatal("Failed adding tiered resource")
}
}
func TestResourceUpdate(t * testing.T) {
r1 := NewResource("r1", "", []Resource{})
r2 := NewResource("r2", "", []Resource{})
r3 := NewResource("r3", "", []Resource{r1, r2})
event_manager := NewEventManager()
err_1 := event_manager.AddResource(r1)
err_2 := event_manager.AddResource(r2)
err_3 := event_manager.AddResource(r3)
if err_1 != nil || err_2 != nil || err_3 != nil {
t.Fatal("Failed to add initial tiered resources for test")
}
r1_l := r1.UpdateChannel()
r2_l := r2.UpdateChannel()
r3_l := r3.UpdateChannel()
// Calling Update() on the parent with no other parents should only notify node listeners
r3.Update()
(*graph_tester)(t).CheckForNone(r1_l)
(*graph_tester)(t).CheckForNone(r2_l)
(*graph_tester)(t).CheckForNil(r3_l)
// Calling Update() on a child should notify listeners of the parent and child, but not siblings
r2.Update()
(*graph_tester)(t).CheckForNone(r1_l)
(*graph_tester)(t).CheckForNil(r2_l)
(*graph_tester)(t).CheckForNil(r3_l)
// Calling Update() on a child should notify listeners of the parent and child, but not siblings
r1.Update()
(*graph_tester)(t).CheckForNil(r1_l)
(*graph_tester)(t).CheckForNone(r2_l)
(*graph_tester)(t).CheckForNil(r3_l)
}
func TestLockResource(t * testing.T) {
r1 := NewResource("r1", "", []Resource{})
r2 := NewResource("r2", "", []Resource{})
r3 := NewResource("r3", "", []Resource{r1, r2})
event_manager := NewEventManager()
err_1 := event_manager.AddResource(r1)
err_2 := event_manager.AddResource(r2)
err_3 := event_manager.AddResource(r3)
if err_1 != nil || err_2 != nil || err_3 != nil {
t.Fatal("Failed to add initial tiered resources for test")
}
}