/**
   * Multiple threads (NUM_THREADS) send messages (NUM_MSGS)
   *
   * @throws Exception
   */
  @Test(dataProvider = "provider")
  public void testMessageReceptionUnderHighLoad(String props) throws Exception {
    CountDownLatch latch = new CountDownLatch(1);
    c1 = new JChannel(props);
    c2 = new JChannel(props);
    MyReceiver r1 = new MyReceiver("c1"), r2 = new MyReceiver("c2");
    c1.setReceiver(r1);
    c2.setReceiver(r2);
    c1.connect("testSimpleMessageReception");
    c2.connect("testSimpleMessageReception");

    Address c1_addr = c1.getAddress(), c2_addr = c2.getAddress();
    MySender[] c1_senders = new MySender[NUM_THREADS];
    for (int i = 0; i < c1_senders.length; i++) {
      c1_senders[i] = new MySender(c1, c2_addr, latch);
      c1_senders[i].start();
    }
    MySender[] c2_senders = new MySender[NUM_THREADS];
    for (int i = 0; i < c2_senders.length; i++) {
      c2_senders[i] = new MySender(c2, c1_addr, latch);
      c2_senders[i].start();
    }

    Util.sleep(500);
    latch.countDown(); // starts all threads

    long NUM_EXPECTED_MSGS = NUM_THREADS * NUM_MSGS;

    for (int i = 0; i < 20; i++) {
      if (r1.getNum() == NUM_EXPECTED_MSGS && r2.getNum() == NUM_EXPECTED_MSGS) break;
      Util.sleep(2000);
      UNICAST2 unicast2 = (UNICAST2) c1.getProtocolStack().findProtocol(UNICAST2.class);
      if (unicast2 != null) unicast2.sendStableMessages();
      unicast2 = (UNICAST2) c2.getProtocolStack().findProtocol(UNICAST2.class);
      if (unicast2 != null) unicast2.sendStableMessages();
    }

    System.out.println(
        "c1 received "
            + r1.getNum()
            + " msgs, "
            + getNumberOfRetransmissions(c1)
            + " retransmissions");
    System.out.println(
        "c2 received "
            + r2.getNum()
            + " msgs, "
            + getNumberOfRetransmissions(c2)
            + " retransmissions");

    assert r1.getNum() == NUM_EXPECTED_MSGS
        : "expected " + NUM_EXPECTED_MSGS + ", but got " + r1.getNum();
    assert r2.getNum() == NUM_EXPECTED_MSGS
        : "expected " + NUM_EXPECTED_MSGS + ", but got " + r2.getNum();
  }
  @Test(dataProvider = "provider")
  public void testSimpleMessageReception(String props) throws Exception {
    c1 = new JChannel(props);
    c2 = new JChannel(props);
    MyReceiver r1 = new MyReceiver("c1"), r2 = new MyReceiver("c2");
    c1.setReceiver(r1);
    c2.setReceiver(r2);
    c1.connect("testSimpleMessageReception");
    c2.connect("testSimpleMessageReception");

    int NUM = 100;
    Address c1_addr = c1.getAddress(), c2_addr = c2.getAddress();
    for (int i = 1; i <= NUM; i++) {
      c1.send(c1_addr, "bla");
      c1.send(c2_addr, "bla");
      c2.send(c2_addr, "bla");
      c2.send(c1_addr, "bla");
    }

    for (int i = 0; i < 10; i++) {
      if (r1.getNum() == NUM * 2 && r2.getNum() == NUM * 2) break;
      Util.sleep(500);
    }

    System.out.println(
        "c1 received "
            + r1.getNum()
            + " msgs, "
            + getNumberOfRetransmissions(c1)
            + " retransmissions");
    System.out.println(
        "c2 received "
            + r2.getNum()
            + " msgs, "
            + getNumberOfRetransmissions(c2)
            + " retransmissions");

    assert r1.getNum() == NUM * 2 : "expected " + NUM * 2 + ", but got " + r1.getNum();
    assert r2.getNum() == NUM * 2 : "expected " + NUM * 2 + ", but got " + r2.getNum();
  }