github.com/thiagoyeds/go-cloud@v0.26.0/runtimevar/constantvar/constantvar_test.go (about)

     1  // Copyright 2018 The Go Cloud Development Kit Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     https://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package constantvar
    16  
    17  import (
    18  	"context"
    19  	"errors"
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/google/go-cmp/cmp"
    24  	"gocloud.dev/runtimevar"
    25  	"gocloud.dev/runtimevar/driver"
    26  	"gocloud.dev/runtimevar/drivertest"
    27  )
    28  
    29  type harness struct {
    30  	// vars stores the variable value(s) that have been set using CreateVariable.
    31  	vars map[string][]byte
    32  }
    33  
    34  func newHarness(t *testing.T) (drivertest.Harness, error) {
    35  	return &harness{vars: map[string][]byte{}}, nil
    36  }
    37  
    38  func (h *harness) MakeWatcher(ctx context.Context, name string, decoder *runtimevar.Decoder) (driver.Watcher, error) {
    39  	rawVal, found := h.vars[name]
    40  	if !found {
    41  		// The variable isn't set. Create a Variable that always returns an error.
    42  		return &watcher{err: errNotExist}, nil
    43  	}
    44  	val, err := decoder.Decode(ctx, rawVal)
    45  	if err != nil {
    46  		// The variable didn't decode.
    47  		return &watcher{err: err}, nil
    48  	}
    49  	return &watcher{value: val, t: time.Now()}, nil
    50  }
    51  
    52  func (h *harness) CreateVariable(ctx context.Context, name string, val []byte) error {
    53  	h.vars[name] = val
    54  	return nil
    55  }
    56  
    57  func (h *harness) UpdateVariable(ctx context.Context, name string, val []byte) error {
    58  	return errors.New("not supported")
    59  }
    60  
    61  func (h *harness) DeleteVariable(ctx context.Context, name string) error {
    62  	return errors.New("not supported")
    63  }
    64  
    65  func (h *harness) Close() {}
    66  
    67  func (h *harness) Mutable() bool { return false }
    68  
    69  func TestConformance(t *testing.T) {
    70  	drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}})
    71  }
    72  
    73  type verifyAs struct{}
    74  
    75  func (verifyAs) Name() string {
    76  	return "verify As"
    77  }
    78  
    79  func (verifyAs) SnapshotCheck(s *runtimevar.Snapshot) error {
    80  	var ss string
    81  	if s.As(&ss) {
    82  		return errors.New("Snapshot.As expected to fail")
    83  	}
    84  	return nil
    85  }
    86  
    87  func (verifyAs) ErrorCheck(v *runtimevar.Variable, err error) error {
    88  	var ss string
    89  	if v.ErrorAs(err, &ss) {
    90  		return errors.New("runtimevar.ErrorAs expected to fail")
    91  	}
    92  	return nil
    93  }
    94  
    95  func TestNew(t *testing.T) {
    96  	ctx := context.Background()
    97  
    98  	// Use New with an error value; it should be plumbed through as a Value.
    99  	errFail := errors.New("fail")
   100  	v := New(errFail)
   101  	defer v.Close()
   102  	val, err := v.Watch(ctx)
   103  	if err != nil {
   104  		t.Fatal(err)
   105  	}
   106  	if val.Value != errFail {
   107  		t.Errorf("got %v want %v", val.Value, errFail)
   108  	}
   109  }
   110  
   111  func TestNewBytes(t *testing.T) {
   112  	ctx := context.Background()
   113  	content := "hello world"
   114  
   115  	// Decode succeeds.
   116  	v := NewBytes([]byte(content), runtimevar.StringDecoder)
   117  	defer v.Close()
   118  	val, err := v.Watch(ctx)
   119  	if err != nil {
   120  		t.Fatal(err)
   121  	}
   122  	if val.Value != content {
   123  		t.Errorf("got %v want %v", val.Value, content)
   124  	}
   125  
   126  	// Decode fails.
   127  	var jsonData []string
   128  	v = NewBytes([]byte(content), runtimevar.NewDecoder(jsonData, runtimevar.JSONDecode))
   129  	defer v.Close()
   130  	val, err = v.Watch(ctx)
   131  	if err == nil {
   132  		t.Errorf("got nil error and %v, want error", val)
   133  	}
   134  }
   135  
   136  func TestNewError(t *testing.T) {
   137  	ctx := context.Background()
   138  
   139  	v := NewError(errors.New("fail"))
   140  	defer v.Close()
   141  	_, err := v.Watch(ctx)
   142  	if err == nil {
   143  		t.Errorf("got nil err want fail err")
   144  	}
   145  }
   146  
   147  func TestOpenVariable(t *testing.T) {
   148  	tests := []struct {
   149  		URL          string
   150  		WantErr      bool
   151  		WantWatchErr bool
   152  		Want         interface{}
   153  	}{
   154  		// Empty URL results in empty byte slice.
   155  		{"constant://", false, false, []byte("")},
   156  		// Invalid query param.
   157  		{"constant://?param=value", true, false, nil},
   158  		// String value.
   159  		{"constant://?val=hello+world&decoder=string", false, false, "hello world"},
   160  		// JSON value; val parameter is {"Foo": "Bar"}, URL-encoded.
   161  		{"constant://?val=%7B%22Foo%22%3A%22Bar%22%7d&decoder=jsonmap", false, false, &map[string]interface{}{"Foo": "Bar"}},
   162  		// Error.
   163  		{"constant://?err=fail", false, true, nil},
   164  		// Invalid decoder.
   165  		{"constant://?decoder=notadecoder", true, false, nil},
   166  	}
   167  
   168  	ctx := context.Background()
   169  	for _, test := range tests {
   170  		t.Run(test.URL, func(t *testing.T) {
   171  			v, err := runtimevar.OpenVariable(ctx, test.URL)
   172  			if (err != nil) != test.WantErr {
   173  				t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr)
   174  			}
   175  			if err != nil {
   176  				return
   177  			}
   178  			defer v.Close()
   179  			snapshot, err := v.Watch(ctx)
   180  			if (err != nil) != test.WantWatchErr {
   181  				t.Errorf("%s: got Watch error %v, want error %v", test.URL, err, test.WantWatchErr)
   182  			}
   183  			if err != nil {
   184  				return
   185  			}
   186  			if !cmp.Equal(snapshot.Value, test.Want) {
   187  				t.Errorf("%s: got snapshot value\n%v\n  want\n%v", test.URL, snapshot.Value, test.Want)
   188  			}
   189  		})
   190  	}
   191  }
   192  
   193  func TestDecryptWithNoURLEnv(t *testing.T) {
   194  	if _, err := runtimevar.OpenVariable(context.Background(), "constant://?decoder=decrypt"); err == nil {
   195  		t.Error("got nil error, want environment variable not set")
   196  	}
   197  }