1 /*******************************************************************************
2  *  Copyright (c) 2008, 2017 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.artifact.repository;
16 
17 import java.io.File;
18 import java.io.IOException;
19 import java.io.PrintStream;
20 import java.net.URI;
21 import java.net.URISyntaxException;
22 import junit.framework.Test;
23 import junit.framework.TestSuite;
24 import org.eclipse.core.runtime.IStatus;
25 import org.eclipse.core.runtime.preferences.IPreferencesService;
26 import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
27 import org.eclipse.equinox.internal.provisional.p2.repository.RepositoryEvent;
28 import org.eclipse.equinox.p2.core.IAgentLocation;
29 import org.eclipse.equinox.p2.core.ProvisionException;
30 import org.eclipse.equinox.p2.repository.IRepository;
31 import org.eclipse.equinox.p2.repository.IRepositoryManager;
32 import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
33 import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager;
34 import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
35 import org.eclipse.equinox.p2.tests.StringBufferStream;
36 import org.eclipse.equinox.p2.tests.TestActivator;
37 import org.eclipse.equinox.p2.tests.TestRepositoryListener;
38 import org.eclipse.equinox.security.storage.EncodingUtils;
39 import org.osgi.framework.BundleException;
40 import org.osgi.service.prefs.BackingStoreException;
41 import org.osgi.service.prefs.Preferences;
42 
43 /**
44  * Tests API of {@link IArtifactRepositoryManager}.
45  */
46 public class ArtifactRepositoryManagerTest extends AbstractProvisioningTest {
47 	private IArtifactRepositoryManager manager;
48 
suite()49 	public static Test suite() {
50 		return new TestSuite(ArtifactRepositoryManagerTest.class);
51 		//		TestSuite suite = new TestSuite();
52 		//		suite.addTest(new ArtifactRepositoryManagerTest("testEnablement"));
53 		//		return suite;
54 	}
55 
ArtifactRepositoryManagerTest(String name)56 	public ArtifactRepositoryManagerTest(String name) {
57 		super(name);
58 	}
59 
60 	/**
61 	 * Returns whether {@link IArtifactRepositoryManager} contains a reference
62 	 * to a repository at the given location.
63 	 */
managerContains(URI location)64 	private boolean managerContains(URI location) {
65 		URI[] locations = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL);
66 		for (URI uri : locations) {
67 			if (uri.equals(location)) {
68 				return true;
69 			}
70 		}
71 		return false;
72 	}
73 
74 	@Override
setUp()75 	protected void setUp() throws Exception {
76 		super.setUp();
77 		manager = getArtifactRepositoryManager();
78 		assertNotNull(manager);
79 	}
80 
81 	/**
82 	 * Tests loading a repository that does not exist throws an appropriate exception.
83 	 */
testLoadMissingRepository()84 	public void testLoadMissingRepository() throws IOException {
85 		File tempFile = File.createTempFile("testLoadMissingArtifactRepository", null);
86 		URI location = tempFile.toURI();
87 		PrintStream out = System.out;
88 		try {
89 			System.setOut(new PrintStream(new StringBufferStream()));
90 			manager.loadRepository(location, null);
91 			fail("1.0");//should fail
92 		} catch (ProvisionException e) {
93 			assertEquals("1.1", IStatus.ERROR, e.getStatus().getSeverity());
94 			assertEquals("1.2", ProvisionException.REPOSITORY_NOT_FOUND, e.getStatus().getCode());
95 		} finally {
96 			System.setOut(out);
97 			tempFile.delete();
98 		}
99 	}
100 
101 	/**
102 	 * Tests loading an artifact repository that is missing the top level repository element.
103 	 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=246452.
104 	 */
testLoadMissingRepositoryElement()105 	public void testLoadMissingRepositoryElement() {
106 		File site = getTestData("Update site", "/testData/artifactRepo/broken/");
107 		try {
108 			URI location = site.toURI();
109 			manager.loadRepository(location, null);
110 			//should have failed
111 			fail("1.0");
112 		} catch (ProvisionException e) {
113 			//expected
114 		}
115 	}
116 
117 	/**
118 	 * This is regression test for bug 236437. In this bug, the repository preference
119 	 * file is being overwritten by an update operation, thus losing all repository state.
120 	 */
testLostArtifactRepositories()121 	public void testLostArtifactRepositories() {
122 		File site = getTestData("Repository", "/testData/artifactRepo/simple/");
123 		URI location = site.toURI();
124 		manager.addRepository(location);
125 		assertTrue("0.1", manager.contains(location));
126 
127 		//bash the repository preference file (don't try this at home, kids)
128 		final String REPO_BUNDLE = "org.eclipse.equinox.p2.artifact.repository";
129 		IPreferencesService prefService = ServiceHelper.getService(TestActivator.getContext(), IPreferencesService.class);
130 		IAgentLocation agentLocation = getAgent().getService(IAgentLocation.class);
131 		String locationString = EncodingUtils.encodeSlashes(agentLocation.getRootLocation().toString());
132 		Preferences prefs = prefService.getRootNode().node("/profile/" + locationString + "/_SELF_/" + REPO_BUNDLE + "/repositories"); //$NON-NLS-1$ //$NON-NLS-2$
133 		try {
134 			String[] children = prefs.childrenNames();
135 			for (String child : children) {
136 				prefs.node(child).removeNode();
137 			}
138 			prefs.flush();
139 		} catch (BackingStoreException e) {
140 			fail("0.99", e);
141 		}
142 
143 		//stop and restart the artifact repository bundle (kids, if I ever catch you doing this I'm taking PackageAdmin away)
144 		try {
145 			restartBundle(TestActivator.getBundle(REPO_BUNDLE));
146 		} catch (BundleException e) {
147 			fail("1.99", e);
148 		}
149 
150 		//everybody's happy again
151 		manager = getAgent().getService(IArtifactRepositoryManager.class);
152 		assertTrue("1.0", manager.contains(location));
153 	}
154 
testNickname()155 	public void testNickname() throws ProvisionException {
156 		File site = getTestData("Repository", "/testData/artifactRepo/simple/");
157 		URI location = site.toURI();
158 		manager.addRepository(location);
159 		String nick = manager.getRepositoryProperty(location, IRepository.PROP_NICKNAME);
160 		assertNull(nick);
161 		nick = "Nick";
162 		manager.setRepositoryProperty(location, IRepository.PROP_NICKNAME, nick);
163 		nick = manager.getRepositoryProperty(location, IRepository.PROP_NICKNAME);
164 		assertEquals("Nick", nick);
165 		//ensure loading the repository doesn't affect the nickname
166 		manager.loadRepository(location, getMonitor());
167 		nick = manager.getRepositoryProperty(location, IRepository.PROP_NICKNAME);
168 		assertEquals("Nick", nick);
169 
170 		//remove and re-add the repository should lose the nickname
171 		manager.removeRepository(location);
172 		manager.loadRepository(location, getMonitor());
173 		nick = manager.getRepositoryProperty(location, IRepository.PROP_NICKNAME);
174 		assertNull(nick);
175 	}
176 
testPathWithSpaces()177 	public void testPathWithSpaces() {
178 		File site = getTestData("Repository", "/testData/artifactRepo/simple with spaces/");
179 		URI location = site.toURI();
180 		assertEquals("1.0", 2, getArtifactKeyCount(location));
181 	}
182 
183 	/**
184 	 * Tests for {@link IMetadataRepositoryManager#refreshRepository(URI, org.eclipse.core.runtime.IProgressMonitor)}.
185 	 */
testRefresh()186 	public void testRefresh() throws ProvisionException {
187 		File site = getTestData("Repositoy", "/testData/artifactRepo/simple/");
188 		URI location = site.toURI();
189 		manager.addRepository(location);
190 		manager.refreshRepository(location, getMonitor());
191 		assertTrue("1.0", manager.contains(location));
192 		assertTrue("1.1", manager.isEnabled(location));
193 
194 		//tests that refreshing doesn't lose repository properties
195 		manager.setEnabled(location, false);
196 		manager.setRepositoryProperty(location, IRepository.PROP_NICKNAME, "MyNick");
197 		manager.refreshRepository(location, getMonitor());
198 		assertTrue("2.0", manager.contains(location));
199 		assertFalse("2.1", manager.isEnabled(location));
200 		assertEquals("2.2", "MyNick", manager.getRepositoryProperty(location, IRepository.PROP_NICKNAME));
201 
202 		// Set it back to null for other tests
203 		manager.setRepositoryProperty(location, IRepository.PROP_NICKNAME, null);
204 	}
205 
206 	/**
207 	 * Tests for {@link IRepositoryManager#setRepositoryProperty}.
208 	 */
testSetRepositoryProperty()209 	public void testSetRepositoryProperty() {
210 		File site = getTestData("Repositoy", "/testData/artifactRepo/simple/");
211 		URI location = site.toURI();
212 		manager.removeRepository(location);
213 		manager.addRepository(location);
214 
215 		//set some properties different from what the repository contains
216 		manager.setRepositoryProperty(location, IRepository.PROP_NAME, "TestName");
217 		manager.setRepositoryProperty(location, IRepository.PROP_DESCRIPTION, "TestDescription");
218 		manager.setRepositoryProperty(location, IRepository.PROP_SYSTEM, "true");
219 		assertEquals("1.0", "TestName", manager.getRepositoryProperty(location, IRepository.PROP_NAME));
220 		assertEquals("1.1", "TestDescription", manager.getRepositoryProperty(location, IRepository.PROP_DESCRIPTION));
221 		assertEquals("1.2", "true", manager.getRepositoryProperty(location, IRepository.PROP_SYSTEM));
222 
223 		//loading the repository should overwrite test values
224 		try {
225 			manager.loadRepository(location, getMonitor());
226 		} catch (ProvisionException e) {
227 			fail("1.99", e);
228 		}
229 
230 		assertEquals("2.0", "Good Test Repository", manager.getRepositoryProperty(location, IRepository.PROP_NAME));
231 		assertEquals("2.1", "Good test repository description", manager.getRepositoryProperty(location, IRepository.PROP_DESCRIPTION));
232 		assertEquals("2.2", "false", manager.getRepositoryProperty(location, IRepository.PROP_SYSTEM));
233 	}
234 
testUpdateSitePathWithSpaces()235 	public void testUpdateSitePathWithSpaces() {
236 		File site = getTestData("Repository", "/testData/updatesite/site with spaces/");
237 		URI location = site.toURI();
238 		assertEquals("1.0", 3, getArtifactKeyCount(location));
239 	}
240 
241 	/**
242 	 * Tests that trailing slashes do not affect repository identity.
243 	 */
testTrailingSlashes()244 	public void testTrailingSlashes() {
245 		File site = getTestData("Repository", "/testData/artifactRepo/simple/");
246 		URI locationSlash, locationNoSlash;
247 		try {
248 			locationSlash = site.toURI();
249 			String locationString = locationSlash.toString();
250 			locationString = locationString.substring(0, locationString.length() - 1);
251 			locationNoSlash = new URI(locationString);
252 		} catch (URISyntaxException e) {
253 			fail("0.99", e);
254 			return;
255 		}
256 
257 		manager.addRepository(locationNoSlash);
258 		try {
259 			IArtifactRepository repoSlash = manager.loadRepository(locationSlash, null);
260 			IArtifactRepository repoNoSlash = manager.loadRepository(locationNoSlash, null);
261 			assertTrue("1.0", repoNoSlash == repoSlash);
262 		} catch (ProvisionException e) {
263 			fail("1.99", e);
264 		}
265 
266 	}
267 
testBasicAddRemove()268 	public void testBasicAddRemove() {
269 		File tempFile = new File(System.getProperty("java.io.tmpdir"));
270 		URI location = tempFile.toURI();
271 		assertTrue(!managerContains(location));
272 		manager.addRepository(location);
273 		assertTrue(managerContains(location));
274 		manager.removeRepository(location);
275 		assertTrue(!managerContains(location));
276 	}
277 
278 	/**
279 	 * Tests for {@link IRepositoryManager#contains(URI).
280 	 */
testContains()281 	public void testContains() {
282 		File site = getTestData("Repositoy", "/testData/artifactRepo/simple/");
283 		URI location = site.toURI();
284 		manager.removeRepository(location);
285 		assertEquals("1.0", false, manager.contains(location));
286 		manager.addRepository(location);
287 		assertEquals("1.1", true, manager.contains(location));
288 		manager.removeRepository(location);
289 		assertEquals("1.2", false, manager.contains(location));
290 	}
291 
292 	/**
293 	 * Tests parsing a repository with a duplicate element. See bug 255401.
294 	 */
testDuplicateElement()295 	public void testDuplicateElement() {
296 		File duplicateElementXML = getTestData("testDuplicateElement", "testData/artifactRepo/duplicateElement");
297 		PrintStream out = System.out;
298 		try {
299 			System.setOut(new PrintStream(new StringBufferStream()));
300 			assertEquals("Ensure correct number of artifact keys exist", 2, getArtifactKeyCount(duplicateElementXML.toURI()));
301 		} finally {
302 			System.setOut(out);
303 		}
304 	}
305 
testEnablement()306 	public void testEnablement() {
307 		File site = getTestData("Repository", "/testData/artifactRepo/simple/");
308 		URI location = site.toURI();
309 		manager.addRepository(location);
310 		assertEquals("1.0", true, manager.isEnabled(location));
311 		TestRepositoryListener listener = new TestRepositoryListener(location);
312 		getEventBus().addListener(listener);
313 
314 		manager.setEnabled(location, false);
315 		listener.waitForEvent();
316 		assertEquals("2.0", false, listener.lastEnablement);
317 		assertEquals("2.1", false, manager.isEnabled(location));
318 		assertEquals("2.2", IRepository.TYPE_ARTIFACT, listener.lastRepoType);
319 		listener.reset();
320 
321 		manager.setEnabled(location, true);
322 		listener.waitForEvent();
323 		assertEquals("3.0", true, manager.isEnabled(location));
324 		assertEquals("3.1", RepositoryEvent.ENABLEMENT, listener.lastKind);
325 		assertEquals("3.2", true, listener.lastEnablement);
326 		assertEquals("3.3", IRepository.TYPE_ARTIFACT, listener.lastRepoType);
327 		listener.reset();
328 	}
329 
330 	/**
331 	 * Tests that adding a repository that is already known but disabled
332 	 * causes the repository to be enabled. See bug 241307 for discussion.
333 	 */
testEnablementOnAdd()334 	public void testEnablementOnAdd() {
335 		File site = getTestData("Repository", "/testData/artifactRepo/simple/");
336 		URI location = site.toURI();
337 		manager.addRepository(location);
338 		manager.setEnabled(location, false);
339 		TestRepositoryListener listener = new TestRepositoryListener(location);
340 		getEventBus().addListener(listener);
341 
342 		//adding the location again should cause it to be enabled
343 		manager.addRepository(location);
344 		listener.waitForEvent();
345 		assertEquals("1.0", true, listener.lastEnablement);
346 		assertEquals("1.1", true, manager.isEnabled(location));
347 		assertEquals("1.2", IRepository.TYPE_ARTIFACT, listener.lastRepoType);
348 	}
349 }