1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
21 // RemoveAll removes all exported variables.
22 // This is for tests only.
25 defer varKeysMu
.Unlock()
26 for _
, k
:= range varKeys
{
32 func TestNil(t
*testing
.T
) {
36 t
.Errorf("got %v, want nil", val
)
40 func TestInt(t
*testing
.T
) {
42 reqs
:= NewInt("requests")
43 if i
:= reqs
.Value(); i
!= 0 {
44 t
.Errorf("reqs.Value() = %v, want 0", i
)
46 if reqs
!= Get("requests").(*Int
) {
47 t
.Errorf("Get() failed.")
52 if i
:= reqs
.Value(); i
!= 4 {
53 t
.Errorf("reqs.Value() = %v, want 4", i
)
56 if s
:= reqs
.String(); s
!= "4" {
57 t
.Errorf("reqs.String() = %q, want \"4\"", s
)
61 if i
:= reqs
.Value(); i
!= -2 {
62 t
.Errorf("reqs.Value() = %v, want -2", i
)
66 func BenchmarkIntAdd(b
*testing
.B
) {
69 b
.RunParallel(func(pb
*testing
.PB
) {
76 func BenchmarkIntSet(b
*testing
.B
) {
79 b
.RunParallel(func(pb
*testing
.PB
) {
86 func TestFloat(t
*testing
.T
) {
88 reqs
:= NewFloat("requests-float")
90 t
.Errorf("reqs.f = %v, want 0", reqs
.f
)
92 if reqs
!= Get("requests-float").(*Float
) {
93 t
.Errorf("Get() failed.")
98 if v
:= reqs
.Value(); v
!= 2.75 {
99 t
.Errorf("reqs.Value() = %v, want 2.75", v
)
102 if s
:= reqs
.String(); s
!= "2.75" {
103 t
.Errorf("reqs.String() = %q, want \"4.64\"", s
)
107 if v
:= reqs
.Value(); v
!= 0.75 {
108 t
.Errorf("reqs.Value() = %v, want 0.75", v
)
112 func BenchmarkFloatAdd(b
*testing
.B
) {
115 b
.RunParallel(func(pb
*testing
.PB
) {
122 func BenchmarkFloatSet(b
*testing
.B
) {
125 b
.RunParallel(func(pb
*testing
.PB
) {
132 func TestString(t
*testing
.T
) {
134 name
:= NewString("my-name")
135 if s
:= name
.Value(); s
!= "" {
136 t
.Errorf(`NewString("my-name").Value() = %q, want ""`, s
)
140 if s
, want
:= name
.String(), `"Mike"`; s
!= want
{
141 t
.Errorf(`after name.Set("Mike"), name.String() = %q, want %q`, s
, want
)
143 if s
, want
:= name
.Value(), "Mike"; s
!= want
{
144 t
.Errorf(`after name.Set("Mike"), name.Value() = %q, want %q`, s
, want
)
147 // Make sure we produce safe JSON output.
149 if s
, want
:= name
.String(), "\"\\u003c\""; s
!= want
{
150 t
.Errorf(`after name.Set("<"), name.String() = %q, want %q`, s
, want
)
154 func BenchmarkStringSet(b
*testing
.B
) {
157 b
.RunParallel(func(pb
*testing
.PB
) {
164 func TestMapInit(t
*testing
.T
) {
166 colors
:= NewMap("bike-shed-colors")
168 colors
.Add("blue", 1)
169 colors
.Add("chartreuse", 1)
172 colors
.Do(func(KeyValue
) { n
++ })
174 t
.Errorf("after three Add calls with distinct keys, Do should invoke f 3 times; got %v", n
)
180 colors
.Do(func(KeyValue
) { n
++ })
182 t
.Errorf("after Init, Do should invoke f 0 times; got %v", n
)
186 func TestMapCounter(t
*testing
.T
) {
188 colors
:= NewMap("bike-shed-colors")
192 colors
.Add("blue", 4)
193 colors
.AddFloat(`green "midori"`, 4.125)
194 if x
:= colors
.Get("red").(*Int
).Value(); x
!= 3 {
195 t
.Errorf("colors.m[\"red\"] = %v, want 3", x
)
197 if x
:= colors
.Get("blue").(*Int
).Value(); x
!= 4 {
198 t
.Errorf("colors.m[\"blue\"] = %v, want 4", x
)
200 if x
:= colors
.Get(`green "midori"`).(*Float
).Value(); x
!= 4.125 {
201 t
.Errorf("colors.m[`green \"midori\"] = %v, want 4.125", x
)
204 // colors.String() should be '{"red":3, "blue":4}',
205 // though the order of red and blue could vary.
208 err
:= json
.Unmarshal([]byte(s
), &j
)
210 t
.Errorf("colors.String() isn't valid JSON: %v", err
)
212 m
, ok
:= j
.(map[string]interface{})
214 t
.Error("colors.String() didn't produce a map.")
217 x
, ok
:= red
.(float64)
219 t
.Error("red.Kind() is not a number.")
222 t
.Errorf("red = %v, want 3", x
)
226 func BenchmarkMapSet(b
*testing
.B
) {
231 b
.RunParallel(func(pb
*testing
.PB
) {
238 func BenchmarkMapSetDifferent(b
*testing
.B
) {
239 procKeys
:= make([][]string, runtime
.GOMAXPROCS(0))
240 for i
:= range procKeys
{
241 keys
:= make([]string, 4)
242 for j
:= range keys
{
243 keys
[j
] = fmt
.Sprint(i
, j
)
253 b
.RunParallel(func(pb
*testing
.PB
) {
254 i
:= int(atomic
.AddInt32(&n
, 1)-1) % len(procKeys
)
258 for _
, k
:= range keys
{
265 func BenchmarkMapSetString(b
*testing
.B
) {
271 b
.RunParallel(func(pb
*testing
.PB
) {
278 func BenchmarkMapAddSame(b
*testing
.B
) {
279 b
.RunParallel(func(pb
*testing
.PB
) {
290 func BenchmarkMapAddDifferent(b
*testing
.B
) {
291 procKeys
:= make([][]string, runtime
.GOMAXPROCS(0))
292 for i
:= range procKeys
{
293 keys
:= make([]string, 4)
294 for j
:= range keys
{
295 keys
[j
] = fmt
.Sprint(i
, j
)
303 b
.RunParallel(func(pb
*testing
.PB
) {
304 i
:= int(atomic
.AddInt32(&n
, 1)-1) % len(procKeys
)
309 for _
, k
:= range keys
{
316 func BenchmarkMapAddSameSteadyState(b
*testing
.B
) {
318 b
.RunParallel(func(pb
*testing
.PB
) {
325 func BenchmarkMapAddDifferentSteadyState(b
*testing
.B
) {
326 procKeys
:= make([][]string, runtime
.GOMAXPROCS(0))
327 for i
:= range procKeys
{
328 keys
:= make([]string, 4)
329 for j
:= range keys
{
330 keys
[j
] = fmt
.Sprint(i
, j
)
339 b
.RunParallel(func(pb
*testing
.PB
) {
340 i
:= int(atomic
.AddInt32(&n
, 1)-1) % len(procKeys
)
344 for _
, k
:= range keys
{
351 func TestFunc(t
*testing
.T
) {
353 var x
interface{} = []string{"a", "b"}
354 f
:= Func(func() interface{} { return x
})
355 if s
, exp
:= f
.String(), `["a","b"]`; s
!= exp
{
356 t
.Errorf(`f.String() = %q, want %q`, s
, exp
)
358 if v
:= f
.Value(); !reflect
.DeepEqual(v
, x
) {
359 t
.Errorf(`f.Value() = %q, want %q`, v
, x
)
363 if s
, exp
:= f
.String(), `17`; s
!= exp
{
364 t
.Errorf(`f.String() = %q, want %q`, s
, exp
)
368 func TestHandler(t
*testing
.T
) {
374 for i
:= 0; i
< 9; i
++ {
375 m2
.Add(strconv
.Itoa(i
), int64(i
))
377 rr
:= httptest
.NewRecorder()
378 rr
.Body
= new(bytes
.Buffer
)
379 expvarHandler(rr
, nil)
381 "map1": {"a": 1, "z": 2},
382 "map2": {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8}
385 if got
:= rr
.Body
.String(); got
!= want
{
386 t
.Errorf("HTTP handler wrote:\n%s\nWant:\n%s", got
, want
)
390 func BenchmarkRealworldExpvarUsage(b
*testing
.B
) {
396 // The benchmark creates GOMAXPROCS client/server pairs.
397 // Each pair creates 4 goroutines: client reader/writer and server reader/writer.
398 // The benchmark stresses concurrent reading and writing to the same connection.
399 // Such pattern is used in net/http and net/rpc.
403 P
:= runtime
.GOMAXPROCS(0)
407 // Setup P client/server connections.
408 clients
:= make([]net
.Conn
, P
)
409 servers
:= make([]net
.Conn
, P
)
410 ln
, err
:= net
.Listen("tcp", "127.0.0.1:0")
412 b
.Fatalf("Listen failed: %v", err
)
415 done
:= make(chan bool)
417 for p
:= 0; p
< P
; p
++ {
418 s
, err
:= ln
.Accept()
420 b
.Errorf("Accept failed: %v", err
)
427 for p
:= 0; p
< P
; p
++ {
428 c
, err
:= net
.Dial("tcp", ln
.Addr().String())
430 b
.Fatalf("Dial failed: %v", err
)
438 var wg sync
.WaitGroup
440 for p
:= 0; p
< P
; p
++ {
442 go func(c net
.Conn
) {
445 for i
:= 0; i
< N
; i
++ {
447 for w
:= 0; w
< W
; w
++ {
451 n
, err
:= c
.Write(buf
[:])
453 b
.Errorf("Write failed: %v", err
)
457 bytesSent
.Add(int64(n
))
461 // Pipe between server reader and server writer.
462 pipe
:= make(chan byte, 128)
465 go func(s net
.Conn
) {
468 for i
:= 0; i
< N
; i
++ {
469 n
, err
:= s
.Read(buf
[:])
472 b
.Errorf("Read failed: %v", err
)
476 bytesRead
.Add(int64(n
))
482 go func(s net
.Conn
) {
485 for i
:= 0; i
< N
; i
++ {
487 for w
:= 0; w
< W
; w
++ {
491 n
, err
:= s
.Write(buf
[:])
493 b
.Errorf("Write failed: %v", err
)
497 bytesSent
.Add(int64(n
))
503 go func(c net
.Conn
) {
506 for i
:= 0; i
< N
; i
++ {
507 n
, err
:= c
.Read(buf
[:])
510 b
.Errorf("Read failed: %v", err
)
514 bytesRead
.Add(int64(n
))