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.
20 // RemoveAll removes all exported variables.
21 // This is for tests only.
25 vars
= make(map[string]Var
)
29 func TestNil(t
*testing
.T
) {
33 t
.Errorf("got %v, want nil", val
)
37 func TestInt(t
*testing
.T
) {
39 reqs
:= NewInt("requests")
41 t
.Errorf("reqs.i = %v, want 0", reqs
.i
)
43 if reqs
!= Get("requests").(*Int
) {
44 t
.Errorf("Get() failed.")
50 t
.Errorf("reqs.i = %v, want 4", reqs
.i
)
53 if s
:= reqs
.String(); s
!= "4" {
54 t
.Errorf("reqs.String() = %q, want \"4\"", s
)
59 t
.Errorf("reqs.i = %v, want -2", reqs
.i
)
63 func BenchmarkIntAdd(b
*testing
.B
) {
66 b
.RunParallel(func(pb
*testing
.PB
) {
73 func BenchmarkIntSet(b
*testing
.B
) {
76 b
.RunParallel(func(pb
*testing
.PB
) {
83 func (v
*Float
) val() float64 {
84 return math
.Float64frombits(atomic
.LoadUint64(&v
.f
))
87 func TestFloat(t
*testing
.T
) {
89 reqs
:= NewFloat("requests-float")
91 t
.Errorf("reqs.f = %v, want 0", reqs
.f
)
93 if reqs
!= Get("requests-float").(*Float
) {
94 t
.Errorf("Get() failed.")
99 if v
:= reqs
.val(); v
!= 2.75 {
100 t
.Errorf("reqs.val() = %v, want 2.75", v
)
103 if s
:= reqs
.String(); s
!= "2.75" {
104 t
.Errorf("reqs.String() = %q, want \"4.64\"", s
)
108 if v
:= reqs
.val(); v
!= 0.75 {
109 t
.Errorf("reqs.val() = %v, want 0.75", v
)
113 func BenchmarkFloatAdd(b
*testing
.B
) {
116 b
.RunParallel(func(pb
*testing
.PB
) {
123 func BenchmarkFloatSet(b
*testing
.B
) {
126 b
.RunParallel(func(pb
*testing
.PB
) {
133 func TestString(t
*testing
.T
) {
135 name
:= NewString("my-name")
137 t
.Errorf("name.s = %q, want \"\"", name
.s
)
141 if name
.s
!= "Mike" {
142 t
.Errorf("name.s = %q, want \"Mike\"", name
.s
)
145 if s
, want
:= name
.String(), `"Mike"`; s
!= want
{
146 t
.Errorf("from %q, name.String() = %q, want %q", name
.s
, s
, want
)
149 // Make sure we produce safe JSON output.
151 if s
, want
:= name
.String(), "\"\\u003c\""; s
!= want
{
152 t
.Errorf("from %q, name.String() = %q, want %q", name
.s
, s
, want
)
156 func BenchmarkStringSet(b
*testing
.B
) {
159 b
.RunParallel(func(pb
*testing
.PB
) {
166 func TestMapCounter(t
*testing
.T
) {
168 colors
:= NewMap("bike-shed-colors")
172 colors
.Add("blue", 4)
173 colors
.AddFloat(`green "midori"`, 4.125)
174 if x
:= colors
.m
["red"].(*Int
).i
; x
!= 3 {
175 t
.Errorf("colors.m[\"red\"] = %v, want 3", x
)
177 if x
:= colors
.m
["blue"].(*Int
).i
; x
!= 4 {
178 t
.Errorf("colors.m[\"blue\"] = %v, want 4", x
)
180 if x
:= colors
.m
[`green "midori"`].(*Float
).val(); x
!= 4.125 {
181 t
.Errorf("colors.m[`green \"midori\"] = %v, want 4.125", x
)
184 // colors.String() should be '{"red":3, "blue":4}',
185 // though the order of red and blue could vary.
188 err
:= json
.Unmarshal([]byte(s
), &j
)
190 t
.Errorf("colors.String() isn't valid JSON: %v", err
)
192 m
, ok
:= j
.(map[string]interface{})
194 t
.Error("colors.String() didn't produce a map.")
197 x
, ok
:= red
.(float64)
199 t
.Error("red.Kind() is not a number.")
202 t
.Errorf("red = %v, want 3", x
)
206 func BenchmarkMapSet(b
*testing
.B
) {
211 b
.RunParallel(func(pb
*testing
.PB
) {
218 func BenchmarkMapAddSame(b
*testing
.B
) {
219 for i
:= 0; i
< b
.N
; i
++ {
228 func BenchmarkMapAddDifferent(b
*testing
.B
) {
229 for i
:= 0; i
< b
.N
; i
++ {
238 func TestFunc(t
*testing
.T
) {
240 var x
interface{} = []string{"a", "b"}
241 f
:= Func(func() interface{} { return x
})
242 if s
, exp
:= f
.String(), `["a","b"]`; s
!= exp
{
243 t
.Errorf(`f.String() = %q, want %q`, s
, exp
)
247 if s
, exp
:= f
.String(), `17`; s
!= exp
{
248 t
.Errorf(`f.String() = %q, want %q`, s
, exp
)
252 func TestHandler(t
*testing
.T
) {
258 for i
:= 0; i
< 9; i
++ {
259 m2
.Add(strconv
.Itoa(i
), int64(i
))
261 rr
:= httptest
.NewRecorder()
262 rr
.Body
= new(bytes
.Buffer
)
263 expvarHandler(rr
, nil)
265 "map1": {"a": 1, "z": 2},
266 "map2": {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8}
269 if got
:= rr
.Body
.String(); got
!= want
{
270 t
.Errorf("HTTP handler wrote:\n%s\nWant:\n%s", got
, want
)
274 func BenchmarkRealworldExpvarUsage(b
*testing
.B
) {
280 // The benchmark creates GOMAXPROCS client/server pairs.
281 // Each pair creates 4 goroutines: client reader/writer and server reader/writer.
282 // The benchmark stresses concurrent reading and writing to the same connection.
283 // Such pattern is used in net/http and net/rpc.
287 P
:= runtime
.GOMAXPROCS(0)
291 // Setup P client/server connections.
292 clients
:= make([]net
.Conn
, P
)
293 servers
:= make([]net
.Conn
, P
)
294 ln
, err
:= net
.Listen("tcp", "127.0.0.1:0")
296 b
.Fatalf("Listen failed: %v", err
)
299 done
:= make(chan bool)
301 for p
:= 0; p
< P
; p
++ {
302 s
, err
:= ln
.Accept()
304 b
.Errorf("Accept failed: %v", err
)
311 for p
:= 0; p
< P
; p
++ {
312 c
, err
:= net
.Dial("tcp", ln
.Addr().String())
314 b
.Fatalf("Dial failed: %v", err
)
322 var wg sync
.WaitGroup
324 for p
:= 0; p
< P
; p
++ {
326 go func(c net
.Conn
) {
329 for i
:= 0; i
< N
; i
++ {
331 for w
:= 0; w
< W
; w
++ {
335 n
, err
:= c
.Write(buf
[:])
337 b
.Errorf("Write failed: %v", err
)
341 bytesSent
.Add(int64(n
))
345 // Pipe between server reader and server writer.
346 pipe
:= make(chan byte, 128)
349 go func(s net
.Conn
) {
352 for i
:= 0; i
< N
; i
++ {
353 n
, err
:= s
.Read(buf
[:])
356 b
.Errorf("Read failed: %v", err
)
360 bytesRead
.Add(int64(n
))
366 go func(s net
.Conn
) {
369 for i
:= 0; i
< N
; i
++ {
371 for w
:= 0; w
< W
; w
++ {
375 n
, err
:= s
.Write(buf
[:])
377 b
.Errorf("Write failed: %v", err
)
381 bytesSent
.Add(int64(n
))
387 go func(c net
.Conn
) {
390 for i
:= 0; i
< N
; i
++ {
391 n
, err
:= c
.Read(buf
[:])
394 b
.Errorf("Read failed: %v", err
)
398 bytesRead
.Add(int64(n
))