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

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

import (
	reflect "reflect"

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

// MockInfrastructureUsageServiceIface is a mock of InfrastructureUsageServiceIface interface.
type MockInfrastructureUsageServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockInfrastructureUsageServiceIfaceMockRecorder
	isgomock struct{}
}

// MockInfrastructureUsageServiceIfaceMockRecorder is the mock recorder for MockInfrastructureUsageServiceIface.
type MockInfrastructureUsageServiceIfaceMockRecorder struct {
	mock *MockInfrastructureUsageServiceIface
}

// NewMockInfrastructureUsageServiceIface creates a new mock instance.
func NewMockInfrastructureUsageServiceIface(ctrl *gomock.Controller) *MockInfrastructureUsageServiceIface {
	mock := &MockInfrastructureUsageServiceIface{ctrl: ctrl}
	mock.recorder = &MockInfrastructureUsageServiceIfaceMockRecorder{mock}
	return mock
}

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

// ListDbMetrics mocks base method.
func (m *MockInfrastructureUsageServiceIface) ListDbMetrics(p *ListDbMetricsParams) (*ListDbMetricsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListDbMetrics", p)
	ret0, _ := ret[0].(*ListDbMetricsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

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