github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/state/annotations_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package state_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/names"
     9  	jc "github.com/juju/testing/checkers"
    10  	"github.com/juju/utils"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/state"
    14  	"github.com/juju/juju/testing"
    15  )
    16  
    17  type AnnotationsSuite struct {
    18  	ConnSuite
    19  	// any entity that implements
    20  	// state.GlobalEntity will do
    21  	testEntity *state.Machine
    22  }
    23  
    24  var _ = gc.Suite(&AnnotationsSuite{})
    25  
    26  func (s *AnnotationsSuite) SetUpTest(c *gc.C) {
    27  	s.ConnSuite.SetUpTest(c)
    28  
    29  	var err error
    30  	s.testEntity, err = s.State.AddMachine("quantal", state.JobHostUnits)
    31  	c.Assert(err, jc.ErrorIsNil)
    32  }
    33  
    34  func (s *AnnotationsSuite) TestSetAnnotationsInvalidKey(c *gc.C) {
    35  	key := "tes.tkey"
    36  	expected := "typo"
    37  	err := s.setAnnotationResult(c, key, expected)
    38  	c.Assert(errors.Cause(err), gc.ErrorMatches, ".*invalid key.*")
    39  }
    40  
    41  func (s *AnnotationsSuite) TestSetAnnotationsCreate(c *gc.C) {
    42  	s.createTestAnnotation(c)
    43  }
    44  
    45  func (s *AnnotationsSuite) createTestAnnotation(c *gc.C) string {
    46  	key := "testkey"
    47  	expected := "typo"
    48  	s.assertSetAnnotation(c, key, expected)
    49  	assertAnnotation(c, s.State, s.testEntity, key, expected)
    50  	return key
    51  }
    52  
    53  func (s *AnnotationsSuite) setAnnotationResult(c *gc.C, key, value string) error {
    54  	annts := map[string]string{key: value}
    55  	return s.State.SetAnnotations(s.testEntity, annts)
    56  }
    57  
    58  func (s *AnnotationsSuite) assertSetAnnotation(c *gc.C, key, value string) {
    59  	err := s.setAnnotationResult(c, key, value)
    60  	c.Assert(err, jc.ErrorIsNil)
    61  }
    62  
    63  func assertAnnotation(c *gc.C, st *state.State, entity state.GlobalEntity, key, expected string) {
    64  	value, err := st.Annotation(entity, key)
    65  	c.Assert(err, jc.ErrorIsNil)
    66  	c.Assert(value, gc.DeepEquals, expected)
    67  }
    68  
    69  func (s *AnnotationsSuite) TestSetAnnotationsUpdate(c *gc.C) {
    70  	key := s.createTestAnnotation(c)
    71  	updated := "fixed"
    72  
    73  	s.assertSetAnnotation(c, key, updated)
    74  	assertAnnotation(c, s.State, s.testEntity, key, updated)
    75  }
    76  
    77  func (s *AnnotationsSuite) TestSetAnnotationsRemove(c *gc.C) {
    78  	key := s.createTestAnnotation(c)
    79  	updated := ""
    80  	s.assertSetAnnotation(c, key, updated)
    81  	assertAnnotation(c, s.State, s.testEntity, key, updated)
    82  
    83  	annts, err := s.State.Annotations(s.testEntity)
    84  	c.Assert(err, jc.ErrorIsNil)
    85  
    86  	// we are expecting not to find this key...
    87  	for akey := range annts {
    88  		c.Assert(akey == key, jc.IsFalse)
    89  	}
    90  }
    91  
    92  func (s *AnnotationsSuite) TestSetAnnotationsDestroyedEntity(c *gc.C) {
    93  	key := s.createTestAnnotation(c)
    94  
    95  	err := s.testEntity.ForceDestroy()
    96  	c.Assert(err, jc.ErrorIsNil)
    97  	err = s.testEntity.EnsureDead()
    98  	c.Assert(err, jc.ErrorIsNil)
    99  	err = s.testEntity.Remove()
   100  	c.Assert(err, jc.ErrorIsNil)
   101  	_, err = s.State.Machine(s.testEntity.Id())
   102  	c.Assert(errors.Cause(err), gc.ErrorMatches, ".*not found.*")
   103  
   104  	annts, err := s.State.Annotations(s.testEntity)
   105  	c.Assert(err, jc.ErrorIsNil)
   106  	c.Assert(annts, gc.DeepEquals, map[string]string{})
   107  
   108  	annts[key] = "oops"
   109  	err = s.State.SetAnnotations(s.testEntity, annts)
   110  	c.Assert(errors.Cause(err), gc.ErrorMatches, ".*no longer exists.*")
   111  	c.Assert(err, gc.ErrorMatches, ".*cannot update annotations.*")
   112  }
   113  
   114  func (s *AnnotationsSuite) TestSetAnnotationsNonExistentEntity(c *gc.C) {
   115  	annts := map[string]string{"key": "oops"}
   116  	err := s.State.SetAnnotations(state.MockGlobalEntity{}, annts)
   117  
   118  	c.Assert(errors.Cause(err), gc.ErrorMatches, ".*no longer exists.*")
   119  	c.Assert(err, gc.ErrorMatches, ".*cannot update annotations.*")
   120  }
   121  
   122  func (s *AnnotationsSuite) TestSetAnnotationsConcurrently(c *gc.C) {
   123  	key := "conkey"
   124  	first := "alpha"
   125  	last := "omega"
   126  
   127  	setAnnotations := func() {
   128  		s.assertSetAnnotation(c, key, first)
   129  		assertAnnotation(c, s.State, s.testEntity, key, first)
   130  	}
   131  	defer state.SetBeforeHooks(c, s.State, setAnnotations).Check()
   132  	s.assertSetAnnotation(c, key, last)
   133  	assertAnnotation(c, s.State, s.testEntity, key, last)
   134  }
   135  
   136  type AnnotationsEnvSuite struct {
   137  	ConnSuite
   138  }
   139  
   140  var _ = gc.Suite(&AnnotationsEnvSuite{})
   141  
   142  func (s *AnnotationsEnvSuite) SetUpTest(c *gc.C) {
   143  	s.ConnSuite.SetUpTest(c)
   144  	s.ConnSuite.PatchValue(&state.TagToCollectionAndId, func(st *state.State, tag names.Tag) (string, interface{}, error) {
   145  		return "", nil, errors.Errorf("this error should not be reached with current implementation %v", tag)
   146  	})
   147  }
   148  
   149  func (s *AnnotationsEnvSuite) TestSetAnnotationsDestroyedEnvironment(c *gc.C) {
   150  	env, st := s.createTestEnv(c)
   151  	defer st.Close()
   152  
   153  	key := "key"
   154  	expected := "oops"
   155  	annts := map[string]string{key: expected}
   156  	err := st.SetAnnotations(env, annts)
   157  	c.Assert(err, jc.ErrorIsNil)
   158  	assertAnnotation(c, st, env, key, expected)
   159  
   160  	err = env.Destroy()
   161  	c.Assert(err, jc.ErrorIsNil)
   162  	err = st.RemoveAllModelDocs()
   163  	c.Assert(err, jc.ErrorIsNil)
   164  	err = st.Close()
   165  	c.Assert(err, jc.ErrorIsNil)
   166  
   167  	expected = "fail"
   168  	annts[key] = expected
   169  	err = s.State.SetAnnotations(env, annts)
   170  	c.Assert(errors.Cause(err), gc.ErrorMatches, ".*model not found.*")
   171  	c.Assert(err, gc.ErrorMatches, ".*cannot update annotations.*")
   172  }
   173  
   174  func (s *AnnotationsEnvSuite) createTestEnv(c *gc.C) (*state.Model, *state.State) {
   175  	uuid, err := utils.NewUUID()
   176  	c.Assert(err, jc.ErrorIsNil)
   177  	cfg := testing.CustomModelConfig(c, testing.Attrs{
   178  		"name": "testing",
   179  		"uuid": uuid.String(),
   180  	})
   181  	owner := names.NewUserTag("test@remote")
   182  	env, st, err := s.State.NewModel(state.ModelArgs{Config: cfg, Owner: owner})
   183  	c.Assert(err, jc.ErrorIsNil)
   184  	return env, st
   185  }