/*
 * Copyright 2019-present Open Networking Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package device

import (
	"context"
	"reflect"
	"strconv"
	"testing"

	"github.com/golang/mock/gomock"
	"github.com/golang/protobuf/ptypes"
	"github.com/golang/protobuf/ptypes/any"
	"github.com/opencord/voltha-go/db/model"
	"github.com/opencord/voltha-go/rw_core/config"
	"github.com/opencord/voltha-go/rw_core/core/adapter"
	tst "github.com/opencord/voltha-go/rw_core/test"
	"github.com/opencord/voltha-lib-go/v5/pkg/db"
	"github.com/opencord/voltha-lib-go/v5/pkg/events"
	"github.com/opencord/voltha-lib-go/v5/pkg/kafka"
	"github.com/opencord/voltha-protos/v4/go/common"
	"github.com/opencord/voltha-protos/v4/go/voltha"
	"github.com/phayes/freeport"
	"github.com/stretchr/testify/assert"
)

const (
	version = "dummy-version"
	url     = "http://127.0.0.1:2222/dummy-image"
	vendor  = "dummy"

	numberOfTestDevices = 10
)

func initialiseTest(ctx context.Context, t *testing.T) (*DATest, *MockInterContainerProxy, []*Agent) {
	dat := newDATest(ctx)

	controller := gomock.NewController(t)
	mockICProxy := NewMockInterContainerProxy(controller)

	// Set expectations for the mock
	mockICProxy.EXPECT().Start(gomock.Any()).AnyTimes().Return(nil)
	mockICProxy.EXPECT().SubscribeWithDefaultRequestHandler(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(nil)

	dat.startCoreWithCustomICProxy(ctx, mockICProxy)

	var agents []*Agent
	for i := 1; i <= numberOfTestDevices; i++ {
		if agent := dat.createDeviceAgent(t); agent != nil {
			agents = append(agents, agent)
		}
	}

	assert.Equal(t, len(agents), numberOfTestDevices)

	dat.oltAdapter, dat.onuAdapter = tst.CreateAndregisterAdapters(ctx,
		t,
		dat.kClient,
		dat.coreInstanceID,
		dat.oltAdapterName,
		dat.onuAdapterName,
		dat.adapterMgr)

	return dat, mockICProxy, agents
}

func (dat *DATest) startCoreWithCustomICProxy(ctx context.Context, kmp kafka.InterContainerProxy) {
	cfg := config.NewRWCoreFlags()
	cfg.CoreTopic = "rw_core"
	cfg.EventTopic = "voltha.events"
	cfg.DefaultRequestTimeout = dat.defaultTimeout
	cfg.KVStoreAddress = "127.0.0.1" + ":" + strconv.Itoa(dat.kvClientPort)
	grpcPort, err := freeport.GetFreePort()
	if err != nil {
		logger.Fatal(ctx, "Cannot get a freeport for grpc")
	}
	cfg.GrpcAddress = "127.0.0.1" + ":" + strconv.Itoa(grpcPort)
	client := tst.SetupKVClient(ctx, cfg, dat.coreInstanceID)
	backend := &db.Backend{
		Client:                  client,
		StoreType:               cfg.KVStoreType,
		Address:                 cfg.KVStoreAddress,
		Timeout:                 cfg.KVStoreTimeout,
		LivenessChannelInterval: cfg.LiveProbeInterval / 2}

	dat.kmp = kmp

	endpointMgr := kafka.NewEndpointManager(backend)
	proxy := model.NewDBPath(backend)
	dat.adapterMgr = adapter.NewAdapterManager(ctx, proxy, dat.coreInstanceID, dat.kClient)
	eventProxy := events.NewEventProxy(events.MsgClient(dat.kEventClient), events.MsgTopic(kafka.Topic{Name: cfg.EventTopic}))
	dat.deviceMgr, dat.logicalDeviceMgr = NewManagers(proxy, dat.adapterMgr, dat.kmp, endpointMgr, cfg, dat.coreInstanceID, eventProxy)
	dat.adapterMgr.Start(context.Background())
	if err = dat.kmp.Start(ctx); err != nil {
		logger.Fatal(ctx, "Cannot start InterContainerProxy")
	}

	if err := dat.kmp.SubscribeWithDefaultRequestHandler(ctx, kafka.Topic{Name: cfg.CoreTopic}, kafka.OffsetNewest); err != nil {
		logger.Fatalf(ctx, "Cannot add default request handler: %s", err)
	}

}

func TestManager_DownloadImageToDevice(t *testing.T) {
	type args struct {
		ctx     context.Context
		request *voltha.DeviceImageDownloadRequest
	}

	ctx := context.Background()
	dat, mockICProxy, agents := initialiseTest(ctx, t)

	tests := []struct {
		name    string
		args    args
		want    *voltha.DeviceImageResponse
		wantErr bool
	}{
		{
			name: "request-for-single-device",
			args: args{
				ctx:     ctx,
				request: newDeviceImageDownloadRequest(agents[:1]),
			},
			want:    newImageResponse(agents[:1], voltha.ImageState_DOWNLOAD_REQUESTED, voltha.ImageState_IMAGE_DOWNLOADING, voltha.ImageState_NO_ERROR),
			wantErr: false,
		},
		{
			name: "request-for-multiple-devices",
			args: args{
				ctx:     ctx,
				request: newDeviceImageDownloadRequest(agents),
			},
			want:    newImageResponse(agents, voltha.ImageState_DOWNLOAD_REQUESTED, voltha.ImageState_IMAGE_DOWNLOADING, voltha.ImageState_NO_ERROR),
			wantErr: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.name == "request-for-single-device" {
				chnl := make(chan *kafka.RpcResponse, 10)
				// Set expectation for the API invocation
				mockICProxy.EXPECT().InvokeAsyncRPC(gomock.Any(),
					"Download_onu_image",
					gomock.Any(),
					gomock.Any(),
					true,
					gomock.Any(), gomock.Any()).Return(chnl)
				// Send the expected response to channel from a goroutine
				go func() {
					reply := newImageDownloadAdapterResponse(t, agents[0].deviceID, voltha.ImageState_DOWNLOAD_REQUESTED, voltha.ImageState_IMAGE_DOWNLOADING, voltha.ImageState_NO_ERROR)

					chnl <- &kafka.RpcResponse{
						MType: kafka.RpcSent,
						Err:   nil,
						Reply: reply,
					}

					chnl <- &kafka.RpcResponse{
						MType: kafka.RpcReply,
						Err:   nil,
						Reply: reply,
					}
				}()
			} else if tt.name == "request-for-multiple-devices" {
				// Map to store per device kafka response channel
				kafkaRespChans := make(map[string]chan *kafka.RpcResponse)
				for _, id := range tt.args.request.DeviceId {
					// Create a kafka response channel per device
					chnl := make(chan *kafka.RpcResponse)

					// Set expectation for the API invocation
					mockICProxy.EXPECT().InvokeAsyncRPC(gomock.Any(),
						"Download_onu_image",
						gomock.Any(),
						gomock.Any(),
						true,
						id.Id, gomock.Any()).Return(chnl)

					kafkaRespChans[id.Id] = chnl
				}

				// Send the expected response to channel from a goroutine
				go func() {
					for _, agent := range agents {
						reply := newImageDownloadAdapterResponse(t, agent.deviceID, voltha.ImageState_DOWNLOAD_REQUESTED, voltha.ImageState_IMAGE_DOWNLOADING, voltha.ImageState_NO_ERROR)

						kafkaRespChans[agent.deviceID] <- &kafka.RpcResponse{
							MType: kafka.RpcSent,
							Err:   nil,
							Reply: reply,
						}

						kafkaRespChans[agent.deviceID] <- &kafka.RpcResponse{
							MType: kafka.RpcReply,
							Err:   nil,
							Reply: reply,
						}
					}
				}()
			}

			got, err := dat.deviceMgr.DownloadImageToDevice(tt.args.ctx, tt.args.request)
			if (err != nil) != tt.wantErr {
				t.Errorf("DownloadImageToDevice() error = %v, wantErr %v", err, tt.wantErr)
				return
			}

			if !gotAllSuccess(got, tt.want) {
				t.Errorf("DownloadImageToDevice() got = %v, want = %v", got, tt.want)
			}
		})
	}
}

func TestManager_GetImageStatus(t *testing.T) {
	type args struct {
		ctx     context.Context
		request *voltha.DeviceImageRequest
	}

	ctx := context.Background()
	dat, mockICProxy, agents := initialiseTest(ctx, t)

	tests := []struct {
		name    string
		args    args
		want    *voltha.DeviceImageResponse
		wantErr bool
	}{
		{
			name: "request-for-single-device",
			args: args{
				ctx:     ctx,
				request: newDeviceImagedRequest(agents[:1]),
			},
			want:    newImageResponse(agents[:1], voltha.ImageState_DOWNLOAD_REQUESTED, voltha.ImageState_IMAGE_DOWNLOADING, voltha.ImageState_NO_ERROR),
			wantErr: false,
		},
		{
			name: "request-for-multiple-devices",
			args: args{
				ctx:     ctx,
				request: newDeviceImagedRequest(agents),
			},
			want:    newImageResponse(agents, voltha.ImageState_DOWNLOAD_REQUESTED, voltha.ImageState_IMAGE_DOWNLOADING, voltha.ImageState_NO_ERROR),
			wantErr: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.name == "request-for-single-device" {
				chnl := make(chan *kafka.RpcResponse, 10)
				// Set expectation for the API invocation
				mockICProxy.EXPECT().InvokeAsyncRPC(gomock.Any(),
					"Get_onu_image_status",
					gomock.Any(),
					gomock.Any(),
					true,
					gomock.Any(), gomock.Any()).Return(chnl)
				// Send the expected response to channel from a goroutine
				go func() {
					reply := newImageStatusAdapterResponse(t, agents[:1], voltha.ImageState_DOWNLOAD_REQUESTED, voltha.ImageState_IMAGE_DOWNLOADING, voltha.ImageState_NO_ERROR)

					chnl <- &kafka.RpcResponse{
						MType: kafka.RpcSent,
						Err:   nil,
						Reply: reply,
					}

					chnl <- &kafka.RpcResponse{
						MType: kafka.RpcReply,
						Err:   nil,
						Reply: reply,
					}
				}()
			} else if tt.name == "request-for-multiple-devices" {
				// Map to store per device kafka response channel
				kafkaRespChans := make(map[string]chan *kafka.RpcResponse)
				for _, id := range tt.args.request.DeviceId {
					// Create a kafka response channel per device
					chnl := make(chan *kafka.RpcResponse)

					// Set expectation for the API invocation
					mockICProxy.EXPECT().InvokeAsyncRPC(gomock.Any(),
						"Get_onu_image_status",
						gomock.Any(),
						gomock.Any(),
						true,
						id.Id, gomock.Any()).Return(chnl)

					kafkaRespChans[id.Id] = chnl
				}

				// Send the expected response to channel from a goroutine
				go func() {
					for _, agent := range agents {
						reply := newImageStatusAdapterResponse(t, agents, voltha.ImageState_DOWNLOAD_REQUESTED, voltha.ImageState_IMAGE_DOWNLOADING, voltha.ImageState_NO_ERROR)

						kafkaRespChans[agent.deviceID] <- &kafka.RpcResponse{
							MType: kafka.RpcSent,
							Err:   nil,
							Reply: reply,
						}

						kafkaRespChans[agent.deviceID] <- &kafka.RpcResponse{
							MType: kafka.RpcReply,
							Err:   nil,
							Reply: reply,
						}
					}
				}()
			}

			got, err := dat.deviceMgr.GetImageStatus(tt.args.ctx, tt.args.request)
			if (err != nil) != tt.wantErr {
				t.Errorf("GetImageStatus() error = %v, wantErr %v", err, tt.wantErr)
				return
			}

			if !gotAllSuccess(got, tt.want) {
				t.Errorf("GetImageStatus() got = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestManager_AbortImageUpgradeToDevice(t *testing.T) {

	type args struct {
		ctx     context.Context
		request *voltha.DeviceImageRequest
	}

	ctx := context.Background()
	dat, mockICProxy, agents := initialiseTest(ctx, t)

	tests := []struct {
		name    string
		args    args
		want    *voltha.DeviceImageResponse
		wantErr bool
	}{
		{
			name: "request-for-single-device",
			args: args{
				ctx:     ctx,
				request: newDeviceImagedRequest(agents[:1]),
			},
			want:    newImageResponse(agents[:1], voltha.ImageState_DOWNLOAD_CANCELLED, voltha.ImageState_IMAGE_ACTIVATION_ABORTED, voltha.ImageState_NO_ERROR),
			wantErr: false,
		},
		{
			name: "request-for-multiple-devices",
			args: args{
				ctx:     ctx,
				request: newDeviceImagedRequest(agents[:1]),
			},
			want:    newImageResponse(agents, voltha.ImageState_DOWNLOAD_CANCELLED, voltha.ImageState_IMAGE_ACTIVATION_ABORTED, voltha.ImageState_NO_ERROR),
			wantErr: false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.name == "request-for-single-device" {
				chnl := make(chan *kafka.RpcResponse, 10)
				// Set expectation for the API invocation
				mockICProxy.EXPECT().InvokeAsyncRPC(gomock.Any(),
					"Abort_onu_image_upgrade",
					gomock.Any(),
					gomock.Any(),
					true,
					gomock.Any(), gomock.Any()).Return(chnl)
				// Send the expected response to channel from a goroutine
				go func() {
					reply := newImageStatusAdapterResponse(t, agents[:1], voltha.ImageState_DOWNLOAD_CANCELLED, voltha.ImageState_IMAGE_ACTIVATION_ABORTED, voltha.ImageState_NO_ERROR)

					chnl <- &kafka.RpcResponse{
						MType: kafka.RpcSent,
						Err:   nil,
						Reply: reply,
					}

					chnl <- &kafka.RpcResponse{
						MType: kafka.RpcReply,
						Err:   nil,
						Reply: reply,
					}
				}()
			} else if tt.name == "request-for-multiple-devices" {
				// Map to store per device kafka response channel
				kafkaRespChans := make(map[string]chan *kafka.RpcResponse)
				for _, id := range tt.args.request.DeviceId {
					// Create a kafka response channel per device
					chnl := make(chan *kafka.RpcResponse)

					// Set expectation for the API invocation
					mockICProxy.EXPECT().InvokeAsyncRPC(gomock.Any(),
						"Abort_onu_image_upgrade",
						gomock.Any(),
						gomock.Any(),
						true,
						id.Id, gomock.Any()).Return(chnl)

					kafkaRespChans[id.Id] = chnl
				}

				// Send the expected response to channel from a goroutine
				go func() {
					for _, agent := range agents {
						reply := newImageStatusAdapterResponse(t, agents, voltha.ImageState_DOWNLOAD_CANCELLED, voltha.ImageState_IMAGE_ACTIVATION_ABORTED, voltha.ImageState_NO_ERROR)

						kafkaRespChans[agent.deviceID] <- &kafka.RpcResponse{
							MType: kafka.RpcSent,
							Err:   nil,
							Reply: reply,
						}

						kafkaRespChans[agent.deviceID] <- &kafka.RpcResponse{
							MType: kafka.RpcReply,
							Err:   nil,
							Reply: reply,
						}
					}
				}()
			}
			got, err := dat.deviceMgr.AbortImageUpgradeToDevice(tt.args.ctx, tt.args.request)
			if (err != nil) != tt.wantErr {
				t.Errorf("AbortImageUpgradeToDevice() error = %v, wantErr %v", err, tt.wantErr)
				return
			}

			if !gotAllSuccess(got, tt.want) {
				t.Errorf("AbortImageUpgradeToDevice() got = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestManager_ActivateImage(t *testing.T) {
	type args struct {
		ctx     context.Context
		request *voltha.DeviceImageRequest
	}

	ctx := context.Background()
	dat, mockICProxy, agents := initialiseTest(ctx, t)

	tests := []struct {
		name    string
		args    args
		want    *voltha.DeviceImageResponse
		wantErr bool
	}{
		{
			name: "request-for-single-device",
			args: args{
				ctx:     ctx,
				request: newDeviceImagedRequest(agents[:1]),
			},
			want:    newImageResponse(agents[:1], voltha.ImageState_DOWNLOAD_SUCCEEDED, voltha.ImageState_IMAGE_ACTIVATING, voltha.ImageState_NO_ERROR),
			wantErr: false,
		},
		{
			name: "request-for-multiple-devices",
			args: args{
				ctx:     ctx,
				request: newDeviceImagedRequest(agents),
			},
			want:    newImageResponse(agents, voltha.ImageState_DOWNLOAD_SUCCEEDED, voltha.ImageState_IMAGE_ACTIVATING, voltha.ImageState_NO_ERROR),
			wantErr: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.name == "request-for-single-device" {
				chnl := make(chan *kafka.RpcResponse, 10)
				// Set expectation for the API invocation
				mockICProxy.EXPECT().InvokeAsyncRPC(gomock.Any(),
					"Activate_onu_image",
					gomock.Any(),
					gomock.Any(),
					true,
					gomock.Any(), gomock.Any()).Return(chnl)
				// Send the expected response to channel from a goroutine
				go func() {
					reply := newImageStatusAdapterResponse(t, agents[:1], voltha.ImageState_DOWNLOAD_SUCCEEDED, voltha.ImageState_IMAGE_ACTIVATING, voltha.ImageState_NO_ERROR)

					chnl <- &kafka.RpcResponse{
						MType: kafka.RpcSent,
						Err:   nil,
						Reply: reply,
					}

					chnl <- &kafka.RpcResponse{
						MType: kafka.RpcReply,
						Err:   nil,
						Reply: reply,
					}
				}()
			} else if tt.name == "request-for-multiple-devices" {
				// Map to store per device kafka response channel
				kafkaRespChans := make(map[string]chan *kafka.RpcResponse)
				for _, id := range tt.args.request.DeviceId {
					// Create a kafka response channel per device
					chnl := make(chan *kafka.RpcResponse)

					// Set expectation for the API invocation
					mockICProxy.EXPECT().InvokeAsyncRPC(gomock.Any(),
						"Activate_onu_image",
						gomock.Any(),
						gomock.Any(),
						true,
						id.Id, gomock.Any()).Return(chnl)

					kafkaRespChans[id.Id] = chnl
				}

				// Send the expected response to channel from a goroutine
				go func() {
					for _, agent := range agents {
						reply := newImageStatusAdapterResponse(t, agents, voltha.ImageState_DOWNLOAD_SUCCEEDED, voltha.ImageState_IMAGE_ACTIVATING, voltha.ImageState_NO_ERROR)

						kafkaRespChans[agent.deviceID] <- &kafka.RpcResponse{
							MType: kafka.RpcSent,
							Err:   nil,
							Reply: reply,
						}

						kafkaRespChans[agent.deviceID] <- &kafka.RpcResponse{
							MType: kafka.RpcReply,
							Err:   nil,
							Reply: reply,
						}
					}
				}()
			}
			got, err := dat.deviceMgr.ActivateImage(tt.args.ctx, tt.args.request)
			if (err != nil) != tt.wantErr {
				t.Errorf("ActivateImage() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if !gotAllSuccess(got, tt.want) {
				t.Errorf("ActivateImage() got = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestManager_CommitImage(t *testing.T) {
	type args struct {
		ctx     context.Context
		request *voltha.DeviceImageRequest
	}

	ctx := context.Background()
	dat, mockICProxy, agents := initialiseTest(ctx, t)

	tests := []struct {
		name    string
		args    args
		want    *voltha.DeviceImageResponse
		wantErr bool
	}{
		{
			name: "request-for-single-device",
			args: args{
				ctx:     ctx,
				request: newDeviceImagedRequest(agents[:1]),
			},
			want:    newImageResponse(agents[:1], voltha.ImageState_DOWNLOAD_SUCCEEDED, voltha.ImageState_IMAGE_COMMITTING, voltha.ImageState_NO_ERROR),
			wantErr: false,
		},
		{
			name: "request-for-multiple-devices",
			args: args{
				ctx:     ctx,
				request: newDeviceImagedRequest(agents),
			},
			want:    newImageResponse(agents, voltha.ImageState_DOWNLOAD_SUCCEEDED, voltha.ImageState_IMAGE_COMMITTING, voltha.ImageState_NO_ERROR),
			wantErr: false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.name == "request-for-single-device" {
				chnl := make(chan *kafka.RpcResponse, 10)
				// Set expectation for the API invocation
				mockICProxy.EXPECT().InvokeAsyncRPC(gomock.Any(),
					"Commit_onu_image",
					gomock.Any(),
					gomock.Any(),
					true,
					gomock.Any(), gomock.Any()).Return(chnl)
				// Send the expected response to channel from a goroutine
				go func() {
					reply := newImageStatusAdapterResponse(t, agents[:1], voltha.ImageState_DOWNLOAD_SUCCEEDED, voltha.ImageState_IMAGE_COMMITTING, voltha.ImageState_NO_ERROR)

					chnl <- &kafka.RpcResponse{
						MType: kafka.RpcSent,
						Err:   nil,
						Reply: reply,
					}

					chnl <- &kafka.RpcResponse{
						MType: kafka.RpcReply,
						Err:   nil,
						Reply: reply,
					}
				}()
			} else if tt.name == "request-for-multiple-devices" {
				// Map to store per device kafka response channel
				kafkaRespChans := make(map[string]chan *kafka.RpcResponse)
				for _, id := range tt.args.request.DeviceId {
					// Create a kafka response channel per device
					chnl := make(chan *kafka.RpcResponse)

					// Set expectation for the API invocation
					mockICProxy.EXPECT().InvokeAsyncRPC(gomock.Any(),
						"Commit_onu_image",
						gomock.Any(),
						gomock.Any(),
						true,
						id.Id, gomock.Any()).Return(chnl)

					kafkaRespChans[id.Id] = chnl
				}

				// Send the expected response to channel from a goroutine
				go func() {
					for _, agent := range agents {
						reply := newImageStatusAdapterResponse(t, agents, voltha.ImageState_DOWNLOAD_SUCCEEDED, voltha.ImageState_IMAGE_COMMITTING, voltha.ImageState_NO_ERROR)

						kafkaRespChans[agent.deviceID] <- &kafka.RpcResponse{
							MType: kafka.RpcSent,
							Err:   nil,
							Reply: reply,
						}

						kafkaRespChans[agent.deviceID] <- &kafka.RpcResponse{
							MType: kafka.RpcReply,
							Err:   nil,
							Reply: reply,
						}
					}
				}()
			}
			got, err := dat.deviceMgr.CommitImage(tt.args.ctx, tt.args.request)
			if (err != nil) != tt.wantErr {
				t.Errorf("CommitImage() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if !gotAllSuccess(got, tt.want) {
				t.Errorf("CommitImage() got = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestManager_GetOnuImages(t *testing.T) {
	type args struct {
		ctx context.Context
		id  *common.ID
	}

	ctx := context.Background()
	dat, mockICProxy, agents := initialiseTest(ctx, t)

	tests := []struct {
		name    string
		args    args
		want    *voltha.OnuImages
		wantErr bool
	}{
		{
			name: "request-for-single-device",
			args: args{
				ctx: ctx,
				id: &common.ID{
					Id: agents[0].deviceID,
				},
			},
			want: &voltha.OnuImages{
				Items: []*voltha.OnuImage{{
					Version:    version,
					IsCommited: true,
					IsActive:   true,
					IsValid:    true,
				}},
			},
			wantErr: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.name == "request-for-single-device" {
				chnl := make(chan *kafka.RpcResponse, 10)
				// Set expectation for the API invocation
				mockICProxy.EXPECT().InvokeAsyncRPC(gomock.Any(),
					"Get_onu_images",
					gomock.Any(),
					gomock.Any(),
					true,
					gomock.Any(), gomock.Any()).Return(chnl)
				// Send the expected response to channel from a goroutine
				go func() {
					reply := newOnuImagesResponse(t)
					chnl <- &kafka.RpcResponse{
						MType: kafka.RpcSent,
						Err:   nil,
						Reply: reply,
					}

					chnl <- &kafka.RpcResponse{
						MType: kafka.RpcReply,
						Err:   nil,
						Reply: reply,
					}
				}()
			}

			got, err := dat.deviceMgr.GetOnuImages(tt.args.ctx, tt.args.id)
			if (err != nil) != tt.wantErr {
				t.Errorf("GetOnuImages() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("GetOnuImages() got = %v, want %v", got, tt.want)
			}
		})
	}
}

// verify that we got all the wanted response (order not important)
func gotAllSuccess(got, want *voltha.DeviceImageResponse) bool {
	for _, imagestateGot := range got.DeviceImageStates {
		found := false
		for _, imageStateWant := range want.DeviceImageStates {
			if reflect.DeepEqual(imagestateGot, imageStateWant) {
				found = true
			}
		}

		if !found {
			return false
		}
	}

	return true
}

func newDeviceImagedRequest(agents []*Agent) *voltha.DeviceImageRequest {
	imgReq := &voltha.DeviceImageRequest{
		Version:         version,
		CommitOnSuccess: true,
	}

	for _, agent := range agents {
		if agent != nil {
			imgReq.DeviceId = append(imgReq.DeviceId, &common.ID{
				Id: agent.deviceID,
			})
		}
	}

	return imgReq
}

func newDeviceImageDownloadRequest(agents []*Agent) *voltha.DeviceImageDownloadRequest {
	imgDownReq := &voltha.DeviceImageDownloadRequest{
		Image: &voltha.Image{
			Version: version,
			Url:     url,
			Vendor:  vendor,
		},
		ActivateOnSuccess: true,
		CommitOnSuccess:   true,
	}

	for _, agent := range agents {
		if agent != nil {
			imgDownReq.DeviceId = append(imgDownReq.DeviceId, &common.ID{
				Id: agent.deviceID,
			})
		}
	}

	return imgDownReq
}

func newImageResponse(agents []*Agent,
	downloadState voltha.ImageState_ImageDownloadState,
	imageSate voltha.ImageState_ImageActivationState,
	reason voltha.ImageState_ImageFailureReason) *voltha.DeviceImageResponse {
	response := &voltha.DeviceImageResponse{}

	for _, agent := range agents {
		response.DeviceImageStates = append(response.DeviceImageStates, &voltha.DeviceImageState{
			DeviceId: agent.deviceID,
			ImageState: &voltha.ImageState{
				Version:       version,
				DownloadState: downloadState,
				Reason:        reason,
				ImageState:    imageSate,
			},
		})
	}

	return response
}

func newImageDownloadAdapterResponse(t *testing.T,
	deviceID string,
	downloadState voltha.ImageState_ImageDownloadState,
	imageSate voltha.ImageState_ImageActivationState,
	reason voltha.ImageState_ImageFailureReason) *any.Any {
	reply, err := ptypes.MarshalAny(&voltha.DeviceImageResponse{
		DeviceImageStates: []*voltha.DeviceImageState{{
			DeviceId: deviceID,
			ImageState: &voltha.ImageState{
				Version:       version,
				DownloadState: downloadState,
				Reason:        reason,
				ImageState:    imageSate,
			},
		}},
	})
	assert.Nil(t, err)
	return reply
}

func newImageStatusAdapterResponse(t *testing.T,
	agents []*Agent,
	downloadState voltha.ImageState_ImageDownloadState,
	imageSate voltha.ImageState_ImageActivationState,
	reason voltha.ImageState_ImageFailureReason) *any.Any {
	imgResponse := &voltha.DeviceImageResponse{}
	for _, agent := range agents {
		imgResponse.DeviceImageStates = append(imgResponse.DeviceImageStates, &voltha.DeviceImageState{
			DeviceId: agent.deviceID,
			ImageState: &voltha.ImageState{
				Version:       version,
				DownloadState: downloadState,
				Reason:        reason,
				ImageState:    imageSate,
			},
		})
	}

	reply, err := ptypes.MarshalAny(imgResponse)
	assert.Nil(t, err)
	return reply
}

func newOnuImagesResponse(t *testing.T) *any.Any {
	onuImages := &voltha.OnuImages{
		Items: []*voltha.OnuImage{{
			Version:    version,
			IsCommited: true,
			IsActive:   true,
			IsValid:    true,
		}},
	}

	reply, err := ptypes.MarshalAny(onuImages)
	assert.Nil(t, err)
	return reply
}
