// Code generated by protoc-gen-go-grpc. DO NOT EDIT.

package api

import (
	context "context"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
)

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7

// TestServiceClient is the client API for TestService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type TestServiceClient interface {
	// Run a build target's ebuild unit tests.
	BuildTargetUnitTest(ctx context.Context, in *BuildTargetUnitTestRequest, opts ...grpc.CallOption) (*BuildTargetUnitTestResponse, error)
	// Run the chromite unit tests.
	ChromiteUnitTest(ctx context.Context, in *ChromiteUnitTestRequest, opts ...grpc.CallOption) (*ChromiteUnitTestResponse, error)
	// Run Pytest in chromite.
	ChromitePytest(ctx context.Context, in *ChromitePytestRequest, opts ...grpc.CallOption) (*ChromitePytestResponse, error)
	// Run the cros-signing unit tests.
	CrosSigningTest(ctx context.Context, in *CrosSigningTestRequest, opts ...grpc.CallOption) (*CrosSigningTestResponse, error)
	// Run the debug info tests on a sysroot.
	DebugInfoTest(ctx context.Context, in *DebugInfoTestRequest, opts ...grpc.CallOption) (*DebugInfoTestResponse, error)
	// Run VM tests and report failures.
	VmTest(ctx context.Context, in *VmTestRequest, opts ...grpc.CallOption) (*VmTestResponse, error)
	// Run Moblab VM tests and report failures.
	MoblabVmTest(ctx context.Context, in *MoblabVmTestRequest, opts ...grpc.CallOption) (*MoblabVmTestResponse, error)
	// Run the Simple Chrome workflow unit tests.
	SimpleChromeWorkflowTest(ctx context.Context, in *SimpleChromeWorkflowTestRequest, opts ...grpc.CallOption) (*SimpleChromeWorkflowTestResponse, error)
}

type testServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewTestServiceClient(cc grpc.ClientConnInterface) TestServiceClient {
	return &testServiceClient{cc}
}

