github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/worker/environ_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package worker_test 5 6 import ( 7 "strings" 8 stdtesting "testing" 9 "time" 10 11 "github.com/juju/loggo" 12 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 "launchpad.net/tomb" 15 16 "github.com/juju/juju/environs" 17 "github.com/juju/juju/juju/testing" 18 "github.com/juju/juju/mongo" 19 "github.com/juju/juju/state" 20 coretesting "github.com/juju/juju/testing" 21 "github.com/juju/juju/worker" 22 ) 23 24 func TestPackage(t *stdtesting.T) { 25 coretesting.MgoTestPackage(t) 26 } 27 28 type environSuite struct { 29 testing.JujuConnSuite 30 } 31 32 var _ = gc.Suite(&environSuite{}) 33 34 func (s *environSuite) TestStop(c *gc.C) { 35 w := s.State.WatchForEnvironConfigChanges() 36 defer stopWatcher(c, w) 37 stop := make(chan struct{}) 38 done := make(chan error) 39 go func() { 40 env, err := worker.WaitForEnviron(w, s.State, stop) 41 c.Check(env, gc.IsNil) 42 done <- err 43 }() 44 close(stop) 45 c.Assert(<-done, gc.Equals, tomb.ErrDying) 46 } 47 48 func stopWatcher(c *gc.C, w state.NotifyWatcher) { 49 err := w.Stop() 50 c.Check(err, jc.ErrorIsNil) 51 } 52 53 func (s *environSuite) TestInvalidConfig(c *gc.C) { 54 var oldType string 55 oldType = s.Environ.Config().AllAttrs()["type"].(string) 56 57 // Create an invalid config by taking the current config and 58 // tweaking the provider type. 59 info := s.MongoInfo(c) 60 opts := mongo.DefaultDialOpts() 61 st2, err := state.Open(info, opts, state.Policy(nil)) 62 c.Assert(err, jc.ErrorIsNil) 63 defer st2.Close() 64 err = st2.UpdateEnvironConfig(map[string]interface{}{"type": "unknown"}, nil, nil) 65 c.Assert(err, jc.ErrorIsNil) 66 67 w := st2.WatchForEnvironConfigChanges() 68 defer stopWatcher(c, w) 69 done := make(chan environs.Environ) 70 go func() { 71 env, err := worker.WaitForEnviron(w, st2, nil) 72 c.Check(err, jc.ErrorIsNil) 73 done <- env 74 }() 75 <-worker.LoadedInvalid 76 77 st2.UpdateEnvironConfig(map[string]interface{}{ 78 "type": oldType, 79 "secret": "environ_test", 80 }, nil, nil) 81 82 st2.StartSync() 83 env := <-done 84 c.Assert(env, gc.NotNil) 85 c.Assert(env.Config().AllAttrs()["secret"], gc.Equals, "environ_test") 86 } 87 88 func (s *environSuite) TestErrorWhenEnvironIsInvalid(c *gc.C) { 89 // reopen the state so that we can wangle a dodgy environ config in there. 90 st, err := state.Open(s.MongoInfo(c), mongo.DefaultDialOpts(), state.Policy(nil)) 91 c.Assert(err, jc.ErrorIsNil) 92 defer st.Close() 93 err = st.UpdateEnvironConfig(map[string]interface{}{"secret": 999}, nil, nil) 94 c.Assert(err, jc.ErrorIsNil) 95 obs, err := worker.NewEnvironObserver(s.State) 96 c.Assert(err, gc.ErrorMatches, `cannot make Environ: secret: expected string, got int\(999\)`) 97 c.Assert(obs, gc.IsNil) 98 } 99 100 func (s *environSuite) TestEnvironmentChanges(c *gc.C) { 101 originalConfig, err := s.State.EnvironConfig() 102 c.Assert(err, jc.ErrorIsNil) 103 104 logc := make(logChan, 1009) 105 c.Assert(loggo.RegisterWriter("testing", logc, loggo.WARNING), gc.IsNil) 106 defer loggo.RemoveWriter("testing") 107 108 obs, err := worker.NewEnvironObserver(s.State) 109 c.Assert(err, jc.ErrorIsNil) 110 111 env := obs.Environ() 112 c.Assert(env.Config().AllAttrs(), gc.DeepEquals, originalConfig.AllAttrs()) 113 var oldType string 114 oldType = env.Config().AllAttrs()["type"].(string) 115 116 info := s.MongoInfo(c) 117 opts := mongo.DefaultDialOpts() 118 st2, err := state.Open(info, opts, state.Policy(nil)) 119 defer st2.Close() 120 121 // Change to an invalid configuration and check 122 // that the observer's environment remains the same. 123 st2.UpdateEnvironConfig(map[string]interface{}{"type": "invalid"}, nil, nil) 124 s.State.StartSync() 125 126 // Wait for the observer to register the invalid environment 127 loop: 128 for { 129 select { 130 case msg := <-logc: 131 if strings.Contains(msg, "error creating Environ") { 132 break loop 133 } 134 case <-time.After(coretesting.LongWait): 135 c.Fatalf("timed out waiting to see broken environment") 136 } 137 } 138 // Check that the returned environ is still the same. 139 env = obs.Environ() 140 c.Assert(env.Config().AllAttrs(), gc.DeepEquals, originalConfig.AllAttrs()) 141 142 // Change the environment back to a valid configuration 143 // with a different name and check that we see it. 144 st2.UpdateEnvironConfig(map[string]interface{}{"type": oldType, "name": "a-new-name"}, nil, nil) 145 s.State.StartSync() 146 147 for a := coretesting.LongAttempt.Start(); a.Next(); { 148 env := obs.Environ() 149 if !a.HasNext() { 150 c.Fatalf("timed out waiting for new environ") 151 } 152 if env.Config().Name() == "a-new-name" { 153 break 154 } 155 } 156 } 157 158 type logChan chan string 159 160 func (logc logChan) Write(level loggo.Level, name, filename string, line int, timestamp time.Time, message string) { 161 logc <- message 162 }