package http import ( "fmt" "net/http" "net/http/httptest" "regexp" "testing" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" ) type TestHttpMock struct { server *httptest.Server } const testDataSourceConfig_basic = ` data "http" "http_test" { url = "%s/meta_%d.txt" } output "body" { value = "${data.http.http_test.body}" } ` func TestDataSource_http200(t *testing.T) { testHttpMock := setUpMockHttpServer() defer testHttpMock.server.Close() resource.UnitTest(t, resource.TestCase{ Providers: testProviders, Steps: []resource.TestStep{ resource.TestStep{ Config: fmt.Sprintf(testDataSourceConfig_basic, testHttpMock.server.URL, 200), Check: func(s *terraform.State) error { _, ok := s.RootModule().Resources["data.http.http_test"] if !ok { return fmt.Errorf("missing data resource") } outputs := s.RootModule().Outputs if outputs["body"].Value != "1.0.0" { return fmt.Errorf( `'body' output is %s; want '1.0.0'`, outputs["body"].Value, ) } return nil }, }, }, }) } func TestDataSource_http404(t *testing.T) { testHttpMock := setUpMockHttpServer() defer testHttpMock.server.Close() resource.UnitTest(t, resource.TestCase{ Providers: testProviders, Steps: []resource.TestStep{ resource.TestStep{ Config: fmt.Sprintf(testDataSourceConfig_basic, testHttpMock.server.URL, 404), ExpectError: regexp.MustCompile("HTTP request error. Response code: 404"), }, }, }) } const testDataSourceConfig_withHeaders = ` data "http" "http_test" { url = "%s/restricted/meta_%d.txt" request_headers = { "Authorization" = "Zm9vOmJhcg==" } } output "body" { value = "${data.http.http_test.body}" } ` func TestDataSource_withHeaders200(t *testing.T) { testHttpMock := setUpMockHttpServer() defer testHttpMock.server.Close() resource.UnitTest(t, resource.TestCase{ Providers: testProviders, Steps: []resource.TestStep{ resource.TestStep{ Config: fmt.Sprintf(testDataSourceConfig_withHeaders, testHttpMock.server.URL, 200), Check: func(s *terraform.State) error { _, ok := s.RootModule().Resources["data.http.http_test"] if !ok { return fmt.Errorf("missing data resource") } outputs := s.RootModule().Outputs if outputs["body"].Value != "1.0.0" { return fmt.Errorf( `'body' output is %s; want '1.0.0'`, outputs["body"].Value, ) } return nil }, }, }, }) } const testDataSourceConfig_error = ` data "http" "http_test" { } ` func TestDataSource_compileError(t *testing.T) { resource.UnitTest(t, resource.TestCase{ Providers: testProviders, Steps: []resource.TestStep{ resource.TestStep{ Config: testDataSourceConfig_error, ExpectError: regexp.MustCompile("required field is not set"), }, }, }) } func setUpMockHttpServer() *TestHttpMock { Server := httptest.NewServer( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/meta_200.txt" { w.WriteHeader(http.StatusOK) w.Write([]byte("1.0.0")) } else if r.URL.Path == "/restricted/meta_200.txt" { if r.Header.Get("Authorization") == "Zm9vOmJhcg==" { w.WriteHeader(http.StatusOK) w.Write([]byte("1.0.0")) } else { w.WriteHeader(http.StatusForbidden) } } else if r.URL.Path == "/meta_404.txt" { w.WriteHeader(http.StatusNotFound) } else { w.WriteHeader(http.StatusNotFound) } w.Header().Add("Content-Type", "text/plain") }), ) return &TestHttpMock{ server: Server, } }