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
22 func runPktSyslog(c net
.PacketConn
, done
chan<- string) {
30 c
.SetReadDeadline(time
.Now().Add(100 * time
.Millisecond
))
31 n
, _
, err
= c
.ReadFrom(buf
[:])
32 rcvd
+= string(buf
[:n
])
34 if oe
, ok
:= err
.(*net
.OpError
); ok
{
35 if ct
< 3 && oe
.Temporary() {
49 func runStreamSyslog(l net
.Listener
, done
chan<- string, wg
*sync
.WaitGroup
) {
53 if c
, err
= l
.Accept(); err
!= nil {
59 c
.SetReadDeadline(time
.Now().Add(5 * time
.Second
))
60 b
:= bufio
.NewReader(c
)
61 for ct
:= 1; !crashy || ct
&7 != 0; ct
++ {
62 s
, err
:= b
.ReadString('\n')
73 func startServer(n
, la
string, done
chan<- string) (addr
string, sock io
.Closer
, wg
*sync
.WaitGroup
) {
74 if n
== "udp" || n
== "tcp" {
77 // unix and unixgram: choose an address if none given
79 // use ioutil.TempFile to get a name that is unique
80 f
, err
:= ioutil
.TempFile("", "syslogtest")
82 log
.Fatal("TempFile: ", err
)
90 wg
= new(sync
.WaitGroup
)
91 if n
== "udp" || n
== "unixgram" {
92 l
, e
:= net
.ListenPacket(n
, la
)
94 log
.Fatalf("startServer failed: %v", e
)
96 addr
= l
.LocalAddr().String()
101 runPktSyslog(l
, done
)
104 l
, e
:= net
.Listen(n
, la
)
106 log
.Fatalf("startServer failed: %v", e
)
108 addr
= l
.Addr().String()
113 runStreamSyslog(l
, done
, wg
)
119 func TestWithSimulated(t
*testing
.T
) {
121 transport
:= []string{"unix", "unixgram", "udp", "tcp"}
123 for _
, tr
:= range transport
{
124 done
:= make(chan string)
125 addr
, sock
, srvWG
:= startServer(tr
, "", done
)
128 if tr
== "unix" || tr
== "unixgram" {
129 defer os
.Remove(addr
)
131 s
, err
:= Dial(tr
, addr
, LOG_INFO|LOG_USER
, "syslog_test")
133 t
.Fatalf("Dial() failed: %v", err
)
137 t
.Fatalf("log failed: %v", err
)
139 check(t
, msg
, <-done
)
144 func TestFlap(t
*testing
.T
) {
146 done
:= make(chan string)
147 addr
, sock
, srvWG
:= startServer(net
, "", done
)
149 defer os
.Remove(addr
)
152 s
, err
:= Dial(net
, addr
, LOG_INFO|LOG_USER
, "syslog_test")
154 t
.Fatalf("Dial() failed: %v", err
)
159 t
.Fatalf("log failed: %v", err
)
161 check(t
, msg
, <-done
)
163 // restart the server
164 _
, sock2
, srvWG2
:= startServer(net
, addr
, done
)
168 // and try retransmitting
172 t
.Fatalf("log failed: %v", err
)
174 check(t
, msg
, <-done
)
179 func TestNew(t
*testing
.T
) {
180 if LOG_LOCAL7
!= 23<<3 {
181 t
.Fatalf("LOG_LOCAL7 has wrong value")
184 // Depends on syslog daemon running, and sometimes it's not.
185 t
.Skip("skipping syslog test during -short")
188 s
, err
:= New(LOG_INFO|LOG_USER
, "the_tag")
190 t
.Fatalf("New() failed: %s", err
)
192 // Don't send any messages.
196 func TestNewLogger(t
*testing
.T
) {
198 t
.Skip("skipping syslog test during -short")
200 f
, err
:= NewLogger(LOG_USER|LOG_INFO
, 0)
206 func TestDial(t
*testing
.T
) {
208 t
.Skip("skipping syslog test during -short")
210 f
, err
:= Dial("", "", (LOG_LOCAL7|LOG_DEBUG
)+1, "syslog_test")
212 t
.Fatalf("Should have trapped bad priority")
214 f
, err
= Dial("", "", -1, "syslog_test")
216 t
.Fatalf("Should have trapped bad priority")
218 l
, err
:= Dial("", "", LOG_USER|LOG_ERR
, "syslog_test")
220 t
.Fatalf("Dial() failed: %s", err
)
225 func check(t
*testing
.T
, in
, out
string) {
226 tmpl
:= fmt
.Sprintf("<%d>%%s %%s syslog_test[%%d]: %s\n", LOG_USER
+LOG_INFO
, in
)
227 if hostname
, err
:= os
.Hostname(); err
!= nil {
228 t
.Error("Error retrieving hostname")
230 var parsedHostname
, timestamp
string
232 if n
, err
:= fmt
.Sscanf(out
, tmpl
, ×tamp
, &parsedHostname
, &pid
); n
!= 3 || err
!= nil || hostname
!= parsedHostname
{
233 t
.Errorf("Got %q, does not match template %q (%d %s)", out
, tmpl
, n
, err
)
238 func TestWrite(t
*testing
.T
) {
245 {LOG_USER | LOG_ERR
, "syslog_test", "", "%s %s syslog_test[%d]: \n"},
246 {LOG_USER | LOG_ERR
, "syslog_test", "write test", "%s %s syslog_test[%d]: write test\n"},
247 // Write should not add \n if there already is one
248 {LOG_USER | LOG_ERR
, "syslog_test", "write test 2\n", "%s %s syslog_test[%d]: write test 2\n"},
251 if hostname
, err
:= os
.Hostname(); err
!= nil {
252 t
.Fatalf("Error retrieving hostname")
254 for _
, test
:= range tests
{
255 done
:= make(chan string)
256 addr
, sock
, srvWG
:= startServer("udp", "", done
)
259 l
, err
:= Dial("udp", addr
, test
.pri
, test
.pre
)
261 t
.Fatalf("syslog.Dial() failed: %v", err
)
264 _
, err
= io
.WriteString(l
, test
.msg
)
266 t
.Fatalf("WriteString() failed: %v", err
)
269 test
.exp
= fmt
.Sprintf("<%d>", test
.pri
) + test
.exp
270 var parsedHostname
, timestamp
string
272 if n
, err
:= fmt
.Sscanf(rcvd
, test
.exp
, ×tamp
, &parsedHostname
, &pid
); n
!= 3 || err
!= nil || hostname
!= parsedHostname
{
273 t
.Errorf("s.Info() = '%q', didn't match '%q' (%d %s)", rcvd
, test
.exp
, n
, err
)
279 func TestConcurrentWrite(t
*testing
.T
) {
280 addr
, sock
, srvWG
:= startServer("udp", "", make(chan string, 1))
283 w
, err
:= Dial("udp", addr
, LOG_USER|LOG_ERR
, "how's it going?")
285 t
.Fatalf("syslog.Dial() failed: %v", err
)
287 var wg sync
.WaitGroup
288 for i
:= 0; i
< 10; i
++ {
292 err
:= w
.Info("test")
294 t
.Errorf("Info() failed: %v", err
)
302 func TestConcurrentReconnect(t
*testing
.T
) {
304 defer func() { crashy
= false }()
309 done
:= make(chan string, N
*M
)
310 addr
, sock
, srvWG
:= startServer(net
, "", done
)
311 defer os
.Remove(addr
)
313 // count all the messages arriving
314 count
:= make(chan int)
319 // we are looking for 500 out of 1000 events
320 // here because lots of log messages are lost
321 // in buffers (kernel and/or bufio)
329 var wg sync
.WaitGroup
331 for i
:= 0; i
< N
; i
++ {
334 w
, err
:= Dial(net
, addr
, LOG_USER|LOG_ERR
, "tag")
336 t
.Fatalf("syslog.Dial() failed: %v", err
)
339 for i
:= 0; i
< M
; i
++ {
340 err
:= w
.Info("test")
342 t
.Errorf("Info() failed: %v", err
)
355 case <-time
.After(100 * time
.Millisecond
):
356 t
.Error("timeout in concurrent reconnect")