func (c *testServiceClient) BuildTargetUnitTest(ctx context.Context, in *BuildTargetUnitTestRequest, opts ...grpc.CallOption) (*BuildTargetUnitTestResponse, error) {
	out := new(BuildTargetUnitTestResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.TestService/BuildTargetUnitTest", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *testServiceClient) ChromiteUnitTest(ctx context.Context, in *ChromiteUnitTestRequest, opts ...grpc.CallOption) (*ChromiteUnitTestResponse, error) {
	out := new(ChromiteUnitTestResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.TestService/ChromiteUnitTest", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *testServiceClient) ChromitePytest(ctx context.Context, in *ChromitePytestRequest, opts ...grpc.CallOption) (*ChromitePytestResponse, error) {
	out := new(ChromitePytestResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.TestService/ChromitePytest", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *testServiceClient) CrosSigningTest(ctx context.Context, in *CrosSigningTestRequest, opts ...grpc.CallOption) (*CrosSigningTestResponse, error) {
	out := new(CrosSigningTestResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.TestService/CrosSigningTest", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *testServiceClient) DebugInfoTest(ctx context.Context, in *DebugInfoTestRequest, opts ...grpc.CallOption) (*DebugInfoTestResponse, error) {
	out := new(DebugInfoTestResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.TestService/DebugInfoTest", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *testServiceClient) VmTest(ctx context.Context, in *VmTestRequest, opts ...grpc.CallOption) (*VmTestResponse, error) {
	out := new(VmTestResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.TestService/VmTest", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *testServiceClient) MoblabVmTest(ctx context.Context, in *MoblabVmTestRequest, opts ...grpc.CallOption) (*MoblabVmTestResponse, error) {
	out := new(MoblabVmTestResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.TestService/MoblabVmTest", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *testServiceClient) SimpleChromeWorkflowTest(ctx context.Context, in *SimpleChromeWorkflowTestRequest, opts ...grpc.CallOption) (*SimpleChromeWorkflowTestResponse, error) {
	out := new(SimpleChromeWorkflowTestResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.TestService/SimpleChromeWorkflowTest", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// TestServiceServer is the server API for TestService service.
// All implementations must embed UnimplementedTestServiceServer
// for forward compatibility
type TestServiceServer interface {
	// Run a build target's ebuild unit tests.
	BuildTargetUnitTest(context.Context, *BuildTargetUnitTestRequest) (*BuildTargetUnitTestResponse, error)
	// Run the chromite unit tests.
	ChromiteUnitTest(context.Context, *ChromiteUnitTestRequest) (*ChromiteUnitTestResponse, error)
	// Run Pytest in chromite.
	ChromitePytest(context.Context, *ChromitePytestRequest) (*ChromitePytestResponse, error)
	// Run the cros-signing unit tests.
	CrosSigningTest(context.Context, *CrosSigningTestRequest) (*CrosSigningTestResponse, error)
	// Run the debug info tests on a sysroot.
	DebugInfoTest(context.Context, *DebugInfoTestRequest) (*DebugInfoTestResponse, error)
	// Run VM tests and report failures.
	VmTest(context.Context, *VmTestRequest) (*VmTestResponse, error)
	// Run Moblab VM tests and report failures.
	MoblabVmTest(context.Context, *MoblabVmTestRequest) (*MoblabVmTestResponse, error)
	// Run the Simple Chrome workflow unit tests.
	SimpleChromeWorkflowTest(context.Context, *SimpleChromeWorkflowTestRequest) (*SimpleChromeWorkflowTestResponse, error)
	mustEmbedUnimplementedTestServiceServer()
}

// UnimplementedTestServiceServer must be embedded to have forward compatible implementations.
type UnimplementedTestServiceServer struct {
}

func (UnimplementedTestServiceServer) BuildTargetUnitTest(context.Context, *BuildTargetUnitTestRequest) (*BuildTargetUnitTestResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method BuildTargetUnitTest not implemented")
}
func (UnimplementedTestServiceServer) ChromiteUnitTest(context.Context, *ChromiteUnitTestRequest) (*ChromiteUnitTestResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ChromiteUnitTest not implemented")
}
func (UnimplementedTestServiceServer) ChromitePytest(context.Context, *ChromitePytestRequest) (*ChromitePytestResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ChromitePytest not implemented")
}
func (UnimplementedTestServiceServer) CrosSigningTest(context.Context, *CrosSigningTestRequest) (*CrosSigningTestResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method CrosSigningTest not implemented")
}
func (UnimplementedTestServiceServer) DebugInfoTest(context.Context, *DebugInfoTestRequest) (*DebugInfoTestResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method DebugInfoTest not implemented")
}
func (UnimplementedTestServiceServer) VmTest(context.Context, *VmTestRequest) (*VmTestResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method VmTest not implemented")
}
func (UnimplementedTestServiceServer) MoblabVmTest(context.Context, *MoblabVmTestRequest) (*MoblabVmTestResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method MoblabVmTest not implemented")
}
func (UnimplementedTestServiceServer) SimpleChromeWorkflowTest(context.Context, *SimpleChromeWorkflowTestRequest) (*SimpleChromeWorkflowTestResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method SimpleChromeWorkflowTest not implemented")
}
func (UnimplementedTestServiceServer) mustEmbedUnimplementedTestServiceServer() {}

// UnsafeTestServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to TestServiceServer will
// result in compilation errors.
type UnsafeTestServiceServer interface {
	mustEmbedUnimplementedTestServiceServer()
}

func RegisterTestServiceServer(s grpc.ServiceRegistrar, srv TestServiceServer) {
	s.RegisterService(&TestService_ServiceDesc, srv)
}

func _TestService_BuildTargetUnitTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(BuildTargetUnitTestRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(TestServiceServer).BuildTargetUnitTest(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.TestService/BuildTargetUnitTest",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(TestServiceServer).BuildTargetUnitTest(ctx, req.(*BuildTargetUnitTestRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _TestService_ChromiteUnitTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ChromiteUnitTestRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(TestServiceServer).ChromiteUnitTest(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.TestService/ChromiteUnitTest",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(TestServiceServer).ChromiteUnitTest(ctx, req.(*ChromiteUnitTestRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _TestService_ChromitePytest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ChromitePytestRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(TestServiceServer).ChromitePytest(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.TestService/ChromitePytest",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(TestServiceServer).ChromitePytest(ctx, req.(*ChromitePytestRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _TestService_CrosSigningTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(CrosSigningTestRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(TestServiceServer).CrosSigningTest(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.TestService/CrosSigningTest",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(TestServiceServer).CrosSigningTest(ctx, req.(*CrosSigningTestRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _TestService_DebugInfoTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(DebugInfoTestRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(TestServiceServer).DebugInfoTest(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.TestService/DebugInfoTest",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(TestServiceServer).DebugInfoTest(ctx, req.(*DebugInfoTestRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _TestService_VmTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(VmTestRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(TestServiceServer).VmTest(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.TestService/VmTest",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(TestServiceServer).VmTest(ctx, req.(*VmTestRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _TestService_MoblabVmTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(MoblabVmTestRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(TestServiceServer).MoblabVmTest(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.TestService/MoblabVmTest",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(TestServiceServer).MoblabVmTest(ctx, req.(*MoblabVmTestRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _TestService_SimpleChromeWorkflowTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(SimpleChromeWorkflowTestRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(TestServiceServer).SimpleChromeWorkflowTest(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.TestService/SimpleChromeWorkflowTest",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(TestServiceServer).SimpleChromeWorkflowTest(ctx, req.(*SimpleChromeWorkflowTestRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// TestService_ServiceDesc is the grpc.ServiceDesc for TestService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var TestService_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "chromite.api.TestService",
	HandlerType: (*TestServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "BuildTargetUnitTest",
			Handler:    _TestService_BuildTargetUnitTest_Handler,
		},
		{
			MethodName: "ChromiteUnitTest",
			Handler:    _TestService_ChromiteUnitTest_Handler,
		},
		{
			MethodName: "ChromitePytest",
			Handler:    _TestService_ChromitePytest_Handler,
		},
		{
			MethodName: "CrosSigningTest",
			Handler:    _TestService_CrosSigningTest_Handler,
		},
		{
			MethodName: "DebugInfoTest",
			Handler:    _TestService_DebugInfoTest_Handler,
		},
		{
			MethodName: "VmTest",
			Handler:    _TestService_VmTest_Handler,
		},
		{
			MethodName: "MoblabVmTest",
			Handler:    _TestService_MoblabVmTest_Handler,
		},
		{
			MethodName: "SimpleChromeWorkflowTest",
			Handler:    _TestService_SimpleChromeWorkflowTest_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/test.proto",
}
