execute: validate that RTD can connect to grpc services

BUG=chromium:1149702
TEST=local runs

Change-Id: Iae89b5a48646aebec3f935d721684995e58f0f00
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/infra/tnull/+/2570326
Tested-by: Sean Abraham <seanabraham@chromium.org>
Reviewed-by: Prathmesh Prabhu <pprabhu@google.com>
Commit-Queue: Prathmesh Prabhu <pprabhu@google.com>
Auto-Submit: Sean Abraham <seanabraham@chromium.org>
diff --git a/src/tnull/cmd/execute.go b/src/tnull/cmd/execute.go
index fabcd95..184ba67 100644
--- a/src/tnull/cmd/execute.go
+++ b/src/tnull/cmd/execute.go
@@ -9,10 +9,14 @@
 	"fmt"
 	"io"
 	"io/ioutil"
+	"log"
 	"strings"
+	"time"
 
 	"tnull/driver"
 
+	"google.golang.org/grpc"
+
 	"github.com/golang/protobuf/jsonpb"
 	"github.com/golang/protobuf/proto"
 	"github.com/maruel/subcommands"
@@ -60,6 +64,10 @@
 		return fmt.Errorf("no requests Invocation")
 	}
 
+	if err := validateGrpcServers(ctx, inv); err != nil {
+		return err
+	}
+
 	lookup, err := extractTestsFromSpecification()
 	if err != nil {
 		return err
@@ -155,6 +163,21 @@
 	return nil
 }
 
+func validateGrpcServers(ctx context.Context, inv rtd.Invocation) error {
+	dialContext, cancel := context.WithTimeout(ctx, time.Second*2)
+	defer cancel()
+	psAddr := fmt.Sprintf(":%d", inv.GetProgressSinkClientConfig().GetPort())
+	if _, err := grpc.DialContext(dialContext, psAddr, grpc.WithInsecure(), grpc.WithBlock()); err != nil {
+		return fmt.Errorf("failed to connect to ProgressSinkService at %s: %w", psAddr, err)
+	}
+	tlsAddr := fmt.Sprintf("%s:%d", inv.GetTestLabServicesConfig().GetTlsAddress(), inv.GetTestLabServicesConfig().GetTlsPort())
+	if _, err := grpc.DialContext(dialContext, tlsAddr, grpc.WithInsecure(), grpc.WithBlock()); err != nil {
+		return fmt.Errorf("failed to connect to TlsCommonService at %s: %w", tlsAddr, err)
+	}
+	log.Printf("Validated that gRPC servers are running for ProgressSinkService and TlsService")
+	return nil
+}
+
 func (r *run) validateArgs() error {
 	if r.invocationPath == "" {
 		return fmt.Errorf("input_json must specify an rtd.Invocation")