github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/provider/common/destroy_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common_test
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  	"strings"
    10  
    11  	gitjujutesting "github.com/juju/testing"
    12  	jc "github.com/juju/testing/checkers"
    13  	gc "gopkg.in/check.v1"
    14  
    15  	"github.com/juju/juju/environs"
    16  	"github.com/juju/juju/environs/config"
    17  	"github.com/juju/juju/instance"
    18  	"github.com/juju/juju/provider/common"
    19  	"github.com/juju/juju/storage"
    20  	"github.com/juju/juju/storage/provider/dummy"
    21  	"github.com/juju/juju/storage/provider/registry"
    22  	"github.com/juju/juju/testing"
    23  	jujuversion "github.com/juju/juju/version"
    24  )
    25  
    26  type DestroySuite struct {
    27  	testing.BaseSuite
    28  }
    29  
    30  var _ = gc.Suite(&DestroySuite{})
    31  
    32  func (s *DestroySuite) TestCannotGetInstances(c *gc.C) {
    33  	env := &mockEnviron{
    34  		allInstances: func() ([]instance.Instance, error) {
    35  			return nil, fmt.Errorf("nope")
    36  		},
    37  		config: configGetter(c),
    38  	}
    39  	err := common.Destroy(env)
    40  	c.Assert(err, gc.ErrorMatches, "destroying instances: nope")
    41  }
    42  
    43  func (s *DestroySuite) TestCannotStopInstances(c *gc.C) {
    44  	env := &mockEnviron{
    45  		allInstances: func() ([]instance.Instance, error) {
    46  			return []instance.Instance{
    47  				&mockInstance{id: "one"},
    48  				&mockInstance{id: "another"},
    49  			}, nil
    50  		},
    51  		stopInstances: func(ids []instance.Id) error {
    52  			c.Assert(ids, gc.HasLen, 2)
    53  			c.Assert(ids[0], gc.Equals, instance.Id("one"))
    54  			c.Assert(ids[1], gc.Equals, instance.Id("another"))
    55  			return fmt.Errorf("nah")
    56  		},
    57  		config: configGetter(c),
    58  	}
    59  	err := common.Destroy(env)
    60  	c.Assert(err, gc.ErrorMatches, "destroying instances: nah")
    61  }
    62  
    63  func (s *DestroySuite) TestSuccessWhenStorageErrors(c *gc.C) {
    64  	// common.Destroy doesn't touch provider/object storage anymore,
    65  	// so failing storage should not affect success.
    66  	env := &mockEnviron{
    67  		storage: &mockStorage{removeAllErr: fmt.Errorf("noes!")},
    68  		allInstances: func() ([]instance.Instance, error) {
    69  			return []instance.Instance{
    70  				&mockInstance{id: "one"},
    71  				&mockInstance{id: "another"},
    72  			}, nil
    73  		},
    74  		stopInstances: func(ids []instance.Id) error {
    75  			c.Assert(ids, gc.HasLen, 2)
    76  			c.Assert(ids[0], gc.Equals, instance.Id("one"))
    77  			c.Assert(ids[1], gc.Equals, instance.Id("another"))
    78  			return nil
    79  		},
    80  		config: configGetter(c),
    81  	}
    82  	err := common.Destroy(env)
    83  	c.Assert(err, jc.ErrorIsNil)
    84  }
    85  
    86  func (s *DestroySuite) TestSuccess(c *gc.C) {
    87  	s.PatchValue(&jujuversion.Current, testing.FakeVersionNumber)
    88  	stor := newStorage(s, c)
    89  	err := stor.Put("somewhere", strings.NewReader("stuff"), 5)
    90  	c.Assert(err, jc.ErrorIsNil)
    91  
    92  	env := &mockEnviron{
    93  		storage: stor,
    94  		allInstances: func() ([]instance.Instance, error) {
    95  			return []instance.Instance{
    96  				&mockInstance{id: "one"},
    97  			}, nil
    98  		},
    99  		stopInstances: func(ids []instance.Id) error {
   100  			c.Assert(ids, gc.HasLen, 1)
   101  			c.Assert(ids[0], gc.Equals, instance.Id("one"))
   102  			return nil
   103  		},
   104  		config: configGetter(c),
   105  	}
   106  	err = common.Destroy(env)
   107  	c.Assert(err, jc.ErrorIsNil)
   108  
   109  	// common.Destroy doesn't touch provider/object storage anymore.
   110  	r, err := stor.Get("somewhere")
   111  	c.Assert(err, jc.ErrorIsNil)
   112  	r.Close()
   113  }
   114  
   115  func (s *DestroySuite) TestSuccessWhenNoInstances(c *gc.C) {
   116  	s.PatchValue(&jujuversion.Current, testing.FakeVersionNumber)
   117  	stor := newStorage(s, c)
   118  	err := stor.Put("elsewhere", strings.NewReader("stuff"), 5)
   119  	c.Assert(err, jc.ErrorIsNil)
   120  
   121  	env := &mockEnviron{
   122  		storage: stor,
   123  		allInstances: func() ([]instance.Instance, error) {
   124  			return nil, environs.ErrNoInstances
   125  		},
   126  		config: configGetter(c),
   127  	}
   128  	err = common.Destroy(env)
   129  	c.Assert(err, jc.ErrorIsNil)
   130  }
   131  
   132  func (s *DestroySuite) TestDestroyEnvScopedVolumes(c *gc.C) {
   133  	volumeSource := &dummy.VolumeSource{
   134  		ListVolumesFunc: func() ([]string, error) {
   135  			return []string{"vol-0", "vol-1", "vol-2"}, nil
   136  		},
   137  		DestroyVolumesFunc: func(ids []string) ([]error, error) {
   138  			return make([]error, len(ids)), nil
   139  		},
   140  	}
   141  	staticProvider := &dummy.StorageProvider{
   142  		IsDynamic:    true,
   143  		StorageScope: storage.ScopeEnviron,
   144  		VolumeSourceFunc: func(*config.Config, *storage.Config) (storage.VolumeSource, error) {
   145  			return volumeSource, nil
   146  		},
   147  	}
   148  	registry.RegisterProvider("environ", staticProvider)
   149  	defer registry.RegisterProvider("environ", nil)
   150  	registry.RegisterEnvironStorageProviders("anything, really", "environ")
   151  	defer registry.ResetEnvironStorageProviders("anything, really")
   152  
   153  	env := &mockEnviron{
   154  		config: configGetter(c),
   155  		allInstances: func() ([]instance.Instance, error) {
   156  			return nil, environs.ErrNoInstances
   157  		},
   158  	}
   159  	err := common.Destroy(env)
   160  	c.Assert(err, jc.ErrorIsNil)
   161  
   162  	// common.Destroy will ignore machine-scoped storage providers.
   163  	staticProvider.CheckCallNames(c, "Dynamic", "Scope", "Supports", "VolumeSource")
   164  	volumeSource.CheckCalls(c, []gitjujutesting.StubCall{
   165  		{"ListVolumes", nil},
   166  		{"DestroyVolumes", []interface{}{[]string{"vol-0", "vol-1", "vol-2"}}},
   167  	})
   168  }
   169  
   170  func (s *DestroySuite) TestDestroyVolumeErrors(c *gc.C) {
   171  	volumeSource := &dummy.VolumeSource{
   172  		ListVolumesFunc: func() ([]string, error) {
   173  			return []string{"vol-0", "vol-1", "vol-2"}, nil
   174  		},
   175  		DestroyVolumesFunc: func(ids []string) ([]error, error) {
   176  			return []error{
   177  				nil,
   178  				errors.New("cannot destroy vol-1"),
   179  				errors.New("cannot destroy vol-2"),
   180  			}, nil
   181  		},
   182  	}
   183  
   184  	staticProvider := &dummy.StorageProvider{
   185  		IsDynamic:    true,
   186  		StorageScope: storage.ScopeEnviron,
   187  		VolumeSourceFunc: func(*config.Config, *storage.Config) (storage.VolumeSource, error) {
   188  			return volumeSource, nil
   189  		},
   190  	}
   191  	registry.RegisterProvider("environ", staticProvider)
   192  	defer registry.RegisterProvider("environ", nil)
   193  	registry.RegisterEnvironStorageProviders("anything, really", "environ")
   194  	defer registry.ResetEnvironStorageProviders("anything, really")
   195  
   196  	env := &mockEnviron{
   197  		config: configGetter(c),
   198  		allInstances: func() ([]instance.Instance, error) {
   199  			return nil, environs.ErrNoInstances
   200  		},
   201  	}
   202  	err := common.Destroy(env)
   203  	c.Assert(err, gc.ErrorMatches, "destroying storage: destroying volumes: cannot destroy vol-1, cannot destroy vol-2")
   204  }
   205  
   206  func (s *DestroySuite) TestIgnoreStaticVolumes(c *gc.C) {
   207  	staticProvider := &dummy.StorageProvider{
   208  		IsDynamic:    false,
   209  		StorageScope: storage.ScopeEnviron,
   210  	}
   211  	registry.RegisterProvider("static", staticProvider)
   212  	defer registry.RegisterProvider("static", nil)
   213  	registry.RegisterEnvironStorageProviders("anything, really", "static")
   214  	defer registry.ResetEnvironStorageProviders("anything, really")
   215  
   216  	env := &mockEnviron{
   217  		config: configGetter(c),
   218  		allInstances: func() ([]instance.Instance, error) {
   219  			return nil, environs.ErrNoInstances
   220  		},
   221  	}
   222  	err := common.Destroy(env)
   223  	c.Assert(err, jc.ErrorIsNil)
   224  
   225  	// common.Destroy will ignore static storage providers.
   226  	staticProvider.CheckCallNames(c, "Dynamic")
   227  }
   228  
   229  func (s *DestroySuite) TestIgnoreMachineScopedVolumes(c *gc.C) {
   230  	staticProvider := &dummy.StorageProvider{
   231  		IsDynamic:    true,
   232  		StorageScope: storage.ScopeMachine,
   233  	}
   234  	registry.RegisterProvider("machine", staticProvider)
   235  	defer registry.RegisterProvider("machine", nil)
   236  	registry.RegisterEnvironStorageProviders("anything, really", "machine")
   237  	defer registry.ResetEnvironStorageProviders("anything, really")
   238  
   239  	env := &mockEnviron{
   240  		config: configGetter(c),
   241  		allInstances: func() ([]instance.Instance, error) {
   242  			return nil, environs.ErrNoInstances
   243  		},
   244  	}
   245  	err := common.Destroy(env)
   246  	c.Assert(err, jc.ErrorIsNil)
   247  
   248  	// common.Destroy will ignore machine-scoped storage providers.
   249  	staticProvider.CheckCallNames(c, "Dynamic", "Scope")
   250  }
   251  
   252  func (s *DestroySuite) TestIgnoreNoVolumeSupport(c *gc.C) {
   253  	staticProvider := &dummy.StorageProvider{
   254  		IsDynamic:    true,
   255  		StorageScope: storage.ScopeEnviron,
   256  		SupportsFunc: func(storage.StorageKind) bool {
   257  			return false
   258  		},
   259  	}
   260  	registry.RegisterProvider("filesystem", staticProvider)
   261  	defer registry.RegisterProvider("filesystem", nil)
   262  	registry.RegisterEnvironStorageProviders("anything, really", "filesystem")
   263  	defer registry.ResetEnvironStorageProviders("anything, really")
   264  
   265  	env := &mockEnviron{
   266  		config: configGetter(c),
   267  		allInstances: func() ([]instance.Instance, error) {
   268  			return nil, environs.ErrNoInstances
   269  		},
   270  	}
   271  	err := common.Destroy(env)
   272  	c.Assert(err, jc.ErrorIsNil)
   273  
   274  	// common.Destroy will ignore storage providers that don't support
   275  	// volumes (until we have persistent filesystems, that is).
   276  	staticProvider.CheckCallNames(c, "Dynamic", "Scope", "Supports")
   277  }