open-match.dev/open-match@v1.8.1/examples/demo/updater/updater_test.go (about)

     1  // Copyright 2019 Google LLC
     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  //     http://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 updater
    16  
    17  import (
    18  	"context"
    19  	"encoding/json"
    20  	"strconv"
    21  	"sync"
    22  	"testing"
    23  )
    24  
    25  func TestUpdater(t *testing.T) {
    26  	ctx, cancel := context.WithCancel(context.Background())
    27  	defer cancel()
    28  
    29  	latest := make(chan string)
    30  
    31  	base := New(ctx, func(b []byte) {
    32  		latest <- string(b)
    33  	})
    34  
    35  	l := <-latest
    36  	if l != "{}" {
    37  		t.Errorf("Got %s, expected %s", l, "{}")
    38  	}
    39  
    40  	child := NewNested(ctx, base.ForField("Foo"))
    41  
    42  	l = <-latest
    43  	if l != "{\"Foo\":{}}" {
    44  		t.Errorf("Got %s, expected %s", l, "{\"Foo\":{}}")
    45  	}
    46  
    47  	child.ForField("Bar")(interface{}((*int)(nil)))
    48  
    49  	l = <-latest
    50  	if l != "{\"Foo\":{\"Bar\":null}}" {
    51  		t.Errorf("Got %s, expected %s", l, "{\"Foo\":{\"Bar\":null}}")
    52  	}
    53  
    54  	child.ForField("Bar")(nil)
    55  
    56  	l = <-latest
    57  	if l != "{\"Foo\":{}}" {
    58  		t.Errorf("Got %s, expected %s", l, "{\"Foo\":{}}")
    59  	}
    60  }
    61  
    62  // Fully testing the updater's logic is difficult because it combines multiple
    63  // calls.  This test method creates 100 different go routines all trying to
    64  // update a value to force the logic to be invoked.
    65  func TestUpdaterInternal(t *testing.T) {
    66  	ctx, cancel := context.WithCancel(context.Background())
    67  
    68  	var wg sync.WaitGroup
    69  	wg.Add(100)
    70  
    71  	go func() {
    72  		wg.Wait()
    73  		cancel()
    74  	}()
    75  
    76  	latest := ""
    77  
    78  	set := SetFunc(func(v interface{}) {
    79  		if v != nil {
    80  			latest = string(*forceMarshalJson(v))
    81  		}
    82  	})
    83  
    84  	u := create(ctx, set)
    85  
    86  	for i := 0; i < 100; i++ {
    87  		set := u.ForField(strconv.Itoa(i))
    88  		go func() {
    89  			set("Hi")
    90  			wg.Done()
    91  		}()
    92  	}
    93  
    94  	// Blocking call ensures that canceling the context will clean up the internal go routine.
    95  	u.start()
    96  
    97  	expectedMap := make(map[string]string)
    98  	for i := 0; i < 100; i++ {
    99  		expectedMap[strconv.Itoa(i)] = "Hi"
   100  	}
   101  	// Not using forceMashal because it by design hides errors, and is used in the
   102  	// code being tested.
   103  	expectedB, err := json.Marshal(expectedMap)
   104  	if err != nil {
   105  		t.Fatal(err)
   106  	}
   107  	expected := string(expectedB)
   108  
   109  	if latest != expected {
   110  		t.Errorf("latest value is wrong.  Expected '%s', got '%s'", expected, latest)
   111  	}
   112  }
   113  
   114  var marshalTests = []struct {
   115  	in  interface{}
   116  	out string
   117  }{
   118  	{map[string]int{"hi": 1}, "{\"hi\":1}"},
   119  	{make(chan int), "{\"Error\":\"json: unsupported type: chan int\"}"},
   120  }
   121  
   122  func TestForceMarshalJson(t *testing.T) {
   123  	for _, tt := range marshalTests {
   124  		t.Run(tt.out, func(t *testing.T) {
   125  			s := string(*forceMarshalJson(tt.in))
   126  			if s != tt.out {
   127  				t.Errorf("got %s, want %s", s, tt.out)
   128  			}
   129  		})
   130  	}
   131  }