1 // Copyright 2019 Google Inc. All rights reserved. 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 android 16 17 import ( 18 "testing" 19 "time" 20 ) 21 22 func TestOncePer_Once(t *testing.T) { 23 once := OncePer{} 24 key := NewOnceKey("key") 25 26 a := once.Once(key, func() interface{} { return "a" }).(string) 27 b := once.Once(key, func() interface{} { return "b" }).(string) 28 29 if a != "a" { 30 t.Errorf(`first call to Once should return "a": %q`, a) 31 } 32 33 if b != "a" { 34 t.Errorf(`second call to Once with the same key should return "a": %q`, b) 35 } 36 } 37 38 func TestOncePer_Once_wait(t *testing.T) { 39 once := OncePer{} 40 key := NewOnceKey("key") 41 42 ch := make(chan bool) 43 44 go once.Once(key, func() interface{} { close(ch); time.Sleep(100 * time.Millisecond); return "foo" }) 45 <-ch 46 a := once.Once(key, func() interface{} { return "bar" }).(string) 47 48 if a != "foo" { 49 t.Errorf("expect %q, got %q", "foo", a) 50 } 51 } 52 53 func TestOncePer_Get(t *testing.T) { 54 once := OncePer{} 55 key := NewOnceKey("key") 56 57 a := once.Once(key, func() interface{} { return "a" }).(string) 58 b := once.Get(key).(string) 59 60 if a != "a" { 61 t.Errorf(`first call to Once should return "a": %q`, a) 62 } 63 64 if b != "a" { 65 t.Errorf(`Get with the same key should return "a": %q`, b) 66 } 67 } 68 69 func TestOncePer_Get_panic(t *testing.T) { 70 once := OncePer{} 71 key := NewOnceKey("key") 72 73 defer func() { 74 p := recover() 75 76 if p == nil { 77 t.Error("call to Get for unused key should panic") 78 } 79 }() 80 81 once.Get(key) 82 } 83 84 func TestOncePer_Get_wait(t *testing.T) { 85 once := OncePer{} 86 key := NewOnceKey("key") 87 88 ch := make(chan bool) 89 90 go once.Once(key, func() interface{} { close(ch); time.Sleep(100 * time.Millisecond); return "foo" }) 91 <-ch 92 a := once.Get(key).(string) 93 94 if a != "foo" { 95 t.Errorf("expect %q, got %q", "foo", a) 96 } 97 } 98 99 func TestOncePer_OnceStringSlice(t *testing.T) { 100 once := OncePer{} 101 key := NewOnceKey("key") 102 103 a := once.OnceStringSlice(key, func() []string { return []string{"a"} }) 104 b := once.OnceStringSlice(key, func() []string { return []string{"a"} }) 105 106 if a[0] != "a" { 107 t.Errorf(`first call to OnceStringSlice should return ["a"]: %q`, a) 108 } 109 110 if b[0] != "a" { 111 t.Errorf(`second call to OnceStringSlice with the same key should return ["a"]: %q`, b) 112 } 113 } 114 115 func TestOncePer_Once2StringSlice(t *testing.T) { 116 once := OncePer{} 117 key := NewOnceKey("key") 118 119 a, b := once.Once2StringSlice(key, func() ([]string, []string) { return []string{"a"}, []string{"b"} }) 120 c, d := once.Once2StringSlice(key, func() ([]string, []string) { return []string{"c"}, []string{"d"} }) 121 122 if a[0] != "a" || b[0] != "b" { 123 t.Errorf(`first call to Once2StringSlice should return ["a"], ["b"]: %q, %q`, a, b) 124 } 125 126 if c[0] != "a" || d[0] != "b" { 127 t.Errorf(`second call to Once2StringSlice with the same key should return ["a"], ["b"]: %q, %q`, c, d) 128 } 129 } 130 131 func TestNewOnceKey(t *testing.T) { 132 once := OncePer{} 133 key1 := NewOnceKey("key") 134 key2 := NewOnceKey("key") 135 136 a := once.Once(key1, func() interface{} { return "a" }).(string) 137 b := once.Once(key2, func() interface{} { return "b" }).(string) 138 139 if a != "a" { 140 t.Errorf(`first call to Once should return "a": %q`, a) 141 } 142 143 if b != "b" { 144 t.Errorf(`second call to Once with the NewOnceKey from same string should return "b": %q`, b) 145 } 146 } 147 148 func TestNewCustomOnceKey(t *testing.T) { 149 type key struct { 150 key string 151 } 152 once := OncePer{} 153 key1 := NewCustomOnceKey(key{"key"}) 154 key2 := NewCustomOnceKey(key{"key"}) 155 156 a := once.Once(key1, func() interface{} { return "a" }).(string) 157 b := once.Once(key2, func() interface{} { return "b" }).(string) 158 159 if a != "a" { 160 t.Errorf(`first call to Once should return "a": %q`, a) 161 } 162 163 if b != "a" { 164 t.Errorf(`second call to Once with the NewCustomOnceKey from equal key should return "a": %q`, b) 165 } 166 } 167 168 func TestOncePerReentrant(t *testing.T) { 169 once := OncePer{} 170 key1 := NewOnceKey("key") 171 key2 := NewOnceKey("key") 172 173 a := once.Once(key1, func() interface{} { return once.Once(key2, func() interface{} { return "a" }) }) 174 if a != "a" { 175 t.Errorf(`reentrant Once should return "a": %q`, a) 176 } 177 } 178