github.com/archgrove/terraform@v0.9.5-0.20170502093151-adb789f0f8d2/command/hook_ui_test.go (about)

     1  package command
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/hashicorp/terraform/terraform"
    10  	"github.com/mitchellh/cli"
    11  	"github.com/mitchellh/colorstring"
    12  )
    13  
    14  func TestUiHookPreApply_periodicTimer(t *testing.T) {
    15  	ui := &cli.MockUi{
    16  		InputReader:  bytes.NewReader([]byte{}),
    17  		ErrorWriter:  bytes.NewBuffer([]byte{}),
    18  		OutputWriter: bytes.NewBuffer([]byte{}),
    19  	}
    20  	h := &UiHook{
    21  		Colorize: &colorstring.Colorize{
    22  			Colors:  colorstring.DefaultColors,
    23  			Disable: true,
    24  			Reset:   true,
    25  		},
    26  		Ui:              ui,
    27  		PeriodicUiTimer: 1 * time.Second,
    28  	}
    29  	h.init()
    30  	h.resources = map[string]uiResourceState{
    31  		"data.aws_availability_zones.available": uiResourceState{
    32  			Op:    uiResourceDestroy,
    33  			Start: time.Now(),
    34  		},
    35  	}
    36  
    37  	n := &terraform.InstanceInfo{
    38  		Id:         "data.aws_availability_zones.available",
    39  		ModulePath: []string{"root"},
    40  		Type:       "aws_availability_zones",
    41  	}
    42  
    43  	s := &terraform.InstanceState{
    44  		ID: "2017-03-05 10:56:59.298784526 +0000 UTC",
    45  		Attributes: map[string]string{
    46  			"id":      "2017-03-05 10:56:59.298784526 +0000 UTC",
    47  			"names.#": "4",
    48  			"names.0": "us-east-1a",
    49  			"names.1": "us-east-1b",
    50  			"names.2": "us-east-1c",
    51  			"names.3": "us-east-1d",
    52  		},
    53  	}
    54  	d := &terraform.InstanceDiff{
    55  		Destroy: true,
    56  	}
    57  
    58  	action, err := h.PreApply(n, s, d)
    59  	if err != nil {
    60  		t.Fatal(err)
    61  	}
    62  	if action != terraform.HookActionContinue {
    63  		t.Fatalf("Expected hook to continue, given: %#v", action)
    64  	}
    65  
    66  	time.Sleep(3100 * time.Millisecond)
    67  
    68  	// stop the background writer
    69  	uiState := h.resources[n.HumanId()]
    70  	close(uiState.DoneCh)
    71  	<-uiState.done
    72  
    73  	expectedOutput := `data.aws_availability_zones.available: Destroying... (ID: 2017-03-05 10:56:59.298784526 +0000 UTC)
    74  data.aws_availability_zones.available: Still destroying... (ID: 2017-03-05 10:56:59.298784526 +0000 UTC, 1s elapsed)
    75  data.aws_availability_zones.available: Still destroying... (ID: 2017-03-05 10:56:59.298784526 +0000 UTC, 2s elapsed)
    76  data.aws_availability_zones.available: Still destroying... (ID: 2017-03-05 10:56:59.298784526 +0000 UTC, 3s elapsed)
    77  `
    78  	output := ui.OutputWriter.String()
    79  	if output != expectedOutput {
    80  		t.Fatalf("Output didn't match.\nExpected: %q\nGiven: %q", expectedOutput, output)
    81  	}
    82  
    83  	expectedErrOutput := ""
    84  	errOutput := ui.ErrorWriter.String()
    85  	if errOutput != expectedErrOutput {
    86  		t.Fatalf("Error output didn't match.\nExpected: %q\nGiven: %q", expectedErrOutput, errOutput)
    87  	}
    88  }
    89  
    90  func TestUiHookPreApply_destroy(t *testing.T) {
    91  	ui := &cli.MockUi{
    92  		InputReader:  bytes.NewReader([]byte{}),
    93  		ErrorWriter:  bytes.NewBuffer([]byte{}),
    94  		OutputWriter: bytes.NewBuffer([]byte{}),
    95  	}
    96  	h := &UiHook{
    97  		Colorize: &colorstring.Colorize{
    98  			Colors:  colorstring.DefaultColors,
    99  			Disable: true,
   100  			Reset:   true,
   101  		},
   102  		Ui: ui,
   103  	}
   104  	h.init()
   105  	h.resources = map[string]uiResourceState{
   106  		"data.aws_availability_zones.available": uiResourceState{
   107  			Op:    uiResourceDestroy,
   108  			Start: time.Now(),
   109  		},
   110  	}
   111  
   112  	n := &terraform.InstanceInfo{
   113  		Id:         "data.aws_availability_zones.available",
   114  		ModulePath: []string{"root"},
   115  		Type:       "aws_availability_zones",
   116  	}
   117  
   118  	s := &terraform.InstanceState{
   119  		ID: "2017-03-05 10:56:59.298784526 +0000 UTC",
   120  		Attributes: map[string]string{
   121  			"id":      "2017-03-05 10:56:59.298784526 +0000 UTC",
   122  			"names.#": "4",
   123  			"names.0": "us-east-1a",
   124  			"names.1": "us-east-1b",
   125  			"names.2": "us-east-1c",
   126  			"names.3": "us-east-1d",
   127  		},
   128  	}
   129  	d := &terraform.InstanceDiff{
   130  		Destroy: true,
   131  	}
   132  
   133  	action, err := h.PreApply(n, s, d)
   134  	if err != nil {
   135  		t.Fatal(err)
   136  	}
   137  	if action != terraform.HookActionContinue {
   138  		t.Fatalf("Expected hook to continue, given: %#v", action)
   139  	}
   140  
   141  	expectedOutput := "data.aws_availability_zones.available: Destroying... (ID: 2017-03-05 10:56:59.298784526 +0000 UTC)\n"
   142  	output := ui.OutputWriter.String()
   143  	if output != expectedOutput {
   144  		t.Fatalf("Output didn't match.\nExpected: %q\nGiven: %q", expectedOutput, output)
   145  	}
   146  
   147  	expectedErrOutput := ""
   148  	errOutput := ui.ErrorWriter.String()
   149  	if errOutput != expectedErrOutput {
   150  		t.Fatalf("Error output didn't match.\nExpected: %q\nGiven: %q", expectedErrOutput, errOutput)
   151  	}
   152  }
   153  
   154  func TestUiHookPostApply_emptyState(t *testing.T) {
   155  	ui := &cli.MockUi{
   156  		InputReader:  bytes.NewReader([]byte{}),
   157  		ErrorWriter:  bytes.NewBuffer([]byte{}),
   158  		OutputWriter: bytes.NewBuffer([]byte{}),
   159  	}
   160  	h := &UiHook{
   161  		Colorize: &colorstring.Colorize{
   162  			Colors:  colorstring.DefaultColors,
   163  			Disable: true,
   164  			Reset:   true,
   165  		},
   166  		Ui: ui,
   167  	}
   168  	h.init()
   169  	h.resources = map[string]uiResourceState{
   170  		"data.google_compute_zones.available": uiResourceState{
   171  			Op:    uiResourceDestroy,
   172  			Start: time.Now(),
   173  		},
   174  	}
   175  
   176  	n := &terraform.InstanceInfo{
   177  		Id:         "data.google_compute_zones.available",
   178  		ModulePath: []string{"root"},
   179  		Type:       "google_compute_zones",
   180  	}
   181  	action, err := h.PostApply(n, nil, nil)
   182  	if err != nil {
   183  		t.Fatal(err)
   184  	}
   185  	if action != terraform.HookActionContinue {
   186  		t.Fatalf("Expected hook to continue, given: %#v", action)
   187  	}
   188  
   189  	expectedOutput := "data.google_compute_zones.available: Destruction complete\n"
   190  	output := ui.OutputWriter.String()
   191  	if output != expectedOutput {
   192  		t.Fatalf("Output didn't match.\nExpected: %q\nGiven: %q", expectedOutput, output)
   193  	}
   194  
   195  	expectedErrOutput := ""
   196  	errOutput := ui.ErrorWriter.String()
   197  	if errOutput != expectedErrOutput {
   198  		t.Fatalf("Error output didn't match.\nExpected: %q\nGiven: %q", expectedErrOutput, errOutput)
   199  	}
   200  }
   201  
   202  func TestTruncateId(t *testing.T) {
   203  	testCases := []struct {
   204  		Input    string
   205  		Expected string
   206  		MaxLen   int
   207  	}{
   208  		{
   209  			Input:    "Hello world",
   210  			Expected: "H...d",
   211  			MaxLen:   3,
   212  		},
   213  		{
   214  			Input:    "Hello world",
   215  			Expected: "H...d",
   216  			MaxLen:   5,
   217  		},
   218  		{
   219  			Input:    "Hello world",
   220  			Expected: "He...d",
   221  			MaxLen:   6,
   222  		},
   223  		{
   224  			Input:    "Hello world",
   225  			Expected: "He...ld",
   226  			MaxLen:   7,
   227  		},
   228  		{
   229  			Input:    "Hello world",
   230  			Expected: "Hel...ld",
   231  			MaxLen:   8,
   232  		},
   233  		{
   234  			Input:    "Hello world",
   235  			Expected: "Hel...rld",
   236  			MaxLen:   9,
   237  		},
   238  		{
   239  			Input:    "Hello world",
   240  			Expected: "Hell...rld",
   241  			MaxLen:   10,
   242  		},
   243  		{
   244  			Input:    "Hello world",
   245  			Expected: "Hello world",
   246  			MaxLen:   11,
   247  		},
   248  		{
   249  			Input:    "Hello world",
   250  			Expected: "Hello world",
   251  			MaxLen:   12,
   252  		},
   253  	}
   254  	for i, tc := range testCases {
   255  		testName := fmt.Sprintf("%d", i)
   256  		t.Run(testName, func(t *testing.T) {
   257  			out := truncateId(tc.Input, tc.MaxLen)
   258  			if out != tc.Expected {
   259  				t.Fatalf("Expected %q to be shortened to %d as %q (given: %q)",
   260  					tc.Input, tc.MaxLen, tc.Expected, out)
   261  			}
   262  		})
   263  	}
   264  }