terraform: test that state is properly sent to Refresh

This commit is contained in:
Mitchell Hashimoto 2014-06-25 15:52:15 -07:00
parent 8a44ca984e
commit c68cfc5e6f
3 changed files with 60 additions and 11 deletions

View File

@ -54,7 +54,7 @@ func Graph(c *config.Config, s *State) *depgraph.Graph {
// First, build the initial resource graph. This only has the resources // First, build the initial resource graph. This only has the resources
// and no dependencies. // and no dependencies.
graphAddConfigResources(g, c) graphAddConfigResources(g, c, s)
// Next, add the state orphans if we have any // Next, add the state orphans if we have any
if s != nil { if s != nil {
@ -103,17 +103,24 @@ func GraphFull(g *depgraph.Graph, ps map[string]ResourceProviderFactory) error {
} }
// configGraph turns a configuration structure into a dependency graph. // configGraph turns a configuration structure into a dependency graph.
func graphAddConfigResources(g *depgraph.Graph, c *config.Config) { func graphAddConfigResources(
g *depgraph.Graph, c *config.Config, s *State) {
// This tracks all the resource nouns // This tracks all the resource nouns
nouns := make(map[string]*depgraph.Noun) nouns := make(map[string]*depgraph.Noun)
for _, r := range c.Resources { for _, r := range c.Resources {
var state *ResourceState
if s != nil {
state = s.Resources[r.Id()]
}
noun := &depgraph.Noun{ noun := &depgraph.Noun{
Name: r.Id(), Name: r.Id(),
Meta: &GraphNodeResource{ Meta: &GraphNodeResource{
Type: r.Type, Type: r.Type,
Config: r, Config: r,
Resource: &Resource{ Resource: &Resource{
Id: r.Id(), Id: r.Id(),
State: state,
}, },
}, },
} }

View File

@ -142,23 +142,22 @@ func (t *Terraform) Plan(s *State) (*Plan, error) {
// Refresh goes through all the resources in the state and refreshes them // Refresh goes through all the resources in the state and refreshes them
// to their latest status. // to their latest status.
func (t *Terraform) Refresh( func (t *Terraform) Refresh(c *config.Config, s *State) (*State, error) {
c *config.Config, s *State, vs map[string]string) (*State, error) {
g, err := t.Graph(c, s) g, err := t.Graph(c, s)
if err != nil { if err != nil {
return s, err return s, err
} }
return t.refresh(g, vs) return t.refresh(g)
} }
func (t *Terraform) refresh(g *depgraph.Graph, vars map[string]string) (*State, error) { func (t *Terraform) refresh(g *depgraph.Graph) (*State, error) {
s := new(State) s := new(State)
err := g.Walk(t.refreshWalkFn(vars, s)) err := g.Walk(t.refreshWalkFn(s))
return s, err return s, err
} }
func (t *Terraform) refreshWalkFn(vars map[string]string, result *State) depgraph.WalkFunc { func (t *Terraform) refreshWalkFn(result *State) depgraph.WalkFunc {
var l sync.Mutex var l sync.Mutex
// Initialize the result so we don't have to nil check everywhere // Initialize the result so we don't have to nil check everywhere
@ -177,7 +176,7 @@ func (t *Terraform) refreshWalkFn(vars map[string]string, result *State) depgrap
return nil, nil return nil, nil
} }
return t.genericWalkFn(vars, cb) return t.genericWalkFn(nil, cb)
} }
func (t *Terraform) applyWalkFn( func (t *Terraform) applyWalkFn(

View File

@ -226,13 +226,56 @@ func TestTerraformRefresh(t *testing.T) {
ID: "foo", ID: "foo",
} }
s, err := tf.Refresh(c, nil, nil) s, err := tf.Refresh(c, nil)
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
if !rpAWS.RefreshCalled { if !rpAWS.RefreshCalled {
t.Fatal("refresh should be called") t.Fatal("refresh should be called")
} }
if rpAWS.RefreshState != nil {
t.Fatalf("bad: %#v", rpAWS.RefreshState)
}
if !reflect.DeepEqual(s.Resources["aws_instance.web"], rpAWS.RefreshReturn) {
t.Fatalf("bad: %#v", s.Resources)
}
}
func TestTerraformRefresh_state(t *testing.T) {
rpAWS := new(MockResourceProvider)
rpAWS.ResourcesReturn = []ResourceType{
ResourceType{Name: "aws_instance"},
}
c := testConfig(t, "refresh-basic")
tf := testTerraform2(t, &Config{
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(rpAWS),
},
})
rpAWS.RefreshReturn = &ResourceState{
ID: "foo",
}
state := &State{
Resources: map[string]*ResourceState{
"aws_instance.web": &ResourceState{
ID: "bar",
},
},
}
s, err := tf.Refresh(c, state)
if err != nil {
t.Fatalf("err: %s", err)
}
if !rpAWS.RefreshCalled {
t.Fatal("refresh should be called")
}
if !reflect.DeepEqual(rpAWS.RefreshState, state.Resources["aws_instance.web"]) {
t.Fatalf("bad: %#v", rpAWS.RefreshState)
}
if !reflect.DeepEqual(s.Resources["aws_instance.web"], rpAWS.RefreshReturn) { if !reflect.DeepEqual(s.Resources["aws_instance.web"], rpAWS.RefreshReturn) {
t.Fatalf("bad: %#v", s.Resources) t.Fatalf("bad: %#v", s.Resources)
} }