github.com/bfallik/terraform@v0.7.1-0.20160814101525-d3a4714efbf5/command/command_test.go (about) 1 package command 2 3 import ( 4 "flag" 5 "io/ioutil" 6 "log" 7 "os" 8 "path/filepath" 9 "strings" 10 "testing" 11 12 "github.com/hashicorp/go-getter" 13 "github.com/hashicorp/terraform/config/module" 14 "github.com/hashicorp/terraform/helper/logging" 15 "github.com/hashicorp/terraform/terraform" 16 ) 17 18 // This is the directory where our test fixtures are. 19 var fixtureDir = "./test-fixtures" 20 21 func init() { 22 test = true 23 24 // Expand the fixture dir on init because we change the working 25 // directory in some tests. 26 var err error 27 fixtureDir, err = filepath.Abs(fixtureDir) 28 if err != nil { 29 panic(err) 30 } 31 } 32 33 func TestMain(m *testing.M) { 34 flag.Parse() 35 if testing.Verbose() { 36 // if we're verbose, use the logging requested by TF_LOG 37 logging.SetOutput() 38 } else { 39 // otherwise silence all logs 40 log.SetOutput(ioutil.Discard) 41 } 42 43 os.Exit(m.Run()) 44 } 45 46 func tempDir(t *testing.T) string { 47 dir, err := ioutil.TempDir("", "tf") 48 if err != nil { 49 t.Fatalf("err: %s", err) 50 } 51 if err := os.RemoveAll(dir); err != nil { 52 t.Fatalf("err: %s", err) 53 } 54 55 return dir 56 } 57 58 func testFixturePath(name string) string { 59 return filepath.Join(fixtureDir, name) 60 } 61 62 func testCtxConfig(p terraform.ResourceProvider) *terraform.ContextOpts { 63 return &terraform.ContextOpts{ 64 Providers: map[string]terraform.ResourceProviderFactory{ 65 "test": func() (terraform.ResourceProvider, error) { 66 return p, nil 67 }, 68 }, 69 } 70 } 71 72 func testCtxConfigWithShell(p terraform.ResourceProvider, pr terraform.ResourceProvisioner) *terraform.ContextOpts { 73 return &terraform.ContextOpts{ 74 Providers: map[string]terraform.ResourceProviderFactory{ 75 "test": func() (terraform.ResourceProvider, error) { 76 return p, nil 77 }, 78 }, 79 Provisioners: map[string]terraform.ResourceProvisionerFactory{ 80 "shell": func() (terraform.ResourceProvisioner, error) { 81 return pr, nil 82 }, 83 }, 84 } 85 } 86 87 func testModule(t *testing.T, name string) *module.Tree { 88 mod, err := module.NewTreeModule("", filepath.Join(fixtureDir, name)) 89 if err != nil { 90 t.Fatalf("err: %s", err) 91 } 92 93 s := &getter.FolderStorage{StorageDir: tempDir(t)} 94 if err := mod.Load(s, module.GetModeGet); err != nil { 95 t.Fatalf("err: %s", err) 96 } 97 98 return mod 99 } 100 101 func testPlanFile(t *testing.T, plan *terraform.Plan) string { 102 path := testTempFile(t) 103 104 f, err := os.Create(path) 105 if err != nil { 106 t.Fatalf("err: %s", err) 107 } 108 defer f.Close() 109 110 if err := terraform.WritePlan(plan, f); err != nil { 111 t.Fatalf("err: %s", err) 112 } 113 114 return path 115 } 116 117 func testReadPlan(t *testing.T, path string) *terraform.Plan { 118 f, err := os.Open(path) 119 if err != nil { 120 t.Fatalf("err: %s", err) 121 } 122 defer f.Close() 123 124 p, err := terraform.ReadPlan(f) 125 if err != nil { 126 t.Fatalf("err: %s", err) 127 } 128 129 return p 130 } 131 132 // testState returns a test State structure that we use for a lot of tests. 133 func testState() *terraform.State { 134 return &terraform.State{ 135 Version: 2, 136 Modules: []*terraform.ModuleState{ 137 &terraform.ModuleState{ 138 Path: []string{"root"}, 139 Resources: map[string]*terraform.ResourceState{ 140 "test_instance.foo": &terraform.ResourceState{ 141 Type: "test_instance", 142 Primary: &terraform.InstanceState{ 143 ID: "bar", 144 }, 145 }, 146 }, 147 Outputs: map[string]*terraform.OutputState{}, 148 }, 149 }, 150 } 151 } 152 153 func testStateFile(t *testing.T, s *terraform.State) string { 154 path := testTempFile(t) 155 156 f, err := os.Create(path) 157 if err != nil { 158 t.Fatalf("err: %s", err) 159 } 160 defer f.Close() 161 162 if err := terraform.WriteState(s, f); err != nil { 163 t.Fatalf("err: %s", err) 164 } 165 166 return path 167 } 168 169 // testStateFileDefault writes the state out to the default statefile 170 // in the cwd. Use `testCwd` to change into a temp cwd. 171 func testStateFileDefault(t *testing.T, s *terraform.State) string { 172 f, err := os.Create(DefaultStateFilename) 173 if err != nil { 174 t.Fatalf("err: %s", err) 175 } 176 defer f.Close() 177 178 if err := terraform.WriteState(s, f); err != nil { 179 t.Fatalf("err: %s", err) 180 } 181 182 return DefaultStateFilename 183 } 184 185 // testStateFileRemote writes the state out to the remote statefile 186 // in the cwd. Use `testCwd` to change into a temp cwd. 187 func testStateFileRemote(t *testing.T, s *terraform.State) string { 188 path := filepath.Join(DefaultDataDir, DefaultStateFilename) 189 if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { 190 t.Fatalf("err: %s", err) 191 } 192 193 f, err := os.Create(path) 194 if err != nil { 195 t.Fatalf("err: %s", err) 196 } 197 defer f.Close() 198 199 if err := terraform.WriteState(s, f); err != nil { 200 t.Fatalf("err: %s", err) 201 } 202 203 return path 204 } 205 206 // testStateOutput tests that the state at the given path contains 207 // the expected state string. 208 func testStateOutput(t *testing.T, path string, expected string) { 209 f, err := os.Open(path) 210 if err != nil { 211 t.Fatalf("err: %s", err) 212 } 213 214 newState, err := terraform.ReadState(f) 215 f.Close() 216 if err != nil { 217 t.Fatalf("err: %s", err) 218 } 219 220 actual := strings.TrimSpace(newState.String()) 221 expected = strings.TrimSpace(expected) 222 if actual != expected { 223 t.Fatalf("expected:\n%s\nactual:\n%s", expected, actual) 224 } 225 } 226 227 func testProvider() *terraform.MockResourceProvider { 228 p := new(terraform.MockResourceProvider) 229 p.DiffReturn = &terraform.InstanceDiff{} 230 p.RefreshFn = func( 231 info *terraform.InstanceInfo, 232 s *terraform.InstanceState) (*terraform.InstanceState, error) { 233 return s, nil 234 } 235 p.ResourcesReturn = []terraform.ResourceType{ 236 terraform.ResourceType{ 237 Name: "test_instance", 238 }, 239 } 240 241 return p 242 } 243 244 func testTempFile(t *testing.T) string { 245 return filepath.Join(testTempDir(t), "state.tfstate") 246 } 247 248 func testTempDir(t *testing.T) string { 249 d, err := ioutil.TempDir("", "tf") 250 if err != nil { 251 t.Fatalf("err: %s", err) 252 } 253 254 return d 255 } 256 257 // testCwd is used to change the current working directory 258 // into a test directory that should be remoted after 259 func testCwd(t *testing.T) (string, string) { 260 tmp, err := ioutil.TempDir("", "tf") 261 if err != nil { 262 t.Fatalf("err: %v", err) 263 } 264 265 cwd, err := os.Getwd() 266 if err != nil { 267 t.Fatalf("err: %v", err) 268 } 269 270 if err := os.Chdir(tmp); err != nil { 271 t.Fatalf("err: %v", err) 272 } 273 274 return tmp, cwd 275 } 276 277 // testFixCwd is used to as a defer to testDir 278 func testFixCwd(t *testing.T, tmp, cwd string) { 279 if err := os.Chdir(cwd); err != nil { 280 t.Fatalf("err: %v", err) 281 } 282 283 if err := os.RemoveAll(tmp); err != nil { 284 t.Fatalf("err: %v", err) 285 } 286 }