package zk import ( "net" "testing" "time" ) var ( zkSrvrOut = `Zookeeper version: 3.4.6-1569965, built on 02/20/2014 09:09 GMT Latency min/avg/max: 0/1/10 Received: 4207 Sent: 4220 Connections: 81 Outstanding: 1 Zxid: 0x110a7a8f37 Mode: leader Node count: 306 ` zkConsOut = ` /10.42.45.231:45361[1](queued=0,recved=9435,sent=9457,sid=0x94c2989e04716b5,lop=PING,est=1427238717217,to=20001,lcxid=0x55120915,lzxid=0xffffffffffffffff,lresp=1427259255908,llat=0,minlat=0,avglat=1,maxlat=17) /10.55.33.98:34342[1](queued=0,recved=9338,sent=9350,sid=0x94c2989e0471731,lop=PING,est=1427238849319,to=20001,lcxid=0x55120944,lzxid=0xffffffffffffffff,lresp=1427259252294,llat=0,minlat=0,avglat=1,maxlat=18) /10.44.145.114:46556[1](queued=0,recved=109253,sent=109617,sid=0x94c2989e0471709,lop=DELE,est=1427238791305,to=20001,lcxid=0x55139618,lzxid=0x110a7b187d,lresp=1427259257423,llat=2,minlat=0,avglat=1,maxlat=23) ` ) func TestFLWRuok(t *testing.T) { t.Parallel() l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } defer l.Close() go tcpServer(l, "") oks := FLWRuok([]string{l.Addr().String()}, time.Second*10) if len(oks) == 0 { t.Errorf("no values returned") } if !oks[0] { t.Errorf("instance should be marked as OK") } // // Confirm that it also returns false for dead instances // l, err = net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } defer l.Close() go tcpServer(l, "dead") oks = FLWRuok([]string{l.Addr().String()}, time.Second*10) if len(oks) == 0 { t.Errorf("no values returned") } if oks[0] { t.Errorf("instance should be marked as not OK") } } func TestFLWSrvr(t *testing.T) { t.Parallel() l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } defer l.Close() go tcpServer(l, "") statsSlice, ok := FLWSrvr([]string{l.Addr().String()}, time.Second*10) if !ok { t.Errorf("failure indicated on 'srvr' parsing") } if len(statsSlice) == 0 { t.Errorf("no *ServerStats instances returned") } stats := statsSlice[0] if stats.Error != nil { t.Fatalf("error seen in stats: %v", err.Error()) } if stats.Sent != 4220 { t.Errorf("Sent != 4220") } if stats.Received != 4207 { t.Errorf("Received != 4207") } if stats.NodeCount != 306 { t.Errorf("NodeCount != 306") } if stats.MinLatency != 0 { t.Errorf("MinLatency != 0") } if stats.AvgLatency != 1 { t.Errorf("AvgLatency != 1") } if stats.MaxLatency != 10 { t.Errorf("MaxLatency != 10") } if stats.Connections != 81 { t.Errorf("Connection != 81") } if stats.Outstanding != 1 { t.Errorf("Outstanding != 1") } if stats.Epoch != 17 { t.Errorf("Epoch != 17") } if stats.Counter != 175804215 { t.Errorf("Counter != 175804215") } if stats.Mode != ModeLeader { t.Errorf("Mode != ModeLeader") } if stats.Version != "3.4.6-1569965" { t.Errorf("Version expected: 3.4.6-1569965") } } func TestFLWCons(t *testing.T) { t.Parallel() l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } defer l.Close() go tcpServer(l, "") clients, ok := FLWCons([]string{l.Addr().String()}, time.Second*10) if !ok { t.Errorf("failure indicated on 'cons' parsing") } if len(clients) == 0 { t.Errorf("no *ServerClients instances returned") } results := []*ServerClient{ { Queued: 0, Received: 9435, Sent: 9457, SessionID: 669956116721374901, LastOperation: "PING", Established: time.Unix(1427238717217, 0), Timeout: 20001, Lcxid: 1427245333, Lzxid: -1, LastResponse: time.Unix(1427259255908, 0), LastLatency: 0, MinLatency: 0, AvgLatency: 1, MaxLatency: 17, Addr: "10.42.45.231:45361", }, { Queued: 0, Received: 9338, Sent: 9350, SessionID: 669956116721375025, LastOperation: "PING", Established: time.Unix(1427238849319, 0), Timeout: 20001, Lcxid: 1427245380, Lzxid: -1, LastResponse: time.Unix(1427259252294, 0), LastLatency: 0, MinLatency: 0, AvgLatency: 1, MaxLatency: 18, Addr: "10.55.33.98:34342", }, { Queued: 0, Received: 109253, Sent: 109617, SessionID: 669956116721374985, LastOperation: "DELE", Established: time.Unix(1427238791305, 0), Timeout: 20001, Lcxid: 1427346968, Lzxid: 73190283389, LastResponse: time.Unix(1427259257423, 0), LastLatency: 2, MinLatency: 0, AvgLatency: 1, MaxLatency: 23, Addr: "10.44.145.114:46556", }, } for _, z := range clients { if z.Error != nil { t.Errorf("error seen: %v", err.Error()) } for i, v := range z.Clients { c := results[i] if v.Error != nil { t.Errorf("client error seen: %v", err.Error()) } if v.Queued != c.Queued { t.Errorf("Queued value mismatch (%d/%d)", v.Queued, c.Queued) } if v.Received != c.Received { t.Errorf("Received value mismatch (%d/%d)", v.Received, c.Received) } if v.Sent != c.Sent { t.Errorf("Sent value mismatch (%d/%d)", v.Sent, c.Sent) } if v.SessionID != c.SessionID { t.Errorf("SessionID value mismatch (%d/%d)", v.SessionID, c.SessionID) } if v.LastOperation != c.LastOperation { t.Errorf("LastOperation value mismatch ('%v'/'%v')", v.LastOperation, c.LastOperation) } if v.Timeout != c.Timeout { t.Errorf("Timeout value mismatch (%d/%d)", v.Timeout, c.Timeout) } if v.Lcxid != c.Lcxid { t.Errorf("Lcxid value mismatch (%d/%d)", v.Lcxid, c.Lcxid) } if v.Lzxid != c.Lzxid { t.Errorf("Lzxid value mismatch (%d/%d)", v.Lzxid, c.Lzxid) } if v.LastLatency != c.LastLatency { t.Errorf("LastLatency value mismatch (%d/%d)", v.LastLatency, c.LastLatency) } if v.MinLatency != c.MinLatency { t.Errorf("MinLatency value mismatch (%d/%d)", v.MinLatency, c.MinLatency) } if v.AvgLatency != c.AvgLatency { t.Errorf("AvgLatency value mismatch (%d/%d)", v.AvgLatency, c.AvgLatency) } if v.MaxLatency != c.MaxLatency { t.Errorf("MaxLatency value mismatch (%d/%d)", v.MaxLatency, c.MaxLatency) } if v.Addr != c.Addr { t.Errorf("Addr value mismatch ('%v'/'%v')", v.Addr, c.Addr) } if !c.Established.Equal(v.Established) { t.Errorf("Established value mismatch (%v/%v)", c.Established, v.Established) } if !c.LastResponse.Equal(v.LastResponse) { t.Errorf("Established value mismatch (%v/%v)", c.LastResponse, v.LastResponse) } } } } func tcpServer(listener net.Listener, thing string) { for { conn, err := listener.Accept() if err != nil { return } go connHandler(conn, thing) } } func connHandler(conn net.Conn, thing string) { defer conn.Close() data := make([]byte, 4) _, err := conn.Read(data) if err != nil { return } switch string(data) { case "ruok": switch thing { case "dead": return default: conn.Write([]byte("imok")) } case "srvr": switch thing { case "dead": return default: conn.Write([]byte(zkSrvrOut)) } case "cons": switch thing { case "dead": return default: conn.Write([]byte(zkConsOut)) } default: conn.Write([]byte("This ZooKeeper instance is not currently serving requests.")) } }