github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/controller/caasunitprovisioner/provisioner_test.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package caasunitprovisioner_test 5 6 import ( 7 "time" 8 9 "github.com/juju/clock" 10 "github.com/juju/clock/testclock" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 "gopkg.in/juju/names.v2" 14 "gopkg.in/juju/worker.v1/workertest" 15 16 "github.com/juju/juju/apiserver/common" 17 "github.com/juju/juju/apiserver/facades/controller/caasunitprovisioner" 18 "github.com/juju/juju/apiserver/params" 19 apiservertesting "github.com/juju/juju/apiserver/testing" 20 "github.com/juju/juju/caas/kubernetes/provider" 21 "github.com/juju/juju/core/constraints" 22 "github.com/juju/juju/core/status" 23 "github.com/juju/juju/network" 24 "github.com/juju/juju/state" 25 statetesting "github.com/juju/juju/state/testing" 26 coretesting "github.com/juju/juju/testing" 27 ) 28 29 var _ = gc.Suite(&CAASProvisionerSuite{}) 30 31 type CAASProvisionerSuite struct { 32 coretesting.BaseSuite 33 34 clock clock.Clock 35 st *mockState 36 storage *mockStorage 37 storageProviderRegistry *mockStorageProviderRegistry 38 storagePoolManager *mockStoragePoolManager 39 devices *mockDeviceBackend 40 applicationsChanges chan []string 41 podSpecChanges chan struct{} 42 scaleChanges chan struct{} 43 44 resources *common.Resources 45 authorizer *apiservertesting.FakeAuthorizer 46 facade *caasunitprovisioner.Facade 47 } 48 49 func (s *CAASProvisionerSuite) SetUpTest(c *gc.C) { 50 s.BaseSuite.SetUpTest(c) 51 52 s.applicationsChanges = make(chan []string, 1) 53 s.podSpecChanges = make(chan struct{}, 1) 54 s.scaleChanges = make(chan struct{}, 1) 55 s.st = &mockState{ 56 application: mockApplication{ 57 tag: names.NewApplicationTag("gitlab"), 58 life: state.Alive, 59 scaleWatcher: statetesting.NewMockNotifyWatcher(s.scaleChanges), 60 }, 61 applicationsWatcher: statetesting.NewMockStringsWatcher(s.applicationsChanges), 62 model: mockModel{ 63 podSpecWatcher: statetesting.NewMockNotifyWatcher(s.podSpecChanges), 64 }, 65 unit: mockUnit{ 66 life: state.Dying, 67 }, 68 } 69 s.storage = &mockStorage{ 70 storageFilesystems: make(map[names.StorageTag]names.FilesystemTag), 71 storageVolumes: make(map[names.StorageTag]names.VolumeTag), 72 storageAttachments: make(map[names.UnitTag]names.StorageTag), 73 } 74 s.storageProviderRegistry = &mockStorageProviderRegistry{} 75 s.storagePoolManager = &mockStoragePoolManager{} 76 s.devices = &mockDeviceBackend{} 77 s.AddCleanup(func(c *gc.C) { workertest.DirtyKill(c, s.st.applicationsWatcher) }) 78 s.AddCleanup(func(c *gc.C) { workertest.DirtyKill(c, s.st.application.scaleWatcher) }) 79 s.AddCleanup(func(c *gc.C) { workertest.DirtyKill(c, s.st.model.podSpecWatcher) }) 80 81 s.resources = common.NewResources() 82 s.authorizer = &apiservertesting.FakeAuthorizer{ 83 Tag: names.NewMachineTag("0"), 84 Controller: true, 85 } 86 s.clock = testclock.NewClock(time.Now()) 87 88 facade, err := caasunitprovisioner.NewFacade( 89 s.resources, s.authorizer, s.st, s.storage, s.devices, s.storageProviderRegistry, s.storagePoolManager, s.clock) 90 c.Assert(err, jc.ErrorIsNil) 91 s.facade = facade 92 } 93 94 func (s *CAASProvisionerSuite) TestPermission(c *gc.C) { 95 s.authorizer = &apiservertesting.FakeAuthorizer{ 96 Tag: names.NewMachineTag("0"), 97 } 98 _, err := caasunitprovisioner.NewFacade( 99 s.resources, s.authorizer, s.st, s.storage, s.devices, s.storageProviderRegistry, s.storagePoolManager, s.clock) 100 c.Assert(err, gc.ErrorMatches, "permission denied") 101 } 102 103 func (s *CAASProvisionerSuite) TestWatchApplications(c *gc.C) { 104 applicationNames := []string{"db2", "hadoop"} 105 s.applicationsChanges <- applicationNames 106 result, err := s.facade.WatchApplications() 107 c.Assert(err, jc.ErrorIsNil) 108 c.Assert(result.Error, gc.IsNil) 109 c.Assert(result.StringsWatcherId, gc.Equals, "1") 110 c.Assert(result.Changes, jc.DeepEquals, applicationNames) 111 112 resource := s.resources.Get("1") 113 c.Assert(resource, gc.Equals, s.st.applicationsWatcher) 114 } 115 116 func (s *CAASProvisionerSuite) TestWatchPodSpec(c *gc.C) { 117 s.podSpecChanges <- struct{}{} 118 119 results, err := s.facade.WatchPodSpec(params.Entities{ 120 Entities: []params.Entity{ 121 {Tag: "application-gitlab"}, 122 {Tag: "unit-gitlab-0"}, 123 }, 124 }) 125 c.Assert(err, jc.ErrorIsNil) 126 c.Assert(results.Results, gc.HasLen, 2) 127 c.Assert(results.Results[0].Error, gc.IsNil) 128 c.Assert(results.Results[1].Error, jc.DeepEquals, ¶ms.Error{ 129 Message: `"unit-gitlab-0" is not a valid application tag`, 130 }) 131 132 c.Assert(results.Results[0].NotifyWatcherId, gc.Equals, "1") 133 resource := s.resources.Get("1") 134 c.Assert(resource, gc.Equals, s.st.model.podSpecWatcher) 135 } 136 137 func (s *CAASProvisionerSuite) TestWatchApplicationsScale(c *gc.C) { 138 s.scaleChanges <- struct{}{} 139 140 results, err := s.facade.WatchApplicationsScale(params.Entities{ 141 Entities: []params.Entity{ 142 {Tag: "application-gitlab"}, 143 {Tag: "unit-gitlab-0"}, 144 }, 145 }) 146 c.Assert(err, jc.ErrorIsNil) 147 c.Assert(results.Results, gc.HasLen, 2) 148 c.Assert(results.Results[0].Error, gc.IsNil) 149 c.Assert(results.Results[1].Error, jc.DeepEquals, ¶ms.Error{ 150 Message: `"unit-gitlab-0" is not a valid application tag`, 151 }) 152 153 c.Assert(results.Results[0].NotifyWatcherId, gc.Equals, "1") 154 resource := s.resources.Get("1") 155 c.Assert(resource, gc.Equals, s.st.application.scaleWatcher) 156 } 157 158 func (s *CAASProvisionerSuite) TestProvisioningInfo(c *gc.C) { 159 s.st.application.units = []caasunitprovisioner.Unit{ 160 &mockUnit{name: "gitlab/0", life: state.Dying}, 161 &mockUnit{name: "gitlab/1", life: state.Alive}, 162 } 163 s.storage.storageFilesystems[names.NewStorageTag("data/0")] = names.NewFilesystemTag("gitlab/1/0") 164 s.storage.storageAttachments[names.NewUnitTag("gitlab/1")] = names.NewStorageTag("data/0") 165 166 results, err := s.facade.ProvisioningInfo(params.Entities{ 167 Entities: []params.Entity{ 168 {Tag: "application-gitlab"}, 169 {Tag: "unit-gitlab-0"}, 170 }, 171 }) 172 c.Assert(err, jc.ErrorIsNil) 173 c.Assert(results, jc.DeepEquals, params.KubernetesProvisioningInfoResults{ 174 Results: []params.KubernetesProvisioningInfoResult{{ 175 Result: ¶ms.KubernetesProvisioningInfo{ 176 PodSpec: "spec(gitlab)", 177 Filesystems: []params.KubernetesFilesystemParams{{ 178 StorageName: "data", 179 Provider: string(provider.K8s_ProviderType), 180 Size: 100, 181 Attributes: map[string]interface{}{"foo": "bar"}, 182 Tags: map[string]string{ 183 "juju-storage-instance": "data/0", 184 "juju-storage-owner": "gitlab", 185 "juju-model-uuid": coretesting.ModelTag.Id(), 186 "juju-controller-uuid": coretesting.ControllerTag.Id()}, 187 Attachment: ¶ms.KubernetesFilesystemAttachmentParams{ 188 Provider: string(provider.K8s_ProviderType), 189 MountPoint: "/path/to/here", 190 ReadOnly: true, 191 }, 192 }}, 193 Devices: []params.KubernetesDeviceParams{ 194 { 195 Type: "nvidia.com/gpu", 196 Count: 3, 197 Attributes: map[string]string{"gpu": "nvidia-tesla-p100"}, 198 }, 199 }, 200 Placement: "placement", 201 Constraints: constraints.MustParse("mem=64G"), 202 Tags: map[string]string{ 203 "juju-model-uuid": coretesting.ModelTag.Id(), 204 "juju-controller-uuid": coretesting.ControllerTag.Id()}, 205 }, 206 }, { 207 Error: ¶ms.Error{ 208 Message: `"unit-gitlab-0" is not a valid application tag`, 209 }, 210 }}, 211 }) 212 s.st.CheckCallNames(c, "Model", "Application", "ControllerConfig") 213 s.storage.CheckCallNames(c, "UnitStorageAttachments", "StorageInstance", "FilesystemAttachment") 214 s.storageProviderRegistry.CheckNoCalls(c) 215 s.storagePoolManager.CheckCallNames(c, "Get") 216 } 217 218 func (s *CAASProvisionerSuite) TestProvisioningInfoNoUnits(c *gc.C) { 219 s.st.application.units = []caasunitprovisioner.Unit{} 220 221 results, err := s.facade.ProvisioningInfo(params.Entities{ 222 Entities: []params.Entity{ 223 {Tag: "application-gitlab"}, 224 }, 225 }) 226 c.Assert(err, jc.ErrorIsNil) 227 c.Assert(results, jc.DeepEquals, params.KubernetesProvisioningInfoResults{ 228 Results: []params.KubernetesProvisioningInfoResult{{}}}) 229 s.st.CheckCallNames(c, "Model", "Application") 230 s.storage.CheckNoCalls(c) 231 s.storageProviderRegistry.CheckNoCalls(c) 232 s.storagePoolManager.CheckNoCalls(c) 233 } 234 235 func (s *CAASProvisionerSuite) TestApplicationScale(c *gc.C) { 236 results, err := s.facade.ApplicationsScale(params.Entities{ 237 Entities: []params.Entity{ 238 {Tag: "application-gitlab"}, 239 {Tag: "unit-gitlab-0"}, 240 }, 241 }) 242 c.Assert(err, jc.ErrorIsNil) 243 c.Assert(results, jc.DeepEquals, params.IntResults{ 244 Results: []params.IntResult{{ 245 Result: 5, 246 }, { 247 Error: ¶ms.Error{ 248 Message: `"unit-gitlab-0" is not a valid application tag`, 249 }, 250 }}, 251 }) 252 s.st.CheckCallNames(c, "Application") 253 } 254 255 func (s *CAASProvisionerSuite) TestLife(c *gc.C) { 256 results, err := s.facade.Life(params.Entities{ 257 Entities: []params.Entity{ 258 {Tag: "unit-gitlab-0"}, 259 {Tag: "application-gitlab"}, 260 {Tag: "machine-0"}, 261 }, 262 }) 263 c.Assert(err, jc.ErrorIsNil) 264 c.Assert(results, jc.DeepEquals, params.LifeResults{ 265 Results: []params.LifeResult{{ 266 Life: params.Dying, 267 }, { 268 Life: params.Alive, 269 }, { 270 Error: ¶ms.Error{ 271 Code: "unauthorized access", 272 Message: "permission denied", 273 }, 274 }}, 275 }) 276 } 277 278 func (s *CAASProvisionerSuite) TestApplicationConfig(c *gc.C) { 279 results, err := s.facade.ApplicationsConfig(params.Entities{ 280 Entities: []params.Entity{ 281 {Tag: "application-gitlab"}, 282 {Tag: "unit-gitlab-0"}, 283 }, 284 }) 285 c.Assert(err, jc.ErrorIsNil) 286 c.Assert(results.Results, gc.HasLen, 2) 287 c.Assert(results.Results[0].Error, gc.IsNil) 288 c.Assert(results.Results[1].Error, jc.DeepEquals, ¶ms.Error{ 289 Message: `"unit-gitlab-0" is not a valid application tag`, 290 }) 291 c.Assert(results.Results[0].Config, jc.DeepEquals, map[string]interface{}{"foo": "bar"}) 292 } 293 294 func strPtr(s string) *string { 295 return &s 296 } 297 298 func (s *CAASProvisionerSuite) TestUpdateApplicationsUnits(c *gc.C) { 299 s.st.application.units = []caasunitprovisioner.Unit{ 300 &mockUnit{name: "gitlab/0", containerInfo: &mockContainerInfo{providerId: "uuid"}, life: state.Alive}, 301 &mockUnit{name: "gitlab/1", life: state.Alive}, 302 &mockUnit{name: "gitlab/2", containerInfo: &mockContainerInfo{providerId: "uuid2"}, life: state.Alive}, 303 &mockUnit{name: "gitlab/3", life: state.Alive}, 304 } 305 306 units := []params.ApplicationUnitParams{ 307 {ProviderId: "uuid", Address: "address", Ports: []string{"port"}, 308 Status: "allocating", Info: ""}, 309 {ProviderId: "another-uuid", Address: "another-address", Ports: []string{"another-port"}, 310 Status: "allocating", Info: "another message"}, 311 {ProviderId: "new-uuid", Address: "new-address", Ports: []string{"new-port"}, 312 Status: "running", Info: "new message"}, 313 {ProviderId: "really-new-uuid", Address: "really-new-address", Ports: []string{"really-new-port"}, 314 Status: "running", Info: "really new message"}, 315 } 316 args := params.UpdateApplicationUnitArgs{ 317 Args: []params.UpdateApplicationUnits{ 318 {ApplicationTag: "application-gitlab", Units: units}, 319 {ApplicationTag: "application-another", Units: []params.ApplicationUnitParams{}}, 320 }, 321 } 322 results, err := s.facade.UpdateApplicationsUnits(args) 323 c.Assert(err, jc.ErrorIsNil) 324 c.Assert(results, gc.DeepEquals, params.ErrorResults{ 325 Results: []params.ErrorResult{ 326 {nil}, 327 {¶ms.Error{Message: "application another not found", Code: "not found"}}, 328 }, 329 }) 330 s.st.application.CheckCallNames(c, "Life", "AddOperation", "Name") 331 s.st.application.CheckCall(c, 1, "AddOperation", state.UnitUpdateProperties{ 332 ProviderId: strPtr("really-new-uuid"), 333 Address: strPtr("really-new-address"), Ports: &[]string{"really-new-port"}, 334 CloudContainerStatus: &status.StatusInfo{Status: status.Running, Message: "really new message"}, 335 AgentStatus: &status.StatusInfo{Status: status.Idle}, 336 }) 337 s.st.application.units[0].(*mockUnit).CheckCallNames(c, "Life", "UpdateOperation") 338 // CloudContainer message is not overwritten based on agent status 339 s.st.application.units[0].(*mockUnit).CheckCall(c, 1, "UpdateOperation", state.UnitUpdateProperties{ 340 ProviderId: strPtr("uuid"), 341 Address: strPtr("address"), Ports: &[]string{"port"}, 342 CloudContainerStatus: &status.StatusInfo{Status: status.Waiting, Message: ""}, 343 AgentStatus: &status.StatusInfo{Status: status.Allocating}, 344 }) 345 s.st.application.units[1].(*mockUnit).CheckCallNames(c, "Life", "UpdateOperation") 346 // CloudContainer message is not overwritten based on agent status 347 s.st.application.units[1].(*mockUnit).CheckCall(c, 1, "UpdateOperation", state.UnitUpdateProperties{ 348 ProviderId: strPtr("another-uuid"), 349 Address: strPtr("another-address"), Ports: &[]string{"another-port"}, 350 CloudContainerStatus: &status.StatusInfo{Status: status.Waiting, Message: "another message"}, 351 AgentStatus: &status.StatusInfo{Status: status.Allocating, Message: "another message"}, 352 }) 353 s.st.application.units[2].(*mockUnit).CheckCallNames(c, "Life", "DestroyOperation", "UpdateOperation") 354 s.st.application.units[2].(*mockUnit).CheckCall(c, 2, "UpdateOperation", state.UnitUpdateProperties{ 355 AgentStatus: &status.StatusInfo{Status: status.Idle}, 356 CloudContainerStatus: &status.StatusInfo{Status: status.Terminated, Message: "unit stopped by the cloud"}, 357 }) 358 s.st.application.units[3].(*mockUnit).CheckCallNames(c, "Life", "UpdateOperation") 359 s.st.application.units[3].(*mockUnit).CheckCall(c, 1, "UpdateOperation", state.UnitUpdateProperties{ 360 ProviderId: strPtr("new-uuid"), 361 Address: strPtr("new-address"), Ports: &[]string{"new-port"}, 362 CloudContainerStatus: &status.StatusInfo{Status: status.Running, Message: "new message"}, 363 AgentStatus: &status.StatusInfo{Status: status.Idle}, 364 }) 365 } 366 367 func (s *CAASProvisionerSuite) TestUpdateApplicationsUnitsNotAlive(c *gc.C) { 368 s.st.application.units = []caasunitprovisioner.Unit{ 369 &mockUnit{name: "gitlab/0", life: state.Alive}, 370 &mockUnit{name: "gitlab/1", life: state.Alive}, 371 &mockUnit{name: "gitlab/2", containerInfo: &mockContainerInfo{providerId: "uuid2"}, life: state.Alive}, 372 } 373 s.st.application.life = state.Dying 374 375 units := []params.ApplicationUnitParams{ 376 {ProviderId: "uuid", UnitTag: "unit-gitlab-0", Address: "address", Ports: []string{"port"}, 377 Status: "running", Info: "message"}, 378 {ProviderId: "another-uuid", UnitTag: "unit-gitlab-1", Address: "another-address", Ports: []string{"another-port"}, 379 Status: "error", Info: "another message"}, 380 } 381 args := params.UpdateApplicationUnitArgs{ 382 Args: []params.UpdateApplicationUnits{ 383 {ApplicationTag: "application-gitlab", Units: units}, 384 }, 385 } 386 results, err := s.facade.UpdateApplicationsUnits(args) 387 c.Assert(err, jc.ErrorIsNil) 388 c.Assert(results, gc.DeepEquals, params.ErrorResults{ 389 Results: []params.ErrorResult{ 390 {nil}, 391 }, 392 }) 393 s.st.application.CheckCallNames(c, "Life", "Name") 394 s.st.application.units[0].(*mockUnit).CheckCallNames(c, "Life") 395 s.st.application.units[1].(*mockUnit).CheckCallNames(c, "Life") 396 s.st.application.units[2].(*mockUnit).CheckCallNames(c, "Life") 397 } 398 399 func (s *CAASProvisionerSuite) TestUpdateApplicationsUnitsWithStorage(c *gc.C) { 400 s.st.application.units = []caasunitprovisioner.Unit{ 401 &mockUnit{name: "gitlab/0", containerInfo: &mockContainerInfo{providerId: "uuid"}, life: state.Alive}, 402 &mockUnit{name: "gitlab/1", life: state.Alive}, 403 &mockUnit{name: "gitlab/2", containerInfo: &mockContainerInfo{providerId: "gone-uuid"}, life: state.Alive}, 404 } 405 s.st.model.containers = []state.CloudContainer{&mockContainerInfo{unitName: "gitlab/1", providerId: "another-uuid"}} 406 s.storage.storageFilesystems[names.NewStorageTag("data/0")] = names.NewFilesystemTag("gitlab/0/0") 407 s.storage.storageFilesystems[names.NewStorageTag("data/1")] = names.NewFilesystemTag("gitlab/1/0") 408 s.storage.storageFilesystems[names.NewStorageTag("data/2")] = names.NewFilesystemTag("gitlab/2/0") 409 s.storage.storageVolumes[names.NewStorageTag("data/0")] = names.NewVolumeTag("0") 410 s.storage.storageVolumes[names.NewStorageTag("data/1")] = names.NewVolumeTag("1") 411 s.storage.storageAttachments[names.NewUnitTag("gitlab/0")] = names.NewStorageTag("data/0") 412 s.storage.storageAttachments[names.NewUnitTag("gitlab/1")] = names.NewStorageTag("data/1") 413 s.storage.storageAttachments[names.NewUnitTag("gitlab/2")] = names.NewStorageTag("data/2") 414 415 units := []params.ApplicationUnitParams{ 416 {ProviderId: "uuid", Address: "address", Ports: []string{"port"}, 417 Status: "running", Info: "message", 418 FilesystemInfo: []params.KubernetesFilesystemInfo{ 419 {StorageName: "data", FilesystemId: "fs-id", Size: 100, MountPoint: "/path/to/here", ReadOnly: true, 420 Status: "pending", Info: "not ready", 421 Volume: params.KubernetesVolumeInfo{ 422 VolumeId: "vol-id", Size: 100, Persistent: true, 423 Status: "pending", Info: "vol not ready", 424 }}, 425 }, 426 }, 427 {ProviderId: "another-uuid", Address: "another-address", Ports: []string{"another-port"}, 428 Status: "running", Info: "another message", 429 FilesystemInfo: []params.KubernetesFilesystemInfo{ 430 {StorageName: "data", FilesystemId: "fs-id2", Size: 200, MountPoint: "/path/to/there", ReadOnly: true, 431 Status: "attached", Info: "ready", 432 Volume: params.KubernetesVolumeInfo{ 433 VolumeId: "vol-id2", Size: 200, Persistent: true, 434 Status: "attached", Info: "vol ready", 435 }}, 436 }, 437 }, 438 } 439 args := params.UpdateApplicationUnitArgs{ 440 Args: []params.UpdateApplicationUnits{ 441 {ApplicationTag: "application-gitlab", Units: units}, 442 }, 443 } 444 results, err := s.facade.UpdateApplicationsUnits(args) 445 c.Assert(err, jc.ErrorIsNil) 446 c.Assert(results, gc.DeepEquals, params.ErrorResults{ 447 Results: []params.ErrorResult{ 448 {nil}, 449 }, 450 }) 451 s.st.application.CheckCallNames(c, "Life", "Name") 452 s.st.application.units[0].(*mockUnit).CheckCallNames(c, "Life", "UpdateOperation") 453 s.st.application.units[0].(*mockUnit).CheckCall(c, 1, "UpdateOperation", state.UnitUpdateProperties{ 454 ProviderId: strPtr("uuid"), 455 Address: strPtr("address"), Ports: &[]string{"port"}, 456 CloudContainerStatus: &status.StatusInfo{Status: status.Running, Message: "message"}, 457 AgentStatus: &status.StatusInfo{Status: status.Idle}, 458 }) 459 s.st.application.units[1].(*mockUnit).CheckCallNames(c, "Life", "UpdateOperation") 460 s.st.application.units[1].(*mockUnit).CheckCall(c, 1, "UpdateOperation", state.UnitUpdateProperties{ 461 ProviderId: strPtr("another-uuid"), 462 Address: strPtr("another-address"), Ports: &[]string{"another-port"}, 463 CloudContainerStatus: &status.StatusInfo{Status: status.Running, Message: "another message"}, 464 AgentStatus: &status.StatusInfo{Status: status.Idle}, 465 }) 466 s.storage.CheckCallNames(c, 467 "UnitStorageAttachments", "UnitStorageAttachments", "StorageInstance", 468 "UnitStorageAttachments", "StorageInstance", "AllFilesystems", 469 "Volume", "SetVolumeInfo", "SetVolumeAttachmentInfo", "Volume", "SetStatus", "Volume", "SetStatus", 470 "Filesystem", "SetFilesystemInfo", "SetFilesystemAttachmentInfo", 471 "Filesystem", "SetStatus", "Filesystem", "SetStatus", "Filesystem", "SetStatus") 472 s.storage.CheckCall(c, 0, "UnitStorageAttachments", names.NewUnitTag("gitlab/2")) 473 s.storage.CheckCall(c, 1, "UnitStorageAttachments", names.NewUnitTag("gitlab/0")) 474 s.storage.CheckCall(c, 2, "StorageInstance", names.NewStorageTag("data/0")) 475 s.storage.CheckCall(c, 3, "UnitStorageAttachments", names.NewUnitTag("gitlab/1")) 476 s.storage.CheckCall(c, 4, "StorageInstance", names.NewStorageTag("data/1")) 477 478 now := s.clock.Now() 479 s.storage.CheckCall(c, 7, "SetVolumeInfo", 480 names.NewVolumeTag("1"), 481 state.VolumeInfo{ 482 Size: 200, 483 VolumeId: "vol-id2", 484 Persistent: true, 485 }) 486 s.storage.CheckCall(c, 8, "SetVolumeAttachmentInfo", 487 names.NewUnitTag("gitlab/1"), names.NewVolumeTag("1"), 488 state.VolumeAttachmentInfo{ 489 ReadOnly: true, 490 }) 491 s.storage.CheckCall(c, 10, "SetStatus", 492 status.StatusInfo{ 493 Status: status.Pending, 494 Message: "vol not ready", 495 Since: &now, 496 }) 497 s.storage.CheckCall(c, 12, "SetStatus", 498 status.StatusInfo{ 499 Status: status.Attached, 500 Message: "vol ready", 501 Since: &now, 502 }) 503 504 s.storage.CheckCall(c, 14, "SetFilesystemInfo", 505 names.NewFilesystemTag("gitlab/1/0"), 506 state.FilesystemInfo{ 507 Size: 200, 508 FilesystemId: "fs-id2", 509 }) 510 s.storage.CheckCall(c, 15, "SetFilesystemAttachmentInfo", 511 names.NewUnitTag("gitlab/1"), names.NewFilesystemTag("gitlab/1/0"), 512 state.FilesystemAttachmentInfo{ 513 MountPoint: "/path/to/there", 514 ReadOnly: true, 515 }) 516 s.storage.CheckCall(c, 19, "SetStatus", 517 status.StatusInfo{ 518 Status: status.Attached, 519 Message: "ready", 520 Since: &now, 521 }) 522 s.storage.CheckCall(c, 21, "SetStatus", 523 status.StatusInfo{ 524 Status: status.Detached, 525 Since: &now, 526 }) 527 } 528 529 func (s *CAASProvisionerSuite) TestUpdateApplicationsService(c *gc.C) { 530 results, err := s.facade.UpdateApplicationsService(params.UpdateApplicationServiceArgs{ 531 Args: []params.UpdateApplicationServiceArg{ 532 {ApplicationTag: "application-gitlab", ProviderId: "id", Addresses: []params.Address{{Value: "10.0.0.1"}}}, 533 {ApplicationTag: "unit-gitlab-0"}, 534 }, 535 }) 536 c.Assert(err, jc.ErrorIsNil) 537 c.Assert(results.Results, gc.HasLen, 2) 538 c.Assert(results.Results[0].Error, gc.IsNil) 539 c.Assert(results.Results[1].Error, jc.DeepEquals, ¶ms.Error{ 540 Message: `"unit-gitlab-0" is not a valid application tag`, 541 }) 542 c.Assert(s.st.application.providerId, gc.Equals, "id") 543 c.Assert(s.st.application.addresses, jc.DeepEquals, []network.Address{{Value: "10.0.0.1"}}) 544 } 545 546 func (s *CAASProvisionerSuite) TestSetOperatorStatus(c *gc.C) { 547 results, err := s.facade.SetOperatorStatus(params.SetStatus{ 548 Entities: []params.EntityStatusArgs{ 549 {Tag: "application-gitlab", Status: "error", Info: "broken", Data: map[string]interface{}{"foo": "bar"}}, 550 {Tag: "unit-gitlab-0"}, 551 }, 552 }) 553 c.Assert(err, jc.ErrorIsNil) 554 c.Assert(results.Results, gc.HasLen, 2) 555 c.Assert(results.Results[0].Error, gc.IsNil) 556 c.Assert(results.Results[1].Error, jc.DeepEquals, ¶ms.Error{ 557 Message: `"unit-gitlab-0" is not a valid application tag`, 558 }) 559 now := s.clock.Now() 560 s.st.application.CheckCall(c, 0, "SetOperatorStatus", status.StatusInfo{ 561 Status: status.Error, 562 Message: "broken", 563 Data: map[string]interface{}{"foo": "bar"}, 564 Since: &now, 565 }) 566 }