/** tests that an uploader will pass a push loc which will be included in the swarm */
  public void testUploaderPassesPushLoc() throws Exception {
    LOG.info("-Testing swarming from two sources one based on a push alt...");
    final int RATE = 500;
    testUploaders[0].setRate(RATE);
    testUploaders[0].stopAfter(800000);

    TestUploader pusher = injector.getInstance(TestUploader.class);
    pusher.start("push uploader");
    pusher.setRate(RATE);

    GUID guid = new GUID();
    AlternateLocation pushLoc =
        alternateLocationFactory.create(
            guid.toHexString() + ";127.0.0.1:" + PPORT_1, TestFile.hash());

    AlternateLocationCollection<AlternateLocation> alCol =
        AlternateLocationCollection.create(TestFile.hash());
    alCol.add(pushLoc);

    testUploaders[0].setGoodAlternateLocations(alCol);

    RemoteFileDesc rfd = newRFDWithURN(PORTS[0], TestFile.hash().toString(), false);

    RemoteFileDesc[] rfds = {rfd};

    testUDPAcceptorFactoryImpl.createTestUDPAcceptor(
        PPORT_1, networkManager.getPort(), savedFile.getName(), pusher, guid, _currentTestName);

    tGeneric(rfds);

    assertGreaterThan(
        "u1 didn't do enough work ", 100 * 1024, testUploaders[0].fullRequestsUploaded());
    assertGreaterThan("pusher didn't do enough work ", 100 * 1024, pusher.fullRequestsUploaded());
  }
  /**
   * Utility method for converting the non-firewalled elements of an AlternateLocationCollection to
   * a smaller set of endpoints.
   */
  private static Set getAsEndpoints(AlternateLocationCollection col) {
    if (col == null || !col.hasAlternateLocations()) return Collections.EMPTY_SET;

    long now = System.currentTimeMillis();
    synchronized (col) {
      Set endpoints = null;
      int i = 0;
      for (Iterator iter = col.iterator(); iter.hasNext() && i < MAX_LOCATIONS; ) {
        Object o = iter.next();
        if (!(o instanceof DirectAltLoc)) continue;
        DirectAltLoc al = (DirectAltLoc) o;
        if (al.canBeSent(AlternateLocation.MESH_RESPONSE)) {
          IpPort host = al.getHost();
          if (!NetworkUtils.isMe(host)) {
            if (endpoints == null) endpoints = new HashSet();

            if (!(host instanceof Endpoint)) host = new Endpoint(host.getAddress(), host.getPort());

            endpoints.add(host);
            i++;
            al.send(now, AlternateLocation.MESH_RESPONSE);
          }
        } else if (!al.canBeSentAny()) iter.remove();
      }
      return endpoints == null ? Collections.EMPTY_SET : endpoints;
    }
  }
  /** tests that bad push locs get removed */
  public void testBadPushLocGetsDemotedNotAdvertised() throws Exception {
    setDownloadWaitTime(2 * DOWNLOAD_WAIT_TIME);
    LOG.info("test that bad push loc gets demoted and not advertised");
    // this test needs to go slowly so that the push attempt may time out
    final int RATE = 15;

    testUploaders[0].setInterestedInFalts(true);
    testUploaders[1].setInterestedInFalts(true);
    testUploaders[0].setRate(RATE);
    testUploaders[1].setRate(RATE);
    testUploaders[0].stopAfter(550000);
    testUploaders[1].stopAfter(550000);

    GUID guid = new GUID();
    AlternateLocation badPushLoc =
        alternateLocationFactory.create(guid.toHexString() + ";1.2.3.4:5", TestFile.hash());
    ((PushAltLoc) badPushLoc).updateProxies(true);

    AlternateLocationCollection<AlternateLocation> alc =
        AlternateLocationCollection.create(TestFile.hash());

    alc.add(badPushLoc);

    testUploaders[0].setGoodAlternateLocations(alc);

    RemoteFileDesc rfd1 = newRFDWithURN(PORTS[0], false);
    RemoteFileDesc rfd2 = newRFDWithURN(PORTS[1], false);

    RemoteFileDesc[] rfds = {rfd1, rfd2};

    tGeneric(rfds);

    assertGreaterThan("u1 did no work", 100 * 1024, testUploaders[0].fullRequestsUploaded());
    assertGreaterThan("u2 did no work", 100 * 1024, testUploaders[1].fullRequestsUploaded());

    assertFalse(
        "bad pushloc got advertised",
        testUploaders[1].getIncomingGoodAltLocs().contains(badPushLoc));
    assertEquals(1, testUploaders[0].getIncomingGoodAltLocs().size());
    assertTrue(
        testUploaders[0].getIncomingGoodAltLocs().contains(alternateLocationFactory.create(rfd2)));

    assertEquals(1, testUploaders[0].getIncomingBadAltLocs().size());
    AlternateLocation current = testUploaders[0].getIncomingBadAltLocs().get(0);
    assertTrue(current instanceof PushAltLoc);
    PushAltLoc pcurrent = (PushAltLoc) current;
    assertEquals(guid.bytes(), pcurrent.getPushAddress().getClientGUID());

    // Now get the PE from our cache and make sure no proxies exist & its demoted.
    PushEndpoint pe = injector.getInstance(PushEndpointCache.class).getPushEndpoint(guid);
    assertTrue("pe: " + pe, pe.getProxies().isEmpty());
    assertTrue("pe: " + pe, badPushLoc.isDemoted());
  }
  /**
   * tests that a push uploader passes push loc and the new push loc receives the first uploader as
   * an altloc.
   */
  public void testPushUploaderPassesPushLoc() throws Exception {
    LOG.info("Test push uploader passes push loc");
    final int RATE = 500;

    TestUploader first = injector.getInstance(TestUploader.class);
    first.start("first pusher");
    first.setRate(RATE / 3);
    first.stopAfter(700000);

    TestUploader second = injector.getInstance(TestUploader.class);
    second.start("second pusher");
    second.setRate(RATE);
    second.stopAfter(700000);
    second.setInterestedInFalts(true);

    GUID guid = new GUID();
    GUID guid2 = new GUID(GUID.makeGuid());

    AlternateLocation firstLoc =
        alternateLocationFactory.create(
            guid.toHexString() + ";127.0.0.2:" + PPORT_1, TestFile.hash());

    AlternateLocation pushLoc =
        alternateLocationFactory.create(
            guid2.toHexString() + ";127.0.0.2:" + PPORT_2, TestFile.hash());

    AlternateLocationCollection<AlternateLocation> alCol =
        AlternateLocationCollection.create(TestFile.hash());
    alCol.add(pushLoc);

    first.setGoodAlternateLocations(alCol);

    testUDPAcceptorFactoryImpl.createTestUDPAcceptor(
        PPORT_1, networkManager.getPort(), savedFile.getName(), first, guid, _currentTestName);
    testUDPAcceptorFactoryImpl.createTestUDPAcceptor(
        PPORT_2, networkManager.getPort(), savedFile.getName(), second, guid2, _currentTestName);

    RemoteFileDesc[] rfd = {newRFDPush(guid, PPORT_1, 1, 2)};

    tGeneric(rfd);

    assertGreaterThan("first pusher did no work", 100000, first.fullRequestsUploaded());
    assertGreaterThan("second pusher did no work", 100000, second.fullRequestsUploaded());

    assertEquals(1, second.getIncomingGoodAltLocs().size());

    assertTrue(
        "interested uploader didn't get first loc",
        second.getIncomingGoodAltLocs().contains(firstLoc));
  }