//
// 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
//
// Generated by this command:
//
//	mockgen -destination=./cloudstack/GuestOSService_mock.go -package=cloudstack -copyright_file=header.txt -source=./cloudstack/GuestOSService.go
//

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

import (
	reflect "reflect"

	gomock "go.uber.org/mock/gomock"
)

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

// 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 any) *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 any) *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 := []any{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 any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{id}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGuestOsMappingByID", reflect.TypeOf((*MockGuestOSServiceIface)(nil).GetGuestOsMappingByID), varargs...)
}

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

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

// GetOsCategoryByID mocks base method.
func (m *MockGuestOSServiceIface) GetOsCategoryByID(id string, opts ...OptionFunc) (*OsCategory, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{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 any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{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 := []any{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 any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{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 := []any{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 any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{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 := []any{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 any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{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 := []any{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 any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{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 := []any{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 any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{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 any) *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 any) *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 any) *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 any) *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 any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddGuestOsParams", reflect.TypeOf((*MockGuestOSServiceIface)(nil).NewAddGuestOsParams), oscategoryid, osdisplayname)
}

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

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

// 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 any) *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 any) *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 any) *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 any) *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 any) *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 any) *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 any) *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 any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateGuestOsMapping", reflect.TypeOf((*MockGuestOSServiceIface)(nil).UpdateGuestOsMapping), p)
}
