sweet/benchmarks/tile38: wait for command success

Starting in 1.26.1
(https://github.com/tidwall/tile38/commit/9e552c362975f66c0cff398a8b703e2dabb6a599),
Tile38 accepts connections before it is fully ready for data processing.
All commands return an error other than OUTPUT, PING, and ECHO until the
server is fully ready.

We need the server to be fully ready before starting the benchmark, so
add a check that a dummy command works before declaring the server
ready.

Our benchmark is still using 1.25.3, but this future-proofs us for when
we do upgrade.

For golang/go#53081.

Change-Id: I0f48196d105d90f3f8440871aa481192cb515bf1
Reviewed-on: https://go-review.googlesource.com/c/benchmarks/+/409794
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Michael Pratt <mpratt@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
diff --git a/sweet/benchmarks/tile38/main.go b/sweet/benchmarks/tile38/main.go
index 6dcca19..e0605bd 100644
--- a/sweet/benchmarks/tile38/main.go
+++ b/sweet/benchmarks/tile38/main.go
@@ -239,14 +239,30 @@
 		return nil, fmt.Errorf("failed to start server: %v", err)
 	}
 
+	testConnection := func() error {
+		c, err := redis.Dial("tcp", fmt.Sprintf("%s:%d", cfg.host, cfg.port))
+		if err != nil {
+			return err
+		}
+		defer c.Close()
+
+		// Starting in 1.26.1, Tile38 accepts connections before
+		// loading data, allowing commands OUTPUT, PING, and ECHO, but
+		// returning errors for all other commands until data finishes
+		// loading.
+		//
+		// We test a command that requires loaded data to ensure the
+		// server is truly ready.
+		_, err = c.Do("SERVER")
+		return err
+	}
+
 	// Poll until the server is ready to serve, up to 120 seconds.
 	var err error
 	start := time.Now()
 	for time.Now().Sub(start) < 120*time.Second {
-		var c redis.Conn
-		c, err = redis.Dial("tcp", fmt.Sprintf("%s:%d", cfg.host, cfg.port))
+		err = testConnection()
 		if err == nil {
-			c.Close()
 			return srvCmd, nil
 		}
 		time.Sleep(2 * time.Second)