How to use Fatalf method of gomock Package

Best Mock code snippet using gomock.Fatalf

controller_test.go

Source:controller_test.go Github

copy

Full Screen

...42 testRegion = "test-region"43 getNewCloudFunc = func(expectedRegion string) func(region string) (cloud.Cloud, error) {44 return func(region string) (cloud.Cloud, error) {45 if region != expectedRegion {46 t.Fatalf("expected region %q but got %q", expectedRegion, region)47 }48 return cloudObj, nil49 }50 }51 )52 testCases := []struct {53 name string54 region string55 newCloudFunc func(string) (cloud.Cloud, error)56 newMetadataFuncErrors bool57 expectPanic bool58 }{59 {60 name: "AWS_REGION variable set, newCloud does not error",61 region: "foo",62 newCloudFunc: getNewCloudFunc("foo"),63 },64 {65 name: "AWS_REGION variable set, newCloud errors",66 region: "foo",67 newCloudFunc: func(region string) (cloud.Cloud, error) {68 return nil, testErr69 },70 expectPanic: true,71 },72 {73 name: "AWS_REGION variable not set, newMetadata does not error",74 newCloudFunc: getNewCloudFunc(testRegion),75 },76 {77 name: "AWS_REGION variable not set, newMetadata errors",78 newCloudFunc: getNewCloudFunc(testRegion),79 newMetadataFuncErrors: true,80 expectPanic: true,81 },82 }83 driverOptions := &DriverOptions{84 endpoint: "test",85 }86 for _, tc := range testCases {87 t.Run(tc.name, func(t *testing.T) {88 oldNewCloudFunc := NewCloudFunc89 defer func() { NewCloudFunc = oldNewCloudFunc }()90 NewCloudFunc = tc.newCloudFunc91 if tc.region == "" {92 mockCtl := gomock.NewController(t)93 defer mockCtl.Finish()94 mockMetadataService := mocks.NewMockMetadataService(mockCtl)95 oldNewMetadataFunc := NewMetadataFunc96 defer func() { NewMetadataFunc = oldNewMetadataFunc }()97 NewMetadataFunc = func() (cloud.MetadataService, error) {98 if tc.newMetadataFuncErrors {99 return nil, testErr100 }101 return mockMetadataService, nil102 }103 if !tc.newMetadataFuncErrors {104 mockMetadataService.EXPECT().GetRegion().Return(testRegion)105 }106 } else {107 os.Setenv("AWS_REGION", tc.region)108 defer os.Unsetenv("AWS_REGION")109 }110 if tc.expectPanic {111 defer func() {112 if r := recover(); r == nil {113 t.Errorf("The code did not panic")114 }115 }()116 }117 controllerSvc := newControllerService(driverOptions)118 if controllerSvc.cloud != cloudObj {119 t.Fatalf("expected cloud attribute to be equal to instantiated cloud object")120 }121 if !reflect.DeepEqual(controllerSvc.driverOptions, driverOptions) {122 t.Fatalf("expected driverOptions attribute to be equal to input")123 }124 })125 }126}127func TestCreateVolume(t *testing.T) {128 stdVolCap := []*csi.VolumeCapability{129 {130 AccessType: &csi.VolumeCapability_Mount{131 Mount: &csi.VolumeCapability_MountVolume{},132 },133 AccessMode: &csi.VolumeCapability_AccessMode{134 Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,135 },136 },137 }138 invalidVolCap := []*csi.VolumeCapability{139 {140 AccessMode: &csi.VolumeCapability_AccessMode{141 Mode: csi.VolumeCapability_AccessMode_MULTI_NODE_SINGLE_WRITER,142 },143 },144 }145 stdVolSize := int64(5 * 1024 * 1024 * 1024)146 stdCapRange := &csi.CapacityRange{RequiredBytes: stdVolSize}147 stdParams := map[string]string{}148 rawOutpostArn := "arn:aws:outposts:us-west-2:111111111111:outpost/op-0aaa000a0aaaa00a0"149 strippedOutpostArn, _ := arn.Parse(strings.ReplaceAll(rawOutpostArn, "outpost/", ""))150 testCases := []struct {151 name string152 testFunc func(t *testing.T)153 }{154 {155 name: "success normal",156 testFunc: func(t *testing.T) {157 req := &csi.CreateVolumeRequest{158 Name: "random-vol-name",159 CapacityRange: stdCapRange,160 VolumeCapabilities: stdVolCap,161 Parameters: nil,162 }163 ctx := context.Background()164 mockDisk := &cloud.Disk{165 VolumeID: req.Name,166 AvailabilityZone: expZone,167 CapacityGiB: util.BytesToGiB(stdVolSize),168 }169 mockCtl := gomock.NewController(t)170 defer mockCtl.Finish()171 mockCloud := mocks.NewMockCloud(mockCtl)172 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)173 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)174 awsDriver := controllerService{175 cloud: mockCloud,176 inFlight: internal.NewInFlight(),177 driverOptions: &DriverOptions{},178 }179 if _, err := awsDriver.CreateVolume(ctx, req); err != nil {180 srvErr, ok := status.FromError(err)181 if !ok {182 t.Fatalf("Could not get error status code from error: %v", srvErr)183 }184 t.Fatalf("Unexpected error: %v", srvErr.Code())185 }186 },187 },188 {189 name: "success outposts",190 testFunc: func(t *testing.T) {191 outpostArn := strippedOutpostArn192 req := &csi.CreateVolumeRequest{193 Name: "test-vol",194 CapacityRange: stdCapRange,195 VolumeCapabilities: stdVolCap,196 Parameters: map[string]string{},197 AccessibilityRequirements: &csi.TopologyRequirement{198 Requisite: []*csi.Topology{199 {200 Segments: map[string]string{201 TopologyKey: expZone,202 AwsAccountIDKey: outpostArn.AccountID,203 AwsOutpostIDKey: outpostArn.Resource,204 AwsRegionKey: outpostArn.Region,205 AwsPartitionKey: outpostArn.Partition,206 },207 },208 },209 },210 }211 expVol := &csi.Volume{212 CapacityBytes: stdVolSize,213 VolumeId: "vol-test",214 VolumeContext: map[string]string{},215 AccessibleTopology: []*csi.Topology{216 {217 Segments: map[string]string{218 TopologyKey: expZone,219 WellKnownTopologyKey: expZone,220 AwsAccountIDKey: outpostArn.AccountID,221 AwsOutpostIDKey: outpostArn.Resource,222 AwsRegionKey: outpostArn.Region,223 AwsPartitionKey: outpostArn.Partition,224 },225 },226 },227 }228 ctx := context.Background()229 mockDisk := &cloud.Disk{230 VolumeID: req.Name,231 AvailabilityZone: expZone,232 CapacityGiB: util.BytesToGiB(stdVolSize),233 OutpostArn: outpostArn.String(),234 }235 mockCtl := gomock.NewController(t)236 defer mockCtl.Finish()237 mockCloud := mocks.NewMockCloud(mockCtl)238 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)239 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)240 awsDriver := controllerService{241 cloud: mockCloud,242 inFlight: internal.NewInFlight(),243 driverOptions: &DriverOptions{},244 }245 resp, err := awsDriver.CreateVolume(ctx, req)246 if err != nil {247 srvErr, ok := status.FromError(err)248 if !ok {249 t.Fatalf("Could not get error status code from error: %v", srvErr)250 }251 t.Fatalf("Unexpected error: %v", srvErr.Code())252 }253 // mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(mockDisk, nil)254 vol := resp.GetVolume()255 if vol == nil {256 t.Fatalf("Expected volume %v, got nil", expVol)257 }258 for expKey, expVal := range expVol.GetVolumeContext() {259 ctx := vol.GetVolumeContext()260 if gotVal, ok := ctx[expKey]; !ok || gotVal != expVal {261 t.Fatalf("Expected volume context for key %v: %v, got: %v", expKey, expVal, gotVal)262 }263 }264 if expVol.GetAccessibleTopology() != nil {265 if !reflect.DeepEqual(expVol.GetAccessibleTopology(), vol.GetAccessibleTopology()) {266 t.Fatalf("Expected AccessibleTopology to be %+v, got: %+v", expVol.GetAccessibleTopology(), vol.GetAccessibleTopology())267 }268 }269 },270 },271 {272 name: "restore snapshot",273 testFunc: func(t *testing.T) {274 req := &csi.CreateVolumeRequest{275 Name: "random-vol-name",276 CapacityRange: stdCapRange,277 VolumeCapabilities: stdVolCap,278 Parameters: nil,279 VolumeContentSource: &csi.VolumeContentSource{280 Type: &csi.VolumeContentSource_Snapshot{281 Snapshot: &csi.VolumeContentSource_SnapshotSource{282 SnapshotId: "snapshot-id",283 },284 },285 },286 }287 ctx := context.Background()288 mockDisk := &cloud.Disk{289 VolumeID: req.Name,290 AvailabilityZone: expZone,291 CapacityGiB: util.BytesToGiB(stdVolSize),292 SnapshotID: "snapshot-id",293 }294 mockCtl := gomock.NewController(t)295 defer mockCtl.Finish()296 mockCloud := mocks.NewMockCloud(mockCtl)297 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)298 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)299 awsDriver := controllerService{300 cloud: mockCloud,301 inFlight: internal.NewInFlight(),302 driverOptions: &DriverOptions{},303 }304 rsp, err := awsDriver.CreateVolume(ctx, req)305 if err != nil {306 srvErr, ok := status.FromError(err)307 if !ok {308 t.Fatalf("Could not get error status code from error: %v", srvErr)309 }310 t.Fatalf("Unexpected error: %v", srvErr.Code())311 }312 snapshotID := ""313 if rsp.Volume != nil && rsp.Volume.ContentSource != nil && rsp.Volume.ContentSource.GetSnapshot() != nil {314 snapshotID = rsp.Volume.ContentSource.GetSnapshot().SnapshotId315 }316 if rsp.Volume.ContentSource.GetSnapshot().SnapshotId != "snapshot-id" {317 t.Errorf("Unexpected snapshot ID: %q", snapshotID)318 }319 },320 },321 {322 name: "restore snapshot, volume already exists",323 testFunc: func(t *testing.T) {324 req := &csi.CreateVolumeRequest{325 Name: "random-vol-name",326 CapacityRange: stdCapRange,327 VolumeCapabilities: stdVolCap,328 Parameters: nil,329 VolumeContentSource: &csi.VolumeContentSource{330 Type: &csi.VolumeContentSource_Snapshot{331 Snapshot: &csi.VolumeContentSource_SnapshotSource{332 SnapshotId: "snapshot-id",333 },334 },335 },336 }337 ctx := context.Background()338 mockDisk := &cloud.Disk{339 VolumeID: req.Name,340 AvailabilityZone: expZone,341 CapacityGiB: util.BytesToGiB(stdVolSize),342 SnapshotID: "snapshot-id",343 }344 mockCtl := gomock.NewController(t)345 defer mockCtl.Finish()346 mockCloud := mocks.NewMockCloud(mockCtl)347 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(mockDisk, nil)348 awsDriver := controllerService{349 cloud: mockCloud,350 inFlight: internal.NewInFlight(),351 driverOptions: &DriverOptions{},352 }353 rsp, err := awsDriver.CreateVolume(ctx, req)354 if err != nil {355 srvErr, ok := status.FromError(err)356 if !ok {357 t.Fatalf("Could not get error status code from error: %v", srvErr)358 }359 t.Fatalf("Unexpected error: %v", srvErr.Code())360 }361 snapshotID := ""362 if rsp.Volume != nil && rsp.Volume.ContentSource != nil && rsp.Volume.ContentSource.GetSnapshot() != nil {363 snapshotID = rsp.Volume.ContentSource.GetSnapshot().SnapshotId364 }365 if rsp.Volume.ContentSource.GetSnapshot().SnapshotId != "snapshot-id" {366 t.Errorf("Unexpected snapshot ID: %q", snapshotID)367 }368 },369 },370 {371 name: "restore snapshot, volume already exists with different snapshot ID",372 testFunc: func(t *testing.T) {373 req := &csi.CreateVolumeRequest{374 Name: "random-vol-name",375 CapacityRange: stdCapRange,376 VolumeCapabilities: stdVolCap,377 Parameters: nil,378 VolumeContentSource: &csi.VolumeContentSource{379 Type: &csi.VolumeContentSource_Snapshot{380 Snapshot: &csi.VolumeContentSource_SnapshotSource{381 SnapshotId: "snapshot-id",382 },383 },384 },385 }386 ctx := context.Background()387 mockDisk := &cloud.Disk{388 VolumeID: req.Name,389 AvailabilityZone: expZone,390 CapacityGiB: util.BytesToGiB(stdVolSize),391 SnapshotID: "another-snapshot-id",392 }393 mockCtl := gomock.NewController(t)394 defer mockCtl.Finish()395 mockCloud := mocks.NewMockCloud(mockCtl)396 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(mockDisk, nil)397 awsDriver := controllerService{398 cloud: mockCloud,399 inFlight: internal.NewInFlight(),400 driverOptions: &DriverOptions{},401 }402 if _, err := awsDriver.CreateVolume(ctx, req); err == nil {403 t.Error("CreateVolume with invalid SnapshotID unexpectedly succeeded")404 }405 },406 },407 {408 name: "fail no name",409 testFunc: func(t *testing.T) {410 req := &csi.CreateVolumeRequest{411 Name: "",412 CapacityRange: stdCapRange,413 VolumeCapabilities: stdVolCap,414 Parameters: stdParams,415 }416 ctx := context.Background()417 mockCtl := gomock.NewController(t)418 defer mockCtl.Finish()419 mockCloud := mocks.NewMockCloud(mockCtl)420 awsDriver := controllerService{421 cloud: mockCloud,422 inFlight: internal.NewInFlight(),423 driverOptions: &DriverOptions{},424 }425 if _, err := awsDriver.CreateVolume(ctx, req); err != nil {426 srvErr, ok := status.FromError(err)427 if !ok {428 t.Fatalf("Could not get error status code from error: %v", srvErr)429 }430 if srvErr.Code() != codes.InvalidArgument {431 t.Fatalf("Expected error code %d, got %d message %s", codes.InvalidArgument, srvErr.Code(), srvErr.Message())432 }433 } else {434 t.Fatalf("Expected error %v, got no error", codes.InvalidArgument)435 }436 },437 },438 {439 name: "success same name and same capacity",440 testFunc: func(t *testing.T) {441 req := &csi.CreateVolumeRequest{442 Name: "test-vol",443 CapacityRange: stdCapRange,444 VolumeCapabilities: stdVolCap,445 Parameters: stdParams,446 }447 extraReq := &csi.CreateVolumeRequest{448 Name: "test-vol",449 CapacityRange: stdCapRange,450 VolumeCapabilities: stdVolCap,451 Parameters: stdParams,452 }453 expVol := &csi.Volume{454 CapacityBytes: stdVolSize,455 VolumeId: "test-vol",456 VolumeContext: map[string]string{},457 }458 ctx := context.Background()459 mockDisk := &cloud.Disk{460 VolumeID: req.Name,461 AvailabilityZone: expZone,462 CapacityGiB: util.BytesToGiB(stdVolSize),463 }464 mockCtl := gomock.NewController(t)465 defer mockCtl.Finish()466 mockCloud := mocks.NewMockCloud(mockCtl)467 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)468 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)469 awsDriver := controllerService{470 cloud: mockCloud,471 inFlight: internal.NewInFlight(),472 driverOptions: &DriverOptions{},473 }474 if _, err := awsDriver.CreateVolume(ctx, req); err != nil {475 srvErr, ok := status.FromError(err)476 if !ok {477 t.Fatalf("Could not get error status code from error: %v", srvErr)478 }479 t.Fatalf("Unexpected error: %v", srvErr.Code())480 }481 // Subsequent call returns the created disk482 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(mockDisk, nil)483 resp, err := awsDriver.CreateVolume(ctx, extraReq)484 if err != nil {485 srvErr, ok := status.FromError(err)486 if !ok {487 t.Fatalf("Could not get error status code from error: %v", srvErr)488 }489 t.Fatalf("Unexpected error: %v", srvErr.Code())490 }491 vol := resp.GetVolume()492 if vol == nil {493 t.Fatalf("Expected volume %v, got nil", expVol)494 }495 if vol.GetCapacityBytes() != expVol.GetCapacityBytes() {496 t.Fatalf("Expected volume capacity bytes: %v, got: %v", expVol.GetCapacityBytes(), vol.GetCapacityBytes())497 }498 if vol.GetVolumeId() != expVol.GetVolumeId() {499 t.Fatalf("Expected volume id: %v, got: %v", expVol.GetVolumeId(), vol.GetVolumeId())500 }501 if expVol.GetAccessibleTopology() != nil {502 if !reflect.DeepEqual(expVol.GetAccessibleTopology(), vol.GetAccessibleTopology()) {503 t.Fatalf("Expected AccessibleTopology to be %+v, got: %+v", expVol.GetAccessibleTopology(), vol.GetAccessibleTopology())504 }505 }506 for expKey, expVal := range expVol.GetVolumeContext() {507 ctx := vol.GetVolumeContext()508 if gotVal, ok := ctx[expKey]; !ok || gotVal != expVal {509 t.Fatalf("Expected volume context for key %v: %v, got: %v", expKey, expVal, gotVal)510 }511 }512 },513 },514 {515 name: "fail same name and different capacity",516 testFunc: func(t *testing.T) {517 req := &csi.CreateVolumeRequest{518 Name: "test-vol",519 CapacityRange: stdCapRange,520 VolumeCapabilities: stdVolCap,521 Parameters: stdParams,522 }523 extraReq := &csi.CreateVolumeRequest{524 Name: "test-vol",525 CapacityRange: &csi.CapacityRange{RequiredBytes: 10000},526 VolumeCapabilities: stdVolCap,527 Parameters: stdParams,528 }529 ctx := context.Background()530 mockDisk := &cloud.Disk{531 VolumeID: req.Name,532 AvailabilityZone: expZone,533 }534 volSizeBytes, err := getVolSizeBytes(req)535 if err != nil {536 t.Fatalf("Unable to get volume size bytes for req: %s", err)537 }538 mockDisk.CapacityGiB = util.BytesToGiB(volSizeBytes)539 mockCtl := gomock.NewController(t)540 defer mockCtl.Finish()541 mockCloud := mocks.NewMockCloud(mockCtl)542 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(volSizeBytes)).Return(nil, cloud.ErrNotFound)543 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)544 awsDriver := controllerService{545 cloud: mockCloud,546 inFlight: internal.NewInFlight(),547 driverOptions: &DriverOptions{},548 }549 _, err = awsDriver.CreateVolume(ctx, req)550 if err != nil {551 srvErr, ok := status.FromError(err)552 if !ok {553 t.Fatalf("Could not get error status code from error: %v", srvErr)554 }555 t.Fatalf("Unexpected error: %v", srvErr.Code())556 }557 extraVolSizeBytes, err := getVolSizeBytes(extraReq)558 if err != nil {559 t.Fatalf("Unable to get volume size bytes for req: %s", err)560 }561 // Subsequent failure562 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(extraReq.Name), gomock.Eq(extraVolSizeBytes)).Return(nil, cloud.ErrDiskExistsDiffSize)563 if _, err := awsDriver.CreateVolume(ctx, extraReq); err != nil {564 srvErr, ok := status.FromError(err)565 if !ok {566 t.Fatalf("Could not get error status code from error: %v", srvErr)567 }568 if srvErr.Code() != codes.AlreadyExists {569 t.Fatalf("Expected error code %d, got %d", codes.AlreadyExists, srvErr.Code())570 }571 } else {572 t.Fatalf("Expected error %v, got no error", codes.AlreadyExists)573 }574 },575 },576 {577 name: "success no capacity range",578 testFunc: func(t *testing.T) {579 req := &csi.CreateVolumeRequest{580 Name: "test-vol",581 VolumeCapabilities: stdVolCap,582 Parameters: stdParams,583 }584 expVol := &csi.Volume{585 CapacityBytes: cloud.DefaultVolumeSize,586 VolumeId: "vol-test",587 VolumeContext: map[string]string{},588 }589 ctx := context.Background()590 mockDisk := &cloud.Disk{591 VolumeID: req.Name,592 AvailabilityZone: expZone,593 CapacityGiB: util.BytesToGiB(cloud.DefaultVolumeSize),594 }595 mockCtl := gomock.NewController(t)596 defer mockCtl.Finish()597 mockCloud := mocks.NewMockCloud(mockCtl)598 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(cloud.DefaultVolumeSize)).Return(nil, cloud.ErrNotFound)599 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)600 awsDriver := controllerService{601 cloud: mockCloud,602 inFlight: internal.NewInFlight(),603 driverOptions: &DriverOptions{},604 }605 resp, err := awsDriver.CreateVolume(ctx, req)606 if err != nil {607 srvErr, ok := status.FromError(err)608 if !ok {609 t.Fatalf("Could not get error status code from error: %v", srvErr)610 }611 t.Fatalf("Unexpected error: %v", srvErr.Code())612 }613 vol := resp.GetVolume()614 if vol == nil {615 t.Fatalf("Expected volume %v, got nil", expVol)616 }617 if vol.GetCapacityBytes() != expVol.GetCapacityBytes() {618 t.Fatalf("Expected volume capacity bytes: %v, got: %v", expVol.GetCapacityBytes(), vol.GetCapacityBytes())619 }620 for expKey, expVal := range expVol.GetVolumeContext() {621 ctx := vol.GetVolumeContext()622 if gotVal, ok := ctx[expKey]; !ok || gotVal != expVal {623 t.Fatalf("Expected volume context for key %v: %v, got: %v", expKey, expVal, gotVal)624 }625 }626 },627 },628 {629 name: "success with correct round up",630 testFunc: func(t *testing.T) {631 req := &csi.CreateVolumeRequest{632 Name: "vol-test",633 CapacityRange: &csi.CapacityRange{RequiredBytes: 1073741825},634 VolumeCapabilities: stdVolCap,635 Parameters: nil,636 }637 expVol := &csi.Volume{638 CapacityBytes: 2147483648, // 1 GiB + 1 byte = 2 GiB639 VolumeId: "vol-test",640 VolumeContext: map[string]string{},641 }642 ctx := context.Background()643 mockDisk := &cloud.Disk{644 VolumeID: req.Name,645 AvailabilityZone: expZone,646 CapacityGiB: util.BytesToGiB(expVol.CapacityBytes),647 }648 mockCtl := gomock.NewController(t)649 defer mockCtl.Finish()650 mockCloud := mocks.NewMockCloud(mockCtl)651 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(expVol.CapacityBytes)).Return(nil, cloud.ErrNotFound)652 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)653 awsDriver := controllerService{654 cloud: mockCloud,655 inFlight: internal.NewInFlight(),656 driverOptions: &DriverOptions{},657 }658 resp, err := awsDriver.CreateVolume(ctx, req)659 if err != nil {660 srvErr, ok := status.FromError(err)661 if !ok {662 t.Fatalf("Could not get error status code from error: %v", srvErr)663 }664 t.Fatalf("Unexpected error: %v", srvErr.Code())665 }666 vol := resp.GetVolume()667 if vol == nil {668 t.Fatalf("Expected volume %v, got nil", expVol)669 }670 if vol.GetCapacityBytes() != expVol.GetCapacityBytes() {671 t.Fatalf("Expected volume capacity bytes: %v, got: %v", expVol.GetCapacityBytes(), vol.GetCapacityBytes())672 }673 },674 },675 {676 name: "success with volume type gp3",677 testFunc: func(t *testing.T) {678 // iops 5000 requires at least 10GB679 volSize := int64(20 * 1024 * 1024 * 1024)680 capRange := &csi.CapacityRange{RequiredBytes: volSize}681 req := &csi.CreateVolumeRequest{682 Name: "vol-test",683 CapacityRange: capRange,684 VolumeCapabilities: stdVolCap,685 Parameters: map[string]string{686 VolumeTypeKey: cloud.VolumeTypeGP3,687 IopsKey: "5000",688 ThroughputKey: "250",689 },690 }691 ctx := context.Background()692 mockDisk := &cloud.Disk{693 VolumeID: req.Name,694 AvailabilityZone: expZone,695 CapacityGiB: util.BytesToGiB(volSize),696 }697 mockCtl := gomock.NewController(t)698 defer mockCtl.Finish()699 mockCloud := mocks.NewMockCloud(mockCtl)700 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(volSize)).Return(nil, cloud.ErrNotFound)701 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)702 awsDriver := controllerService{703 cloud: mockCloud,704 inFlight: internal.NewInFlight(),705 driverOptions: &DriverOptions{},706 }707 if _, err := awsDriver.CreateVolume(ctx, req); err != nil {708 srvErr, ok := status.FromError(err)709 if !ok {710 t.Fatalf("Could not get error status code from error: %v", srvErr)711 }712 t.Fatalf("Unexpected error: %v", srvErr.Code())713 }714 },715 },716 {717 name: "success with volume type io1",718 testFunc: func(t *testing.T) {719 req := &csi.CreateVolumeRequest{720 Name: "vol-test",721 CapacityRange: stdCapRange,722 VolumeCapabilities: stdVolCap,723 Parameters: map[string]string{724 VolumeTypeKey: cloud.VolumeTypeIO1,725 IopsPerGBKey: "5",726 },727 }728 ctx := context.Background()729 mockDisk := &cloud.Disk{730 VolumeID: req.Name,731 AvailabilityZone: expZone,732 CapacityGiB: util.BytesToGiB(stdVolSize),733 }734 mockCtl := gomock.NewController(t)735 defer mockCtl.Finish()736 mockCloud := mocks.NewMockCloud(mockCtl)737 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)738 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)739 awsDriver := controllerService{740 cloud: mockCloud,741 inFlight: internal.NewInFlight(),742 driverOptions: &DriverOptions{},743 }744 if _, err := awsDriver.CreateVolume(ctx, req); err != nil {745 srvErr, ok := status.FromError(err)746 if !ok {747 t.Fatalf("Could not get error status code from error: %v", srvErr)748 }749 t.Fatalf("Unexpected error: %v", srvErr.Code())750 }751 },752 },753 {754 name: "success with volume type io2",755 testFunc: func(t *testing.T) {756 req := &csi.CreateVolumeRequest{757 Name: "vol-test",758 CapacityRange: stdCapRange,759 VolumeCapabilities: stdVolCap,760 Parameters: map[string]string{761 VolumeTypeKey: cloud.VolumeTypeIO2,762 IopsPerGBKey: "5",763 },764 }765 ctx := context.Background()766 mockDisk := &cloud.Disk{767 VolumeID: req.Name,768 AvailabilityZone: expZone,769 CapacityGiB: util.BytesToGiB(stdVolSize),770 }771 mockCtl := gomock.NewController(t)772 defer mockCtl.Finish()773 mockCloud := mocks.NewMockCloud(mockCtl)774 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)775 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)776 awsDriver := controllerService{777 cloud: mockCloud,778 inFlight: internal.NewInFlight(),779 driverOptions: &DriverOptions{},780 }781 if _, err := awsDriver.CreateVolume(ctx, req); err != nil {782 srvErr, ok := status.FromError(err)783 if !ok {784 t.Fatalf("Could not get error status code from error: %v", srvErr)785 }786 t.Fatalf("Unexpected error: %v", srvErr.Code())787 }788 },789 },790 {791 name: "success with volume type sc1",792 testFunc: func(t *testing.T) {793 req := &csi.CreateVolumeRequest{794 Name: "vol-test",795 CapacityRange: stdCapRange,796 VolumeCapabilities: stdVolCap,797 Parameters: map[string]string{798 VolumeTypeKey: cloud.VolumeTypeSC1,799 },800 }801 ctx := context.Background()802 mockDisk := &cloud.Disk{803 VolumeID: req.Name,804 AvailabilityZone: expZone,805 CapacityGiB: util.BytesToGiB(stdVolSize),806 }807 mockCtl := gomock.NewController(t)808 defer mockCtl.Finish()809 mockCloud := mocks.NewMockCloud(mockCtl)810 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)811 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)812 awsDriver := controllerService{813 cloud: mockCloud,814 inFlight: internal.NewInFlight(),815 driverOptions: &DriverOptions{},816 }817 if _, err := awsDriver.CreateVolume(ctx, req); err != nil {818 srvErr, ok := status.FromError(err)819 if !ok {820 t.Fatalf("Could not get error status code from error: %v", srvErr)821 }822 t.Fatalf("Unexpected error: %v", srvErr.Code())823 }824 },825 },826 {827 name: "success with volume type standard",828 testFunc: func(t *testing.T) {829 req := &csi.CreateVolumeRequest{830 Name: "vol-test",831 CapacityRange: stdCapRange,832 VolumeCapabilities: stdVolCap,833 Parameters: map[string]string{834 VolumeTypeKey: cloud.VolumeTypeStandard,835 },836 }837 ctx := context.Background()838 mockDisk := &cloud.Disk{839 VolumeID: req.Name,840 AvailabilityZone: expZone,841 CapacityGiB: util.BytesToGiB(stdVolSize),842 }843 mockCtl := gomock.NewController(t)844 defer mockCtl.Finish()845 mockCloud := mocks.NewMockCloud(mockCtl)846 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)847 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)848 awsDriver := controllerService{849 cloud: mockCloud,850 inFlight: internal.NewInFlight(),851 driverOptions: &DriverOptions{},852 }853 if _, err := awsDriver.CreateVolume(ctx, req); err != nil {854 srvErr, ok := status.FromError(err)855 if !ok {856 t.Fatalf("Could not get error status code from error: %v", srvErr)857 }858 t.Fatalf("Unexpected error: %v", srvErr.Code())859 }860 },861 },862 {863 name: "success with volume encryption",864 testFunc: func(t *testing.T) {865 req := &csi.CreateVolumeRequest{866 Name: "vol-test",867 CapacityRange: stdCapRange,868 VolumeCapabilities: stdVolCap,869 Parameters: map[string]string{870 EncryptedKey: "true",871 },872 }873 ctx := context.Background()874 mockDisk := &cloud.Disk{875 VolumeID: req.Name,876 AvailabilityZone: expZone,877 CapacityGiB: util.BytesToGiB(stdVolSize),878 }879 mockCtl := gomock.NewController(t)880 defer mockCtl.Finish()881 mockCloud := mocks.NewMockCloud(mockCtl)882 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)883 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)884 awsDriver := controllerService{885 cloud: mockCloud,886 inFlight: internal.NewInFlight(),887 driverOptions: &DriverOptions{},888 }889 if _, err := awsDriver.CreateVolume(ctx, req); err != nil {890 srvErr, ok := status.FromError(err)891 if !ok {892 t.Fatalf("Could not get error status code from error: %v", srvErr)893 }894 t.Fatalf("Unexpected error: %v", srvErr.Code())895 }896 },897 },898 {899 name: "success with volume encryption with KMS key",900 testFunc: func(t *testing.T) {901 req := &csi.CreateVolumeRequest{902 Name: "vol-test",903 CapacityRange: stdCapRange,904 VolumeCapabilities: stdVolCap,905 Parameters: map[string]string{906 EncryptedKey: "true",907 KmsKeyIDKey: "arn:aws:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef",908 },909 }910 ctx := context.Background()911 mockDisk := &cloud.Disk{912 VolumeID: req.Name,913 AvailabilityZone: expZone,914 CapacityGiB: util.BytesToGiB(stdVolSize),915 }916 mockCtl := gomock.NewController(t)917 defer mockCtl.Finish()918 mockCloud := mocks.NewMockCloud(mockCtl)919 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)920 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)921 awsDriver := controllerService{922 cloud: mockCloud,923 inFlight: internal.NewInFlight(),924 driverOptions: &DriverOptions{},925 }926 if _, err := awsDriver.CreateVolume(ctx, req); err != nil {927 srvErr, ok := status.FromError(err)928 if !ok {929 t.Fatalf("Could not get error status code from error: %v", srvErr)930 }931 t.Fatalf("Unexpected error: %v", srvErr.Code())932 }933 },934 },935 {936 name: "fail with invalid volume parameter",937 testFunc: func(t *testing.T) {938 req := &csi.CreateVolumeRequest{939 Name: "vol-test",940 CapacityRange: stdCapRange,941 VolumeCapabilities: stdVolCap,942 Parameters: map[string]string{943 VolumeTypeKey: cloud.VolumeTypeIO1,944 IopsPerGBKey: "5",945 "unknownKey": "unknownValue",946 },947 }948 ctx := context.Background()949 mockCtl := gomock.NewController(t)950 defer mockCtl.Finish()951 mockCloud := mocks.NewMockCloud(mockCtl)952 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)953 awsDriver := controllerService{954 cloud: mockCloud,955 inFlight: internal.NewInFlight(),956 driverOptions: &DriverOptions{},957 }958 _, err := awsDriver.CreateVolume(ctx, req)959 if err == nil {960 t.Fatalf("Expected CreateVolume to fail but got no error")961 }962 srvErr, ok := status.FromError(err)963 if !ok {964 t.Fatalf("Could not get error status code from error: %v", srvErr)965 }966 if srvErr.Code() != codes.InvalidArgument {967 t.Fatalf("Expect InvalidArgument but got: %s", srvErr.Code())968 }969 },970 },971 {972 name: "fail with invalid iops parameter",973 testFunc: func(t *testing.T) {974 req := &csi.CreateVolumeRequest{975 Name: "vol-test",976 CapacityRange: stdCapRange,977 VolumeCapabilities: stdVolCap,978 Parameters: map[string]string{979 VolumeTypeKey: cloud.VolumeTypeGP3,980 IopsKey: "aaa",981 },982 }983 ctx := context.Background()984 mockCtl := gomock.NewController(t)985 defer mockCtl.Finish()986 mockCloud := mocks.NewMockCloud(mockCtl)987 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)988 awsDriver := controllerService{989 cloud: mockCloud,990 inFlight: internal.NewInFlight(),991 driverOptions: &DriverOptions{},992 }993 _, err := awsDriver.CreateVolume(ctx, req)994 if err == nil {995 t.Fatalf("Expected CreateVolume to fail but got no error")996 }997 srvErr, ok := status.FromError(err)998 if !ok {999 t.Fatalf("Could not get error status code from error: %v", srvErr)1000 }1001 if srvErr.Code() != codes.InvalidArgument {1002 t.Fatalf("Expect InvalidArgument but got: %s", srvErr.Code())1003 }1004 },1005 },1006 {1007 name: "fail with invalid throughput parameter",1008 testFunc: func(t *testing.T) {1009 req := &csi.CreateVolumeRequest{1010 Name: "vol-test",1011 CapacityRange: stdCapRange,1012 VolumeCapabilities: stdVolCap,1013 Parameters: map[string]string{1014 VolumeTypeKey: cloud.VolumeTypeGP3,1015 ThroughputKey: "aaa",1016 },1017 }1018 ctx := context.Background()1019 mockCtl := gomock.NewController(t)1020 defer mockCtl.Finish()1021 mockCloud := mocks.NewMockCloud(mockCtl)1022 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)1023 awsDriver := controllerService{1024 cloud: mockCloud,1025 inFlight: internal.NewInFlight(),1026 driverOptions: &DriverOptions{},1027 }1028 _, err := awsDriver.CreateVolume(ctx, req)1029 if err == nil {1030 t.Fatalf("Expected CreateVolume to fail but got no error")1031 }1032 srvErr, ok := status.FromError(err)1033 if !ok {1034 t.Fatalf("Could not get error status code from error: %v", srvErr)1035 }1036 if srvErr.Code() != codes.InvalidArgument {1037 t.Fatalf("Expect InvalidArgument but got: %s", srvErr.Code())1038 }1039 },1040 },1041 {1042 name: "success when volume exists and contains VolumeContext and AccessibleTopology",1043 testFunc: func(t *testing.T) {1044 req := &csi.CreateVolumeRequest{1045 Name: "test-vol",1046 CapacityRange: stdCapRange,1047 VolumeCapabilities: stdVolCap,1048 Parameters: map[string]string{},1049 AccessibilityRequirements: &csi.TopologyRequirement{1050 Requisite: []*csi.Topology{1051 {1052 Segments: map[string]string{TopologyKey: expZone},1053 },1054 },1055 },1056 }1057 extraReq := &csi.CreateVolumeRequest{1058 Name: "test-vol",1059 CapacityRange: stdCapRange,1060 VolumeCapabilities: stdVolCap,1061 Parameters: map[string]string{},1062 AccessibilityRequirements: &csi.TopologyRequirement{1063 Requisite: []*csi.Topology{1064 {1065 Segments: map[string]string{TopologyKey: expZone},1066 },1067 },1068 },1069 }1070 expVol := &csi.Volume{1071 CapacityBytes: stdVolSize,1072 VolumeId: "vol-test",1073 VolumeContext: map[string]string{},1074 AccessibleTopology: []*csi.Topology{1075 {1076 Segments: map[string]string{TopologyKey: expZone, WellKnownTopologyKey: expZone},1077 },1078 },1079 }1080 ctx := context.Background()1081 mockDisk := &cloud.Disk{1082 VolumeID: req.Name,1083 AvailabilityZone: expZone,1084 CapacityGiB: util.BytesToGiB(stdVolSize),1085 }1086 mockCtl := gomock.NewController(t)1087 defer mockCtl.Finish()1088 mockCloud := mocks.NewMockCloud(mockCtl)1089 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)1090 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Any()).Return(mockDisk, nil)1091 awsDriver := controllerService{1092 cloud: mockCloud,1093 inFlight: internal.NewInFlight(),1094 driverOptions: &DriverOptions{},1095 }1096 if _, err := awsDriver.CreateVolume(ctx, req); err != nil {1097 srvErr, ok := status.FromError(err)1098 if !ok {1099 t.Fatalf("Could not get error status code from error: %v", srvErr)1100 }1101 t.Fatalf("Unexpected error: %v", srvErr.Code())1102 }1103 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(mockDisk, nil)1104 resp, err := awsDriver.CreateVolume(ctx, extraReq)1105 if err != nil {1106 srvErr, ok := status.FromError(err)1107 if !ok {1108 t.Fatalf("Could not get error status code from error: %v", srvErr)1109 }1110 t.Fatalf("Unexpected error: %v", srvErr.Code())1111 }1112 vol := resp.GetVolume()1113 if vol == nil {1114 t.Fatalf("Expected volume %v, got nil", expVol)1115 }1116 for expKey, expVal := range expVol.GetVolumeContext() {1117 ctx := vol.GetVolumeContext()1118 if gotVal, ok := ctx[expKey]; !ok || gotVal != expVal {1119 t.Fatalf("Expected volume context for key %v: %v, got: %v", expKey, expVal, gotVal)1120 }1121 }1122 if expVol.GetAccessibleTopology() != nil {1123 if !reflect.DeepEqual(expVol.GetAccessibleTopology(), vol.GetAccessibleTopology()) {1124 t.Fatalf("Expected AccessibleTopology to be %+v, got: %+v", expVol.GetAccessibleTopology(), vol.GetAccessibleTopology())1125 }1126 }1127 },1128 },1129 {1130 name: "success with extra tags",1131 testFunc: func(t *testing.T) {1132 const (1133 volumeName = "random-vol-name"1134 extraVolumeTagKey = "extra-tag-key"1135 extraVolumeTagValue = "extra-tag-value"1136 )1137 req := &csi.CreateVolumeRequest{1138 Name: volumeName,1139 CapacityRange: stdCapRange,1140 VolumeCapabilities: stdVolCap,1141 Parameters: nil,1142 }1143 ctx := context.Background()1144 mockDisk := &cloud.Disk{1145 VolumeID: req.Name,1146 AvailabilityZone: expZone,1147 CapacityGiB: util.BytesToGiB(stdVolSize),1148 }1149 diskOptions := &cloud.DiskOptions{1150 CapacityBytes: stdVolSize,1151 Tags: map[string]string{1152 cloud.VolumeNameTagKey: volumeName,1153 extraVolumeTagKey: extraVolumeTagValue,1154 },1155 }1156 mockCtl := gomock.NewController(t)1157 defer mockCtl.Finish()1158 mockCloud := mocks.NewMockCloud(mockCtl)1159 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)1160 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(diskOptions)).Return(mockDisk, nil)1161 awsDriver := controllerService{1162 cloud: mockCloud,1163 inFlight: internal.NewInFlight(),1164 driverOptions: &DriverOptions{1165 extraTags: map[string]string{1166 extraVolumeTagKey: extraVolumeTagValue,1167 },1168 },1169 }1170 _, err := awsDriver.CreateVolume(ctx, req)1171 if err != nil {1172 srvErr, ok := status.FromError(err)1173 if !ok {1174 t.Fatalf("Could not get error status code from error: %v", srvErr)1175 }1176 t.Fatalf("Unexpected error: %v", srvErr.Code())1177 }1178 },1179 },1180 {1181 name: "success with cluster-id",1182 testFunc: func(t *testing.T) {1183 const (1184 volumeName = "random-vol-name"1185 clusterID = "test-cluster-id"1186 expectedOwnerTag = "kubernetes.io/cluster/test-cluster-id"1187 expectedOwnerTagValue = "owned"1188 expectedNameTag = "Name"1189 expectedNameTagValue = "test-cluster-id-dynamic-random-vol-name"1190 )1191 req := &csi.CreateVolumeRequest{1192 Name: volumeName,1193 CapacityRange: stdCapRange,1194 VolumeCapabilities: stdVolCap,1195 Parameters: nil,1196 }1197 ctx := context.Background()1198 mockDisk := &cloud.Disk{1199 VolumeID: req.Name,1200 AvailabilityZone: expZone,1201 CapacityGiB: util.BytesToGiB(stdVolSize),1202 }1203 diskOptions := &cloud.DiskOptions{1204 CapacityBytes: stdVolSize,1205 Tags: map[string]string{1206 cloud.VolumeNameTagKey: volumeName,1207 expectedOwnerTag: expectedOwnerTagValue,1208 expectedNameTag: expectedNameTagValue,1209 },1210 }1211 mockCtl := gomock.NewController(t)1212 defer mockCtl.Finish()1213 mockCloud := mocks.NewMockCloud(mockCtl)1214 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)1215 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(diskOptions)).Return(mockDisk, nil)1216 awsDriver := controllerService{1217 cloud: mockCloud,1218 inFlight: internal.NewInFlight(),1219 driverOptions: &DriverOptions{1220 kubernetesClusterID: clusterID,1221 },1222 }1223 _, err := awsDriver.CreateVolume(ctx, req)1224 if err != nil {1225 srvErr, ok := status.FromError(err)1226 if !ok {1227 t.Fatalf("Could not get error status code from error: %v", srvErr)1228 }1229 t.Fatalf("Unexpected error: %v", srvErr.Code())1230 }1231 },1232 },1233 {1234 name: "success with legacy tags",1235 testFunc: func(t *testing.T) {1236 const (1237 volumeName = "random-vol-name"1238 clusterID = "test-cluster-id"1239 expectedPVCNameTag = "kubernetes.io/created-for/pvc/name"1240 expectedPVCNamespaceTag = "kubernetes.io/created-for/pvc/namespace"1241 expectedPVNameTag = "kubernetes.io/created-for/pv/name"1242 pvcNamespace = "default"1243 pvcName = "my-pvc"1244 pvName = volumeName1245 )1246 req := &csi.CreateVolumeRequest{1247 Name: volumeName,1248 CapacityRange: stdCapRange,1249 VolumeCapabilities: stdVolCap,1250 Parameters: map[string]string{1251 "csi.storage.k8s.io/pvc/name": pvcName,1252 "csi.storage.k8s.io/pvc/namespace": pvcNamespace,1253 "csi.storage.k8s.io/pv/name": pvName,1254 },1255 }1256 ctx := context.Background()1257 mockDisk := &cloud.Disk{1258 VolumeID: req.Name,1259 AvailabilityZone: expZone,1260 CapacityGiB: util.BytesToGiB(stdVolSize),1261 }1262 diskOptions := &cloud.DiskOptions{1263 CapacityBytes: stdVolSize,1264 Tags: map[string]string{1265 cloud.VolumeNameTagKey: volumeName,1266 expectedPVCNameTag: pvcName,1267 expectedPVCNamespaceTag: pvcNamespace,1268 expectedPVNameTag: pvName,1269 },1270 }1271 mockCtl := gomock.NewController(t)1272 defer mockCtl.Finish()1273 mockCloud := mocks.NewMockCloud(mockCtl)1274 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)1275 mockCloud.EXPECT().CreateDisk(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(diskOptions)).Return(mockDisk, nil)1276 awsDriver := controllerService{1277 cloud: mockCloud,1278 inFlight: internal.NewInFlight(),1279 driverOptions: &DriverOptions{},1280 }1281 _, err := awsDriver.CreateVolume(ctx, req)1282 if err != nil {1283 srvErr, ok := status.FromError(err)1284 if !ok {1285 t.Fatalf("Could not get error status code from error: %v", srvErr)1286 }1287 t.Fatalf("Unexpected error: %v", srvErr.Code())1288 }1289 },1290 },1291 {1292 name: "fail with invalid volume access modes",1293 testFunc: func(t *testing.T) {1294 req := &csi.CreateVolumeRequest{1295 Name: "vol-test",1296 CapacityRange: stdCapRange,1297 VolumeCapabilities: invalidVolCap,1298 Parameters: map[string]string{1299 VolumeTypeKey: cloud.VolumeTypeIO1,1300 IopsPerGBKey: "5",1301 "unknownKey": "unknownValue",1302 },1303 }1304 ctx := context.Background()1305 mockCtl := gomock.NewController(t)1306 defer mockCtl.Finish()1307 mockCloud := mocks.NewMockCloud(mockCtl)1308 awsDriver := controllerService{1309 cloud: mockCloud,1310 inFlight: internal.NewInFlight(),1311 driverOptions: &DriverOptions{},1312 }1313 _, err := awsDriver.CreateVolume(ctx, req)1314 if err == nil {1315 t.Fatalf("Expected CreateVolume to fail but got no error")1316 }1317 srvErr, ok := status.FromError(err)1318 if !ok {1319 t.Fatalf("Could not get error status code from error: %v", srvErr)1320 }1321 if srvErr.Code() != codes.InvalidArgument {1322 t.Fatalf("Expect InvalidArgument but got: %s", srvErr.Code())1323 }1324 },1325 },1326 {1327 name: "fail with in-flight request",1328 testFunc: func(t *testing.T) {1329 req := &csi.CreateVolumeRequest{1330 Name: "random-vol-name",1331 CapacityRange: stdCapRange,1332 VolumeCapabilities: stdVolCap,1333 Parameters: nil,1334 }1335 ctx := context.Background()1336 mockCtl := gomock.NewController(t)1337 defer mockCtl.Finish()1338 mockCloud := mocks.NewMockCloud(mockCtl)1339 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)1340 inFlight := internal.NewInFlight()1341 inFlight.Insert(req.String())1342 defer inFlight.Delete(req.String())1343 awsDriver := controllerService{1344 cloud: mockCloud,1345 inFlight: inFlight,1346 driverOptions: &DriverOptions{},1347 }1348 _, err := awsDriver.CreateVolume(ctx, req)1349 if err == nil {1350 t.Fatalf("Expected CreateVolume to fail but got no error")1351 }1352 srvErr, ok := status.FromError(err)1353 if !ok {1354 t.Fatalf("Could not get error status code from error: %v", srvErr)1355 }1356 if srvErr.Code() != codes.Aborted {1357 t.Fatalf("Expected Aborted but got: %s", srvErr.Code())1358 }1359 },1360 },1361 {1362 name: "fail with missing iopsPerGB parameter",1363 testFunc: func(t *testing.T) {1364 req := &csi.CreateVolumeRequest{1365 Name: "vol-test",1366 CapacityRange: stdCapRange,1367 VolumeCapabilities: stdVolCap,1368 Parameters: map[string]string{1369 VolumeTypeKey: cloud.VolumeTypeIO1,1370 },1371 }1372 ctx := context.Background()1373 mockCtl := gomock.NewController(t)1374 defer mockCtl.Finish()1375 mockCloud := mocks.NewMockCloud(mockCtl)1376 mockCloud.EXPECT().GetDiskByName(gomock.Eq(ctx), gomock.Eq(req.Name), gomock.Eq(stdVolSize)).Return(nil, cloud.ErrNotFound)1377 awsDriver := controllerService{1378 cloud: mockCloud,1379 inFlight: internal.NewInFlight(),1380 driverOptions: &DriverOptions{},1381 }1382 _, err := awsDriver.CreateVolume(ctx, req)1383 if err == nil {1384 t.Fatalf("Expected CreateVolume to fail but got no error")1385 }1386 srvErr, ok := status.FromError(err)1387 if !ok {1388 t.Fatalf("Could not get error status code from error: %v", srvErr)1389 }1390 if srvErr.Code() != codes.InvalidArgument {1391 t.Fatalf("Expect InvalidArgument but got: %s", srvErr.Code())1392 }1393 },1394 },1395 }1396 for _, tc := range testCases {1397 t.Run(tc.name, tc.testFunc)1398 }1399}1400func TestDeleteVolume(t *testing.T) {1401 testCases := []struct {1402 name string1403 testFunc func(t *testing.T)1404 }{1405 {1406 name: "success normal",1407 testFunc: func(t *testing.T) {1408 req := &csi.DeleteVolumeRequest{1409 VolumeId: "vol-test",1410 }1411 expResp := &csi.DeleteVolumeResponse{}1412 ctx := context.Background()1413 mockCtl := gomock.NewController(t)1414 defer mockCtl.Finish()1415 mockCloud := mocks.NewMockCloud(mockCtl)1416 mockCloud.EXPECT().DeleteDisk(gomock.Eq(ctx), gomock.Eq(req.VolumeId)).Return(true, nil)1417 awsDriver := controllerService{1418 cloud: mockCloud,1419 inFlight: internal.NewInFlight(),1420 driverOptions: &DriverOptions{},1421 }1422 resp, err := awsDriver.DeleteVolume(ctx, req)1423 if err != nil {1424 srvErr, ok := status.FromError(err)1425 if !ok {1426 t.Fatalf("Could not get error status code from error: %v", srvErr)1427 }1428 t.Fatalf("Unexpected error: %v", srvErr.Code())1429 }1430 if !reflect.DeepEqual(resp, expResp) {1431 t.Fatalf("Expected resp to be %+v, got: %+v", expResp, resp)1432 }1433 },1434 },1435 {1436 name: "success invalid volume id",1437 testFunc: func(t *testing.T) {1438 req := &csi.DeleteVolumeRequest{1439 VolumeId: "invalid-volume-name",1440 }1441 expResp := &csi.DeleteVolumeResponse{}1442 ctx := context.Background()1443 mockCtl := gomock.NewController(t)1444 defer mockCtl.Finish()1445 mockCloud := mocks.NewMockCloud(mockCtl)1446 mockCloud.EXPECT().DeleteDisk(gomock.Eq(ctx), gomock.Eq(req.VolumeId)).Return(false, cloud.ErrNotFound)1447 awsDriver := controllerService{1448 cloud: mockCloud,1449 inFlight: internal.NewInFlight(),1450 driverOptions: &DriverOptions{},1451 }1452 resp, err := awsDriver.DeleteVolume(ctx, req)1453 if err != nil {1454 srvErr, ok := status.FromError(err)1455 if !ok {1456 t.Fatalf("Could not get error status code from error: %v", srvErr)1457 }1458 t.Fatalf("Unexpected error: %v", srvErr.Code())1459 }1460 if !reflect.DeepEqual(resp, expResp) {1461 t.Fatalf("Expected resp to be %+v, got: %+v", expResp, resp)1462 }1463 },1464 },1465 {1466 name: "fail delete disk",1467 testFunc: func(t *testing.T) {1468 req := &csi.DeleteVolumeRequest{1469 VolumeId: "test-vol",1470 }1471 ctx := context.Background()1472 mockCtl := gomock.NewController(t)1473 defer mockCtl.Finish()1474 mockCloud := mocks.NewMockCloud(mockCtl)1475 mockCloud.EXPECT().DeleteDisk(gomock.Eq(ctx), gomock.Eq(req.VolumeId)).Return(false, fmt.Errorf("DeleteDisk could not delete volume"))1476 awsDriver := controllerService{1477 cloud: mockCloud,1478 inFlight: internal.NewInFlight(),1479 driverOptions: &DriverOptions{},1480 }1481 resp, err := awsDriver.DeleteVolume(ctx, req)1482 if err != nil {1483 srvErr, ok := status.FromError(err)1484 if !ok {1485 t.Fatalf("Could not get error status code from error: %v", srvErr)1486 }1487 if srvErr.Code() != codes.Internal {1488 t.Fatalf("Unexpected error: %v", srvErr.Code())1489 }1490 } else {1491 t.Fatalf("Expected error, got nil")1492 }1493 if resp != nil {1494 t.Fatalf("Expected resp to be nil, got: %+v", resp)1495 }1496 },1497 },1498 }1499 for _, tc := range testCases {1500 t.Run(tc.name, tc.testFunc)1501 }1502}1503func TestPickAvailabilityZone(t *testing.T) {1504 testCases := []struct {1505 name string1506 requirement *csi.TopologyRequirement1507 expZone string1508 }{1509 {1510 name: "Return WellKnownTopologyKey if present from preferred",1511 requirement: &csi.TopologyRequirement{1512 Requisite: []*csi.Topology{1513 {1514 Segments: map[string]string{TopologyKey: ""},1515 },1516 },1517 Preferred: []*csi.Topology{1518 {1519 Segments: map[string]string{TopologyKey: expZone, WellKnownTopologyKey: "foobar"},1520 },1521 },1522 },1523 expZone: "foobar",1524 },1525 {1526 name: "Return WellKnownTopologyKey if present from requisite",1527 requirement: &csi.TopologyRequirement{1528 Requisite: []*csi.Topology{1529 {1530 Segments: map[string]string{TopologyKey: expZone, WellKnownTopologyKey: "foobar"},1531 },1532 },1533 },1534 expZone: "foobar",1535 },1536 {1537 name: "Pick from preferred",1538 requirement: &csi.TopologyRequirement{1539 Requisite: []*csi.Topology{1540 {1541 Segments: map[string]string{TopologyKey: ""},1542 },1543 },1544 Preferred: []*csi.Topology{1545 {1546 Segments: map[string]string{TopologyKey: expZone},1547 },1548 },1549 },1550 expZone: expZone,1551 },1552 {1553 name: "Pick from requisite",1554 requirement: &csi.TopologyRequirement{1555 Requisite: []*csi.Topology{1556 {1557 Segments: map[string]string{TopologyKey: expZone},1558 },1559 },1560 },1561 expZone: expZone,1562 },1563 {1564 name: "Pick from empty topology",1565 requirement: &csi.TopologyRequirement{1566 Preferred: []*csi.Topology{{}},1567 Requisite: []*csi.Topology{{}},1568 },1569 expZone: "",1570 },1571 {1572 name: "Topology Requirement is nil",1573 requirement: nil,1574 expZone: "",1575 },1576 }1577 for _, tc := range testCases {1578 t.Run(tc.name, func(t *testing.T) {1579 actual := pickAvailabilityZone(tc.requirement)1580 if actual != tc.expZone {1581 t.Fatalf("Expected zone %v, got zone: %v", tc.expZone, actual)1582 }1583 })1584 }1585}1586func TestGetOutpostArn(t *testing.T) {1587 expRawOutpostArn := "arn:aws:outposts:us-west-2:111111111111:outpost/op-0aaa000a0aaaa00a0"1588 outpostArn, _ := arn.Parse(strings.ReplaceAll(expRawOutpostArn, "outpost/", ""))1589 testCases := []struct {1590 name string1591 requirement *csi.TopologyRequirement1592 expZone string1593 expOutpostArn string1594 }{1595 {1596 name: "Get from preferred",1597 requirement: &csi.TopologyRequirement{1598 Requisite: []*csi.Topology{1599 {1600 Segments: map[string]string{TopologyKey: expZone},1601 },1602 },1603 Preferred: []*csi.Topology{1604 {1605 Segments: map[string]string{1606 TopologyKey: expZone,1607 AwsAccountIDKey: outpostArn.AccountID,1608 AwsOutpostIDKey: outpostArn.Resource,1609 AwsRegionKey: outpostArn.Region,1610 AwsPartitionKey: outpostArn.Partition,1611 },1612 },1613 },1614 },1615 expZone: expZone,1616 expOutpostArn: expRawOutpostArn,1617 },1618 {1619 name: "Get from requisite",1620 requirement: &csi.TopologyRequirement{1621 Requisite: []*csi.Topology{1622 {1623 Segments: map[string]string{1624 TopologyKey: expZone,1625 AwsAccountIDKey: outpostArn.AccountID,1626 AwsOutpostIDKey: outpostArn.Resource,1627 AwsRegionKey: outpostArn.Region,1628 AwsPartitionKey: outpostArn.Partition,1629 },1630 },1631 },1632 },1633 expZone: expZone,1634 expOutpostArn: expRawOutpostArn,1635 },1636 {1637 name: "Get from empty topology",1638 requirement: &csi.TopologyRequirement{1639 Preferred: []*csi.Topology{{}},1640 Requisite: []*csi.Topology{{}},1641 },1642 expZone: "",1643 expOutpostArn: "",1644 },1645 {1646 name: "Topology Requirement is nil",1647 requirement: nil,1648 expZone: "",1649 expOutpostArn: "",1650 },1651 }1652 for _, tc := range testCases {1653 t.Run(tc.name, func(t *testing.T) {1654 actual := getOutpostArn(tc.requirement)1655 if actual != tc.expOutpostArn {1656 t.Fatalf("Expected %v, got outpostArn: %v", tc.expOutpostArn, actual)1657 }1658 })1659 }1660}1661func TestBuildOutpostArn(t *testing.T) {1662 expRawOutpostArn := "arn:aws:outposts:us-west-2:111111111111:outpost/op-0aaa000a0aaaa00a0"1663 testCases := []struct {1664 name string1665 awsPartition string1666 awsRegion string1667 awsAccountID string1668 awsOutpostID string1669 expectedArn string1670 }{1671 {1672 name: "all fields are present",1673 awsPartition: "aws",1674 awsRegion: "us-west-2",1675 awsOutpostID: "op-0aaa000a0aaaa00a0",1676 awsAccountID: "111111111111",1677 expectedArn: expRawOutpostArn,1678 },1679 {1680 name: "partition is missing",1681 awsRegion: "us-west-2",1682 awsOutpostID: "op-0aaa000a0aaaa00a0",1683 awsAccountID: "111111111111",1684 expectedArn: "",1685 },1686 {1687 name: "region is missing",1688 awsPartition: "aws",1689 awsOutpostID: "op-0aaa000a0aaaa00a0",1690 awsAccountID: "111111111111",1691 expectedArn: "",1692 },1693 {1694 name: "account id is missing",1695 awsPartition: "aws",1696 awsRegion: "us-west-2",1697 awsOutpostID: "op-0aaa000a0aaaa00a0",1698 expectedArn: "",1699 },1700 {1701 name: "outpost id is missing",1702 awsPartition: "aws",1703 awsRegion: "us-west-2",1704 awsAccountID: "111111111111",1705 expectedArn: "",1706 },1707 }1708 for _, tc := range testCases {1709 t.Run(tc.name, func(t *testing.T) {1710 segment := map[string]string{1711 AwsRegionKey: tc.awsRegion,1712 AwsPartitionKey: tc.awsPartition,1713 AwsAccountIDKey: tc.awsAccountID,1714 AwsOutpostIDKey: tc.awsOutpostID,1715 }1716 actual := BuildOutpostArn(segment)1717 if actual != tc.expectedArn {1718 t.Fatalf("Expected %v, got outpostArn: %v", tc.expectedArn, actual)1719 }1720 })1721 }1722}1723func TestCreateSnapshot(t *testing.T) {1724 testCases := []struct {1725 name string1726 testFunc func(t *testing.T)1727 }{1728 {1729 name: "success normal",1730 testFunc: func(t *testing.T) {1731 req := &csi.CreateSnapshotRequest{1732 Name: "test-snapshot",1733 Parameters: nil,1734 SourceVolumeId: "vol-test",1735 }1736 expSnapshot := &csi.Snapshot{1737 ReadyToUse: true,1738 }1739 ctx := context.Background()1740 mockSnapshot := &cloud.Snapshot{1741 SnapshotID: fmt.Sprintf("snapshot-%d", rand.New(rand.NewSource(time.Now().UnixNano())).Uint64()),1742 SourceVolumeID: req.SourceVolumeId,1743 Size: 1,1744 CreationTime: time.Now(),1745 }1746 mockCtl := gomock.NewController(t)1747 defer mockCtl.Finish()1748 mockCloud := mocks.NewMockCloud(mockCtl)1749 mockCloud.EXPECT().CreateSnapshot(gomock.Eq(ctx), gomock.Eq(req.SourceVolumeId), gomock.Any()).Return(mockSnapshot, nil)1750 mockCloud.EXPECT().GetSnapshotByName(gomock.Eq(ctx), gomock.Eq(req.GetName())).Return(nil, cloud.ErrNotFound)1751 awsDriver := controllerService{1752 cloud: mockCloud,1753 inFlight: internal.NewInFlight(),1754 driverOptions: &DriverOptions{},1755 }1756 resp, err := awsDriver.CreateSnapshot(context.Background(), req)1757 if err != nil {1758 t.Fatalf("Unexpected error: %v", err)1759 }1760 if snap := resp.GetSnapshot(); snap == nil {1761 t.Fatalf("Expected snapshot %v, got nil", expSnapshot)1762 }1763 },1764 },1765 {1766 name: "success with cluster-id",1767 testFunc: func(t *testing.T) {1768 const (1769 snapshotName = "test-snapshot"1770 clusterID = "test-cluster-id"1771 expectedOwnerTag = "kubernetes.io/cluster/test-cluster-id"1772 expectedOwnerTagValue = "owned"1773 expectedNameTag = "Name"1774 expectedNameTagValue = "test-cluster-id-dynamic-test-snapshot"1775 )1776 req := &csi.CreateSnapshotRequest{1777 Name: snapshotName,1778 Parameters: nil,1779 SourceVolumeId: "vol-test",1780 }1781 expSnapshot := &csi.Snapshot{1782 ReadyToUse: true,1783 }1784 ctx := context.Background()1785 mockSnapshot := &cloud.Snapshot{1786 SnapshotID: fmt.Sprintf("snapshot-%d", rand.New(rand.NewSource(time.Now().UnixNano())).Uint64()),1787 SourceVolumeID: req.SourceVolumeId,1788 Size: 1,1789 CreationTime: time.Now(),1790 }1791 snapshotOptions := &cloud.SnapshotOptions{1792 Tags: map[string]string{1793 cloud.SnapshotNameTagKey: snapshotName,1794 expectedOwnerTag: expectedOwnerTagValue,1795 expectedNameTag: expectedNameTagValue,1796 },1797 }1798 mockCtl := gomock.NewController(t)1799 defer mockCtl.Finish()1800 mockCloud := mocks.NewMockCloud(mockCtl)1801 mockCloud.EXPECT().CreateSnapshot(gomock.Eq(ctx), gomock.Eq(req.SourceVolumeId), gomock.Eq(snapshotOptions)).Return(mockSnapshot, nil)1802 mockCloud.EXPECT().GetSnapshotByName(gomock.Eq(ctx), gomock.Eq(req.GetName())).Return(nil, cloud.ErrNotFound)1803 awsDriver := controllerService{1804 cloud: mockCloud,1805 inFlight: internal.NewInFlight(),1806 driverOptions: &DriverOptions{1807 kubernetesClusterID: clusterID,1808 },1809 }1810 resp, err := awsDriver.CreateSnapshot(context.Background(), req)1811 if err != nil {1812 t.Fatalf("Unexpected error: %v", err)1813 }1814 if snap := resp.GetSnapshot(); snap == nil {1815 t.Fatalf("Expected snapshot %v, got nil", expSnapshot)1816 }1817 },1818 },1819 {1820 name: "success with extra tags",1821 testFunc: func(t *testing.T) {1822 const (1823 snapshotName = "test-snapshot"1824 extraVolumeTagKey = "extra-tag-key"1825 extraVolumeTagValue = "extra-tag-value"1826 )1827 req := &csi.CreateSnapshotRequest{1828 Name: snapshotName,1829 Parameters: nil,1830 SourceVolumeId: "vol-test",1831 }1832 expSnapshot := &csi.Snapshot{1833 ReadyToUse: true,1834 }1835 ctx := context.Background()1836 mockSnapshot := &cloud.Snapshot{1837 SnapshotID: fmt.Sprintf("snapshot-%d", rand.New(rand.NewSource(time.Now().UnixNano())).Uint64()),1838 SourceVolumeID: req.SourceVolumeId,1839 Size: 1,1840 CreationTime: time.Now(),1841 }1842 snapshotOptions := &cloud.SnapshotOptions{1843 Tags: map[string]string{1844 cloud.SnapshotNameTagKey: snapshotName,1845 extraVolumeTagKey: extraVolumeTagValue,1846 },1847 }1848 mockCtl := gomock.NewController(t)1849 defer mockCtl.Finish()1850 mockCloud := mocks.NewMockCloud(mockCtl)1851 mockCloud.EXPECT().CreateSnapshot(gomock.Eq(ctx), gomock.Eq(req.SourceVolumeId), gomock.Eq(snapshotOptions)).Return(mockSnapshot, nil)1852 mockCloud.EXPECT().GetSnapshotByName(gomock.Eq(ctx), gomock.Eq(req.GetName())).Return(nil, cloud.ErrNotFound)1853 awsDriver := controllerService{1854 cloud: mockCloud,1855 inFlight: internal.NewInFlight(),1856 driverOptions: &DriverOptions{1857 extraTags: map[string]string{1858 extraVolumeTagKey: extraVolumeTagValue,1859 },1860 },1861 }1862 resp, err := awsDriver.CreateSnapshot(context.Background(), req)1863 if err != nil {1864 t.Fatalf("Unexpected error: %v", err)1865 }1866 if snap := resp.GetSnapshot(); snap == nil {1867 t.Fatalf("Expected snapshot %v, got nil", expSnapshot)1868 }1869 },1870 },1871 {1872 name: "fail no name",1873 testFunc: func(t *testing.T) {1874 req := &csi.CreateSnapshotRequest{1875 Parameters: nil,1876 SourceVolumeId: "vol-test",1877 }1878 mockCtl := gomock.NewController(t)1879 defer mockCtl.Finish()1880 mockCloud := mocks.NewMockCloud(mockCtl)1881 awsDriver := controllerService{1882 cloud: mockCloud,1883 inFlight: internal.NewInFlight(),1884 driverOptions: &DriverOptions{},1885 }1886 if _, err := awsDriver.CreateSnapshot(context.Background(), req); err != nil {1887 srvErr, ok := status.FromError(err)1888 if !ok {1889 t.Fatalf("Could not get error status code from error: %v", srvErr)1890 }1891 if srvErr.Code() != codes.InvalidArgument {1892 t.Fatalf("Expected error code %d, got %d message %s", codes.InvalidArgument, srvErr.Code(), srvErr.Message())1893 }1894 } else {1895 t.Fatalf("Expected error %v, got no error", codes.InvalidArgument)1896 }1897 },1898 },1899 {1900 name: "fail same name different volume ID",1901 testFunc: func(t *testing.T) {1902 req := &csi.CreateSnapshotRequest{1903 Name: "test-snapshot",1904 Parameters: nil,1905 SourceVolumeId: "vol-test",1906 }1907 extraReq := &csi.CreateSnapshotRequest{1908 Name: "test-snapshot",1909 Parameters: nil,1910 SourceVolumeId: "vol-xxx",1911 }1912 expSnapshot := &csi.Snapshot{1913 ReadyToUse: true,1914 }1915 ctx := context.Background()1916 mockSnapshot := &cloud.Snapshot{1917 SnapshotID: fmt.Sprintf("snapshot-%d", rand.New(rand.NewSource(time.Now().UnixNano())).Uint64()),1918 SourceVolumeID: req.SourceVolumeId,1919 Size: 1,1920 CreationTime: time.Now(),1921 }1922 mockCtl := gomock.NewController(t)1923 defer mockCtl.Finish()1924 mockCloud := mocks.NewMockCloud(mockCtl)1925 mockCloud.EXPECT().GetSnapshotByName(gomock.Eq(ctx), gomock.Eq(req.GetName())).Return(nil, cloud.ErrNotFound)1926 mockCloud.EXPECT().CreateSnapshot(gomock.Eq(ctx), gomock.Eq(req.SourceVolumeId), gomock.Any()).Return(mockSnapshot, nil)1927 awsDriver := controllerService{1928 cloud: mockCloud,1929 inFlight: internal.NewInFlight(),1930 driverOptions: &DriverOptions{},1931 }1932 resp, err := awsDriver.CreateSnapshot(context.Background(), req)1933 if err != nil {1934 srvErr, ok := status.FromError(err)1935 if !ok {1936 t.Fatalf("Could not get error status code from error: %v", srvErr)1937 }1938 if srvErr.Code() != codes.OK {1939 t.Fatalf("Expected error code %d, got %d message %s", codes.OK, srvErr.Code(), srvErr.Message())1940 }1941 t.Fatalf("Unexpected error: %v", err)1942 }1943 snap := resp.GetSnapshot()1944 if snap == nil {1945 t.Fatalf("Expected snapshot %v, got nil", expSnapshot)1946 }1947 mockCloud.EXPECT().GetSnapshotByName(gomock.Eq(ctx), gomock.Eq(extraReq.GetName())).Return(mockSnapshot, nil)1948 _, err = awsDriver.CreateSnapshot(ctx, extraReq)1949 if err != nil {1950 srvErr, ok := status.FromError(err)1951 if !ok {1952 t.Fatalf("Could not get error status code from error: %v", srvErr)1953 }1954 if srvErr.Code() != codes.AlreadyExists {1955 t.Fatalf("Expected error code %d, got %d message %s", codes.AlreadyExists, srvErr.Code(), srvErr.Message())1956 }1957 } else {1958 t.Fatalf("Expected error %v, got no error", codes.AlreadyExists)1959 }1960 },1961 },1962 {1963 name: "success same name same volume ID",1964 testFunc: func(t *testing.T) {1965 req := &csi.CreateSnapshotRequest{1966 Name: "test-snapshot",1967 Parameters: nil,1968 SourceVolumeId: "vol-test",1969 }1970 extraReq := &csi.CreateSnapshotRequest{1971 Name: "test-snapshot",1972 Parameters: nil,1973 SourceVolumeId: "vol-test",1974 }1975 expSnapshot := &csi.Snapshot{1976 ReadyToUse: true,1977 }1978 ctx := context.Background()1979 mockSnapshot := &cloud.Snapshot{1980 SnapshotID: fmt.Sprintf("snapshot-%d", rand.New(rand.NewSource(time.Now().UnixNano())).Uint64()),1981 SourceVolumeID: req.SourceVolumeId,1982 Size: 1,1983 CreationTime: time.Now(),1984 }1985 mockCtl := gomock.NewController(t)1986 defer mockCtl.Finish()1987 mockCloud := mocks.NewMockCloud(mockCtl)1988 mockCloud.EXPECT().GetSnapshotByName(gomock.Eq(ctx), gomock.Eq(req.GetName())).Return(nil, cloud.ErrNotFound)1989 mockCloud.EXPECT().CreateSnapshot(gomock.Eq(ctx), gomock.Eq(req.SourceVolumeId), gomock.Any()).Return(mockSnapshot, nil)1990 awsDriver := controllerService{1991 cloud: mockCloud,1992 inFlight: internal.NewInFlight(),1993 driverOptions: &DriverOptions{},1994 }1995 resp, err := awsDriver.CreateSnapshot(context.Background(), req)1996 if err != nil {1997 t.Fatalf("Unexpected error: %v", err)1998 }1999 snap := resp.GetSnapshot()2000 if snap == nil {2001 t.Fatalf("Expected snapshot %v, got nil", expSnapshot)2002 }2003 mockCloud.EXPECT().GetSnapshotByName(gomock.Eq(ctx), gomock.Eq(extraReq.GetName())).Return(mockSnapshot, nil)2004 _, err = awsDriver.CreateSnapshot(ctx, extraReq)2005 if err != nil {2006 t.Fatalf("Unexpected error: %v", err)2007 }2008 },2009 },2010 }2011 for _, tc := range testCases {2012 t.Run(tc.name, tc.testFunc)2013 }2014}2015func TestDeleteSnapshot(t *testing.T) {2016 testCases := []struct {2017 name string2018 testFunc func(t *testing.T)2019 }{2020 {2021 name: "success normal",2022 testFunc: func(t *testing.T) {2023 ctx := context.Background()2024 mockCtl := gomock.NewController(t)2025 defer mockCtl.Finish()2026 mockCloud := mocks.NewMockCloud(mockCtl)2027 awsDriver := controllerService{2028 cloud: mockCloud,2029 inFlight: internal.NewInFlight(),2030 driverOptions: &DriverOptions{},2031 }2032 req := &csi.DeleteSnapshotRequest{2033 SnapshotId: "xxx",2034 }2035 mockCloud.EXPECT().DeleteSnapshot(gomock.Eq(ctx), gomock.Eq("xxx")).Return(true, nil)2036 if _, err := awsDriver.DeleteSnapshot(ctx, req); err != nil {2037 t.Fatalf("Unexpected error: %v", err)2038 }2039 },2040 },2041 {2042 name: "success not found",2043 testFunc: func(t *testing.T) {2044 ctx := context.Background()2045 mockCtl := gomock.NewController(t)2046 defer mockCtl.Finish()2047 mockCloud := mocks.NewMockCloud(mockCtl)2048 awsDriver := controllerService{2049 cloud: mockCloud,2050 inFlight: internal.NewInFlight(),2051 driverOptions: &DriverOptions{},2052 }2053 req := &csi.DeleteSnapshotRequest{2054 SnapshotId: "xxx",2055 }2056 mockCloud.EXPECT().DeleteSnapshot(gomock.Eq(ctx), gomock.Eq("xxx")).Return(false, cloud.ErrNotFound)2057 if _, err := awsDriver.DeleteSnapshot(ctx, req); err != nil {2058 t.Fatalf("Unexpected error: %v", err)2059 }2060 },2061 },2062 }2063 for _, tc := range testCases {2064 t.Run(tc.name, tc.testFunc)2065 }2066}2067func TestListSnapshots(t *testing.T) {2068 testCases := []struct {2069 name string2070 testFunc func(t *testing.T)2071 }{2072 {2073 name: "success normal",2074 testFunc: func(t *testing.T) {2075 req := &csi.ListSnapshotsRequest{}2076 mockCloudSnapshotsResponse := &cloud.ListSnapshotsResponse{2077 Snapshots: []*cloud.Snapshot{2078 {2079 SnapshotID: "snapshot-1",2080 SourceVolumeID: "test-vol",2081 Size: 1,2082 CreationTime: time.Now(),2083 },2084 {2085 SnapshotID: "snapshot-2",2086 SourceVolumeID: "test-vol",2087 Size: 1,2088 CreationTime: time.Now(),2089 },2090 },2091 NextToken: "",2092 }2093 ctx := context.Background()2094 mockCtl := gomock.NewController(t)2095 defer mockCtl.Finish()2096 mockCloud := mocks.NewMockCloud(mockCtl)2097 mockCloud.EXPECT().ListSnapshots(gomock.Eq(ctx), gomock.Eq(""), gomock.Eq(int64(0)), gomock.Eq("")).Return(mockCloudSnapshotsResponse, nil)2098 awsDriver := controllerService{2099 cloud: mockCloud,2100 inFlight: internal.NewInFlight(),2101 driverOptions: &DriverOptions{},2102 }2103 resp, err := awsDriver.ListSnapshots(context.Background(), req)2104 if err != nil {2105 t.Fatalf("Unexpected error: %v", err)2106 }2107 if len(resp.GetEntries()) != len(mockCloudSnapshotsResponse.Snapshots) {2108 t.Fatalf("Expected %d entries, got %d", len(mockCloudSnapshotsResponse.Snapshots), len(resp.GetEntries()))2109 }2110 },2111 },2112 {2113 name: "success no snapshots",2114 testFunc: func(t *testing.T) {2115 req := &csi.ListSnapshotsRequest{}2116 ctx := context.Background()2117 mockCtl := gomock.NewController(t)2118 defer mockCtl.Finish()2119 mockCloud := mocks.NewMockCloud(mockCtl)2120 mockCloud.EXPECT().ListSnapshots(gomock.Eq(ctx), gomock.Eq(""), gomock.Eq(int64(0)), gomock.Eq("")).Return(nil, cloud.ErrNotFound)2121 awsDriver := controllerService{2122 cloud: mockCloud,2123 inFlight: internal.NewInFlight(),2124 driverOptions: &DriverOptions{},2125 }2126 resp, err := awsDriver.ListSnapshots(context.Background(), req)2127 if err != nil {2128 t.Fatalf("Unexpected error: %v", err)2129 }2130 if !reflect.DeepEqual(resp, &csi.ListSnapshotsResponse{}) {2131 t.Fatalf("Expected empty response, got %+v", resp)2132 }2133 },2134 },2135 {2136 name: "success snapshot ID",2137 testFunc: func(t *testing.T) {2138 req := &csi.ListSnapshotsRequest{2139 SnapshotId: "snapshot-1",2140 }2141 mockCloudSnapshotsResponse := &cloud.Snapshot{2142 SnapshotID: "snapshot-1",2143 SourceVolumeID: "test-vol",2144 Size: 1,2145 CreationTime: time.Now(),2146 }2147 ctx := context.Background()2148 mockCtl := gomock.NewController(t)2149 defer mockCtl.Finish()2150 mockCloud := mocks.NewMockCloud(mockCtl)2151 mockCloud.EXPECT().GetSnapshotByID(gomock.Eq(ctx), gomock.Eq("snapshot-1")).Return(mockCloudSnapshotsResponse, nil)2152 awsDriver := controllerService{2153 cloud: mockCloud,2154 inFlight: internal.NewInFlight(),2155 driverOptions: &DriverOptions{},2156 }2157 resp, err := awsDriver.ListSnapshots(context.Background(), req)2158 if err != nil {2159 t.Fatalf("Unexpected error: %v", err)2160 }2161 if len(resp.GetEntries()) != 1 {2162 t.Fatalf("Expected %d entry, got %d", 1, len(resp.GetEntries()))2163 }2164 },2165 },2166 {2167 name: "success snapshot ID not found",2168 testFunc: func(t *testing.T) {2169 req := &csi.ListSnapshotsRequest{2170 SnapshotId: "snapshot-1",2171 }2172 ctx := context.Background()2173 mockCtl := gomock.NewController(t)2174 defer mockCtl.Finish()2175 mockCloud := mocks.NewMockCloud(mockCtl)2176 mockCloud.EXPECT().GetSnapshotByID(gomock.Eq(ctx), gomock.Eq("snapshot-1")).Return(nil, cloud.ErrNotFound)2177 awsDriver := controllerService{2178 cloud: mockCloud,2179 inFlight: internal.NewInFlight(),2180 driverOptions: &DriverOptions{},2181 }2182 resp, err := awsDriver.ListSnapshots(context.Background(), req)2183 if err != nil {2184 t.Fatalf("Unexpected error: %v", err)2185 }2186 if !reflect.DeepEqual(resp, &csi.ListSnapshotsResponse{}) {2187 t.Fatalf("Expected empty response, got %+v", resp)2188 }2189 },2190 },2191 {2192 name: "fail snapshot ID multiple found",2193 testFunc: func(t *testing.T) {2194 req := &csi.ListSnapshotsRequest{2195 SnapshotId: "snapshot-1",2196 }2197 ctx := context.Background()2198 mockCtl := gomock.NewController(t)2199 defer mockCtl.Finish()2200 mockCloud := mocks.NewMockCloud(mockCtl)2201 mockCloud.EXPECT().GetSnapshotByID(gomock.Eq(ctx), gomock.Eq("snapshot-1")).Return(nil, cloud.ErrMultiSnapshots)2202 awsDriver := controllerService{2203 cloud: mockCloud,2204 inFlight: internal.NewInFlight(),2205 driverOptions: &DriverOptions{},2206 }2207 if _, err := awsDriver.ListSnapshots(context.Background(), req); err != nil {2208 srvErr, ok := status.FromError(err)2209 if !ok {2210 t.Fatalf("Could not get error status code from error: %v", srvErr)2211 }2212 if srvErr.Code() != codes.Internal {2213 t.Fatalf("Expected error code %d, got %d message %s", codes.Internal, srvErr.Code(), srvErr.Message())2214 }2215 } else {2216 t.Fatalf("Expected error code %d, got no error", codes.Internal)2217 }2218 },2219 },2220 {2221 name: "fail 0 < MaxEntries < 5",2222 testFunc: func(t *testing.T) {2223 req := &csi.ListSnapshotsRequest{2224 MaxEntries: 4,2225 }2226 ctx := context.Background()2227 mockCtl := gomock.NewController(t)2228 defer mockCtl.Finish()2229 mockCloud := mocks.NewMockCloud(mockCtl)2230 mockCloud.EXPECT().ListSnapshots(gomock.Eq(ctx), gomock.Eq(""), gomock.Eq(int64(4)), gomock.Eq("")).Return(nil, cloud.ErrInvalidMaxResults)2231 awsDriver := controllerService{2232 cloud: mockCloud,2233 inFlight: internal.NewInFlight(),2234 driverOptions: &DriverOptions{},2235 }2236 if _, err := awsDriver.ListSnapshots(context.Background(), req); err != nil {2237 srvErr, ok := status.FromError(err)2238 if !ok {2239 t.Fatalf("Could not get error status code from error: %v", srvErr)2240 }2241 if srvErr.Code() != codes.InvalidArgument {2242 t.Fatalf("Expected error code %d, got %d message %s", codes.InvalidArgument, srvErr.Code(), srvErr.Message())2243 }2244 } else {2245 t.Fatalf("Expected error code %d, got no error", codes.InvalidArgument)2246 }2247 },2248 },2249 }2250 for _, tc := range testCases {2251 t.Run(tc.name, tc.testFunc)2252 }2253}2254func TestControllerPublishVolume(t *testing.T) {2255 stdVolCap := &csi.VolumeCapability{2256 AccessType: &csi.VolumeCapability_Mount{2257 Mount: &csi.VolumeCapability_MountVolume{},2258 },2259 AccessMode: &csi.VolumeCapability_AccessMode{2260 Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,2261 },2262 }2263 expDevicePath := "/dev/xvda"2264 testCases := []struct {2265 name string2266 testFunc func(t *testing.T)2267 }{2268 {2269 name: "success normal",2270 testFunc: func(t *testing.T) {2271 req := &csi.ControllerPublishVolumeRequest{2272 NodeId: expInstanceID,2273 VolumeCapability: stdVolCap,2274 VolumeId: "vol-test",2275 }2276 expResp := &csi.ControllerPublishVolumeResponse{2277 PublishContext: map[string]string{DevicePathKey: expDevicePath},2278 }2279 ctx := context.Background()2280 mockCtl := gomock.NewController(t)2281 defer mockCtl.Finish()2282 mockCloud := mocks.NewMockCloud(mockCtl)2283 mockCloud.EXPECT().IsExistInstance(gomock.Eq(ctx), gomock.Eq(req.NodeId)).Return(true)2284 mockCloud.EXPECT().GetDiskByID(gomock.Eq(ctx), gomock.Any()).Return(&cloud.Disk{}, nil)2285 mockCloud.EXPECT().AttachDisk(gomock.Eq(ctx), gomock.Any(), gomock.Eq(req.NodeId)).Return(expDevicePath, nil)2286 awsDriver := controllerService{2287 cloud: mockCloud,2288 inFlight: internal.NewInFlight(),2289 driverOptions: &DriverOptions{},2290 }2291 resp, err := awsDriver.ControllerPublishVolume(ctx, req)2292 if err != nil {2293 t.Fatalf("Unexpected error: %v", err)2294 }2295 if !reflect.DeepEqual(resp, expResp) {2296 t.Fatalf("Expected resp to be %+v, got: %+v", expResp, resp)2297 }2298 },2299 },2300 {2301 name: "success when resource is not found",2302 testFunc: func(t *testing.T) {2303 req := &csi.ControllerUnpublishVolumeRequest{2304 NodeId: expInstanceID,2305 VolumeId: "vol-test",2306 }2307 expResp := &csi.ControllerUnpublishVolumeResponse{}2308 ctx := context.Background()2309 mockCtl := gomock.NewController(t)2310 defer mockCtl.Finish()2311 mockCloud := mocks.NewMockCloud(mockCtl)2312 mockCloud.EXPECT().DetachDisk(gomock.Eq(ctx), req.VolumeId, req.NodeId).Return(cloud.ErrNotFound)2313 awsDriver := controllerService{2314 cloud: mockCloud,2315 inFlight: internal.NewInFlight(),2316 driverOptions: &DriverOptions{},2317 }2318 resp, err := awsDriver.ControllerUnpublishVolume(ctx, req)2319 if err != nil {2320 t.Fatalf("Unexpected error: %v", err)2321 }2322 if !reflect.DeepEqual(resp, expResp) {2323 t.Fatalf("Expected resp to be %+v, got: %+v", expResp, resp)2324 }2325 },2326 },2327 {2328 name: "fail no VolumeId",2329 testFunc: func(t *testing.T) {2330 req := &csi.ControllerPublishVolumeRequest{}2331 ctx := context.Background()2332 mockCtl := gomock.NewController(t)2333 defer mockCtl.Finish()2334 mockCloud := mocks.NewMockCloud(mockCtl)2335 awsDriver := controllerService{2336 cloud: mockCloud,2337 inFlight: internal.NewInFlight(),2338 driverOptions: &DriverOptions{},2339 }2340 if _, err := awsDriver.ControllerPublishVolume(ctx, req); err != nil {2341 srvErr, ok := status.FromError(err)2342 if !ok {2343 t.Fatalf("Could not get error status code from error: %v", srvErr)2344 }2345 if srvErr.Code() != codes.InvalidArgument {2346 t.Fatalf("Expected error code %d, got %d message %s", codes.InvalidArgument, srvErr.Code(), srvErr.Message())2347 }2348 } else {2349 t.Fatalf("Expected error %v, got no error", codes.InvalidArgument)2350 }2351 },2352 },2353 {2354 name: "fail no NodeId",2355 testFunc: func(t *testing.T) {2356 req := &csi.ControllerPublishVolumeRequest{2357 VolumeId: "vol-test",2358 }2359 ctx := context.Background()2360 mockCtl := gomock.NewController(t)2361 defer mockCtl.Finish()2362 mockCloud := mocks.NewMockCloud(mockCtl)2363 awsDriver := controllerService{2364 cloud: mockCloud,2365 inFlight: internal.NewInFlight(),2366 driverOptions: &DriverOptions{},2367 }2368 if _, err := awsDriver.ControllerPublishVolume(ctx, req); err != nil {2369 srvErr, ok := status.FromError(err)2370 if !ok {2371 t.Fatalf("Could not get error status code from error: %v", srvErr)2372 }2373 if srvErr.Code() != codes.InvalidArgument {2374 t.Fatalf("Expected error code %d, got %d message %s", codes.InvalidArgument, srvErr.Code(), srvErr.Message())2375 }2376 } else {2377 t.Fatalf("Expected error %v, got no error", codes.InvalidArgument)2378 }2379 },2380 },2381 {2382 name: "fail no VolumeCapability",2383 testFunc: func(t *testing.T) {2384 req := &csi.ControllerPublishVolumeRequest{2385 NodeId: expInstanceID,2386 VolumeId: "vol-test",2387 }2388 ctx := context.Background()2389 mockCtl := gomock.NewController(t)2390 defer mockCtl.Finish()2391 mockCloud := mocks.NewMockCloud(mockCtl)2392 awsDriver := controllerService{2393 cloud: mockCloud,2394 inFlight: internal.NewInFlight(),2395 driverOptions: &DriverOptions{},2396 }2397 if _, err := awsDriver.ControllerPublishVolume(ctx, req); err != nil {2398 srvErr, ok := status.FromError(err)2399 if !ok {2400 t.Fatalf("Could not get error status code from error: %v", srvErr)2401 }2402 if srvErr.Code() != codes.InvalidArgument {2403 t.Fatalf("Expected error code %d, got %d message %s", codes.InvalidArgument, srvErr.Code(), srvErr.Message())2404 }2405 } else {2406 t.Fatalf("Expected error %v, got no error", codes.InvalidArgument)2407 }2408 },2409 },2410 {2411 name: "fail invalid VolumeCapability",2412 testFunc: func(t *testing.T) {2413 req := &csi.ControllerPublishVolumeRequest{2414 NodeId: expInstanceID,2415 VolumeCapability: &csi.VolumeCapability{2416 AccessMode: &csi.VolumeCapability_AccessMode{2417 Mode: csi.VolumeCapability_AccessMode_UNKNOWN,2418 },2419 },2420 VolumeId: "vol-test",2421 }2422 ctx := context.Background()2423 mockCtl := gomock.NewController(t)2424 defer mockCtl.Finish()2425 mockCloud := mocks.NewMockCloud(mockCtl)2426 awsDriver := controllerService{2427 cloud: mockCloud,2428 inFlight: internal.NewInFlight(),2429 driverOptions: &DriverOptions{},2430 }2431 if _, err := awsDriver.ControllerPublishVolume(ctx, req); err != nil {2432 srvErr, ok := status.FromError(err)2433 if !ok {2434 t.Fatalf("Could not get error status code from error: %v", srvErr)2435 }2436 if srvErr.Code() != codes.InvalidArgument {2437 t.Fatalf("Expected error code %d, got %d message %s", codes.InvalidArgument, srvErr.Code(), srvErr.Message())2438 }2439 } else {2440 t.Fatalf("Expected error %v, got no error", codes.InvalidArgument)2441 }2442 },2443 },2444 {2445 name: "fail instance not found",2446 testFunc: func(t *testing.T) {2447 req := &csi.ControllerPublishVolumeRequest{2448 NodeId: "does-not-exist",2449 VolumeId: "vol-test",2450 VolumeCapability: stdVolCap,2451 }2452 ctx := context.Background()2453 mockCtl := gomock.NewController(t)2454 defer mockCtl.Finish()2455 mockCloud := mocks.NewMockCloud(mockCtl)2456 mockCloud.EXPECT().IsExistInstance(gomock.Eq(ctx), gomock.Eq(req.NodeId)).Return(false)2457 awsDriver := controllerService{2458 cloud: mockCloud,2459 inFlight: internal.NewInFlight(),2460 driverOptions: &DriverOptions{},2461 }2462 if _, err := awsDriver.ControllerPublishVolume(ctx, req); err != nil {2463 srvErr, ok := status.FromError(err)2464 if !ok {2465 t.Fatalf("Could not get error status code from error: %v", srvErr)2466 }2467 if srvErr.Code() != codes.NotFound {2468 t.Fatalf("Expected error code %d, got %d message %s", codes.NotFound, srvErr.Code(), srvErr.Message())2469 }2470 } else {2471 t.Fatalf("Expected error %v, got no error", codes.NotFound)2472 }2473 },2474 },2475 {2476 name: "fail volume not found",2477 testFunc: func(t *testing.T) {2478 req := &csi.ControllerPublishVolumeRequest{2479 VolumeId: "does-not-exist",2480 NodeId: expInstanceID,2481 VolumeCapability: stdVolCap,2482 }2483 ctx := context.Background()2484 mockCtl := gomock.NewController(t)2485 defer mockCtl.Finish()2486 mockCloud := mocks.NewMockCloud(mockCtl)2487 mockCloud.EXPECT().IsExistInstance(gomock.Eq(ctx), gomock.Eq(req.NodeId)).Return(true)2488 mockCloud.EXPECT().GetDiskByID(gomock.Eq(ctx), gomock.Any()).Return(nil, cloud.ErrNotFound)2489 awsDriver := controllerService{2490 cloud: mockCloud,2491 inFlight: internal.NewInFlight(),2492 driverOptions: &DriverOptions{},2493 }2494 if _, err := awsDriver.ControllerPublishVolume(ctx, req); err != nil {2495 srvErr, ok := status.FromError(err)2496 if !ok {2497 t.Fatalf("Could not get error status code from error: %v", srvErr)2498 }2499 if srvErr.Code() != codes.NotFound {2500 t.Fatalf("Expected error code %d, got %d message %s", codes.NotFound, srvErr.Code(), srvErr.Message())2501 }2502 } else {2503 t.Fatalf("Expected error %v, got no error", codes.NotFound)2504 }2505 },2506 },2507 {2508 name: "fail attach disk with volume already in use error",2509 testFunc: func(t *testing.T) {2510 attachedInstancId := "test-instance-id-attached"2511 disk := &cloud.Disk{2512 Attachments: []string{attachedInstancId},2513 }2514 req := &csi.ControllerPublishVolumeRequest{2515 VolumeId: "does-not-exist",2516 NodeId: expInstanceID,2517 VolumeCapability: stdVolCap,2518 }2519 ctx := context.Background()2520 mockCtl := gomock.NewController(t)2521 defer mockCtl.Finish()2522 mockCloud := mocks.NewMockCloud(mockCtl)2523 mockCloud.EXPECT().IsExistInstance(gomock.Eq(ctx), gomock.Eq(req.NodeId)).Return(true)2524 mockCloud.EXPECT().GetDiskByID(gomock.Eq(ctx), gomock.Any()).Return(disk, nil)2525 mockCloud.EXPECT().AttachDisk(gomock.Eq(ctx), gomock.Any(), gomock.Eq(req.NodeId)).Return("", cloud.ErrVolumeInUse)2526 awsDriver := controllerService{2527 cloud: mockCloud,2528 inFlight: internal.NewInFlight(),2529 driverOptions: &DriverOptions{},2530 }2531 if _, err := awsDriver.ControllerPublishVolume(ctx, req); err != nil {2532 srvErr, ok := status.FromError(err)2533 if !ok {2534 t.Fatalf("Could not get error status code from error: %v", srvErr)2535 }2536 if srvErr.Code() != codes.FailedPrecondition {2537 t.Fatalf("Expected error code %d, got %d message %s", codes.FailedPrecondition, srvErr.Code(), srvErr.Message())2538 }2539 if srvErr.Message() != attachedInstancId {2540 t.Fatalf("Expected error message to contain previous attached instanceId %s, but get error message %s", attachedInstancId, srvErr.Message())2541 }2542 } else {2543 t.Fatalf("Expected error %v, got no error", codes.AlreadyExists)2544 }2545 },2546 },2547 }2548 for _, tc := range testCases {2549 t.Run(tc.name, tc.testFunc)2550 }2551}2552func TestControllerUnpublishVolume(t *testing.T) {2553 testCases := []struct {2554 name string2555 testFunc func(t *testing.T)2556 }{2557 {2558 name: "success normal",2559 testFunc: func(t *testing.T) {2560 req := &csi.ControllerUnpublishVolumeRequest{2561 NodeId: expInstanceID,2562 VolumeId: "vol-test",2563 }2564 expResp := &csi.ControllerUnpublishVolumeResponse{}2565 ctx := context.Background()2566 mockCtl := gomock.NewController(t)2567 defer mockCtl.Finish()2568 mockCloud := mocks.NewMockCloud(mockCtl)2569 mockCloud.EXPECT().DetachDisk(gomock.Eq(ctx), req.VolumeId, req.NodeId).Return(nil)2570 awsDriver := controllerService{2571 cloud: mockCloud,2572 inFlight: internal.NewInFlight(),2573 driverOptions: &DriverOptions{},2574 }2575 resp, err := awsDriver.ControllerUnpublishVolume(ctx, req)2576 if err != nil {2577 t.Fatalf("Unexpected error: %v", err)2578 }2579 if !reflect.DeepEqual(resp, expResp) {2580 t.Fatalf("Expected resp to be %+v, got: %+v", expResp, resp)2581 }2582 },2583 },2584 {2585 name: "fail no VolumeId",2586 testFunc: func(t *testing.T) {2587 req := &csi.ControllerUnpublishVolumeRequest{}2588 ctx := context.Background()2589 mockCtl := gomock.NewController(t)2590 defer mockCtl.Finish()2591 mockCloud := mocks.NewMockCloud(mockCtl)2592 awsDriver := controllerService{2593 cloud: mockCloud,2594 inFlight: internal.NewInFlight(),2595 driverOptions: &DriverOptions{},2596 }2597 if _, err := awsDriver.ControllerUnpublishVolume(ctx, req); err != nil {2598 srvErr, ok := status.FromError(err)2599 if !ok {2600 t.Fatalf("Could not get error status code from error: %v", srvErr)2601 }2602 if srvErr.Code() != codes.InvalidArgument {2603 t.Fatalf("Expected error code %d, got %d message %s", codes.InvalidArgument, srvErr.Code(), srvErr.Message())2604 }2605 } else {2606 t.Fatalf("Expected error %v, got no error", codes.InvalidArgument)2607 }2608 },2609 },2610 {2611 name: "fail no NodeId",2612 testFunc: func(t *testing.T) {2613 req := &csi.ControllerUnpublishVolumeRequest{2614 VolumeId: "vol-test",2615 }2616 ctx := context.Background()2617 mockCtl := gomock.NewController(t)2618 defer mockCtl.Finish()2619 mockCloud := mocks.NewMockCloud(mockCtl)2620 awsDriver := controllerService{2621 cloud: mockCloud,2622 inFlight: internal.NewInFlight(),2623 driverOptions: &DriverOptions{},2624 }2625 if _, err := awsDriver.ControllerUnpublishVolume(ctx, req); err != nil {2626 srvErr, ok := status.FromError(err)2627 if !ok {2628 t.Fatalf("Could not get error status code from error: %v", srvErr)2629 }2630 if srvErr.Code() != codes.InvalidArgument {2631 t.Fatalf("Expected error code %d, got %d message %s", codes.InvalidArgument, srvErr.Code(), srvErr.Message())2632 }2633 } else {2634 t.Fatalf("Expected error %v, got no error", codes.InvalidArgument)2635 }2636 },2637 },2638 }2639 for _, tc := range testCases {2640 t.Run(tc.name, tc.testFunc)2641 }2642}2643func TestControllerExpandVolume(t *testing.T) {2644 testCases := []struct {2645 name string2646 req *csi.ControllerExpandVolumeRequest2647 newSize int642648 expResp *csi.ControllerExpandVolumeResponse2649 expError bool2650 }{2651 {2652 name: "success normal",2653 req: &csi.ControllerExpandVolumeRequest{2654 VolumeId: "vol-test",2655 CapacityRange: &csi.CapacityRange{2656 RequiredBytes: 5 * util.GiB,2657 },2658 },2659 expResp: &csi.ControllerExpandVolumeResponse{2660 CapacityBytes: 5 * util.GiB,2661 },2662 },2663 {2664 name: "fail empty request",2665 req: &csi.ControllerExpandVolumeRequest{},2666 expError: true,2667 },2668 {2669 name: "fail exceeds limit after round up",2670 req: &csi.ControllerExpandVolumeRequest{2671 VolumeId: "vol-test",2672 CapacityRange: &csi.CapacityRange{2673 RequiredBytes: 5*util.GiB + 1, // should round up to 6 GiB2674 LimitBytes: 5 * util.GiB,2675 },2676 },2677 expError: true,2678 },2679 }2680 for _, tc := range testCases {2681 t.Run(tc.name, func(t *testing.T) {2682 ctx := context.Background()2683 mockCtl := gomock.NewController(t)2684 defer mockCtl.Finish()2685 var retSizeGiB int642686 if tc.newSize != 0 {2687 retSizeGiB = tc.newSize2688 } else {2689 retSizeGiB = util.BytesToGiB(tc.req.CapacityRange.GetRequiredBytes())2690 }2691 mockCloud := mocks.NewMockCloud(mockCtl)2692 mockCloud.EXPECT().ResizeDisk(gomock.Eq(ctx), gomock.Eq(tc.req.VolumeId), gomock.Any()).Return(retSizeGiB, nil).AnyTimes()2693 awsDriver := controllerService{2694 cloud: mockCloud,2695 inFlight: internal.NewInFlight(),2696 driverOptions: &DriverOptions{},2697 }2698 resp, err := awsDriver.ControllerExpandVolume(ctx, tc.req)2699 if err != nil {2700 srvErr, ok := status.FromError(err)2701 if !ok {2702 t.Fatalf("Could not get error status code from error: %v", srvErr)2703 }2704 if !tc.expError {2705 t.Fatalf("Unexpected error: %v", err)2706 }2707 } else {2708 if tc.expError {2709 t.Fatalf("Expected error from ControllerExpandVolume, got nothing")2710 }2711 }2712 sizeGiB := util.BytesToGiB(resp.GetCapacityBytes())2713 expSizeGiB := util.BytesToGiB(tc.expResp.GetCapacityBytes())2714 if sizeGiB != expSizeGiB {2715 t.Fatalf("Expected size %d GiB, got %d GiB", expSizeGiB, sizeGiB)2716 }2717 })2718 }2719}...

