PR c++/86342 - -Wdeprecated-copy and system headers.
[official-gcc.git] / libgo / go / log / syslog / syslog_test.go
blob1263be6d783b1ad4d9641d56d52aa432e1912cb4
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
7 package syslog
9 import (
10 "bufio"
11 "fmt"
12 "io"
13 "io/ioutil"
14 "log"
15 "net"
16 "os"
17 "runtime"
18 "sync"
19 "testing"
20 "time"
23 func runPktSyslog(c net.PacketConn, done chan<- string) {
24 var buf [4096]byte
25 var rcvd string
26 ct := 0
27 for {
28 var n int
29 var err error
31 c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
32 n, _, err = c.ReadFrom(buf[:])
33 rcvd += string(buf[:n])
34 if err != nil {
35 if oe, ok := err.(*net.OpError); ok {
36 if ct < 3 && oe.Temporary() {
37 ct++
38 continue
41 break
44 c.Close()
45 done <- rcvd
48 var crashy = false
50 func testableNetwork(network string) bool {
51 switch network {
52 case "unix", "unixgram":
53 switch runtime.GOOS {
54 case "darwin":
55 switch runtime.GOARCH {
56 case "arm", "arm64":
57 return false
59 case "android":
60 return false
63 return true
66 func runStreamSyslog(l net.Listener, done chan<- string, wg *sync.WaitGroup) {
67 for {
68 var c net.Conn
69 var err error
70 if c, err = l.Accept(); err != nil {
71 return
73 wg.Add(1)
74 go func(c net.Conn) {
75 defer wg.Done()
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')
80 if err != nil {
81 break
83 done <- s
85 c.Close()
86 }(c)
90 func startServer(n, la string, done chan<- string) (addr string, sock io.Closer, wg *sync.WaitGroup) {
91 if n == "udp" || n == "tcp" {
92 la = "127.0.0.1:0"
93 } else {
94 // unix and unixgram: choose an address if none given
95 if la == "" {
96 // use ioutil.TempFile to get a name that is unique
97 f, err := ioutil.TempFile("", "syslogtest")
98 if err != nil {
99 log.Fatal("TempFile: ", err)
101 f.Close()
102 la = f.Name()
104 os.Remove(la)
107 wg = new(sync.WaitGroup)
108 if n == "udp" || n == "unixgram" {
109 l, e := net.ListenPacket(n, la)
110 if e != nil {
111 log.Fatalf("startServer failed: %v", e)
113 addr = l.LocalAddr().String()
114 sock = l
115 wg.Add(1)
116 go func() {
117 defer wg.Done()
118 runPktSyslog(l, done)
120 } else {
121 l, e := net.Listen(n, la)
122 if e != nil {
123 log.Fatalf("startServer failed: %v", e)
125 addr = l.Addr().String()
126 sock = l
127 wg.Add(1)
128 go func() {
129 defer wg.Done()
130 runStreamSyslog(l, done, wg)
133 return
136 func TestWithSimulated(t *testing.T) {
137 t.Parallel()
138 msg := "Test 123"
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)
149 defer srvWG.Wait()
150 defer sock.Close()
151 if tr == "unix" || tr == "unixgram" {
152 defer os.Remove(addr)
154 s, err := Dial(tr, addr, LOG_INFO|LOG_USER, "syslog_test")
155 if err != nil {
156 t.Fatalf("Dial() failed: %v", err)
158 err = s.Info(msg)
159 if err != nil {
160 t.Fatalf("log failed: %v", err)
162 check(t, msg, <-done)
163 s.Close()
167 func TestFlap(t *testing.T) {
168 net := "unix"
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)
175 defer srvWG.Wait()
176 defer os.Remove(addr)
177 defer sock.Close()
179 s, err := Dial(net, addr, LOG_INFO|LOG_USER, "syslog_test")
180 if err != nil {
181 t.Fatalf("Dial() failed: %v", err)
183 msg := "Moo 2"
184 err = s.Info(msg)
185 if err != nil {
186 t.Fatalf("log failed: %v", err)
188 check(t, msg, <-done)
190 // restart the server
191 _, sock2, srvWG2 := startServer(net, addr, done)
192 defer srvWG2.Wait()
193 defer sock2.Close()
195 // and try retransmitting
196 msg = "Moo 3"
197 err = s.Info(msg)
198 if err != nil {
199 t.Fatalf("log failed: %v", err)
201 check(t, msg, <-done)
203 s.Close()
206 func TestNew(t *testing.T) {
207 if LOG_LOCAL7 != 23<<3 {
208 t.Fatalf("LOG_LOCAL7 has wrong value")
210 if testing.Short() {
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")
216 if err != nil {
217 t.Fatalf("New() failed: %s", err)
219 // Don't send any messages.
220 s.Close()
223 func TestNewLogger(t *testing.T) {
224 if testing.Short() {
225 t.Skip("skipping syslog test during -short")
227 f, err := NewLogger(LOG_USER|LOG_INFO, 0)
228 if f == nil {
229 t.Error(err)
233 func TestDial(t *testing.T) {
234 if testing.Short() {
235 t.Skip("skipping syslog test during -short")
237 f, err := Dial("", "", (LOG_LOCAL7|LOG_DEBUG)+1, "syslog_test")
238 if f != nil {
239 t.Fatalf("Should have trapped bad priority")
241 f, err = Dial("", "", -1, "syslog_test")
242 if f != nil {
243 t.Fatalf("Should have trapped bad priority")
245 l, err := Dial("", "", LOG_USER|LOG_ERR, "syslog_test")
246 if err != nil {
247 t.Fatalf("Dial() failed: %s", err)
249 l.Close()
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")
256 } else {
257 var parsedHostname, timestamp string
258 var pid int
259 if n, err := fmt.Sscanf(out, tmpl, &timestamp, &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) {
266 t.Parallel()
267 tests := []struct {
268 pri Priority
269 pre string
270 msg string
271 exp string
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")
281 } else {
282 for _, test := range tests {
283 done := make(chan string)
284 addr, sock, srvWG := startServer("udp", "", done)
285 defer srvWG.Wait()
286 defer sock.Close()
287 l, err := Dial("udp", addr, test.pri, test.pre)
288 if err != nil {
289 t.Fatalf("syslog.Dial() failed: %v", err)
291 defer l.Close()
292 _, err = io.WriteString(l, test.msg)
293 if err != nil {
294 t.Fatalf("WriteString() failed: %v", err)
296 rcvd := <-done
297 test.exp = fmt.Sprintf("<%d>", test.pri) + test.exp
298 var parsedHostname, timestamp string
299 var pid int
300 if n, err := fmt.Sscanf(rcvd, test.exp, &timestamp, &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))
309 defer srvWG.Wait()
310 defer sock.Close()
311 w, err := Dial("udp", addr, LOG_USER|LOG_ERR, "how's it going?")
312 if err != nil {
313 t.Fatalf("syslog.Dial() failed: %v", err)
315 var wg sync.WaitGroup
316 for i := 0; i < 10; i++ {
317 wg.Add(1)
318 go func() {
319 defer wg.Done()
320 err := w.Info("test")
321 if err != nil {
322 t.Errorf("Info() failed: %v", err)
323 return
327 wg.Wait()
330 func TestConcurrentReconnect(t *testing.T) {
331 crashy = true
332 defer func() { crashy = false }()
334 const N = 10
335 const M = 100
336 net := "unix"
337 if !testableNetwork(net) {
338 net = "tcp"
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)
345 if net == "unix" {
346 defer os.Remove(addr)
349 // count all the messages arriving
350 count := make(chan int)
351 go func() {
352 ct := 0
353 for range done {
354 ct++
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)
358 if ct > N*M/2 {
359 break
362 count <- ct
365 var wg sync.WaitGroup
366 wg.Add(N)
367 for i := 0; i < N; i++ {
368 go func() {
369 defer wg.Done()
370 w, err := Dial(net, addr, LOG_USER|LOG_ERR, "tag")
371 if err != nil {
372 t.Errorf("syslog.Dial() failed: %v", err)
373 return
375 defer w.Close()
376 for i := 0; i < M; i++ {
377 err := w.Info("test")
378 if err != nil {
379 t.Errorf("Info() failed: %v", err)
380 return
385 wg.Wait()
386 sock.Close()
387 srvWG.Wait()
388 close(done)
390 select {
391 case <-count:
392 case <-time.After(100 * time.Millisecond):
393 t.Error("timeout in concurrent reconnect")