// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Code generated by MockGen. DO NOT EDIT.
// Source: google.golang.org/genproto/googleapis/devtools/resultstore/v2 (interfaces: ResultStoreUploadClient)

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

import (
	context "context"
	reflect "reflect"

	gomock "github.com/golang/mock/gomock"
	v2 "google.golang.org/genproto/googleapis/devtools/resultstore/v2"
	grpc "google.golang.org/grpc"
)

// MockResultStoreUploadClient is a mock of ResultStoreUploadClient interface
type MockResultStoreUploadClient struct {
	ctrl     *gomock.Controller
	recorder *MockResultStoreUploadClientMockRecorder
}

// MockResultStoreUploadClientMockRecorder is the mock recorder for MockResultStoreUploadClient
type MockResultStoreUploadClientMockRecorder struct {
	mock *MockResultStoreUploadClient
}

// NewMockResultStoreUploadClient creates a new mock instance
func NewMockResultStoreUploadClient(ctrl *gomock.Controller) *MockResultStoreUploadClient {
	mock := &MockResultStoreUploadClient{ctrl: ctrl}
	mock.recorder = &MockResultStoreUploadClientMockRecorder{mock}
	return mock
}

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

// CreateAction mocks base method
func (m *MockResultStoreUploadClient) CreateAction(arg0 context.Context, arg1 *v2.CreateActionRequest, arg2 ...grpc.CallOption) (*v2.Action, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "CreateAction", varargs...)
	ret0, _ := ret[0].(*v2.Action)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateAction indicates an expected call of CreateAction
func (mr *MockResultStoreUploadClientMockRecorder) CreateAction(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAction", reflect.TypeOf((*MockResultStoreUploadClient)(nil).CreateAction), varargs...)
}

// CreateConfiguration mocks base method
func (m *MockResultStoreUploadClient) CreateConfiguration(arg0 context.Context, arg1 *v2.CreateConfigurationRequest, arg2 ...grpc.CallOption) (*v2.Configuration, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "CreateConfiguration", varargs...)
	ret0, _ := ret[0].(*v2.Configuration)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateConfiguration indicates an expected call of CreateConfiguration
func (mr *MockResultStoreUploadClientMockRecorder) CreateConfiguration(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateConfiguration", reflect.TypeOf((*MockResultStoreUploadClient)(nil).CreateConfiguration), varargs...)
}

// CreateConfiguredTarget mocks base method
func (m *MockResultStoreUploadClient) CreateConfiguredTarget(arg0 context.Context, arg1 *v2.CreateConfiguredTargetRequest, arg2 ...grpc.CallOption) (*v2.ConfiguredTarget, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "CreateConfiguredTarget", varargs...)
	ret0, _ := ret[0].(*v2.ConfiguredTarget)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateConfiguredTarget indicates an expected call of CreateConfiguredTarget
func (mr *MockResultStoreUploadClientMockRecorder) CreateConfiguredTarget(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateConfiguredTarget", reflect.TypeOf((*MockResultStoreUploadClient)(nil).CreateConfiguredTarget), varargs...)
}

// CreateFileSet mocks base method
func (m *MockResultStoreUploadClient) CreateFileSet(arg0 context.Context, arg1 *v2.CreateFileSetRequest, arg2 ...grpc.CallOption) (*v2.FileSet, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "CreateFileSet", varargs...)
	ret0, _ := ret[0].(*v2.FileSet)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateFileSet indicates an expected call of CreateFileSet
func (mr *MockResultStoreUploadClientMockRecorder) CreateFileSet(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateFileSet", reflect.TypeOf((*MockResultStoreUploadClient)(nil).CreateFileSet), varargs...)
}

// CreateInvocation mocks base method
func (m *MockResultStoreUploadClient) CreateInvocation(arg0 context.Context, arg1 *v2.CreateInvocationRequest, arg2 ...grpc.CallOption) (*v2.Invocation, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "CreateInvocation", varargs...)
	ret0, _ := ret[0].(*v2.Invocation)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateInvocation indicates an expected call of CreateInvocation
func (mr *MockResultStoreUploadClientMockRecorder) CreateInvocation(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateInvocation", reflect.TypeOf((*MockResultStoreUploadClient)(nil).CreateInvocation), varargs...)
}

// CreateTarget mocks base method
func (m *MockResultStoreUploadClient) CreateTarget(arg0 context.Context, arg1 *v2.CreateTargetRequest, arg2 ...grpc.CallOption) (*v2.Target, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "CreateTarget", varargs...)
	ret0, _ := ret[0].(*v2.Target)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateTarget indicates an expected call of CreateTarget
func (mr *MockResultStoreUploadClientMockRecorder) CreateTarget(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTarget", reflect.TypeOf((*MockResultStoreUploadClient)(nil).CreateTarget), varargs...)
}

// FinishConfiguredTarget mocks base method
func (m *MockResultStoreUploadClient) FinishConfiguredTarget(arg0 context.Context, arg1 *v2.FinishConfiguredTargetRequest, arg2 ...grpc.CallOption) (*v2.FinishConfiguredTargetResponse, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "FinishConfiguredTarget", varargs...)
	ret0, _ := ret[0].(*v2.FinishConfiguredTargetResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// FinishConfiguredTarget indicates an expected call of FinishConfiguredTarget
func (mr *MockResultStoreUploadClientMockRecorder) FinishConfiguredTarget(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FinishConfiguredTarget", reflect.TypeOf((*MockResultStoreUploadClient)(nil).FinishConfiguredTarget), varargs...)
}

// FinishInvocation mocks base method
func (m *MockResultStoreUploadClient) FinishInvocation(arg0 context.Context, arg1 *v2.FinishInvocationRequest, arg2 ...grpc.CallOption) (*v2.FinishInvocationResponse, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "FinishInvocation", varargs...)
	ret0, _ := ret[0].(*v2.FinishInvocationResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// FinishInvocation indicates an expected call of FinishInvocation
func (mr *MockResultStoreUploadClientMockRecorder) FinishInvocation(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FinishInvocation", reflect.TypeOf((*MockResultStoreUploadClient)(nil).FinishInvocation), varargs...)
}

// FinishTarget mocks base method
func (m *MockResultStoreUploadClient) FinishTarget(arg0 context.Context, arg1 *v2.FinishTargetRequest, arg2 ...grpc.CallOption) (*v2.FinishTargetResponse, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "FinishTarget", varargs...)
	ret0, _ := ret[0].(*v2.FinishTargetResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// FinishTarget indicates an expected call of FinishTarget
func (mr *MockResultStoreUploadClientMockRecorder) FinishTarget(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FinishTarget", reflect.TypeOf((*MockResultStoreUploadClient)(nil).FinishTarget), varargs...)
}

// UpdateAction mocks base method
func (m *MockResultStoreUploadClient) UpdateAction(arg0 context.Context, arg1 *v2.UpdateActionRequest, arg2 ...grpc.CallOption) (*v2.Action, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "UpdateAction", varargs...)
	ret0, _ := ret[0].(*v2.Action)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateAction indicates an expected call of UpdateAction
func (mr *MockResultStoreUploadClientMockRecorder) UpdateAction(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAction", reflect.TypeOf((*MockResultStoreUploadClient)(nil).UpdateAction), varargs...)
}

// UpdateConfiguration mocks base method
func (m *MockResultStoreUploadClient) UpdateConfiguration(arg0 context.Context, arg1 *v2.UpdateConfigurationRequest, arg2 ...grpc.CallOption) (*v2.Configuration, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "UpdateConfiguration", varargs...)
	ret0, _ := ret[0].(*v2.Configuration)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateConfiguration indicates an expected call of UpdateConfiguration
func (mr *MockResultStoreUploadClientMockRecorder) UpdateConfiguration(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateConfiguration", reflect.TypeOf((*MockResultStoreUploadClient)(nil).UpdateConfiguration), varargs...)
}

// UpdateConfiguredTarget mocks base method
func (m *MockResultStoreUploadClient) UpdateConfiguredTarget(arg0 context.Context, arg1 *v2.UpdateConfiguredTargetRequest, arg2 ...grpc.CallOption) (*v2.ConfiguredTarget, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "UpdateConfiguredTarget", varargs...)
	ret0, _ := ret[0].(*v2.ConfiguredTarget)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateConfiguredTarget indicates an expected call of UpdateConfiguredTarget
func (mr *MockResultStoreUploadClientMockRecorder) UpdateConfiguredTarget(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateConfiguredTarget", reflect.TypeOf((*MockResultStoreUploadClient)(nil).UpdateConfiguredTarget), varargs...)
}

// UpdateFileSet mocks base method
func (m *MockResultStoreUploadClient) UpdateFileSet(arg0 context.Context, arg1 *v2.UpdateFileSetRequest, arg2 ...grpc.CallOption) (*v2.FileSet, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "UpdateFileSet", varargs...)
	ret0, _ := ret[0].(*v2.FileSet)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateFileSet indicates an expected call of UpdateFileSet
func (mr *MockResultStoreUploadClientMockRecorder) UpdateFileSet(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateFileSet", reflect.TypeOf((*MockResultStoreUploadClient)(nil).UpdateFileSet), varargs...)
}

// UpdateInvocation mocks base method
func (m *MockResultStoreUploadClient) UpdateInvocation(arg0 context.Context, arg1 *v2.UpdateInvocationRequest, arg2 ...grpc.CallOption) (*v2.Invocation, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "UpdateInvocation", varargs...)
	ret0, _ := ret[0].(*v2.Invocation)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateInvocation indicates an expected call of UpdateInvocation
func (mr *MockResultStoreUploadClientMockRecorder) UpdateInvocation(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateInvocation", reflect.TypeOf((*MockResultStoreUploadClient)(nil).UpdateInvocation), varargs...)
}

// UpdateTarget mocks base method
func (m *MockResultStoreUploadClient) UpdateTarget(arg0 context.Context, arg1 *v2.UpdateTargetRequest, arg2 ...grpc.CallOption) (*v2.Target, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{arg0, arg1}
	for _, a := range arg2 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "UpdateTarget", varargs...)
	ret0, _ := ret[0].(*v2.Target)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateTarget indicates an expected call of UpdateTarget
func (mr *MockResultStoreUploadClientMockRecorder) UpdateTarget(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{arg0, arg1}, arg2...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTarget", reflect.TypeOf((*MockResultStoreUploadClient)(nil).UpdateTarget), varargs...)
}
