You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: redis_test.go
    path of file: ./repos/tegola/cache/redis
    
    the code of the file until where you have to start completion: package redis_test

import (
	"crypto/tls"
	"net"
	"os"
	"reflect"
	"syscall"
	"testing"

	goredis "github.com/go-redis/redis"
	"github.com/go-spatial/tegola/cache"
	"github.com/go-spatial/tegola/cache/redis"
	"github.com/go-spatial/tegola/dict"
	"github.com/go-spatial/tegola/internal/ttools"
)

// TESTENV is the environment variable that must be set to "yes" to run the redis tests.
const TESTENV = "RUN_REDIS_TESTS"

func TestCreateOptions(t *testing.T) {
	ttools.ShouldSkip(t, TESTENV)

	type tcase struct {
		name        string
		config      dict.Dict
		expected    *goredis.Options
		expectedErr error
	}

	fn := func(tc tcase) func(*testing.T) {
		return func(t *testing.T) {
			t.Parallel()

			actual, err := redis.CreateOptions(tc.config)
			if tc.expectedErr == nil && err != nil {
				t.Fatalf("unexpected error: %q", err)
				return
			}
			if tc.expectedErr != nil && err != nil {
				if reflect.TypeOf(err) != reflect.TypeOf(tc.expectedErr) {
					t.Errorf("invalid error type. expected %T, got %T", tc.expectedErr, err)
					return
				}
				return
			}
			compareOptions(t, actual, tc.expected)
		}
	}

	tests := map[string]tcase{
		"test complete config": {
			config: map[string]interface{}{
				"network":  "tcp",
				"address":  "127.0.0.1:6379",
				"password": "test",
				"db":       0,
				"max_zoom": uint(10),
				"ssl":      false,
			},
			expected: &goredis.Options{
				Network:  "tcp",
				DB:       0,
				Addr:     "127.0.0.1:6379",
				Password: "test",
			},
		},
		"test empty config": {
			config: map[string]interface{}{},
			expected: &goredis.Options{
				Network:  "tcp",
				DB:       0,
				Addr:     "127.0.0.1:6379",
				Password: "",
			},
		},
		"test ssl config": {
			name: "test test ssl config",
			config: map[string]interface{}{
				"network":  "tcp",
				"address":  "127.0.0.1:6379",
				"password": "test",
				"db":       0,
				"max_zoom": uint(10),
				"ssl":      true,
			},
			expected: &goredis.Options{
				Network:   "tcp",
				DB:        0,
				Addr:      "127.0.0.1:6379",
				Password:  "test",
				TLSConfig: &tls.Config{ /* no deep comparison */ },
    
func TestNew(t *testing.T) {
	ttools.ShouldSkip(t, TESTENV)

	type tcase struct {
		config      dict.Dict
		expectedErr error
	}

	fn := func(tc tcase) func(*testing.T) {
		return func(t *testing.T) {
			t.Parallel()

			_, err := redis.New(tc.config)
			if tc.expectedErr != nil {
				if err == nil {
					t.Errorf("expected err %v, got nil", tc.expectedErr.Error())
					return
				}

				// check error types
				if reflect.TypeOf(err) != reflect.TypeOf(tc.expectedErr) {
					t.Errorf("invalid error type. expected %T, got %T", tc.expectedErr, err)
					return
				}

				switch e := err.(type) {
				case *net.OpError:
					expectedErr := tc.expectedErr.(*net.OpError)

					if reflect.TypeOf(e.Err) != reflect.TypeOf(expectedErr.Err) {
						t.Errorf("invalid error type. expected %T, got %T", expectedErr.Err, e.Err)
						return
					}
				default:
					// check error messages
					if err.Error() != tc.expectedErr.Error() {
						t.Errorf("invalid error. expected %v, got %v", tc.expectedErr, err.Error())
						return
					}
				}

				return
			}
			if err != nil {
				t.Errorf("unexpected err: %v", err)
				return
			}
		}
	}

	tests := map[string]tcase{
		"explicit config": {
			config: map[string]interface{}{
				"network":  "tcp",
				"address":  "127.0.0.1:6379",
				"password": "",
				"db":       0,
				"max_zoom": uint(10),
				"ssl":      false,
			},
		},
		"implicit config": {
			config: map[string]interface{}{},
		},
		"bad config address": {
			config: map[string]interface{}{"address": 0},
			expectedErr: dict.ErrKeyType{
				Key:   "address",
				Value: 0,
				T:     reflect.TypeOf(""),
			},
		},
		"bad config ttl": {
			config: map[string]interface{}{"ttl": "fails"},
			expectedErr: dict.ErrKeyType{
				Key:   "ttl",
				Value: "fails",
				T:     reflect.TypeOf(1),
			},
		},
		"bad address": {
			config: map[string]interface{}{
				"address": "127.0.0.1:6000",
			},
			expectedErr: &net.OpError{
				Op:  "dial",
				Net: "tcp",
				Addr: &net.TCPAddr{
					IP:   net.ParseIP("127.0.0.1"),
					Port: 6000,
				},
				Err: &os.SyscallError{
					Err: syscall.ECONNREFUSED,
				},
			},
		},
		"bad max_zoom": {
			config: map[string]interface{}{
				"max_zoom": "2",
			},
			expectedErr: dict.ErrKeyType{
				Key:   "max_zoom",
				Value: "2",
				T:     reflect.TypeOf(uint(0)),
			},
		},
		"bad max_zoom 2": {
			config: map[string]interface{}{
				"max_zoom": -2,
			},
			expectedErr: dict.ErrKeyType{
				Key:   "max_zoom",
				Value: -2,
				T:     reflect.TypeOf(uint(0)),
			},
		},
	}

	for name, tc := range tests {
		t.Run(name, fn(tc))
	}
}