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.
19 // RemoveAll removes all exported variables.
20 // This is for tests only.
24 vars
= make(map[string]Var
)
28 func TestNil(t
*testing
.T
) {
32 t
.Errorf("got %v, want nil", val
)
36 func TestInt(t
*testing
.T
) {
38 reqs
:= NewInt("requests")
40 t
.Errorf("reqs.i = %v, want 0", reqs
.i
)
42 if reqs
!= Get("requests").(*Int
) {
43 t
.Errorf("Get() failed.")
49 t
.Errorf("reqs.i = %v, want 4", reqs
.i
)
52 if s
:= reqs
.String(); s
!= "4" {
53 t
.Errorf("reqs.String() = %q, want \"4\"", s
)
58 t
.Errorf("reqs.i = %v, want -2", reqs
.i
)
61 if v
, want
:= reqs
.Value(), int64(-2); v
!= want
{
62 t
.Errorf("reqs.Value() = %q, want %q", v
, want
)
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")
136 t
.Errorf("name.s = %q, want \"\"", name
.s
)
140 if name
.s
!= "Mike" {
141 t
.Errorf("name.s = %q, want \"Mike\"", name
.s
)
144 if s
, want
:= name
.String(), `"Mike"`; s
!= want
{
145 t
.Errorf("from %q, name.String() = %q, want %q", name
.s
, s
, want
)
148 if s
, want
:= name
.Value(), "Mike"; s
!= want
{
149 t
.Errorf("from %q, name.Value() = %q, want %q", name
.s
, s
, want
)
152 // Make sure we produce safe JSON output.
154 if s
, want
:= name
.String(), "\"\\u003c\""; s
!= want
{
155 t
.Errorf("from %q, name.String() = %q, want %q", name
.s
, s
, want
)
159 func BenchmarkStringSet(b
*testing
.B
) {
162 b
.RunParallel(func(pb
*testing
.PB
) {
169 func TestMapCounter(t
*testing
.T
) {
171 colors
:= NewMap("bike-shed-colors")
175 colors
.Add("blue", 4)
176 colors
.AddFloat(`green "midori"`, 4.125)
177 if x
:= colors
.m
["red"].(*Int
).i
; x
!= 3 {
178 t
.Errorf("colors.m[\"red\"] = %v, want 3", x
)
180 if x
:= colors
.m
["blue"].(*Int
).i
; x
!= 4 {
181 t
.Errorf("colors.m[\"blue\"] = %v, want 4", x
)
183 if x
:= colors
.m
[`green "midori"`].(*Float
).Value(); x
!= 4.125 {
184 t
.Errorf("colors.m[`green \"midori\"] = %v, want 4.125", x
)
187 // colors.String() should be '{"red":3, "blue":4}',
188 // though the order of red and blue could vary.
191 err
:= json
.Unmarshal([]byte(s
), &j
)
193 t
.Errorf("colors.String() isn't valid JSON: %v", err
)
195 m
, ok
:= j
.(map[string]interface{})
197 t
.Error("colors.String() didn't produce a map.")
200 x
, ok
:= red
.(float64)
202 t
.Error("red.Kind() is not a number.")
205 t
.Errorf("red = %v, want 3", x
)
209 func BenchmarkMapSet(b
*testing
.B
) {
214 b
.RunParallel(func(pb
*testing
.PB
) {
221 func BenchmarkMapAddSame(b
*testing
.B
) {
222 for i
:= 0; i
< b
.N
; i
++ {
231 func BenchmarkMapAddDifferent(b
*testing
.B
) {
232 for i
:= 0; i
< b
.N
; i
++ {
241 func TestFunc(t
*testing
.T
) {
243 var x
interface{} = []string{"a", "b"}
244 f
:= Func(func() interface{} { return x
})
245 if s
, exp
:= f
.String(), `["a","b"]`; s
!= exp
{
246 t
.Errorf(`f.String() = %q, want %q`, s
, exp
)
248 if v
:= f
.Value(); !reflect
.DeepEqual(v
, x
) {
249 t
.Errorf(`f.Value() = %q, want %q`, v
, x
)
253 if s
, exp
:= f
.String(), `17`; s
!= exp
{
254 t
.Errorf(`f.String() = %q, want %q`, s
, exp
)
258 func TestHandler(t
*testing
.T
) {
264 for i
:= 0; i
< 9; i
++ {
265 m2
.Add(strconv
.Itoa(i
), int64(i
))
267 rr
:= httptest
.NewRecorder()
268 rr
.Body
= new(bytes
.Buffer
)
269 expvarHandler(rr
, nil)
271 "map1": {"a": 1, "z": 2},
272 "map2": {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8}
275 if got
:= rr
.Body
.String(); got
!= want
{
276 t
.Errorf("HTTP handler wrote:\n%s\nWant:\n%s", got
, want
)
280 func BenchmarkRealworldExpvarUsage(b
*testing
.B
) {
286 // The benchmark creates GOMAXPROCS client/server pairs.
287 // Each pair creates 4 goroutines: client reader/writer and server reader/writer.
288 // The benchmark stresses concurrent reading and writing to the same connection.
289 // Such pattern is used in net/http and net/rpc.
293 P
:= runtime
.GOMAXPROCS(0)
297 // Setup P client/server connections.
298 clients
:= make([]net
.Conn
, P
)
299 servers
:= make([]net
.Conn
, P
)
300 ln
, err
:= net
.Listen("tcp", "127.0.0.1:0")
302 b
.Fatalf("Listen failed: %v", err
)
305 done
:= make(chan bool)
307 for p
:= 0; p
< P
; p
++ {
308 s
, err
:= ln
.Accept()
310 b
.Errorf("Accept failed: %v", err
)
317 for p
:= 0; p
< P
; p
++ {
318 c
, err
:= net
.Dial("tcp", ln
.Addr().String())
320 b
.Fatalf("Dial failed: %v", err
)
328 var wg sync
.WaitGroup
330 for p
:= 0; p
< P
; p
++ {
332 go func(c net
.Conn
) {
335 for i
:= 0; i
< N
; i
++ {
337 for w
:= 0; w
< W
; w
++ {
341 n
, err
:= c
.Write(buf
[:])
343 b
.Errorf("Write failed: %v", err
)
347 bytesSent
.Add(int64(n
))
351 // Pipe between server reader and server writer.
352 pipe
:= make(chan byte, 128)
355 go func(s net
.Conn
) {
358 for i
:= 0; i
< N
; i
++ {
359 n
, err
:= s
.Read(buf
[:])
362 b
.Errorf("Read failed: %v", err
)
366 bytesRead
.Add(int64(n
))
372 go func(s net
.Conn
) {
375 for i
:= 0; i
< N
; i
++ {
377 for w
:= 0; w
< W
; w
++ {
381 n
, err
:= s
.Write(buf
[:])
383 b
.Errorf("Write failed: %v", err
)
387 bytesSent
.Add(int64(n
))
393 go func(c net
.Conn
) {
396 for i
:= 0; i
< N
; i
++ {
397 n
, err
:= c
.Read(buf
[:])
400 b
.Errorf("Read failed: %v", err
)
404 bytesRead
.Add(int64(n
))