github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ccl/baseccl/encryption_spec_test.go (about)

     1  // Copyright 2017 The Cockroach Authors.
     2  //
     3  // Licensed as a CockroachDB Enterprise file under the Cockroach Community
     4  // License (the "License"); you may not use this file except in compliance with
     5  // the License. You may obtain a copy of the License at
     6  //
     7  //     https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt
     8  
     9  package baseccl
    10  
    11  import (
    12  	"fmt"
    13  	"reflect"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    18  )
    19  
    20  // TestNewStoreEncryptionSpec verifies that the --enterprise-encryption arguments are correctly parsed
    21  // into StoreEncryptionSpecs.
    22  func TestNewStoreEncryptionSpec(t *testing.T) {
    23  	defer leaktest.AfterTest(t)()
    24  
    25  	testCases := []struct {
    26  		value       string
    27  		expectedErr string
    28  		expected    StoreEncryptionSpec
    29  	}{
    30  		// path
    31  		{",", "no path specified", StoreEncryptionSpec{}},
    32  		{"", "no path specified", StoreEncryptionSpec{}},
    33  		{"/mnt/hda1", "field not in the form <key>=<value>: /mnt/hda1", StoreEncryptionSpec{}},
    34  		{"path=", "no value specified for path", StoreEncryptionSpec{}},
    35  		{"path=~/data", "path cannot start with '~': ~/data", StoreEncryptionSpec{}},
    36  		{"path=data,path=data2", "path field was used twice in encryption definition", StoreEncryptionSpec{}},
    37  
    38  		// The same logic applies to key and old-key, don't repeat everything.
    39  		{"path=data", "no key specified", StoreEncryptionSpec{}},
    40  		{"path=data,key=new.key", "no old-key specified", StoreEncryptionSpec{}},
    41  
    42  		// Rotation period.
    43  		{"path=data,key=new.key,old-key=old.key,rotation-period", "field not in the form <key>=<value>: rotation-period", StoreEncryptionSpec{}},
    44  		{"path=data,key=new.key,old-key=old.key,rotation-period=", "no value specified for rotation-period", StoreEncryptionSpec{}},
    45  		{"path=data,key=new.key,old-key=old.key,rotation-period=1", "could not parse rotation-duration value: 1: time: missing unit in duration 1", StoreEncryptionSpec{}},
    46  		{"path=data,key=new.key,old-key=old.key,rotation-period=1d", "could not parse rotation-duration value: 1d: time: unknown unit d in duration 1d", StoreEncryptionSpec{}},
    47  
    48  		// Good values.
    49  		{"path=/data,key=/new.key,old-key=/old.key", "", StoreEncryptionSpec{Path: "/data", KeyPath: "/new.key", OldKeyPath: "/old.key", RotationPeriod: DefaultRotationPeriod}},
    50  		{"path=/data,key=/new.key,old-key=/old.key,rotation-period=1h", "", StoreEncryptionSpec{Path: "/data", KeyPath: "/new.key", OldKeyPath: "/old.key", RotationPeriod: time.Hour}},
    51  		{"path=/data,key=plain,old-key=/old.key,rotation-period=1h", "", StoreEncryptionSpec{Path: "/data", KeyPath: "plain", OldKeyPath: "/old.key", RotationPeriod: time.Hour}},
    52  		{"path=/data,key=/new.key,old-key=plain,rotation-period=1h", "", StoreEncryptionSpec{Path: "/data", KeyPath: "/new.key", OldKeyPath: "plain", RotationPeriod: time.Hour}},
    53  	}
    54  
    55  	for i, testCase := range testCases {
    56  		storeEncryptionSpec, err := NewStoreEncryptionSpec(testCase.value)
    57  		if err != nil {
    58  			if len(testCase.expectedErr) == 0 {
    59  				t.Errorf("%d(%s): no expected error, got %s", i, testCase.value, err)
    60  			}
    61  			if testCase.expectedErr != fmt.Sprint(err) {
    62  				t.Errorf("%d(%s): expected error \"%s\" does not match actual \"%s\"", i, testCase.value,
    63  					testCase.expectedErr, err)
    64  			}
    65  			continue
    66  		}
    67  		if len(testCase.expectedErr) > 0 {
    68  			t.Errorf("%d(%s): expected error %s but there was none", i, testCase.value, testCase.expectedErr)
    69  			continue
    70  		}
    71  		if !reflect.DeepEqual(testCase.expected, storeEncryptionSpec) {
    72  			t.Errorf("%d(%s): actual doesn't match expected\nactual:   %+v\nexpected: %+v", i,
    73  				testCase.value, storeEncryptionSpec, testCase.expected)
    74  		}
    75  
    76  		// Now test String() to make sure the result can be parsed.
    77  		storeEncryptionSpecString := storeEncryptionSpec.String()
    78  		storeEncryptionSpec2, err := NewStoreEncryptionSpec(storeEncryptionSpecString)
    79  		if err != nil {
    80  			t.Errorf("%d(%s): error parsing String() result: %s", i, testCase.value, err)
    81  			continue
    82  		}
    83  		// Compare strings to deal with floats not matching exactly.
    84  		if !reflect.DeepEqual(storeEncryptionSpecString, storeEncryptionSpec2.String()) {
    85  			t.Errorf("%d(%s): actual doesn't match expected\nactual:   %#+v\nexpected: %#+v", i, testCase.value,
    86  				storeEncryptionSpec, storeEncryptionSpec2)
    87  		}
    88  	}
    89  }