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.
5 // +build !windows,!nacl,!plan9
23 func runPktSyslog(c net
.PacketConn
, done
chan<- string) {
31 c
.SetReadDeadline(time
.Now().Add(100 * time
.Millisecond
))
32 n
, _
, err
= c
.ReadFrom(buf
[:])
33 rcvd
+= string(buf
[:n
])
35 if oe
, ok
:= err
.(*net
.OpError
); ok
{
36 if ct
< 3 && oe
.Temporary() {
50 func testableNetwork(network
string) bool {
52 case "unix", "unixgram":
55 switch runtime
.GOARCH
{
66 func runStreamSyslog(l net
.Listener
, done
chan<- string, wg
*sync
.WaitGroup
) {
70 if c
, err
= l
.Accept(); err
!= nil {
76 c
.SetReadDeadline(time
.Now().Add(5 * time
.Second
))
77 b
:= bufio
.NewReader(c
)
78 for ct
:= 1; !crashy || ct
&7 != 0; ct
++ {
79 s
, err
:= b
.ReadString('\n')
90 func startServer(n
, la
string, done
chan<- string) (addr
string, sock io
.Closer
, wg
*sync
.WaitGroup
) {
91 if n
== "udp" || n
== "tcp" {
94 // unix and unixgram: choose an address if none given
96 // use ioutil.TempFile to get a name that is unique
97 f
, err
:= ioutil
.TempFile("", "syslogtest")
99 log
.Fatal("TempFile: ", err
)
107 wg
= new(sync
.WaitGroup
)
108 if n
== "udp" || n
== "unixgram" {
109 l
, e
:= net
.ListenPacket(n
, la
)
111 log
.Fatalf("startServer failed: %v", e
)
113 addr
= l
.LocalAddr().String()
118 runPktSyslog(l
, done
)
121 l
, e
:= net
.Listen(n
, la
)
123 log
.Fatalf("startServer failed: %v", e
)
125 addr
= l
.Addr().String()
130 runStreamSyslog(l
, done
, wg
)
136 func TestWithSimulated(t
*testing
.T
) {
139 var transport
[]string
140 for _
, n
:= range []string{"unix", "unixgram", "udp", "tcp"} {
141 if testableNetwork(n
) {
142 transport
= append(transport
, n
)
146 for _
, tr
:= range transport
{
147 done
:= make(chan string)
148 addr
, sock
, srvWG
:= startServer(tr
, "", done
)
151 if tr
== "unix" || tr
== "unixgram" {
152 defer os
.Remove(addr
)
154 s
, err
:= Dial(tr
, addr
, LOG_INFO|LOG_USER
, "syslog_test")
156 t
.Fatalf("Dial() failed: %v", err
)
160 t
.Fatalf("log failed: %v", err
)
162 check(t
, msg
, <-done
)
167 func TestFlap(t
*testing
.T
) {
169 if !testableNetwork(net
) {
170 t
.Skipf("skipping on %s/%s; 'unix' is not supported", runtime
.GOOS
, runtime
.GOARCH
)
173 done
:= make(chan string)
174 addr
, sock
, srvWG
:= startServer(net
, "", done
)
176 defer os
.Remove(addr
)
179 s
, err
:= Dial(net
, addr
, LOG_INFO|LOG_USER
, "syslog_test")
181 t
.Fatalf("Dial() failed: %v", err
)
186 t
.Fatalf("log failed: %v", err
)
188 check(t
, msg
, <-done
)
190 // restart the server
191 _
, sock2
, srvWG2
:= startServer(net
, addr
, done
)
195 // and try retransmitting
199 t
.Fatalf("log failed: %v", err
)
201 check(t
, msg
, <-done
)
206 func TestNew(t
*testing
.T
) {
207 if LOG_LOCAL7
!= 23<<3 {
208 t
.Fatalf("LOG_LOCAL7 has wrong value")
211 // Depends on syslog daemon running, and sometimes it's not.
212 t
.Skip("skipping syslog test during -short")
215 s
, err
:= New(LOG_INFO|LOG_USER
, "the_tag")
217 t
.Fatalf("New() failed: %s", err
)
219 // Don't send any messages.
223 func TestNewLogger(t
*testing
.T
) {
225 t
.Skip("skipping syslog test during -short")
227 f
, err
:= NewLogger(LOG_USER|LOG_INFO
, 0)
233 func TestDial(t
*testing
.T
) {
235 t
.Skip("skipping syslog test during -short")
237 f
, err
:= Dial("", "", (LOG_LOCAL7|LOG_DEBUG
)+1, "syslog_test")
239 t
.Fatalf("Should have trapped bad priority")
241 f
, err
= Dial("", "", -1, "syslog_test")
243 t
.Fatalf("Should have trapped bad priority")
245 l
, err
:= Dial("", "", LOG_USER|LOG_ERR
, "syslog_test")
247 t
.Fatalf("Dial() failed: %s", err
)
252 func check(t
*testing
.T
, in
, out
string) {
253 tmpl
:= fmt
.Sprintf("<%d>%%s %%s syslog_test[%%d]: %s\n", LOG_USER
+LOG_INFO
, in
)
254 if hostname
, err
:= os
.Hostname(); err
!= nil {
255 t
.Error("Error retrieving hostname")
257 var parsedHostname
, timestamp
string
259 if n
, err
:= fmt
.Sscanf(out
, tmpl
, ×tamp
, &parsedHostname
, &pid
); n
!= 3 || err
!= nil || hostname
!= parsedHostname
{
260 t
.Errorf("Got %q, does not match template %q (%d %s)", out
, tmpl
, n
, err
)
265 func TestWrite(t
*testing
.T
) {
273 {LOG_USER | LOG_ERR
, "syslog_test", "", "%s %s syslog_test[%d]: \n"},
274 {LOG_USER | LOG_ERR
, "syslog_test", "write test", "%s %s syslog_test[%d]: write test\n"},
275 // Write should not add \n if there already is one
276 {LOG_USER | LOG_ERR
, "syslog_test", "write test 2\n", "%s %s syslog_test[%d]: write test 2\n"},
279 if hostname
, err
:= os
.Hostname(); err
!= nil {
280 t
.Fatalf("Error retrieving hostname")
282 for _
, test
:= range tests
{
283 done
:= make(chan string)
284 addr
, sock
, srvWG
:= startServer("udp", "", done
)
287 l
, err
:= Dial("udp", addr
, test
.pri
, test
.pre
)
289 t
.Fatalf("syslog.Dial() failed: %v", err
)
292 _
, err
= io
.WriteString(l
, test
.msg
)
294 t
.Fatalf("WriteString() failed: %v", err
)
297 test
.exp
= fmt
.Sprintf("<%d>", test
.pri
) + test
.exp
298 var parsedHostname
, timestamp
string
300 if n
, err
:= fmt
.Sscanf(rcvd
, test
.exp
, ×tamp
, &parsedHostname
, &pid
); n
!= 3 || err
!= nil || hostname
!= parsedHostname
{
301 t
.Errorf("s.Info() = '%q', didn't match '%q' (%d %s)", rcvd
, test
.exp
, n
, err
)
307 func TestConcurrentWrite(t
*testing
.T
) {
308 addr
, sock
, srvWG
:= startServer("udp", "", make(chan string, 1))
311 w
, err
:= Dial("udp", addr
, LOG_USER|LOG_ERR
, "how's it going?")
313 t
.Fatalf("syslog.Dial() failed: %v", err
)
315 var wg sync
.WaitGroup
316 for i
:= 0; i
< 10; i
++ {
320 err
:= w
.Info("test")
322 t
.Errorf("Info() failed: %v", err
)
330 func TestConcurrentReconnect(t
*testing
.T
) {
332 defer func() { crashy
= false }()
337 if !testableNetwork(net
) {
339 if !testableNetwork(net
) {
340 t
.Skipf("skipping on %s/%s; neither 'unix' or 'tcp' is supported", runtime
.GOOS
, runtime
.GOARCH
)
343 done
:= make(chan string, N
*M
)
344 addr
, sock
, srvWG
:= startServer(net
, "", done
)
346 defer os
.Remove(addr
)
349 // count all the messages arriving
350 count
:= make(chan int)
355 // we are looking for 500 out of 1000 events
356 // here because lots of log messages are lost
357 // in buffers (kernel and/or bufio)
365 var wg sync
.WaitGroup
367 for i
:= 0; i
< N
; i
++ {
370 w
, err
:= Dial(net
, addr
, LOG_USER|LOG_ERR
, "tag")
372 t
.Errorf("syslog.Dial() failed: %v", err
)
376 for i
:= 0; i
< M
; i
++ {
377 err
:= w
.Info("test")
379 t
.Errorf("Info() failed: %v", err
)
392 case <-time
.After(100 * time
.Millisecond
):
393 t
.Error("timeout in concurrent reconnect")