Full Screen

Full Screen

cloud_test.go

Source:cloud_test.go Github

copy

Full Screen

...67 ctx := context.Background()68 mockEfs.EXPECT().CreateAccessPointWithContext(gomock.Eq(ctx), gomock.Any()).Return(output, nil)69 res, err := c.CreateAccessPoint(ctx, volName, req)70 if err != nil {71 t.Fatalf("CreateAccessPointFailed is failed: %v", err)72 }73 if res == nil {74 t.Fatal("Result is nil")75 }76 if accessPointId != res.AccessPointId {77 t.Fatalf("AccessPointId mismatched. Expected: %v, Actual: %v", accessPointId, res.AccessPointId)78 }79 if fsId != res.FileSystemId {80 t.Fatalf("FileSystemId mismatched. Expected: %v, Actual: %v", fsId, res.FileSystemId)81 }82 mockCtl.Finish()83 },84 },85 {86 name: "Fail",87 testFunc: func(t *testing.T) {88 mockCtl := gomock.NewController(t)89 mockEfs := mocks.NewMockEfs(mockCtl)90 c := &cloud{efs: mockEfs}91 req := &AccessPointOptions{92 FileSystemId: fsId,93 Uid: uid,94 Gid: gid,95 DirectoryPerms: directoryPerms,96 DirectoryPath: directoryPath,97 }98 ctx := context.Background()99 mockEfs.EXPECT().CreateAccessPointWithContext(gomock.Eq(ctx), gomock.Any()).Return(nil, errors.New("CreateAccessPointWithContext failed"))100 _, err := c.CreateAccessPoint(ctx, volName, req)101 if err == nil {102 t.Fatalf("CreateAccessPoint did not fail")103 }104 mockCtl.Finish()105 },106 },107 {108 name: "Fail: Access Denied",109 testFunc: func(t *testing.T) {110 mockCtl := gomock.NewController(t)111 mockEfs := mocks.NewMockEfs(mockCtl)112 c := &cloud{efs: mockEfs}113 req := &AccessPointOptions{114 FileSystemId: fsId,115 Uid: uid,116 Gid: gid,117 DirectoryPerms: directoryPerms,118 DirectoryPath: directoryPath,119 }120 ctx := context.Background()121 mockEfs.EXPECT().CreateAccessPointWithContext(gomock.Eq(ctx), gomock.Any()).Return(nil, awserr.New(AccessDeniedException, "Access Denied", errors.New("Access Denied")))122 _, err := c.CreateAccessPoint(ctx, volName, req)123 if err == nil {124 t.Fatalf("CreateAccessPoint did not fail")125 }126 if err != ErrAccessDenied {127 t.Fatalf("Failed. Expected: %v, Actual:%v", ErrAccessDenied, err)128 }129 mockCtl.Finish()130 },131 },132 }133 for _, tc := range testCases {134 t.Run(tc.name, tc.testFunc)135 }136}137func TestDeleteAccessPoint(t *testing.T) {138 var (139 accessPointId = "fsap-abcd1234xyz987"140 )141 testCases := []struct {142 name string143 testFunc func(t *testing.T)144 }{145 {146 name: "Success",147 testFunc: func(t *testing.T) {148 mockctl := gomock.NewController(t)149 mockEfs := mocks.NewMockEfs(mockctl)150 c := &cloud{efs: mockEfs}151 output := &efs.DeleteAccessPointOutput{}152 ctx := context.Background()153 mockEfs.EXPECT().DeleteAccessPointWithContext(gomock.Eq(ctx), gomock.Any()).Return(output, nil)154 err := c.DeleteAccessPoint(ctx, accessPointId)155 if err != nil {156 t.Fatalf("Delete Access Point failed: %v", err)157 }158 mockctl.Finish()159 },160 },161 {162 name: "Fail: Access Point Not Found",163 testFunc: func(t *testing.T) {164 mockctl := gomock.NewController(t)165 mockEfs := mocks.NewMockEfs(mockctl)166 c := &cloud{efs: mockEfs}167 ctx := context.Background()168 mockEfs.EXPECT().DeleteAccessPointWithContext(gomock.Eq(ctx), gomock.Any()).Return(nil, awserr.New(efs.ErrCodeAccessPointNotFound, "Access Point not found", errors.New("DeleteAccessPointWithContext failed")))169 err := c.DeleteAccessPoint(ctx, accessPointId)170 if err == nil {171 t.Fatalf("DeleteAccessPoint did not fail")172 }173 if err != ErrNotFound {174 t.Fatalf("Failed. Expected: %v, Actual:%v", ErrNotFound, err)175 }176 mockctl.Finish()177 },178 },179 {180 name: "Fail: Access Denied",181 testFunc: func(t *testing.T) {182 mockctl := gomock.NewController(t)183 mockEfs := mocks.NewMockEfs(mockctl)184 c := &cloud{efs: mockEfs}185 ctx := context.Background()186 mockEfs.EXPECT().DeleteAccessPointWithContext(gomock.Eq(ctx), gomock.Any()).Return(nil, awserr.New(AccessDeniedException, "Access Denied", errors.New("Access Denied")))187 err := c.DeleteAccessPoint(ctx, accessPointId)188 if err == nil {189 t.Fatalf("DeleteAccessPoint did not fail")190 }191 if err != ErrAccessDenied {192 t.Fatalf("Failed. Expected: %v, Actual:%v", ErrAccessDenied, err)193 }194 mockctl.Finish()195 },196 },197 {198 name: "Fail: Other",199 testFunc: func(t *testing.T) {200 mockctl := gomock.NewController(t)201 mockEfs := mocks.NewMockEfs(mockctl)202 c := &cloud{efs: mockEfs}203 ctx := context.Background()204 mockEfs.EXPECT().DeleteAccessPointWithContext(gomock.Eq(ctx), gomock.Any()).Return(nil, errors.New("DeleteAccessPointWithContext failed"))205 err := c.DeleteAccessPoint(ctx, accessPointId)206 if err == nil {207 t.Fatalf("DeleteAccessPoint did not fail")208 }209 mockctl.Finish()210 },211 },212 }213 for _, tc := range testCases {214 t.Run(tc.name, tc.testFunc)215 }216}217func TestDescribeAccessPoint(t *testing.T) {218 var (219 arn = "arn:aws:elasticfilesystem:us-east-1:1234567890:access-point/fsap-abcd1234xyz987"220 accessPointId = "fsap-abcd1234xyz987"221 fsId = "fs-abcd1234"222 uid int64 = 1001223 gid int64 = 1001224 directoryPerms = "0777"225 directoryPath = "/test"226 )227 testCases := []struct {228 name string229 testFunc func(t *testing.T)230 }{231 {232 name: "Success",233 testFunc: func(t *testing.T) {234 mockctl := gomock.NewController(t)235 mockEfs := mocks.NewMockEfs(mockctl)236 c := &cloud{efs: mockEfs}237 output := &efs.DescribeAccessPointsOutput{238 AccessPoints: []*efs.AccessPointDescription{239 {240 AccessPointArn: aws.String(arn),241 AccessPointId: aws.String(accessPointId),242 ClientToken: aws.String("test"),243 FileSystemId: aws.String(fsId),244 OwnerId: aws.String("1234567890"),245 PosixUser: &efs.PosixUser{246 Gid: aws.Int64(gid),247 Uid: aws.Int64(uid),248 },249 RootDirectory: &efs.RootDirectory{250 CreationInfo: &efs.CreationInfo{251 OwnerGid: aws.Int64(gid),252 OwnerUid: aws.Int64(uid),253 Permissions: aws.String(directoryPerms),254 },255 Path: aws.String(directoryPath),256 },257 },258 },259 NextToken: nil,260 }261 ctx := context.Background()262 mockEfs.EXPECT().DescribeAccessPointsWithContext(gomock.Eq(ctx), gomock.Any()).Return(output, nil)263 res, err := c.DescribeAccessPoint(ctx, accessPointId)264 if err != nil {265 t.Fatalf("Describe Access Point failed: %v", err)266 }267 if res == nil {268 t.Fatal("Result is nil")269 }270 if accessPointId != res.AccessPointId {271 t.Fatalf("AccessPointId mismatched. Expected: %v, Actual: %v", accessPointId, res.AccessPointId)272 }273 if fsId != res.FileSystemId {274 t.Fatalf("FileSystemId mismatched. Expected: %v, Actual: %v", fsId, res.FileSystemId)275 }276 mockctl.Finish()277 },278 },279 {280 name: "Fail: DescribeAccessPoint result has 0 access points",281 testFunc: func(t *testing.T) {282 mockctl := gomock.NewController(t)283 mockEfs := mocks.NewMockEfs(mockctl)284 c := &cloud{efs: mockEfs}285 output := &efs.DescribeAccessPointsOutput{286 AccessPoints: []*efs.AccessPointDescription{},287 NextToken: nil,288 }289 ctx := context.Background()290 mockEfs.EXPECT().DescribeAccessPointsWithContext(gomock.Eq(ctx), gomock.Any()).Return(output, nil)291 _, err := c.DescribeAccessPoint(ctx, accessPointId)292 if err == nil {293 t.Fatalf("DescribeAccessPoint did not fail")294 }295 mockctl.Finish()296 },297 },298 {299 name: "Fail: DescribeAccessPoint result has more than 1 access points",300 testFunc: func(t *testing.T) {301 mockctl := gomock.NewController(t)302 mockEfs := mocks.NewMockEfs(mockctl)303 c := &cloud{efs: mockEfs}304 output := &efs.DescribeAccessPointsOutput{305 AccessPoints: []*efs.AccessPointDescription{306 {307 AccessPointArn: aws.String(arn),308 AccessPointId: aws.String(accessPointId),309 ClientToken: aws.String("test"),310 FileSystemId: aws.String(fsId),311 OwnerId: aws.String("1234567890"),312 PosixUser: &efs.PosixUser{313 Gid: aws.Int64(gid),314 Uid: aws.Int64(uid),315 },316 RootDirectory: &efs.RootDirectory{317 CreationInfo: &efs.CreationInfo{318 OwnerGid: aws.Int64(gid),319 OwnerUid: aws.Int64(uid),320 Permissions: aws.String(directoryPerms),321 },322 Path: aws.String(directoryPath),323 },324 },325 {326 AccessPointArn: aws.String(arn),327 AccessPointId: aws.String(accessPointId),328 ClientToken: aws.String("test"),329 FileSystemId: aws.String(fsId),330 OwnerId: aws.String("1234567890"),331 PosixUser: &efs.PosixUser{332 Gid: aws.Int64(gid),333 Uid: aws.Int64(uid),334 },335 RootDirectory: &efs.RootDirectory{336 CreationInfo: &efs.CreationInfo{337 OwnerGid: aws.Int64(gid),338 OwnerUid: aws.Int64(uid),339 Permissions: aws.String(directoryPerms),340 },341 Path: aws.String(directoryPath),342 },343 },344 },345 NextToken: nil,346 }347 ctx := context.Background()348 mockEfs.EXPECT().DescribeAccessPointsWithContext(gomock.Eq(ctx), gomock.Any()).Return(output, nil)349 _, err := c.DescribeAccessPoint(ctx, accessPointId)350 if err == nil {351 t.Fatalf("DescribeAccessPoint did not fail")352 }353 mockctl.Finish()354 },355 },356 {357 name: "Fail: Access Point Not Found",358 testFunc: func(t *testing.T) {359 mockctl := gomock.NewController(t)360 mockEfs := mocks.NewMockEfs(mockctl)361 c := &cloud{efs: mockEfs}362 ctx := context.Background()363 mockEfs.EXPECT().DescribeAccessPointsWithContext(gomock.Eq(ctx), gomock.Any()).Return(nil, awserr.New(efs.ErrCodeAccessPointNotFound, "Access Point not found", errors.New("DeleteAccessPointWithContext failed")))364 _, err := c.DescribeAccessPoint(ctx, accessPointId)365 if err == nil {366 t.Fatalf("DescribeAccessPoint did not fail")367 }368 if err != ErrNotFound {369 t.Fatalf("Failed. Expected: %v, Actuak: %v", ErrNotFound, err)370 }371 mockctl.Finish()372 },373 },374 {375 name: "Fail: Access Denied",376 testFunc: func(t *testing.T) {377 mockctl := gomock.NewController(t)378 mockEfs := mocks.NewMockEfs(mockctl)379 c := &cloud{efs: mockEfs}380 ctx := context.Background()381 mockEfs.EXPECT().DescribeAccessPointsWithContext(gomock.Eq(ctx), gomock.Any()).Return(nil, awserr.New(AccessDeniedException, "Access Denied", errors.New("Access Denied")))382 _, err := c.DescribeAccessPoint(ctx, accessPointId)383 if err == nil {384 t.Fatalf("DescribeAccessPoint did not fail")385 }386 if err != ErrAccessDenied {387 t.Fatalf("Failed. Expected: %v, Actual:%v", ErrAccessDenied, err)388 }389 mockctl.Finish()390 },391 },392 {393 name: "Fail: Other",394 testFunc: func(t *testing.T) {395 mockctl := gomock.NewController(t)396 mockEfs := mocks.NewMockEfs(mockctl)397 c := &cloud{efs: mockEfs}398 ctx := context.Background()399 mockEfs.EXPECT().DescribeAccessPointsWithContext(gomock.Eq(ctx), gomock.Any()).Return(nil, errors.New("DescribeAccessPointWithContext failed"))400 _, err := c.DescribeAccessPoint(ctx, accessPointId)401 if err == nil {402 t.Fatalf("DescribeAccessPoint did not fail")403 }404 mockctl.Finish()405 },406 },407 }408 for _, tc := range testCases {409 t.Run(tc.name, tc.testFunc)410 }411}412func TestDescribeFileSystem(t *testing.T) {413 var (414 fsId = "fs-abcd1234"415 )416 testCases := []struct {417 name string418 testFunc func(t *testing.T)419 }{420 {421 name: "Success",422 testFunc: func(t *testing.T) {423 mockctl := gomock.NewController(t)424 mockEfs := mocks.NewMockEfs(mockctl)425 c := &cloud{efs: mockEfs}426 output := &efs.DescribeFileSystemsOutput{427 FileSystems: []*efs.FileSystemDescription{428 {429 CreationToken: aws.String("test"),430 Encrypted: aws.Bool(true),431 FileSystemId: aws.String(fsId),432 Name: aws.String("test"),433 OwnerId: aws.String("1234567890"),434 },435 },436 }437 ctx := context.Background()438 mockEfs.EXPECT().DescribeFileSystemsWithContext(gomock.Eq(ctx), gomock.Any()).Return(output, nil)439 res, err := c.DescribeFileSystem(ctx, fsId)440 if err != nil {441 t.Fatalf("Describe File System failed: %v", err)442 }443 if res == nil {444 t.Fatal("Result is nil")445 }446 if fsId != res.FileSystemId {447 t.Fatalf("FileSystemId mismatched. Expected: %v, Actual: %v", fsId, res.FileSystemId)448 }449 mockctl.Finish()450 },451 },452 {453 name: "Fail: DescribeFileSystems result has 0 file systems",454 testFunc: func(t *testing.T) {455 mockctl := gomock.NewController(t)456 mockEfs := mocks.NewMockEfs(mockctl)457 c := &cloud{efs: mockEfs}458 output := &efs.DescribeFileSystemsOutput{459 FileSystems: []*efs.FileSystemDescription{},460 }461 ctx := context.Background()462 mockEfs.EXPECT().DescribeFileSystemsWithContext(gomock.Eq(ctx), gomock.Any()).Return(output, nil)463 _, err := c.DescribeFileSystem(ctx, fsId)464 if err == nil {465 t.Fatalf("DescribeFileSystem did not fail")466 }467 mockctl.Finish()468 },469 },470 {471 name: "Fail: DescribeFileSystem result has more than 1 file-system",472 testFunc: func(t *testing.T) {473 mockctl := gomock.NewController(t)474 mockEfs := mocks.NewMockEfs(mockctl)475 c := &cloud{efs: mockEfs}476 output := &efs.DescribeFileSystemsOutput{477 FileSystems: []*efs.FileSystemDescription{478 {479 CreationToken: aws.String("test"),480 Encrypted: aws.Bool(true),481 FileSystemId: aws.String(fsId),482 Name: aws.String("test"),483 OwnerId: aws.String("1234567890"),484 },485 {486 CreationToken: aws.String("test"),487 Encrypted: aws.Bool(true),488 FileSystemId: aws.String(fsId),489 Name: aws.String("test"),490 OwnerId: aws.String("1234567890"),491 },492 },493 }494 ctx := context.Background()495 mockEfs.EXPECT().DescribeFileSystemsWithContext(gomock.Eq(ctx), gomock.Any()).Return(output, nil)496 _, err := c.DescribeFileSystem(ctx, fsId)497 if err == nil {498 t.Fatalf("DescribeFileSystem did not fail")499 }500 mockctl.Finish()501 },502 },503 {504 name: "Fail: File System Not Found",505 testFunc: func(t *testing.T) {506 mockctl := gomock.NewController(t)507 mockEfs := mocks.NewMockEfs(mockctl)508 c := &cloud{efs: mockEfs}509 ctx := context.Background()510 mockEfs.EXPECT().DescribeFileSystemsWithContext(gomock.Eq(ctx), gomock.Any()).Return(nil, awserr.New(efs.ErrCodeFileSystemNotFound, "File System not found", errors.New("DescribeFileSystemWithContext failed")))511 _, err := c.DescribeFileSystem(ctx, fsId)512 if err == nil {513 t.Fatalf("DescribeFileSystem did not fail")514 }515 if err != ErrNotFound {516 t.Fatalf("Failed. Expected: %v, Actual:%v", ErrNotFound, err)517 }518 mockctl.Finish()519 },520 },521 {522 name: "Fail: Access Denied",523 testFunc: func(t *testing.T) {524 mockctl := gomock.NewController(t)525 mockEfs := mocks.NewMockEfs(mockctl)526 c := &cloud{efs: mockEfs}527 ctx := context.Background()528 mockEfs.EXPECT().DescribeFileSystemsWithContext(gomock.Eq(ctx), gomock.Any()).Return(nil, awserr.New(AccessDeniedException, "Access Denied", errors.New("Access Denied")))529 _, err := c.DescribeFileSystem(ctx, fsId)530 if err == nil {531 t.Fatalf("DescribeFileSystem did not fail")532 }533 if err != ErrAccessDenied {534 t.Fatalf("Failed. Expected: %v, Actual:%v", ErrAccessDenied, err)535 }536 mockctl.Finish()537 },538 },539 {540 name: "Fail: Other",541 testFunc: func(t *testing.T) {542 mockctl := gomock.NewController(t)543 mockEfs := mocks.NewMockEfs(mockctl)544 c := &cloud{efs: mockEfs}545 ctx := context.Background()546 mockEfs.EXPECT().DescribeFileSystemsWithContext(gomock.Eq(ctx), gomock.Any()).Return(nil, errors.New("DescribeFileSystemWithContext failed"))547 _, err := c.DescribeFileSystem(ctx, fsId)548 if err == nil {549 t.Fatalf("DescribeFileSystem did not fail")550 }551 mockctl.Finish()552 },553 },554 }555 for _, tc := range testCases {556 t.Run(tc.name, tc.testFunc)557 }558}559func TestDescribeMountTargets(t *testing.T) {560 var (561 fsId = "fs-abcd1234"562 az = "us-east-1a"563 mtId = "fsmt-abcd1234"564 )565 testCases := []struct {566 name string567 mockOutput *efs.DescribeMountTargetsOutput568 mockError error569 expectError errtyp570 }{571 {572 name: "Success: normal flow",573 mockOutput: &efs.DescribeMountTargetsOutput{574 MountTargets: []*efs.MountTargetDescription{575 {576 AvailabilityZoneId: aws.String("az-id"),577 AvailabilityZoneName: aws.String(az),578 FileSystemId: aws.String(fsId),579 IpAddress: aws.String("127.0.0.1"),580 LifeCycleState: aws.String("available"),581 MountTargetId: aws.String(mtId),582 NetworkInterfaceId: aws.String("eni-abcd1234"),583 OwnerId: aws.String("1234567890"),584 SubnetId: aws.String("subnet-abcd1234"),585 },586 },587 },588 expectError: errtyp{},589 },590 {591 name: "Success: Mount target with preferred AZ does not exist. Pick random Az.",592 mockOutput: &efs.DescribeMountTargetsOutput{593 MountTargets: []*efs.MountTargetDescription{594 {595 AvailabilityZoneId: aws.String("az-id"),596 AvailabilityZoneName: aws.String("us-east-1f"),597 FileSystemId: aws.String(fsId),598 IpAddress: aws.String("127.0.0.1"),599 LifeCycleState: aws.String("available"),600 MountTargetId: aws.String(mtId),601 NetworkInterfaceId: aws.String("eni-abcd1234"),602 OwnerId: aws.String("1234567890"),603 SubnetId: aws.String("subnet-abcd1234"),604 },605 },606 },607 expectError: errtyp{},608 },609 {610 name: "Fail: File system does not have any mount targets",611 mockOutput: &efs.DescribeMountTargetsOutput{612 MountTargets: []*efs.MountTargetDescription{},613 },614 expectError: errtyp{615 code: "",616 message: "Cannot find mount targets for file system fs-abcd1234. Please create mount targets for file system.",617 },618 },619 {620 name: "Fail: File system does not have any mount targets in available life cycle state",621 mockOutput: &efs.DescribeMountTargetsOutput{622 MountTargets: []*efs.MountTargetDescription{623 {624 AvailabilityZoneId: aws.String("az-id"),625 AvailabilityZoneName: aws.String(az),626 FileSystemId: aws.String(fsId),627 IpAddress: aws.String("127.0.0.1"),628 LifeCycleState: aws.String("creating"),629 MountTargetId: aws.String(mtId),630 NetworkInterfaceId: aws.String("eni-abcd1234"),631 OwnerId: aws.String("1234567890"),632 SubnetId: aws.String("subnet-abcd1234"),633 },634 },635 },636 expectError: errtyp{637 code: "",638 message: "No mount target for file system fs-abcd1234 is in available state. Please retry in 5 minutes.",639 },640 },641 {642 name: "Fail: File System Not Found",643 mockError: awserr.New(efs.ErrCodeFileSystemNotFound, "File system not found", errors.New("File system not found")),644 expectError: errtyp{message: "Resource was not found"},645 },646 {647 name: "Fail: Access Denied",648 mockError: awserr.New(AccessDeniedException, "Access Denied", errors.New("Access Denied")),649 expectError: errtyp{message: "Access denied"},650 },651 {652 name: "Fail: Other",653 mockError: errors.New("DescribeMountTargetsWithContext failed"),654 expectError: errtyp{message: "Describe Mount Targets failed: DescribeMountTargetsWithContext failed"},655 },656 }657 for _, tc := range testCases {658 t.Run(tc.name, func(t *testing.T) {659 mockctl := gomock.NewController(t)660 defer mockctl.Finish()661 mockEfs := mocks.NewMockEfs(mockctl)662 c := &cloud{efs: mockEfs}663 ctx := context.Background()664 if tc.mockOutput != nil {665 mockEfs.EXPECT().DescribeMountTargetsWithContext(gomock.Eq(ctx), gomock.Any(), gomock.Any()).Return(tc.mockOutput, nil)666 }667 if tc.mockError != nil {668 mockEfs.EXPECT().DescribeMountTargetsWithContext(gomock.Eq(ctx), gomock.Any(), gomock.Any()).Return(nil, tc.mockError)669 }670 res, err := c.DescribeMountTargets(ctx, fsId, az)671 testResult(t, "DescribeMountTargets", res, err, tc.expectError)672 })673 }674}675func testResult(t *testing.T, funcName string, ret interface{}, err error, expectError errtyp) {676 if expectError.message == "" {677 if err != nil {678 t.Fatalf("%s is failed: %v", funcName, err)679 }680 if ret == nil {681 t.Fatal("Expected non-nil return value")682 }683 } else {684 if err == nil {685 t.Fatalf("%s is not failed", funcName)686 }687 if err.Error() != expectError.message {688 t.Fatalf("\nExpected error message: %s\nActual error message: %s", expectError.message, err.Error())689 }690 }691}...

