| 1512 | } |
| 1513 | |
| 1514 | func TestNoPanicOnSrvPoolSizeChanging(t *testing.T) { |
| 1515 | listeners := []net.Listener{} |
| 1516 | ports := []int{} |
| 1517 | |
| 1518 | for i := 0; i < 3; i++ { |
| 1519 | l, err := net.Listen("tcp", "127.0.0.1:0") |
| 1520 | if err != nil { |
| 1521 | t.Fatalf("Could not listen on an ephemeral port: %v", err) |
| 1522 | } |
| 1523 | defer l.Close() |
| 1524 | tl := l.(*net.TCPListener) |
| 1525 | ports = append(ports, tl.Addr().(*net.TCPAddr).Port) |
| 1526 | listeners = append(listeners, l) |
| 1527 | } |
| 1528 | |
| 1529 | wg := sync.WaitGroup{} |
| 1530 | wg.Add(len(listeners)) |
| 1531 | |
| 1532 | connect := int32(0) |
| 1533 | srv := func(l net.Listener) { |
| 1534 | defer wg.Done() |
| 1535 | for { |
| 1536 | conn, err := l.Accept() |
| 1537 | if err != nil { |
| 1538 | return |
| 1539 | } |
| 1540 | defer conn.Close() |
| 1541 | |
| 1542 | var info string |
| 1543 | |
| 1544 | reject := atomic.AddInt32(&connect, 1) <= 2 |
| 1545 | if reject { |
| 1546 | // Sends a list of 3 servers, where the second does not actually run. |
| 1547 | // This server is going to reject the connect (with auth error), so |
| 1548 | // client will move to 2nd, fail, then go to third... |
| 1549 | info = fmt.Sprintf("INFO {\"server_id\":\"foobar\",\"connect_urls\":[\"127.0.0.1:%d\",\"127.0.0.1:%d\",\"127.0.0.1:%d\"]}\r\n", |
| 1550 | ports[0], ports[1], ports[2]) |
| 1551 | } else { |
| 1552 | // This third server will return the INFO with only the original server |
| 1553 | // and the third one, which will make the srvPool size shrink down to 2. |
| 1554 | info = fmt.Sprintf("INFO {\"server_id\":\"foobar\",\"connect_urls\":[\"127.0.0.1:%d\",\"127.0.0.1:%d\"]}\r\n", |
| 1555 | ports[0], ports[2]) |
| 1556 | } |
| 1557 | conn.Write([]byte(info)) |
| 1558 | |
| 1559 | // Read connect and ping commands sent from the client |
| 1560 | br := bufio.NewReaderSize(conn, 10*1024) |
| 1561 | br.ReadLine() |
| 1562 | br.ReadLine() |
| 1563 | |
| 1564 | if reject { |
| 1565 | conn.Write([]byte(fmt.Sprintf("-ERR '%s'\r\n", AUTHORIZATION_ERR))) |
| 1566 | conn.Close() |
| 1567 | } else { |
| 1568 | conn.Write([]byte(pongProto)) |
| 1569 | br.ReadLine() |
| 1570 | } |
| 1571 | } |