github.com/lymingtonprecision/terraform@v0.9.9-0.20170613092852-62acef9611a9/builtin/providers/test/data_source_test.go (about)

     1  package test
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/hashicorp/terraform/helper/resource"
    10  	"github.com/hashicorp/terraform/terraform"
    11  )
    12  
    13  func TestDataSource_dataSourceCount(t *testing.T) {
    14  	resource.UnitTest(t, resource.TestCase{
    15  		Providers: testAccProviders,
    16  		CheckDestroy: func(s *terraform.State) error {
    17  			return nil
    18  		},
    19  		Steps: []resource.TestStep{
    20  			{
    21  				Config: strings.TrimSpace(`
    22  data "test_data_source" "test" {
    23    count = 3
    24    input = "count-${count.index}"
    25  }
    26  
    27  resource "test_resource" "foo" {
    28    required     = "yep"
    29    required_map = {
    30      key = "value"
    31    }
    32  
    33    list = ["${data.test_data_source.test.*.output}"]
    34  }
    35  				`),
    36  				Check: func(s *terraform.State) error {
    37  					res, hasRes := s.RootModule().Resources["test_resource.foo"]
    38  					if !hasRes {
    39  						return errors.New("No test_resource.foo in state")
    40  					}
    41  					if res.Primary.Attributes["list.#"] != "3" {
    42  						return errors.New("Wrong list.#, expected 3")
    43  					}
    44  					if res.Primary.Attributes["list.0"] != "count-0" {
    45  						return errors.New("Wrong list.0, expected count-0")
    46  					}
    47  					if res.Primary.Attributes["list.1"] != "count-1" {
    48  						return errors.New("Wrong list.0, expected count-1")
    49  					}
    50  					if res.Primary.Attributes["list.2"] != "count-2" {
    51  						return errors.New("Wrong list.0, expected count-2")
    52  					}
    53  					return nil
    54  				},
    55  			},
    56  		},
    57  	})
    58  }
    59  
    60  // Test that the output of a data source can be used as the value for
    61  // a "count" in a real resource. This would fail with "count cannot be computed"
    62  // at some point.
    63  func TestDataSource_valueAsResourceCount(t *testing.T) {
    64  	resource.UnitTest(t, resource.TestCase{
    65  		Providers: testAccProviders,
    66  		CheckDestroy: func(s *terraform.State) error {
    67  			return nil
    68  		},
    69  		Steps: []resource.TestStep{
    70  			{
    71  				Config: strings.TrimSpace(`
    72  data "test_data_source" "test" {
    73    input = "4"
    74  }
    75  
    76  resource "test_resource" "foo" {
    77    count = "${data.test_data_source.test.output}"
    78  
    79    required     = "yep"
    80    required_map = {
    81      key = "value"
    82    }
    83  }
    84  				`),
    85  				Check: func(s *terraform.State) error {
    86  					count := 0
    87  					for k, _ := range s.RootModule().Resources {
    88  						if strings.HasPrefix(k, "test_resource.foo.") {
    89  							count++
    90  						}
    91  					}
    92  
    93  					if count != 4 {
    94  						return fmt.Errorf("bad count: %d", count)
    95  					}
    96  					return nil
    97  				},
    98  			},
    99  		},
   100  	})
   101  }
   102  
   103  // TestDataSource_dataSourceCountGrandChild tests that a grandchild data source
   104  // that is based off of count works, ie: dependency chain foo -> bar -> baz.
   105  // This was failing because CountBoundaryTransformer is being run during apply
   106  // instead of plan, which meant that it wasn't firing after data sources were
   107  // potentially changing state and causing diff/interpolation issues.
   108  //
   109  // This happens after the initial apply, after state is saved.
   110  func TestDataSource_dataSourceCountGrandChild(t *testing.T) {
   111  	resource.UnitTest(t, resource.TestCase{
   112  		Providers: testAccProviders,
   113  		CheckDestroy: func(s *terraform.State) error {
   114  			return nil
   115  		},
   116  		Steps: []resource.TestStep{
   117  			{
   118  				Config: dataSourceCountGrandChildConfig,
   119  			},
   120  			{
   121  				Config: dataSourceCountGrandChildConfig,
   122  				Check: func(s *terraform.State) error {
   123  					for _, v := range []string{"foo", "bar", "baz"} {
   124  						count := 0
   125  						for k := range s.RootModule().Resources {
   126  							if strings.HasPrefix(k, fmt.Sprintf("data.test_data_source.%s.", v)) {
   127  								count++
   128  							}
   129  						}
   130  
   131  						if count != 2 {
   132  							return fmt.Errorf("bad count for data.test_data_source.%s: %d", v, count)
   133  						}
   134  					}
   135  					return nil
   136  				},
   137  			},
   138  		},
   139  	})
   140  }
   141  
   142  const dataSourceCountGrandChildConfig = `
   143  data "test_data_source" "foo" {
   144    count = 2
   145    input = "one"
   146  }
   147  
   148  data "test_data_source" "bar" {
   149    count = "${length(data.test_data_source.foo.*.id)}"
   150    input = "${data.test_data_source.foo.*.output[count.index]}"
   151  }
   152  
   153  data "test_data_source" "baz" {
   154    count = "${length(data.test_data_source.bar.*.id)}"
   155    input = "${data.test_data_source.bar.*.output[count.index]}"
   156  }
   157  `