Full Screen

Full Screen

Fatalf

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ctrl := gomock.NewController(t)4 defer ctrl.Finish()5 mock := NewMockInterface(ctrl)6 mock.EXPECT().Method().Return(0, nil)7 fmt.Println("Hello World")8}9In this example, we have created a mock of an interface. The mock interface is created using the gomock library. The mock is created using the NewMockInterface method. The NewMockInterface method takes the controller as an argument. The controller is created using the gomock.NewController method. The controller is used to create the mock. The mock is then used to call the method of the interface. The method of the interface is called using the EXPECT() method. The EXPECT() method returns the mock of the interface. The mock is then used to call the method of the interface. The method of the interface is called using the EXPECT() method. The EXPECT() method returns the mock of the interface. The mock is then used to call the method of the interface. The method of the interface is called using the EXPECT() method. The EXPECT() method returns the mock of the interface. The mock is then used to call the method of the interface. The method of the interface is called using the EXPECT() method. The EXPECT() method returns the mock of the interface. The mock is then used to call the method of the interface. The method of the interface is called using the EXPECT() method. The EXPECT() method returns the mock of the interface. The mock is then used to call the method of the interface. The method of the interface is called using the EXPECT() method. The EXPECT() method returns the mock of the interface. The mock is then used to call the method of the interface. The method of the interface is called using the EXPECT() method. The EXPECT() method returns the mock of the interface. The mock is then used to call the method of the interface. The method of the interface is called using the EXPECT() method. The EXPECT() method returns the mock of the interface. The mock is then used to call the method of the interface. The method of the interface is called using the EXPECT() method. The EXPECT() method returns the mock of the interface. The mock is then used to call the method of the interface. The method of the interface

