PageRenderTime 884ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/components/core-glue/src/test/java/org/limewire/core/impl/browse/FriendBrowseDownloadRUDPTest.java

https://github.com/r3n/limewire5-ruby
Java | 294 lines | 221 code | 53 blank | 20 comment | 12 complexity | af16c9a3812cb103a7fe3b455110acd0 MD5 | raw file
Possible License(s): LGPL-2.1
  1. package org.limewire.core.impl.browse;
  2. import java.beans.PropertyChangeEvent;
  3. import java.beans.PropertyChangeListener;
  4. import java.net.URI;
  5. import java.util.ArrayList;
  6. import java.util.Collection;
  7. import java.util.Collections;
  8. import java.util.HashSet;
  9. import java.util.List;
  10. import java.util.Map;
  11. import java.util.Set;
  12. import java.util.concurrent.ConcurrentHashMap;
  13. import java.util.concurrent.CountDownLatch;
  14. import java.util.concurrent.TimeUnit;
  15. import org.limewire.concurrent.ListeningFuture;
  16. import org.limewire.core.api.URN;
  17. import org.limewire.core.api.browse.BrowseListener;
  18. import org.limewire.core.api.download.DownloadItem;
  19. import org.limewire.core.api.download.DownloadListManager;
  20. import org.limewire.core.api.download.DownloadState;
  21. import org.limewire.core.api.download.SaveLocationException;
  22. import org.limewire.core.api.friend.feature.FeatureEvent;
  23. import org.limewire.core.api.friend.feature.features.AddressFeature;
  24. import org.limewire.core.api.search.SearchResult;
  25. import org.limewire.core.impl.CoreGlueModule;
  26. import org.limewire.core.impl.search.QueryReplyListenerList;
  27. import org.limewire.core.impl.search.RemoteFileDescAdapter;
  28. import org.limewire.core.impl.xmpp.XMPPRemoteFileDescDeserializer;
  29. import org.limewire.gnutella.tests.LimeTestCase;
  30. import org.limewire.io.IpPort;
  31. import org.limewire.io.UnresolvedIpPort;
  32. import org.limewire.lifecycle.ServiceRegistry;
  33. import org.limewire.listener.EventListener;
  34. import org.limewire.listener.ListenerSupport;
  35. import org.limewire.logging.Log;
  36. import org.limewire.logging.LogFactory;
  37. import org.limewire.xmpp.api.client.Presence;
  38. import org.limewire.xmpp.api.client.RosterEvent;
  39. import org.limewire.xmpp.api.client.User;
  40. import org.limewire.xmpp.api.client.XMPPAddress;
  41. import org.limewire.xmpp.api.client.XMPPConnection;
  42. import org.limewire.xmpp.api.client.XMPPConnectionConfiguration;
  43. import org.limewire.xmpp.api.client.XMPPService;
  44. import com.google.inject.Guice;
  45. import com.google.inject.Injector;
  46. import com.google.inject.Key;
  47. import com.google.inject.Module;
  48. import com.google.inject.Stage;
  49. import com.google.inject.TypeLiteral;
  50. import com.limegroup.gnutella.LimeWireCoreModule;
  51. import com.limegroup.gnutella.RemoteFileDesc;
  52. import com.limegroup.gnutella.SearchServices;
  53. /**
  54. *
  55. * Test browse/downloads over a real life network.
  56. */
  57. public class FriendBrowseDownloadRUDPTest extends LimeTestCase {
  58. private static Log LOG = LogFactory.getLog(FriendBrowseDownloadRUDPTest.class);
  59. private static final int SECONDS_TO_WAIT = 10;
  60. private static final String USERNAME_1 = "limenetworktest1@gmail.com";
  61. private static final String FRIEND = "limenetworktest2@gmail.com";
  62. private static final String PASSWORD_1 = "limebuddy123";
  63. private static final String SERVICE = "gmail.com";
  64. private XMPPConnection conn;
  65. private ServiceRegistry registry;
  66. protected XMPPService service;
  67. protected Injector injector;
  68. public FriendBrowseDownloadRUDPTest(String name) {
  69. super(name);
  70. }
  71. @Override
  72. protected void setUp() throws Exception {
  73. injector = createInjector(getModules());
  74. registry = injector.getInstance(ServiceRegistry.class);
  75. registry.initialize();
  76. registry.start();
  77. service = injector.getInstance(XMPPService.class);
  78. XMPPConnectionConfiguration config = getDefaultXmppConnectionConfig(USERNAME_1, PASSWORD_1, SERVICE);
  79. ListeningFuture<XMPPConnection> loginTask = service.login(config);
  80. conn = loginTask.get(SECONDS_TO_WAIT, TimeUnit.SECONDS);
  81. }
  82. @Override
  83. public void tearDown() throws Exception {
  84. service.logout();
  85. registry.stop();
  86. }
  87. private Injector createInjector(Module... modules) {
  88. return Guice.createInjector(Stage.PRODUCTION, modules);
  89. }
  90. private XMPPConnectionConfiguration getDefaultXmppConnectionConfig(final String userName, final String passwd,
  91. final String serviceName) {
  92. return new XMPPConnectionConfiguration() {
  93. @Override public boolean isDebugEnabled() { return true; }
  94. @Override public String getUserInputLocalID() { return userName; }
  95. @Override public String getPassword() { return passwd; }
  96. @Override public String getLabel() { return getServiceName(); }
  97. @Override public String getServiceName() { return serviceName; }
  98. @Override public String getResource() { return "LimeWire"; }
  99. @Override public EventListener<RosterEvent> getRosterListener() { return null; }
  100. @Override public String getCanonicalizedLocalID() { return getUserInputLocalID(); }
  101. @Override public String getNetworkName() { return getServiceName(); }
  102. @Override public List<UnresolvedIpPort> getDefaultServers() { return UnresolvedIpPort.EMPTY_LIST;}
  103. };
  104. }
  105. private Module[] getModules() {
  106. List<Module> modules = new ArrayList<Module>();
  107. modules.add(new LimeWireCoreModule());
  108. modules.add(new CoreGlueModule());
  109. return modules.toArray(new Module[modules.size()]);
  110. }
  111. /**
  112. * Tests browsing a friend, and downloading a file from one of the browse results
  113. *
  114. */
  115. public void testBrowseDownloadFromFriendBehindFirewall() throws Exception {
  116. waitForFeature(AddressFeature.ID, FRIEND);
  117. Collection<Presence> presences = conn.getUser(FRIEND).getPresences().values();
  118. assertEquals(1, presences.size());
  119. Presence presence = presences.iterator().next();
  120. SearchServices searchServices = injector.getInstance(SearchServices.class);
  121. QueryReplyListenerList queryReplyListenerList = injector.getInstance(QueryReplyListenerList.class);
  122. CoreBrowse coreBrowse = new CoreBrowse(presence, searchServices, queryReplyListenerList);
  123. BrowseStatistics browser = new BrowseStatistics(presence);
  124. coreBrowse.start(browser);
  125. Map<String, SearchResult> browseResults = waitForBrowse(browser);
  126. // checking browse results
  127. assertEquals(4, browseResults.size());
  128. assertEquals("urn:sha1:M44YAZ2RDV2A5ZF4XLWGCTWIXE63F7M2", browseResults.get("2610431487_a7f2e127e7.jpg").getUrn().toString());
  129. assertEquals("urn:sha1:DQCI4IOVHEHNR3BWOUKANM2S2AMVUVFN", browseResults.get("2611264598_f5b419bbd1.jpg").getUrn().toString());
  130. assertEquals("urn:sha1:TGYN5XX62CLPKGMINUL2ZU3GVBMWTXEQ", browseResults.get("2611264634_c650e4fd81.jpg").getUrn().toString());
  131. assertEquals("urn:sha1:FEZP6EIMEPRXUEHSRQNEBJB3JNYBUNEC", browseResults.get("2611264936_6103872e4d.jpg").getUrn().toString());
  132. // test downloading from buddy
  133. String fileNameToDownload = "2611264598_f5b419bbd1.jpg";
  134. URN urnOfFile = browseResults.get(fileNameToDownload).getUrn();
  135. SearchResult resultToDownload = browseResults.get(fileNameToDownload);
  136. List<SearchResult> toDownload = Collections.singletonList(resultToDownload);
  137. DownloadListManager downloader = injector.getInstance(DownloadListManager.class);
  138. DownloadItem dlItem = downloader.getDownloadItem(urnOfFile);
  139. try {
  140. dlItem = downloader.addDownload(null, toDownload);
  141. waitForDownloadCompletion(dlItem);
  142. } catch (SaveLocationException e) {
  143. e.printStackTrace();
  144. fail("Failed to save the file: " + e.getMessage());
  145. }
  146. // check size of downloaded file
  147. assertEquals(142682L, dlItem.getTotalSize());
  148. }
  149. private Map<String, SearchResult> waitForBrowse(BrowseStatistics browse) throws Exception {
  150. return browse.waitForBrowseToFinish();
  151. }
  152. private void waitForDownloadCompletion(final DownloadItem dlItem) throws Exception {
  153. // check to see if download is already done.
  154. if (dlItem.getState() == DownloadState.DONE) {
  155. return;
  156. }
  157. final CountDownLatch latch = new CountDownLatch(1);
  158. int downloadTimeLimit = SECONDS_TO_WAIT;
  159. dlItem.addPropertyChangeListener(new PropertyChangeListener() {
  160. public void propertyChange(PropertyChangeEvent evt) {
  161. if ("state".equals(evt.getPropertyName())) {
  162. DownloadState state = (DownloadState) evt.getNewValue();
  163. if (state == DownloadState.DONE) {
  164. latch.countDown();
  165. }
  166. LOG.debugf("current download state: {0}", state);
  167. }
  168. }
  169. });
  170. assertTrue("Download not completed within " + downloadTimeLimit + " seconds",
  171. latch.await(downloadTimeLimit, TimeUnit.SECONDS));
  172. }
  173. private void waitForFeature(final URI featureUri, final String friendId) throws Exception {
  174. int featureWaitTimeout = SECONDS_TO_WAIT;
  175. final CountDownLatch latch = new CountDownLatch(1);
  176. final ListenerSupport<FeatureEvent> featureListener =
  177. injector.getInstance(Key.get(new TypeLiteral<ListenerSupport<FeatureEvent>>() {
  178. }));
  179. final EventListener<FeatureEvent> listener = new EventListener<FeatureEvent>() {
  180. public void handleEvent(FeatureEvent event) {
  181. if (event.getType() == FeatureEvent.Type.ADDED &&
  182. event.getData().getID().equals(featureUri) &&
  183. event.getSource().getFriend().getId().equals(friendId)) {
  184. latch.countDown();
  185. featureListener.removeListener(this);
  186. }
  187. }
  188. };
  189. featureListener.addListener(listener);
  190. // check for the feature in case it already came in prior to listener being added
  191. User user = conn.getUser(friendId);
  192. if (user != null && !user.getPresences().isEmpty()) {
  193. // friend already signed in
  194. Presence presence = conn.getUser(friendId).getPresences().values().iterator().next();
  195. if (presence.getFeature(featureUri) != null) {
  196. return;
  197. }
  198. }
  199. // wait at most 5 seconds for feature to be detected
  200. assertTrue("Feature " + featureUri + " not detected in " + featureWaitTimeout + " seconds.",
  201. latch.await(featureWaitTimeout, TimeUnit.SECONDS));
  202. }
  203. private class BrowseStatistics implements BrowseListener {
  204. private final Map<String, SearchResult> searchResults;
  205. private final CountDownLatch latch;
  206. private final XMPPRemoteFileDescDeserializer searchResultToXmppAdapter;
  207. private final Presence presence;
  208. BrowseStatistics(Presence presence) {
  209. this.presence = presence;
  210. this.searchResultToXmppAdapter = injector.getInstance(XMPPRemoteFileDescDeserializer.class);
  211. this.searchResults = new ConcurrentHashMap<String, SearchResult>();
  212. this.latch = new CountDownLatch(1);
  213. }
  214. public void handleBrowseResult(SearchResult searchResult) {
  215. SearchResult adaptedSearchResultWithXmppAddress = convertToXmppCompatibleSearchResult(searchResult);
  216. searchResults.put(searchResult.getFileName(), adaptedSearchResultWithXmppAddress);
  217. }
  218. public void browseFinished(boolean success) {
  219. latch.countDown();
  220. }
  221. /**
  222. * This method (hack) is necessary because it is not currently possible to perform a
  223. * friend browse, and use the results of the browse ({@link SearchResult} objects) for
  224. * downloading, because the FriendPresence contained in such a SearchResult is a GnutellaPresence
  225. */
  226. private SearchResult convertToXmppCompatibleSearchResult(SearchResult gnutellaOnlySearchResult) {
  227. RemoteFileDescAdapter rfdAdapter = (RemoteFileDescAdapter)gnutellaOnlySearchResult;
  228. RemoteFileDesc oldRfd = rfdAdapter.getRfd();
  229. XMPPAddress xmppAddress = new XMPPAddress(presence.getJID());
  230. RemoteFileDesc newRfd = searchResultToXmppAdapter.promoteRemoteFileDescAndExchangeAddress(oldRfd, xmppAddress);
  231. Set<IpPort> ipPort = new HashSet<IpPort>();
  232. ipPort.addAll(rfdAdapter.getAlts());
  233. return new RemoteFileDescAdapter(newRfd, ipPort);
  234. }
  235. public Map<String, SearchResult> waitForBrowseToFinish() throws InterruptedException {
  236. assertTrue("Browse not completed within " + SECONDS_TO_WAIT + " seconds",
  237. latch.await(SECONDS_TO_WAIT, TimeUnit.SECONDS));
  238. return searchResults;
  239. }
  240. }
  241. }