github.com/dahs81/otto@v0.2.1-0.20160126165905-6400716cf085/helper/vagrant/layered_test.go (about)

     1  package vagrant
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  	"reflect"
     8  	"testing"
     9  
    10  	"github.com/hashicorp/otto/context"
    11  	"github.com/hashicorp/otto/helper/exec"
    12  	"github.com/hashicorp/otto/ui"
    13  	"github.com/hashicorp/terraform/dag"
    14  )
    15  
    16  func TestLayerVertex_impl(t *testing.T) {
    17  	var _ dag.Hashable = new(layerVertex)
    18  }
    19  
    20  func TestLayeredBuild(t *testing.T) {
    21  	dir := tempDir(t)
    22  	defer os.RemoveAll(dir)
    23  
    24  	runner := new(exec.MockRunner)
    25  	defer exec.TestChrunner(runner.Run)()
    26  
    27  	// Build an environment using foo and bar
    28  	layer := &Layered{
    29  		DataDir: dir,
    30  		Layers: []*Layer{
    31  			testLayer(t, "foo", dir),
    32  			testLayer(t, "bar", dir),
    33  		},
    34  	}
    35  
    36  	ctx := testContextShared(t)
    37  	if err := layer.Build(ctx); err != nil {
    38  		t.Fatalf("err: %s", err)
    39  	}
    40  
    41  	if len(runner.Commands) != 6 {
    42  		t.Fatalf("bad: %#v", runner.Commands)
    43  	}
    44  
    45  	// Clear the commands so we only count what is next
    46  	runner.Commands = nil
    47  
    48  	// Setup the output
    49  	okayOutput := "1451607142,default,state,running\n"
    50  	runner.CommandOutput = []string{okayOutput, okayOutput}
    51  
    52  	// Repeat the test since this should be a no-op
    53  	if err := layer.Build(ctx); err != nil {
    54  		t.Fatalf("err: %s", err)
    55  	}
    56  	if len(runner.Commands) != 2 {
    57  		t.Fatalf("bad: %#v", runner.Commands)
    58  	}
    59  }
    60  
    61  func TestLayeredBuild_verify(t *testing.T) {
    62  	dir := tempDir(t)
    63  	defer os.RemoveAll(dir)
    64  
    65  	runner := new(exec.MockRunner)
    66  	defer exec.TestChrunner(runner.Run)()
    67  
    68  	// Build an environment using foo and bar
    69  	layer := &Layered{
    70  		DataDir: dir,
    71  		Layers: []*Layer{
    72  			testLayer(t, "foo", dir),
    73  			testLayer(t, "bar", dir),
    74  		},
    75  	}
    76  
    77  	ctx := testContextShared(t)
    78  	if err := layer.Build(ctx); err != nil {
    79  		t.Fatalf("err: %s", err)
    80  	}
    81  
    82  	if len(runner.Commands) != 6 {
    83  		t.Fatalf("bad: %#v", runner.Commands)
    84  	}
    85  
    86  	// Clear the commands so we only count what is next
    87  	runner.Commands = nil
    88  
    89  	// Setup the output so we recreate the second
    90  	okayOutput := "1451607142,default,state,running\n"
    91  	runner.CommandOutput = []string{okayOutput, "bad"}
    92  
    93  	// Repeat the test since this should be a no-op
    94  	if err := layer.Build(ctx); err != nil {
    95  		t.Fatalf("err: %s", err)
    96  	}
    97  	if len(runner.Commands) != 5 {
    98  		t.Fatalf("bad: %#v", runner.Commands)
    99  	}
   100  }
   101  
   102  func TestLayeredPending_new(t *testing.T) {
   103  	dir := tempDir(t)
   104  	defer os.RemoveAll(dir)
   105  
   106  	runner := new(exec.MockRunner)
   107  	defer exec.TestChrunner(runner.Run)()
   108  
   109  	layer := &Layered{
   110  		DataDir: dir,
   111  		Layers: []*Layer{
   112  			testLayer(t, "foo", dir),
   113  			testLayer(t, "bar", dir),
   114  		},
   115  	}
   116  
   117  	pending, err := layer.Pending()
   118  	if err != nil {
   119  		t.Fatalf("err: %s", err)
   120  	}
   121  
   122  	expected := []string{"foo", "bar"}
   123  	if !reflect.DeepEqual(pending, expected) {
   124  		t.Fatalf("bad: %#v", pending)
   125  	}
   126  }
   127  
   128  func TestLayeredPending_partial(t *testing.T) {
   129  	dir := tempDir(t)
   130  	defer os.RemoveAll(dir)
   131  
   132  	runner := new(exec.MockRunner)
   133  	defer exec.TestChrunner(runner.Run)()
   134  
   135  	// Build the foo layer
   136  	layer := &Layered{
   137  		DataDir: dir,
   138  		Layers: []*Layer{
   139  			testLayer(t, "foo", dir),
   140  		},
   141  	}
   142  
   143  	ctx := testContextShared(t)
   144  	if err := layer.Build(ctx); err != nil {
   145  		t.Fatalf("err: %s", err)
   146  	}
   147  
   148  	// Add the bar layer
   149  	layer.Layers = append(layer.Layers, testLayer(t, "bar", dir))
   150  
   151  	// Grab the pending
   152  	pending, err := layer.Pending()
   153  	if err != nil {
   154  		t.Fatalf("err: %s", err)
   155  	}
   156  
   157  	expected := []string{"bar"}
   158  	if !reflect.DeepEqual(pending, expected) {
   159  		t.Fatalf("bad: %#v", pending)
   160  	}
   161  }
   162  
   163  func TestLayeredPrune(t *testing.T) {
   164  	dir := tempDir(t)
   165  	defer os.RemoveAll(dir)
   166  
   167  	runner := new(exec.MockRunner)
   168  	defer exec.TestChrunner(runner.Run)()
   169  
   170  	// Build an environment using foo and bar
   171  	layer := &Layered{
   172  		DataDir: dir,
   173  		Layers: []*Layer{
   174  			testLayer(t, "foo", dir),
   175  			testLayer(t, "bar", dir),
   176  		},
   177  	}
   178  
   179  	ctx := testContextShared(t)
   180  	if err := layer.Build(ctx); err != nil {
   181  		t.Fatalf("err: %s", err)
   182  	}
   183  
   184  	// Add an environment
   185  	env := &Vagrant{DataDir: filepath.Join(dir, "v1")}
   186  	if err := layer.ConfigureEnv(env); err != nil {
   187  		t.Fatalf("err: %s", err)
   188  	}
   189  	if err := layer.SetEnv(env, envStateReady); err != nil {
   190  		t.Fatalf("err: %s", err)
   191  	}
   192  
   193  	// Clear the commands because we only want to count those
   194  	runner.Commands = nil
   195  
   196  	// Prune should not do anything
   197  	if _, err := layer.Prune(ctx); err != nil {
   198  		t.Fatalf("err: %s", err)
   199  	}
   200  	if len(runner.Commands) > 0 {
   201  		t.Fatalf("bad: %#v", runner.Commands)
   202  	}
   203  }
   204  
   205  func TestLayeredPrune_empty(t *testing.T) {
   206  	dir := tempDir(t)
   207  	defer os.RemoveAll(dir)
   208  
   209  	runner := new(exec.MockRunner)
   210  	defer exec.TestChrunner(runner.Run)()
   211  
   212  	layer := &Layered{
   213  		DataDir: dir,
   214  		Layers: []*Layer{
   215  			testLayer(t, "foo", dir),
   216  			testLayer(t, "bar", dir),
   217  		},
   218  	}
   219  
   220  	if _, err := layer.Prune(testContextShared(t)); err != nil {
   221  		t.Fatalf("err: %s", err)
   222  	}
   223  
   224  	if len(runner.Commands) > 0 {
   225  		t.Fatalf("bad: %#v", runner.Commands)
   226  	}
   227  }
   228  
   229  func TestLayeredPrune_all(t *testing.T) {
   230  	dir := tempDir(t)
   231  	defer os.RemoveAll(dir)
   232  
   233  	runner := new(exec.MockRunner)
   234  	defer exec.TestChrunner(runner.Run)()
   235  
   236  	layer := &Layered{
   237  		DataDir: dir,
   238  		Layers: []*Layer{
   239  			testLayer(t, "foo", dir),
   240  			testLayer(t, "bar", dir),
   241  		},
   242  	}
   243  
   244  	ctx := testContextShared(t)
   245  	if err := layer.Build(ctx); err != nil {
   246  		t.Fatalf("err: %s", err)
   247  	}
   248  
   249  	// Clear the commands because we only want to count those
   250  	runner.Commands = nil
   251  	if _, err := layer.Prune(ctx); err != nil {
   252  		t.Fatalf("err: %s", err)
   253  	}
   254  
   255  	// 2 vagrant destroy -f
   256  	if len(runner.Commands) != 2 {
   257  		t.Fatalf("bad: %#v", runner.Commands)
   258  	}
   259  }
   260  
   261  func testContextShared(t *testing.T) *context.Shared {
   262  	return &context.Shared{
   263  		Ui: &ui.Logged{Ui: new(ui.Mock)},
   264  	}
   265  }
   266  
   267  func testLayer(t *testing.T, id string, dir string) *Layer {
   268  	dir = filepath.Join(dir, id)
   269  	if err := os.MkdirAll(dir, 0755); err != nil {
   270  		t.Fatalf("err: %s", err)
   271  	}
   272  
   273  	vagrantfile := filepath.Join(dir, "Vagrantfile")
   274  	if err := ioutil.WriteFile(vagrantfile, []byte("hello"), 0644); err != nil {
   275  		t.Fatalf("err: %s", err)
   276  	}
   277  
   278  	return &Layer{
   279  		ID:          id,
   280  		Vagrantfile: vagrantfile,
   281  	}
   282  }
   283  
   284  func tempDir(t *testing.T) string {
   285  	dir, err := ioutil.TempDir("", "otto")
   286  	if err != nil {
   287  		t.Fatalf("err: %s", err)
   288  	}
   289  
   290  	return dir
   291  }