Full Screen

Full Screen

Fatalf

Using AI Code Generation

copy

Full Screen

1import (2func TestMock(t *testing.T) {3 ctrl := gomock.NewController(t)4 defer ctrl.Finish()5 m := mock.NewMockInterface(ctrl)6 m.EXPECT().Method().Return("mock return")7 fmt.Println(m.Method())8}9import (10type MockInterface struct {11}12type _MockInterfaceRecorder struct {13}14func NewMockInterface(ctrl *gomock.Controller) *MockInterface {15 mock := &MockInterface{ctrl: ctrl}16 mock.recorder = &_MockInterfaceRecorder{mock}17}18func (_m *MockInterface) EXPECT() *_MockInterfaceRecorder {19}20func (_m *MockInterface) Method() string {21 ret := _m.ctrl.Call(_m, "Method")22 ret0, _ := ret[0].(string)23}24func (_mr *_MockInterfaceRecorder) Method() *gomock.Call {25 return _mr.mock.ctrl.RecordCall(_mr.mock, "Method")26}

Full Screen

Full Screen

Fatalf

Using AI Code Generation

copy

Full Screen

1import (2func TestFatalfMethod(t *testing.T) {3 ctrl := gomock.NewController(t)4 defer ctrl.Finish()5 log := NewMockLogger(ctrl)6 log.EXPECT().Fatalf("Fatalf %v", "test").Times(1)7 Fatalf(log, "test")8}9func Fatalf(log Logger, msg string) {10 log.Fatalf("Fatalf %v", msg)11}12type Logger interface {13 Fatalf(format string, args ...interface{})14}15type MockLogger struct {16}17type MockLoggerMockRecorder struct {18}19func NewMockLogger(ctrl *gomock.Controller) *MockLogger {20 mock := &MockLogger{ctrl: ctrl}21 mock.recorder = &MockLoggerMockRecorder{mock}22}23func (m *MockLogger) EXPECT() *MockLoggerMockRecorder {24}25func (m *MockLogger) Fatalf(format string, args ...interface{}) {26 fmt.Println("Fatalf method called")27}28import (29func TestFatalfMethod(t *testing.T) {30 ctrl := gomock.NewController(t)31 defer ctrl.Finish()32 log := NewMockLogger(ctrl)33 log.EXPECT().Fatalf("Fatalf %v", "test").Times(1)34 Fatalf(log, "test")35}36func Fatalf(log Logger, msg string) {37 log.Fatalf("Fatalf %v", msg)38}39type Logger interface {40 Fatalf(format string, args ...interface{})41}42type MockLogger struct {43}44type MockLoggerMockRecorder struct {45}46func NewMockLogger(ctrl *gomock.Controller) *MockLogger {47 mock := &MockLogger{ctrl: ctrl}48 mock.recorder = &MockLoggerMockRecorder{mock}49}50func (m *MockLogger) EXPECT() *MockLoggerMockRecorder {51}52func (m *MockLogger) Fatalf(format string, args ...interface{}) {53 fmt.Println("

Full Screen

Full Screen

Fatalf

Using AI Code Generation

copy

Full Screen

1import (2func TestFoo(t *testing.T) {3 ctrl := gomock.NewController(t)4 defer ctrl.Finish()5 mockBar := NewMockBar(ctrl)6 mockBar.EXPECT().Name().Return("gomock")7 fmt.Println(mockBar.Name())8}9import (10func TestFoo(t *testing.T) {11 ctrl := gomock.NewController(t)12 defer ctrl.Finish()13 mockBar := NewMockBar(ctrl)14 mockBar.EXPECT().Name().Return("gomock")15 fmt.Println(mockBar.Name())16}17--- FAIL: TestFoo (0.00s)18testing.tRunner.func1(0xc0000b8000)19panic(0x4a6a60, 0xc0000d9b60)20github.com/golang/mock/gomock.(*Controller).FailNow(0xc0000d9b40, 0x4b2c32, 0x2d, 0xc0000d9b40, 0xc0000d9b40)

Full Screen

Full Screen

Fatalf

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ctrl := gomock.NewController(t)4 defer ctrl.Finish()5 mock := NewMockMyInterface(ctrl)6 mock.EXPECT().MyMethod().Return("Hello")7 fmt.Println(mock.MyMethod())8}9import (10func main() {11 ctrl := gomock.NewController(t)12 defer ctrl.Finish()13 mock := NewMockMyInterface(ctrl)14 mock.EXPECT().MyMethod().Return("Hello")15 fmt.Println(mock.MyMethod())16}17import (18func main() {19 ctrl := gomock.NewController(t)20 defer ctrl.Finish()21 mock := NewMockMyInterface(ctrl)22 mock.EXPECT().MyMethod().Return("Hello")23 fmt.Println(mock.MyMethod())24}25import (26func main() {27 ctrl := gomock.NewController(t)28 defer ctrl.Finish()29 mock := NewMockMyInterface(ctrl)30 mock.EXPECT().MyMethod().Return("Hello")31 fmt.Println(mock.MyMethod())32}33import (34func main() {35 ctrl := gomock.NewController(t)36 defer ctrl.Finish()37 mock := NewMockMyInterface(ctrl)38 mock.EXPECT().MyMethod().Return("Hello")39 fmt.Println(mock.MyMethod())40}41import (42func main() {43 ctrl := gomock.NewController(t)44 defer ctrl.Finish()45 mock := NewMockMyInterface(ctrl)46 mock.EXPECT().MyMethod().Return("Hello")47 fmt.Println(mock.MyMethod())48}

Full Screen

Full Screen

Fatalf

Using AI Code Generation

copy

Full Screen

1import (2func TestMain(m *testing.M) {3 ctrl := gomock.NewController(t)4 defer ctrl.Finish()5 mock := mock.NewMockInt(ctrl)6 mock.EXPECT().Int().Return(1).Times(1)7 mock.EXPECT().Int().Return(2).Times(1)8 mock.EXPECT().Int().Return(3).Times(1)9 fmt.Println(mock.Int())10 fmt.Println(mock.Int())11 fmt.Println(mock.Int())12}13import (14func TestMain(t *testing.T) {15 ctrl := gomock.NewController(t)16 defer ctrl.Finish()17 mock := mock.NewMockInt(ctrl)18 mock.EXPECT().Int().Return(1).Times(1)19 mock.EXPECT().Int().Return(2).Times(1)20 mock.EXPECT().Int().Return(3).Times(1)21 fmt.Println(mock.Int())22 fmt.Println(mock.Int())23 fmt.Println(mock.Int())24}

Full Screen

Full Screen

Fatalf

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println("Hello, playground")4 t := new(testing.T)5 t.Fatalf("Error")6}7--- FAIL: TestMain (0.00s)8import (9func main() {10 fmt.Println("Hello, playground")11 t := new(testing.T)12 t.Logf("Error")13}14--- FAIL: TestMain (0.00s)15import (16func main() {17 fmt.Println("Hello, playground")18 t := new(testing.T)19 t.Errorf("Error")20}21--- FAIL: TestMain (0.00s)22import (23func main() {24 fmt.Println("Hello, playground")25 t := new(testing.T)26 t.Skipf("Error")27}28--- SKIP: TestMain (0.00s)

Full Screen

Full Screen

Fatalf

Using AI Code Generation

copy

Full Screen

1import "github.com/golang/mock/gomock"2mockCtrl := gomock.NewController(t)3defer mockCtrl.Finish()4mockObj := mock.NewMockInterface(mockCtrl)5mockObj := mock.NewMockStruct(mockCtrl)6mockObj.EXPECT().FunctionName().Return()7mockObj.EXPECT().FunctionName().Return()8mockObj.EXPECT().FunctionName(arg1).Return()9mockObj.EXPECT().FunctionName(arg1, arg2, arg3).Return()10mockObj.EXPECT().FunctionName(arg1).Return()11mockObj.EXPECT().FunctionName(arg1, arg2, arg3).Return()12mockObj.EXPECT().FunctionName(arg1).Return(returnValue)13mockObj.EXPECT().FunctionName(arg1, arg2, arg3).Return(returnValue)14mockObj.EXPECT().FunctionName(arg1).Return(returnValue)15mockObj.EXPECT().FunctionName(arg1, arg2, arg3).Return(returnValue)16mockObj.EXPECT().FunctionName(arg1).Return(returnValue1, returnValue2)17mockObj.EXPECT().FunctionName(arg1, arg2, arg3).Return(returnValue1, returnValue2)18mockObj.EXPECT().FunctionName(arg1).Return(returnValue1, returnValue2)19mockObj.EXPECT().FunctionName(arg1, arg2, arg3).Return(returnValue1, returnValue2)20mockObj.EXPECT().FunctionName(arg1).Return(nil)

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful