// 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"
	gomock "github.com/golang/mock/gomock"
	v2 "google.golang.org/genproto/googleapis/devtools/resultstore/v2"
	grpc "google.golang.org/grpc"
	reflect "reflect"
)

// 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...)
}
