1 /*******************************************************************************
2  *  Copyright (c) 2007, 2018 IBM Corporation and others.
3  *
4  *  This program and the accompanying materials
5  *  are made available under the terms of the Eclipse Public License 2.0
6  *  which accompanies this distribution, and is available at
7  *  https://www.eclipse.org/legal/epl-2.0/
8  *
9  *  SPDX-License-Identifier: EPL-2.0
10  *
11  *  Contributors:
12  *     IBM Corporation - initial API and implementation
13  *     Red Hat Inc. - Bug 460967
14  *******************************************************************************/
15 package org.eclipse.equinox.p2.tests.metadata.repository;
16 
17 import java.io.File;
18 import java.io.IOException;
19 import java.io.PrintStream;
20 import java.lang.reflect.Field;
21 import java.net.URI;
22 import java.net.URISyntaxException;
23 import java.util.ArrayList;
24 import java.util.List;
25 import junit.framework.Test;
26 import junit.framework.TestSuite;
27 import org.eclipse.core.runtime.IProgressMonitor;
28 import org.eclipse.core.runtime.IStatus;
29 import org.eclipse.core.runtime.NullProgressMonitor;
30 import org.eclipse.core.runtime.Status;
31 import org.eclipse.core.runtime.URIUtil;
32 import org.eclipse.core.runtime.jobs.Job;
33 import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
34 import org.eclipse.equinox.internal.p2.metadata.repository.SimpleMetadataRepositoryFactory;
35 import org.eclipse.equinox.internal.p2.repository.helpers.AbstractRepositoryManager;
36 import org.eclipse.equinox.internal.p2.updatesite.metadata.UpdateSiteMetadataRepositoryFactory;
37 import org.eclipse.equinox.internal.provisional.p2.core.eventbus.SynchronousProvisioningListener;
38 import org.eclipse.equinox.internal.provisional.p2.repository.RepositoryEvent;
39 import org.eclipse.equinox.p2.core.IAgentLocation;
40 import org.eclipse.equinox.p2.core.ProvisionException;
41 import org.eclipse.equinox.p2.metadata.IInstallableUnit;
42 import org.eclipse.equinox.p2.query.IQueryResult;
43 import org.eclipse.equinox.p2.query.QueryUtil;
44 import org.eclipse.equinox.p2.repository.IRepository;
45 import org.eclipse.equinox.p2.repository.IRepositoryManager;
46 import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
47 import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
48 import org.eclipse.equinox.p2.repository.metadata.spi.MetadataRepositoryFactory;
49 import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
50 import org.eclipse.equinox.p2.tests.FailingMetadataRepositoryFactory;
51 import org.eclipse.equinox.p2.tests.StringBufferStream;
52 import org.eclipse.equinox.p2.tests.TestActivator;
53 import org.eclipse.equinox.p2.tests.TestRepositoryListener;
54 
55 /**
56  * Tests for API of {@link IMetadataRepositoryManager}.
57  */
58 public class MetadataRepositoryManagerTest extends AbstractProvisioningTest {
59 	protected IMetadataRepositoryManager manager;
60 	/**
61 	 * Contains temp File handles that should be deleted at the end of the test.
62 	 */
63 	private final List<File> toDelete = new ArrayList<>();
64 
suite()65 	public static Test suite() {
66 		return new TestSuite(MetadataRepositoryManagerTest.class);
67 	}
68 
69 	@Override
setUp()70 	protected void setUp() throws Exception {
71 		super.setUp();
72 		manager = getAgent().getService(IMetadataRepositoryManager.class);
73 		//only enable the failing repository factory for this test to avoid noise in other tests.
74 		FailingMetadataRepositoryFactory.FAIL = true;
75 	}
76 
77 	@Override
tearDown()78 	protected void tearDown() throws Exception {
79 		super.tearDown();
80 		for (File file : toDelete) {
81 			delete(file);
82 		}
83 		toDelete.clear();
84 		FailingMetadataRepositoryFactory.FAIL = false;
85 	}
86 
testBasicAddRemove()87 	public void testBasicAddRemove() {
88 		File tempFile = new File(System.getProperty("java.io.tmpdir"));
89 		URI location = tempFile.toURI();
90 		assertTrue(!managerContains(location));
91 		manager.addRepository(location);
92 		assertTrue(managerContains(location));
93 		manager.removeRepository(location);
94 		assertTrue(!managerContains(location));
95 	}
96 
97 	/**
98 	 * Tests for {@link IRepositoryManager#contains(URI).
99 	 */
testContains()100 	public void testContains() {
101 		File site = getTestData("Repositoy", "/testData/metadataRepo/good/");
102 		URI location = site.toURI();
103 		manager.removeRepository(location);
104 		assertEquals("1.0", false, manager.contains(location));
105 		manager.addRepository(location);
106 		assertEquals("1.1", true, manager.contains(location));
107 		manager.removeRepository(location);
108 		assertEquals("1.2", false, manager.contains(location));
109 	}
110 
testEnablement()111 	public void testEnablement() {
112 		File site = getTestData("Repositoy", "/testData/metadataRepo/good/");
113 		URI location = site.toURI();
114 		manager.addRepository(location);
115 		assertEquals("1.0", true, manager.isEnabled(location));
116 		TestRepositoryListener listener = new TestRepositoryListener(location);
117 		getEventBus().addListener(listener);
118 
119 		manager.setEnabled(location, false);
120 		listener.waitForEvent();
121 		assertEquals("2.0", false, listener.lastEnablement);
122 		assertEquals("2.1", false, manager.isEnabled(location));
123 		listener.reset();
124 
125 		manager.setEnabled(location, true);
126 		listener.waitForEvent();
127 		assertEquals("3.0", true, listener.lastEnablement);
128 		assertEquals("3.1", true, manager.isEnabled(location));
129 		listener.reset();
130 	}
131 
132 	/**
133 	 * Adds a repository that has a non-standard (non ECF) scheme.  This should
134 	 * return REPOSITORY_NOT_FOUND, since any other status code gets logged.
135 	 *
136 	 * @throws URISyntaxException
137 	 */
testFailedConnection()138 	public void testFailedConnection() throws URISyntaxException {
139 		URI location = new URI("invalid://example");
140 		MetadataRepositoryFactory factory;
141 
142 		factory = new SimpleMetadataRepositoryFactory();
143 		factory.setAgent(getAgent());
144 		try {
145 			factory.load(location, 0, new NullProgressMonitor());
146 		} catch (ProvisionException e) {
147 			assertEquals(ProvisionException.REPOSITORY_NOT_FOUND, e.getStatus().getCode());
148 		}
149 		factory = new UpdateSiteMetadataRepositoryFactory();
150 		factory.setAgent(getAgent());
151 		try {
152 			factory.load(location, 0, new NullProgressMonitor());
153 		} catch (ProvisionException e) {
154 			assertEquals(ProvisionException.REPOSITORY_NOT_FOUND, e.getStatus().getCode());
155 		}
156 	}
157 
158 	/**
159 	 * Tests that adding a repository that is already known but disabled
160 	 * causes the repository to be enabled. See bug 241307 for discussion.
161 	 */
testEnablementOnAdd()162 	public void testEnablementOnAdd() {
163 		File site = getTestData("Repositoy", "/testData/metadataRepo/good/");
164 		URI location = site.toURI();
165 		manager.addRepository(location);
166 		manager.setEnabled(location, false);
167 		TestRepositoryListener listener = new TestRepositoryListener(location);
168 		getEventBus().addListener(listener);
169 
170 		//adding the location again should cause it to be enabled
171 		manager.addRepository(location);
172 		listener.waitForEvent();
173 		assertEquals("1.0", true, listener.lastEnablement);
174 		assertEquals("1.1", true, manager.isEnabled(location));
175 	}
176 
testGetKnownRepositories()177 	public void testGetKnownRepositories() throws ProvisionException {
178 		int nonSystemCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_NON_SYSTEM).length;
179 		int systemCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_SYSTEM).length;
180 		int allCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL).length;
181 		assertEquals("1.0", allCount, nonSystemCount + systemCount);
182 
183 		//create a new repository
184 		File repoLocation = getTempLocation();
185 		IMetadataRepository testRepo = manager.createRepository(repoLocation.toURI(), "MetadataRepositoryManagerTest", IMetadataRepositoryManager.TYPE_SIMPLE_REPOSITORY, null);
186 		int newNonSystemCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_NON_SYSTEM).length;
187 		int newSystemCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_SYSTEM).length;
188 		int newAllCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL).length;
189 
190 		//there should be one more non-system repository
191 		assertEquals("2.0", nonSystemCount + 1, newNonSystemCount);
192 		assertEquals("2.1", systemCount, newSystemCount);
193 		assertEquals("2.2", allCount + 1, newAllCount);
194 
195 		//make the repository a system repository
196 		testRepo.setProperty(IRepository.PROP_SYSTEM, Boolean.TRUE.toString());
197 
198 		//there should be one more system repository
199 		newNonSystemCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_NON_SYSTEM).length;
200 		newSystemCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_SYSTEM).length;
201 		newAllCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL).length;
202 		assertEquals("3.0", nonSystemCount, newNonSystemCount);
203 		assertEquals("3.1", systemCount + 1, newSystemCount);
204 		assertEquals("3.2", allCount + 1, newAllCount);
205 
206 		int disabledCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_DISABLED).length;
207 		allCount = newAllCount;
208 
209 		//mark the repository as disabled
210 		manager.setEnabled(testRepo.getLocation(), false);
211 
212 		//should be one less enabled repository and one more disabled repository
213 		int newDisabledCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_DISABLED).length;
214 		newAllCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL).length;
215 		assertEquals("4.0", disabledCount + 1, newDisabledCount);
216 		assertEquals("4.1", allCount - 1, newAllCount);
217 
218 		//re-loading the repository should not change anything
219 		manager.loadRepository(testRepo.getLocation(), null);
220 		newDisabledCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_DISABLED).length;
221 		newAllCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL).length;
222 		assertEquals("5.0", disabledCount + 1, newDisabledCount);
223 		assertEquals("5.1", allCount - 1, newAllCount);
224 
225 		//re-enable the repository
226 		manager.setEnabled(testRepo.getLocation(), true);
227 
228 		//should be back to the original counts
229 		newDisabledCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_DISABLED).length;
230 		newAllCount = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL).length;
231 		assertEquals("6.0", disabledCount, newDisabledCount);
232 		assertEquals("6.1", allCount, newAllCount);
233 	}
234 
235 	/**
236 	 * Tests contention for the repository load lock
237 	 */
testLoadContention()238 	public void testLoadContention() {
239 		File site = getTestData("Repositoy", "/testData/metadataRepo/good/");
240 		final URI location = site.toURI();
241 		final List<Exception> failures = new ArrayList<>();
242 		final IMetadataRepositoryManager repoManager = getMetadataRepositoryManager();
243 		class LoadJob extends Job {
244 			LoadJob() {
245 				super("");
246 			}
247 
248 			@Override
249 			protected IStatus run(IProgressMonitor monitor) {
250 				for (int i = 0; i < 100; i++) {
251 					try {
252 						repoManager.loadRepository(location, null);
253 					} catch (Exception e) {
254 						failures.add(e);
255 					}
256 				}
257 				return Status.OK_STATUS;
258 			}
259 		}
260 		Job job1 = new LoadJob();
261 		Job job2 = new LoadJob();
262 		job1.schedule();
263 		job2.schedule();
264 		try {
265 			job1.join();
266 			job2.join();
267 		} catch (InterruptedException e) {
268 			fail("4.99", e);
269 		}
270 		if (!failures.isEmpty())
271 			fail("1.0", failures.iterator().next());
272 	}
273 
274 	/**
275 	 * Tests loading a repository that does not exist throws an appropriate exception.
276 	 */
testLoadMissingRepository()277 	public void testLoadMissingRepository() throws IOException {
278 		File tempFile = File.createTempFile("testLoadMissingArtifactRepository", null);
279 		tempFile.delete();
280 		URI location = tempFile.toURI();
281 		PrintStream out = System.out;
282 		try {
283 			System.setOut(new PrintStream(new StringBufferStream()));
284 			manager.loadRepository(location, null);
285 			fail("1.0");//should fail
286 		} catch (ProvisionException e) {
287 			assertEquals("1.1", IStatus.ERROR, e.getStatus().getSeverity());
288 			assertEquals("1.2", ProvisionException.REPOSITORY_NOT_FOUND, e.getStatus().getCode());
289 		} finally {
290 			System.setOut(out);
291 		}
292 	}
293 
294 	/**
295 	 * Tests that loading a disabled system repository does not damage its properties.
296 	 * This is a regression test for bug 267707.
297 	 */
testLoadDisabledSystemRepository()298 	public void testLoadDisabledSystemRepository() throws ProvisionException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
299 		File site = getTestData("Repositoy", "/testData/metadataRepo/goodNonSystem/");
300 		URI location = site.toURI();
301 		manager.removeRepository(location);
302 		manager.addRepository(location);
303 		manager.setEnabled(location, false);
304 		manager.setRepositoryProperty(location, IRepository.PROP_SYSTEM, String.valueOf(true));
305 		manager.loadRepository(location, getMonitor());
306 
307 		//simulate shutdown/restart by bashing repository manager field
308 		Field field = AbstractRepositoryManager.class.getDeclaredField("repositories");
309 		field.setAccessible(true);
310 		field.set(manager, null);
311 
312 		String system = manager.getRepositoryProperty(location, IRepository.PROP_SYSTEM);
313 		assertEquals("true", system);
314 		assertFalse(manager.isEnabled(location));
315 
316 	}
317 
318 	/**
319 	 * Tests loading a repository that is malformed
320 	 */
testLoadBrokenRepository()321 	public void testLoadBrokenRepository() {
322 		File site = getTestData("Repository", "/testData/metadataRepo/bad/");
323 		URI location = site.toURI();
324 		PrintStream err = System.err;
325 		try {
326 			System.setErr(new PrintStream(new StringBufferStream()));
327 			manager.loadRepository(location, null);
328 			fail("1.0");//should fail
329 		} catch (ProvisionException e) {
330 			assertEquals("1.1", IStatus.ERROR, e.getStatus().getSeverity());
331 			assertEquals("1.2", ProvisionException.REPOSITORY_FAILED_READ, e.getStatus().getCode());
332 		} finally {
333 			System.setErr(err);
334 		}
335 	}
336 
337 	/**
338 	 * Tests loading a repository that is malformed, that is co-located with a well-formed
339 	 * update site repository. The load should fail due to the malformed simple repository,
340 	 * and not fall back to the well-formed update site repository. See bug 247566 for details.
341 	 */
testLoadBrokenSimpleRepositoryWithGoodUpdateSite()342 	public void testLoadBrokenSimpleRepositoryWithGoodUpdateSite() {
343 		File site = getTestData("Repository", "/testData/metadataRepo/badSimpleGoodUpdateSite/");
344 		URI location = site.toURI();
345 		PrintStream err = System.err;
346 		try {
347 			System.setErr(new PrintStream(new StringBufferStream()));
348 			manager.loadRepository(location, null);
349 			fail("1.0");//should fail
350 		} catch (ProvisionException e) {
351 			assertEquals("1.1", IStatus.ERROR, e.getStatus().getSeverity());
352 			assertEquals("1.2", ProvisionException.REPOSITORY_FAILED_READ, e.getStatus().getCode());
353 		} finally {
354 			System.setErr(err);
355 		}
356 	}
357 
358 	/**
359 	 * Tests that we don't create a local cache when contacting a local metadata repository.
360 	 */
testMetadataCachingLocalRepo()361 	public void testMetadataCachingLocalRepo() throws ProvisionException {
362 		File repoLocation = getTempLocation();
363 		IAgentLocation agentLocation = ServiceHelper.getService(TestActivator.getContext(), IAgentLocation.class);
364 		URI dataArea = agentLocation.getDataArea("org.eclipse.equinox.p2.metadata.repository/cache/");
365 		File dataAreaFile = URIUtil.toFile(dataArea);
366 		File cacheFileXML = new File(dataAreaFile, "content" + repoLocation.hashCode() + ".xml");
367 		File cacheFileJAR = new File(dataAreaFile, "content" + repoLocation.hashCode() + ".jar");
368 
369 		// create a local repository
370 		manager.createRepository(repoLocation.toURI(), "MetadataRepositoryCachingTest", IMetadataRepositoryManager.TYPE_SIMPLE_REPOSITORY, null);
371 		manager.loadRepository(repoLocation.toURI(), null);
372 
373 		// check that a local cache was not created
374 		assertFalse("Cache file was created.", cacheFileXML.exists() || cacheFileJAR.exists());
375 	}
376 
377 	/**
378 	 * Tests that local caching of remote metadata repositories works, and that the
379 	 * cache is updated when it becomes stale.
380 	 */
testMetadataCachingRemoteRepo()381 	public void testMetadataCachingRemoteRepo() throws URISyntaxException, ProvisionException {
382 		URI repoLocation = new URI("http://download.eclipse.org/eclipse/updates/3.4milestones/");
383 		if (!repoAvailable(repoLocation))
384 			return;
385 		IAgentLocation agentLocation = ServiceHelper.getService(TestActivator.getContext(), IAgentLocation.class);
386 		URI dataArea = agentLocation.getDataArea("org.eclipse.equinox.p2.metadata.repository/cache/");
387 		File dataAreaFile = URIUtil.toFile(dataArea);
388 		File cacheFileXML = new File(dataAreaFile, "content" + repoLocation.hashCode() + ".xml");
389 		File cacheFileJAR = new File(dataAreaFile, "content" + repoLocation.hashCode() + ".jar");
390 		File cacheFile;
391 
392 		// load a remote repository and check that a local cache was created
393 		manager.loadRepository(repoLocation, null);
394 		assertTrue("Cache file was not created.", cacheFileXML.exists() || cacheFileJAR.exists());
395 		if (cacheFileXML.exists())
396 			cacheFile = cacheFileXML;
397 		else
398 			cacheFile = cacheFileJAR;
399 
400 		// modify the last modified date to be older than the remote file
401 		cacheFile.setLastModified(0);
402 		// reload the repository and check that the cache was updated
403 		manager.removeRepository(repoLocation);
404 		manager.loadRepository(repoLocation, null);
405 		long lastModified = cacheFile.lastModified();
406 		assertTrue(0 != lastModified);
407 
408 		// reload the repository and check that the cache was not updated
409 		manager.loadRepository(repoLocation, null);
410 		assertEquals(lastModified, cacheFile.lastModified());
411 
412 		cacheFile.delete();
413 	}
414 
testNickname()415 	public void testNickname() throws ProvisionException {
416 		File site = getTestData("Repositoy", "/testData/metadataRepo/good/");
417 		URI location = site.toURI();
418 		manager.addRepository(location);
419 		String nick = manager.getRepositoryProperty(location, IRepository.PROP_NICKNAME);
420 		assertNull(nick);
421 		nick = "Nick";
422 		manager.setRepositoryProperty(location, IRepository.PROP_NICKNAME, nick);
423 		nick = manager.getRepositoryProperty(location, IRepository.PROP_NICKNAME);
424 		assertEquals("Nick", nick);
425 		//ensure loading the repository doesn't affect the nickname
426 		manager.loadRepository(location, getMonitor());
427 		nick = manager.getRepositoryProperty(location, IRepository.PROP_NICKNAME);
428 		assertEquals("Nick", nick);
429 
430 		//remove and re-add the repository should lose the nickname
431 		manager.removeRepository(location);
432 		manager.loadRepository(location, getMonitor());
433 		nick = manager.getRepositoryProperty(location, IRepository.PROP_NICKNAME);
434 		assertNull(nick);
435 	}
436 
testPathWithSpaces()437 	public void testPathWithSpaces() {
438 		File site = getTestData("Repository", "/testData/metadataRepo/good with spaces/");
439 		URI location = site.toURI();
440 		try {
441 			IMetadataRepository repository = manager.loadRepository(location, getMonitor());
442 			IQueryResult<IInstallableUnit> result = repository.query(QueryUtil.createIUQuery("test.bundle"), getMonitor());
443 			assertEquals("1.0", 1, queryResultSize(result));
444 		} catch (ProvisionException e) {
445 			fail("=.99", e);
446 		}
447 	}
448 
testRelativePath()449 	public void testRelativePath() throws URISyntaxException {
450 		URI location = new URI("test");
451 		try {
452 			manager.loadRepository(location, getMonitor());
453 			fail();
454 		} catch (IllegalArgumentException e) {
455 			//expected
456 		} catch (ProvisionException e) {
457 			fail("4.99", e);
458 		}
459 	}
460 
461 	/**
462 	 * Tests for {@link IMetadataRepositoryManager#refreshRepository(URI, org.eclipse.core.runtime.IProgressMonitor)}.
463 	 */
testRefresh()464 	public void testRefresh() throws ProvisionException {
465 		File site = getTestData("Repositoy", "/testData/metadataRepo/good/");
466 		URI location = site.toURI();
467 		manager.addRepository(location);
468 		manager.refreshRepository(location, getMonitor());
469 		assertTrue("1.0", manager.contains(location));
470 		assertTrue("1.1", manager.isEnabled(location));
471 
472 		//tests that refreshing doesn't lose repository properties
473 		manager.setEnabled(location, false);
474 		manager.setRepositoryProperty(location, IRepository.PROP_NICKNAME, "MyNick");
475 		manager.refreshRepository(location, getMonitor());
476 		assertTrue("2.0", manager.contains(location));
477 		assertFalse("2.1", manager.isEnabled(location));
478 		assertEquals("2.2", "MyNick", manager.getRepositoryProperty(location, IRepository.PROP_NICKNAME));
479 
480 		// Set the nickname back to null for other tests
481 		manager.setRepositoryProperty(location, IRepository.PROP_NICKNAME, null);
482 	}
483 
484 	/**
485 	 * Repository references were originally encoded as URL, but we now encode
486 	 * as URI. This test ensures we handle both old and new references.
487 	 */
testRepositoryReferenceCompatibility()488 	public void testRepositoryReferenceCompatibility() throws URISyntaxException {
489 		File site = getTestData("Repository", "/testData/metadataRepo/unencodedreporeferences/");
490 		URI location = site.toURI();
491 		final List<URI> references = new ArrayList<>();
492 		SynchronousProvisioningListener referenceCollector = o -> {
493 			if (!(o instanceof RepositoryEvent))
494 				return;
495 			RepositoryEvent event = (RepositoryEvent) o;
496 			if (event.getKind() == RepositoryEvent.DISCOVERED)
497 				references.add(event.getRepositoryLocation());
498 		};
499 		getEventBus().addListener(referenceCollector);
500 		try {
501 			manager.loadRepository(location, getMonitor());
502 		} catch (ProvisionException e) {
503 			fail("=.99", e);
504 		} finally {
505 			getEventBus().removeListener(referenceCollector);
506 		}
507 		assertEquals("1.0", 4, references.size());
508 		assertTrue("1.1", references.contains(new URI("http://download.eclipse.org/url/with/spaces/a%20b")));
509 		assertTrue("1.2", references.contains(new URI("file:/c:/tmp/url%20with%20spaces/")));
510 		assertTrue("1.3", references.contains(new URI("http://download.eclipse.org/uri/with/spaces/a%20b")));
511 		assertTrue("1.4", references.contains(new URI("file:/c:/tmp/uri%20with%20spaces/")));
512 	}
513 
514 	/**
515 	 * Tests for {@link IRepositoryManager#setRepositoryProperty}.
516 	 */
testSetRepositoryProperty()517 	public void testSetRepositoryProperty() {
518 		File site = getTestData("Repositoy", "/testData/metadataRepo/good/");
519 		URI location = site.toURI();
520 		manager.removeRepository(location);
521 		manager.addRepository(location);
522 
523 		//set some properties different from what the repository contains
524 		manager.setRepositoryProperty(location, IRepository.PROP_NAME, "TestName");
525 		manager.setRepositoryProperty(location, IRepository.PROP_DESCRIPTION, "TestDescription");
526 		manager.setRepositoryProperty(location, IRepository.PROP_SYSTEM, "false");
527 		assertEquals("1.0", "TestName", manager.getRepositoryProperty(location, IRepository.PROP_NAME));
528 		assertEquals("1.1", "TestDescription", manager.getRepositoryProperty(location, IRepository.PROP_DESCRIPTION));
529 		assertEquals("1.2", "false", manager.getRepositoryProperty(location, IRepository.PROP_SYSTEM));
530 
531 		//loading the repository should overwrite test values
532 		try {
533 			manager.loadRepository(location, getMonitor());
534 		} catch (ProvisionException e) {
535 			fail("1.99", e);
536 		}
537 
538 		assertEquals("2.0", "Good Test Repository", manager.getRepositoryProperty(location, IRepository.PROP_NAME));
539 		assertEquals("2.1", "Good test repository description", manager.getRepositoryProperty(location, IRepository.PROP_DESCRIPTION));
540 		assertEquals("2.2", "true", manager.getRepositoryProperty(location, IRepository.PROP_SYSTEM));
541 	}
542 
543 	/**
544 	 * Tests that trailing slashes do not affect repository identity.
545 	 */
testTrailingSlashes()546 	public void testTrailingSlashes() {
547 		File site = getTestData("Repository", "/testData/metadataRepo/good/");
548 		URI locationSlash, locationNoSlash;
549 		try {
550 			locationSlash = site.toURI();
551 			String locationString = locationSlash.toString();
552 			locationString = locationString.substring(0, locationString.length() - 1);
553 			locationNoSlash = new URI(locationString);
554 		} catch (URISyntaxException e) {
555 			fail("0.99", e);
556 			return;
557 		}
558 
559 		manager.addRepository(locationNoSlash);
560 		try {
561 			IMetadataRepository repoSlash = manager.loadRepository(locationSlash, null);
562 			IMetadataRepository repoNoSlash = manager.loadRepository(locationNoSlash, null);
563 			assertTrue("1.0", repoNoSlash == repoSlash);
564 		} catch (ProvisionException e) {
565 			fail("1.99", e);
566 		}
567 	}
568 
testReadableFilter()569 	public void testReadableFilter() throws ProvisionException {
570 		File site = getTestData("readable", "/testData/metadataRepo/badFilter/readable");
571 		IMetadataRepository loadRepository = manager.loadRepository(site.toURI(), null);
572 		assertEquals(1, loadRepository.query(QueryUtil.createIUAnyQuery(), null).toSet().size());
573 	}
574 
testUnreadableFailingFilter()575 	public void testUnreadableFailingFilter() {
576 		File site = getTestData("unreadable", "/testData/metadataRepo/badFilter/unreadable");
577 		PrintStream out = System.out;
578 		try {
579 			System.setOut(new PrintStream(new StringBufferStream()));
580 			manager.loadRepository(site.toURI(), null);
581 		} catch (ProvisionException e) {
582 			return;
583 		} finally {
584 			System.setOut(out);
585 		}
586 		fail("Unexpected code path, the unreadable repo should not have loaded");
587 
588 	}
589 
repoAvailable(URI repoLocation)590 	private boolean repoAvailable(URI repoLocation) {
591 		try {
592 			repoLocation.toURL().openStream().close();
593 		} catch (IOException e) {
594 			return false;
595 		}
596 		return true;
597 	}
598 
599 	/**
600 	 * Returns a non-existent file that can be used to write a temporary
601 	 * file or directory. The location will be deleted in the test tearDown method.
602 	 */
getTempLocation()603 	private File getTempLocation() {
604 		File tempDir = new File(System.getProperty("java.io.tmpdir"));
605 		File tempFile = new File(tempDir, "MetadataRepositoryManagerTest");
606 		delete(tempFile);
607 		assertTrue(!tempFile.exists());
608 		toDelete.add(tempFile);
609 		return tempFile;
610 	}
611 
testFailureAddRemove()612 	public void testFailureAddRemove() {
613 		try {
614 			manager.addRepository(null);
615 			fail();
616 		} catch (RuntimeException e) {
617 			//expected
618 		}
619 		try {
620 			manager.removeRepository(null);
621 			fail();
622 		} catch (RuntimeException e) {
623 			//expected
624 		}
625 	}
626 
627 	/**
628 	 * Returns whether {@link IMetadataRepositoryManager} contains a reference
629 	 * to a repository at the given location.
630 	 */
managerContains(URI location)631 	private boolean managerContains(URI location) {
632 		URI[] locations = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL);
633 		for (URI location2 : locations) {
634 			if (location2.equals(location))
635 				return true;
636 		}
637 		return false;
638 	}
639 }
640