//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.
//

// Code generated by MockGen. DO NOT EDIT.
// Source: ./cloudstack/GuestOSService.go

// Package cloudstack is a generated GoMock package.
package cloudstack

import (
	reflect "reflect"

	gomock "github.com/golang/mock/gomock"
)

// MockGuestOSServiceIface is a mock of GuestOSServiceIface interface.
type MockGuestOSServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockGuestOSServiceIfaceMockRecorder
}

// MockGuestOSServiceIfaceMockRecorder is the mock recorder for MockGuestOSServiceIface.
type MockGuestOSServiceIfaceMockRecorder struct {
	mock *MockGuestOSServiceIface
}

// NewMockGuestOSServiceIface creates a new mock instance.
func NewMockGuestOSServiceIface(ctrl *gomock.Controller) *MockGuestOSServiceIface {
	mock := &MockGuestOSServiceIface{ctrl: ctrl}
	mock.recorder = &MockGuestOSServiceIfaceMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockGuestOSServiceIface) EXPECT() *MockGuestOSServiceIfaceMockRecorder {
	return m.recorder
}

// AddGuestOs mocks base method.
func (m *MockGuestOSServiceIface) AddGuestOs(p *AddGuestOsParams) (*AddGuestOsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "AddGuestOs", p)
	ret0, _ := ret[0].(*AddGuestOsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// AddGuestOs indicates an expected call of AddGuestOs.
func (mr *MockGuestOSServiceIfaceMockRecorder) AddGuestOs(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddGuestOs", reflect.TypeOf((*MockGuestOSServiceIface)(nil).AddGuestOs), p)
}

// AddGuestOsMapping mocks base method.
func (m *MockGuestOSServiceIface) AddGuestOsMapping(p *AddGuestOsMappingParams) (*AddGuestOsMappingResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "AddGuestOsMapping", p)
	ret0, _ := ret[0].(*AddGuestOsMappingResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// AddGuestOsMapping indicates an expected call of AddGuestOsMapping.
func (mr *MockGuestOSServiceIfaceMockRecorder) AddGuestOsMapping(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddGuestOsMapping", reflect.TypeOf((*MockGuestOSServiceIface)(nil).AddGuestOsMapping), p)
}

// GetGuestOsMappingByID mocks base method.
func (m *MockGuestOSServiceIface) GetGuestOsMappingByID(id string, opts ...OptionFunc) (*GuestOsMapping, int, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{id}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetGuestOsMappingByID", varargs...)
	ret0, _ := ret[0].(*GuestOsMapping)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetGuestOsMappingByID indicates an expected call of GetGuestOsMappingByID.
func (mr *MockGuestOSServiceIfaceMockRecorder) GetGuestOsMappingByID(id interface{}, opts ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{id}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGuestOsMappingByID", reflect.TypeOf((*MockGuestOSServiceIface)(nil).GetGuestOsMappingByID), varargs...)
}

// GetOsCategoryByID mocks base method.
func (m *MockGuestOSServiceIface) GetOsCategoryByID(id string, opts ...OptionFunc) (*OsCategory, int, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{id}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetOsCategoryByID", varargs...)
	ret0, _ := ret[0].(*OsCategory)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetOsCategoryByID indicates an expected call of GetOsCategoryByID.
func (mr *MockGuestOSServiceIfaceMockRecorder) GetOsCategoryByID(id interface{}, opts ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{id}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOsCategoryByID", reflect.TypeOf((*MockGuestOSServiceIface)(nil).GetOsCategoryByID), varargs...)
}

// GetOsCategoryByName mocks base method.
func (m *MockGuestOSServiceIface) GetOsCategoryByName(name string, opts ...OptionFunc) (*OsCategory, int, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetOsCategoryByName", varargs...)
	ret0, _ := ret[0].(*OsCategory)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetOsCategoryByName indicates an expected call of GetOsCategoryByName.
func (mr *MockGuestOSServiceIfaceMockRecorder) GetOsCategoryByName(name interface{}, opts ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOsCategoryByName", reflect.TypeOf((*MockGuestOSServiceIface)(nil).GetOsCategoryByName), varargs...)
}

// GetOsCategoryID mocks base method.
func (m *MockGuestOSServiceIface) GetOsCategoryID(name string, opts ...OptionFunc) (string, int, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetOsCategoryID", varargs...)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetOsCategoryID indicates an expected call of GetOsCategoryID.
func (mr *MockGuestOSServiceIfaceMockRecorder) GetOsCategoryID(name interface{}, opts ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOsCategoryID", reflect.TypeOf((*MockGuestOSServiceIface)(nil).GetOsCategoryID), varargs...)
}

// GetOsTypeByID mocks base method.
func (m *MockGuestOSServiceIface) GetOsTypeByID(id string, opts ...OptionFunc) (*OsType, int, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{id}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetOsTypeByID", varargs...)
	ret0, _ := ret[0].(*OsType)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetOsTypeByID indicates an expected call of GetOsTypeByID.
func (mr *MockGuestOSServiceIfaceMockRecorder) GetOsTypeByID(id interface{}, opts ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{id}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOsTypeByID", reflect.TypeOf((*MockGuestOSServiceIface)(nil).GetOsTypeByID), varargs...)
}

// GetOsTypeByName mocks base method.
func (m *MockGuestOSServiceIface) GetOsTypeByName(name string, opts ...OptionFunc) (*OsType, int, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetOsTypeByName", varargs...)
	ret0, _ := ret[0].(*OsType)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetOsTypeByName indicates an expected call of GetOsTypeByName.
func (mr *MockGuestOSServiceIfaceMockRecorder) GetOsTypeByName(name interface{}, opts ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOsTypeByName", reflect.TypeOf((*MockGuestOSServiceIface)(nil).GetOsTypeByName), varargs...)
}

// GetOsTypeID mocks base method.
func (m *MockGuestOSServiceIface) GetOsTypeID(keyword string, opts ...OptionFunc) (string, int, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{keyword}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetOsTypeID", varargs...)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetOsTypeID indicates an expected call of GetOsTypeID.
func (mr *MockGuestOSServiceIfaceMockRecorder) GetOsTypeID(keyword interface{}, opts ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{keyword}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOsTypeID", reflect.TypeOf((*MockGuestOSServiceIface)(nil).GetOsTypeID), varargs...)
}

// ListGuestOsMapping mocks base method.
func (m *MockGuestOSServiceIface) ListGuestOsMapping(p *ListGuestOsMappingParams) (*ListGuestOsMappingResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListGuestOsMapping", p)
	ret0, _ := ret[0].(*ListGuestOsMappingResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListGuestOsMapping indicates an expected call of ListGuestOsMapping.
func (mr *MockGuestOSServiceIfaceMockRecorder) ListGuestOsMapping(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListGuestOsMapping", reflect.TypeOf((*MockGuestOSServiceIface)(nil).ListGuestOsMapping), p)
}

// ListOsCategories mocks base method.
func (m *MockGuestOSServiceIface) ListOsCategories(p *ListOsCategoriesParams) (*ListOsCategoriesResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListOsCategories", p)
	ret0, _ := ret[0].(*ListOsCategoriesResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListOsCategories indicates an expected call of ListOsCategories.
func (mr *MockGuestOSServiceIfaceMockRecorder) ListOsCategories(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListOsCategories", reflect.TypeOf((*MockGuestOSServiceIface)(nil).ListOsCategories), p)
}

// ListOsTypes mocks base method.
func (m *MockGuestOSServiceIface) ListOsTypes(p *ListOsTypesParams) (*ListOsTypesResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListOsTypes", p)
	ret0, _ := ret[0].(*ListOsTypesResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListOsTypes indicates an expected call of ListOsTypes.
func (mr *MockGuestOSServiceIfaceMockRecorder) ListOsTypes(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListOsTypes", reflect.TypeOf((*MockGuestOSServiceIface)(nil).ListOsTypes), p)
}

// NewAddGuestOsMappingParams mocks base method.
func (m *MockGuestOSServiceIface) NewAddGuestOsMappingParams(hypervisor, hypervisorversion, osnameforhypervisor string) *AddGuestOsMappingParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewAddGuestOsMappingParams", hypervisor, hypervisorversion, osnameforhypervisor)
	ret0, _ := ret[0].(*AddGuestOsMappingParams)
	return ret0
}

// NewAddGuestOsMappingParams indicates an expected call of NewAddGuestOsMappingParams.
func (mr *MockGuestOSServiceIfaceMockRecorder) NewAddGuestOsMappingParams(hypervisor, hypervisorversion, osnameforhypervisor interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddGuestOsMappingParams", reflect.TypeOf((*MockGuestOSServiceIface)(nil).NewAddGuestOsMappingParams), hypervisor, hypervisorversion, osnameforhypervisor)
}

// NewAddGuestOsParams mocks base method.
func (m *MockGuestOSServiceIface) NewAddGuestOsParams(oscategoryid, osdisplayname string) *AddGuestOsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewAddGuestOsParams", oscategoryid, osdisplayname)
	ret0, _ := ret[0].(*AddGuestOsParams)
	return ret0
}

// NewAddGuestOsParams indicates an expected call of NewAddGuestOsParams.
func (mr *MockGuestOSServiceIfaceMockRecorder) NewAddGuestOsParams(oscategoryid, osdisplayname interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddGuestOsParams", reflect.TypeOf((*MockGuestOSServiceIface)(nil).NewAddGuestOsParams), oscategoryid, osdisplayname)
}

// NewListGuestOsMappingParams mocks base method.
func (m *MockGuestOSServiceIface) NewListGuestOsMappingParams() *ListGuestOsMappingParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListGuestOsMappingParams")
	ret0, _ := ret[0].(*ListGuestOsMappingParams)
	return ret0
}

// NewListGuestOsMappingParams indicates an expected call of NewListGuestOsMappingParams.
func (mr *MockGuestOSServiceIfaceMockRecorder) NewListGuestOsMappingParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListGuestOsMappingParams", reflect.TypeOf((*MockGuestOSServiceIface)(nil).NewListGuestOsMappingParams))
}

// NewListOsCategoriesParams mocks base method.
func (m *MockGuestOSServiceIface) NewListOsCategoriesParams() *ListOsCategoriesParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListOsCategoriesParams")
	ret0, _ := ret[0].(*ListOsCategoriesParams)
	return ret0
}

// NewListOsCategoriesParams indicates an expected call of NewListOsCategoriesParams.
func (mr *MockGuestOSServiceIfaceMockRecorder) NewListOsCategoriesParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListOsCategoriesParams", reflect.TypeOf((*MockGuestOSServiceIface)(nil).NewListOsCategoriesParams))
}

// NewListOsTypesParams mocks base method.
func (m *MockGuestOSServiceIface) NewListOsTypesParams() *ListOsTypesParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListOsTypesParams")
	ret0, _ := ret[0].(*ListOsTypesParams)
	return ret0
}

// NewListOsTypesParams indicates an expected call of NewListOsTypesParams.
func (mr *MockGuestOSServiceIfaceMockRecorder) NewListOsTypesParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListOsTypesParams", reflect.TypeOf((*MockGuestOSServiceIface)(nil).NewListOsTypesParams))
}

// NewRemoveGuestOsMappingParams mocks base method.
func (m *MockGuestOSServiceIface) NewRemoveGuestOsMappingParams(id string) *RemoveGuestOsMappingParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewRemoveGuestOsMappingParams", id)
	ret0, _ := ret[0].(*RemoveGuestOsMappingParams)
	return ret0
}

// NewRemoveGuestOsMappingParams indicates an expected call of NewRemoveGuestOsMappingParams.
func (mr *MockGuestOSServiceIfaceMockRecorder) NewRemoveGuestOsMappingParams(id interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewRemoveGuestOsMappingParams", reflect.TypeOf((*MockGuestOSServiceIface)(nil).NewRemoveGuestOsMappingParams), id)
}

// NewRemoveGuestOsParams mocks base method.
func (m *MockGuestOSServiceIface) NewRemoveGuestOsParams(id string) *RemoveGuestOsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewRemoveGuestOsParams", id)
	ret0, _ := ret[0].(*RemoveGuestOsParams)
	return ret0
}

// NewRemoveGuestOsParams indicates an expected call of NewRemoveGuestOsParams.
func (mr *MockGuestOSServiceIfaceMockRecorder) NewRemoveGuestOsParams(id interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewRemoveGuestOsParams", reflect.TypeOf((*MockGuestOSServiceIface)(nil).NewRemoveGuestOsParams), id)
}

// NewUpdateGuestOsMappingParams mocks base method.
func (m *MockGuestOSServiceIface) NewUpdateGuestOsMappingParams(id, osnameforhypervisor string) *UpdateGuestOsMappingParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUpdateGuestOsMappingParams", id, osnameforhypervisor)
	ret0, _ := ret[0].(*UpdateGuestOsMappingParams)
	return ret0
}

// NewUpdateGuestOsMappingParams indicates an expected call of NewUpdateGuestOsMappingParams.
func (mr *MockGuestOSServiceIfaceMockRecorder) NewUpdateGuestOsMappingParams(id, osnameforhypervisor interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateGuestOsMappingParams", reflect.TypeOf((*MockGuestOSServiceIface)(nil).NewUpdateGuestOsMappingParams), id, osnameforhypervisor)
}

// NewUpdateGuestOsParams mocks base method.
func (m *MockGuestOSServiceIface) NewUpdateGuestOsParams(id, osdisplayname string) *UpdateGuestOsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUpdateGuestOsParams", id, osdisplayname)
	ret0, _ := ret[0].(*UpdateGuestOsParams)
	return ret0
}

// NewUpdateGuestOsParams indicates an expected call of NewUpdateGuestOsParams.
func (mr *MockGuestOSServiceIfaceMockRecorder) NewUpdateGuestOsParams(id, osdisplayname interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateGuestOsParams", reflect.TypeOf((*MockGuestOSServiceIface)(nil).NewUpdateGuestOsParams), id, osdisplayname)
}

// RemoveGuestOs mocks base method.
func (m *MockGuestOSServiceIface) RemoveGuestOs(p *RemoveGuestOsParams) (*RemoveGuestOsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "RemoveGuestOs", p)
	ret0, _ := ret[0].(*RemoveGuestOsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// RemoveGuestOs indicates an expected call of RemoveGuestOs.
func (mr *MockGuestOSServiceIfaceMockRecorder) RemoveGuestOs(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveGuestOs", reflect.TypeOf((*MockGuestOSServiceIface)(nil).RemoveGuestOs), p)
}

// RemoveGuestOsMapping mocks base method.
func (m *MockGuestOSServiceIface) RemoveGuestOsMapping(p *RemoveGuestOsMappingParams) (*RemoveGuestOsMappingResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "RemoveGuestOsMapping", p)
	ret0, _ := ret[0].(*RemoveGuestOsMappingResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// RemoveGuestOsMapping indicates an expected call of RemoveGuestOsMapping.
func (mr *MockGuestOSServiceIfaceMockRecorder) RemoveGuestOsMapping(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveGuestOsMapping", reflect.TypeOf((*MockGuestOSServiceIface)(nil).RemoveGuestOsMapping), p)
}

// UpdateGuestOs mocks base method.
func (m *MockGuestOSServiceIface) UpdateGuestOs(p *UpdateGuestOsParams) (*UpdateGuestOsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateGuestOs", p)
	ret0, _ := ret[0].(*UpdateGuestOsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateGuestOs indicates an expected call of UpdateGuestOs.
func (mr *MockGuestOSServiceIfaceMockRecorder) UpdateGuestOs(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateGuestOs", reflect.TypeOf((*MockGuestOSServiceIface)(nil).UpdateGuestOs), p)
}

// UpdateGuestOsMapping mocks base method.
func (m *MockGuestOSServiceIface) UpdateGuestOsMapping(p *UpdateGuestOsMappingParams) (*UpdateGuestOsMappingResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateGuestOsMapping", p)
	ret0, _ := ret[0].(*UpdateGuestOsMappingResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateGuestOsMapping indicates an expected call of UpdateGuestOsMapping.
func (mr *MockGuestOSServiceIfaceMockRecorder) UpdateGuestOsMapping(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateGuestOsMapping", reflect.TypeOf((*MockGuestOSServiceIface)(nil).UpdateGuestOsMapping), p)
}
