github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/service/common/testing/fake.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package testing 5 6 import ( 7 "strings" 8 "sync" 9 10 "github.com/juju/errors" 11 "github.com/juju/testing" 12 "github.com/juju/utils/set" 13 14 "github.com/juju/juju/service/common" 15 ) 16 17 type ServiceInfo interface { 18 Name() string 19 Conf() common.Conf 20 } 21 22 // FakeServiceData holds the results of Service method calls. 23 type FakeServiceData struct { 24 testing.Stub 25 26 mu sync.Mutex 27 28 // installed is the list of all services that were installed. 29 installed []ServiceInfo 30 31 // removed is the list of all services that were removed. 32 removed []ServiceInfo 33 34 // managedNames is the set of "currently" juju-managed services. 35 managedNames set.Strings 36 37 // installedNames is the set of "currently" installed services. 38 installedNames set.Strings 39 40 // runningNames is the set of "currently" running services. 41 runningNames set.Strings 42 } 43 44 // NewFakeServiceData returns a new FakeServiceData. 45 func NewFakeServiceData(names ...string) *FakeServiceData { 46 fsd := FakeServiceData{ 47 managedNames: set.NewStrings(), 48 installedNames: set.NewStrings(), 49 runningNames: set.NewStrings(), 50 } 51 for _, name := range names { 52 fsd.installedNames.Add(name) 53 } 54 return &fsd 55 } 56 57 // InstalledNames returns a copy of the list of the installed names. 58 func (f *FakeServiceData) InstalledNames() []string { 59 f.mu.Lock() 60 defer f.mu.Unlock() 61 return f.installedNames.Values() 62 } 63 64 // Installed returns a copy of the list of installed Services 65 func (f *FakeServiceData) Installed() []ServiceInfo { 66 f.mu.Lock() 67 defer f.mu.Unlock() 68 names := make([]ServiceInfo, len(f.installed)) 69 copy(names, f.installed) 70 return names 71 } 72 73 // GetInstalled returns the installed service that matches name. 74 75 // Removed returns a copy of the list of removed Services 76 func (f *FakeServiceData) Removed() []ServiceInfo { 77 f.mu.Lock() 78 defer f.mu.Unlock() 79 names := make([]ServiceInfo, len(f.removed)) 80 copy(names, f.removed) 81 return names 82 } 83 84 // GetInstalled returns the installed service that matches name. 85 // If name is not found, the method panics. 86 func (f *FakeServiceData) GetInstalled(name string) ServiceInfo { 87 f.mu.Lock() 88 defer f.mu.Unlock() 89 90 for _, i := range f.installed { 91 if i.Name() == name { 92 return i 93 } 94 } 95 panic(name + " not found") 96 } 97 98 // SetStatus updates the status of the named service. 99 func (f *FakeServiceData) SetStatus(name, status string) error { 100 f.mu.Lock() 101 defer f.mu.Unlock() 102 if status == "" { 103 f.managedNames.Remove(name) 104 f.installedNames.Remove(name) 105 f.runningNames.Remove(name) 106 return nil 107 } 108 109 managed := true 110 if strings.HasPrefix(status, "(") && strings.HasSuffix(status, ")") { 111 status = status[1 : len(status)-1] 112 managed = false 113 } 114 115 switch status { 116 case "installed": 117 f.installedNames.Add(name) 118 f.runningNames.Remove(name) 119 case "running": 120 f.installedNames.Add(name) 121 f.runningNames.Add(name) 122 default: 123 return errors.NotSupportedf("status %q", status) 124 } 125 126 if managed { 127 f.managedNames.Add(name) 128 } 129 return nil 130 } 131 132 // FakeService is a Service implementation for testing. 133 type FakeService struct { 134 *FakeServiceData 135 common.Service 136 } 137 138 // NewFakeService returns a new FakeService. 139 func NewFakeService(name string, conf common.Conf) *FakeService { 140 return &FakeService{ 141 FakeServiceData: NewFakeServiceData(), 142 Service: common.Service{ 143 Name: name, 144 Conf: conf, 145 }, 146 } 147 } 148 149 // Name implements Service. 150 func (ss *FakeService) Name() string { 151 ss.AddCall("Name") 152 153 ss.NextErr() 154 return ss.Service.Name 155 } 156 157 // Conf implements Service. 158 func (ss *FakeService) Conf() common.Conf { 159 ss.AddCall("Conf") 160 161 ss.NextErr() 162 return ss.Service.Conf 163 } 164 165 // Running implements Service. 166 func (ss *FakeService) Running() (bool, error) { 167 ss.AddCall("Running") 168 169 return ss.running(), ss.NextErr() 170 } 171 172 func (ss *FakeService) running() bool { 173 ss.mu.Lock() 174 defer ss.mu.Unlock() 175 return ss.FakeServiceData.runningNames.Contains(ss.Service.Name) 176 } 177 178 // Start implements Service. 179 func (ss *FakeService) Start() error { 180 ss.AddCall("Start") 181 // TODO(ericsnow) Check managed? 182 if ss.running() { 183 ss.mu.Lock() 184 ss.FakeServiceData.runningNames.Add(ss.Service.Name) 185 ss.mu.Unlock() 186 } 187 188 return ss.NextErr() 189 } 190 191 // Stop implements Service. 192 func (ss *FakeService) Stop() error { 193 ss.AddCall("Stop") 194 if !ss.running() { 195 ss.mu.Lock() 196 ss.FakeServiceData.runningNames.Remove(ss.Service.Name) 197 ss.mu.Unlock() 198 } 199 200 return ss.NextErr() 201 } 202 203 // Exists implements Service. 204 func (ss *FakeService) Exists() (bool, error) { 205 ss.AddCall("Exists") 206 207 return ss.managed(), ss.NextErr() 208 } 209 210 func (ss *FakeService) managed() bool { 211 ss.mu.Lock() 212 defer ss.mu.Unlock() 213 return ss.FakeServiceData.managedNames.Contains(ss.Service.Name) 214 } 215 216 // Installed implements Service. 217 func (ss *FakeService) Installed() (bool, error) { 218 ss.AddCall("Installed") 219 220 return ss.installed(), ss.NextErr() 221 } 222 223 func (ss *FakeService) installed() bool { 224 ss.mu.Lock() 225 defer ss.mu.Unlock() 226 return ss.FakeServiceData.installedNames.Contains(ss.Service.Name) 227 } 228 229 // Install implements Service. 230 func (ss *FakeService) Install() error { 231 ss.AddCall("Install") 232 if !ss.running() && !ss.installed() { 233 ss.mu.Lock() 234 ss.FakeServiceData.installed = append(ss.FakeServiceData.installed, ss) 235 ss.FakeServiceData.installedNames.Add(ss.Service.Name) 236 ss.mu.Unlock() 237 } 238 239 return ss.NextErr() 240 } 241 242 // Remove implements Service. 243 func (ss *FakeService) Remove() error { 244 ss.AddCall("Remove") 245 if ss.installed() { 246 ss.mu.Lock() 247 ss.FakeServiceData.removed = append(ss.FakeServiceData.removed, ss) 248 ss.FakeServiceData.installedNames.Remove(ss.Service.Name) 249 ss.mu.Unlock() 250 } 251 252 return ss.NextErr() 253 } 254 255 // InstallCommands implements Service. 256 func (ss *FakeService) InstallCommands() ([]string, error) { 257 ss.AddCall("InstallCommands") 258 259 return nil, ss.NextErr() 260 } 261 262 // StartCommands implements Service. 263 func (ss *FakeService) StartCommands() ([]string, error) { 264 ss.AddCall("StartCommands") 265 266 return nil, ss.NextErr() 267 }