| /******************************************************************************* |
| * Copyright (c) 2013, 2017 Ericsson AB and others. |
| * |
| * This |
| * program and the accompanying materials are made available under the terms of |
| * the Eclipse Public License 2.0 which accompanies this distribution, and is |
| * available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Ericsson AB - initial API and implementation |
| * Red Hat, Inc. - fragments support |
| ******************************************************************************/ |
| package org.eclipse.equinox.p2.tests.sharedinstall; |
| |
| import java.io.*; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.nio.file.attribute.*; |
| import java.util.*; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.equinox.internal.p2.engine.SimpleProfileRegistry; |
| import org.eclipse.equinox.p2.tests.reconciler.dropins.AbstractReconcilerTest; |
| |
| public abstract class AbstractSharedInstallTest extends AbstractReconcilerTest { |
| public static final boolean WINDOWS = java.io.File.separatorChar == '\\'; |
| protected static File readOnlyBase; |
| protected static File userBase; |
| protected static String profileId; |
| public boolean runningWithReconciler = true; |
| |
| public File getUserBundleInfo() { |
| return new File(userBase, "configuration/org.eclipse.equinox.simpleconfigurator/bundles.info"); |
| } |
| |
| protected String getTestRepo() { |
| return getTestData("repo for shared install tests", "testData/sharedInstall/repo").toURI().toString(); |
| } |
| |
| protected File getUserBundleInfoTimestamp() { |
| return new File(userBase, "configuration/org.eclipse.equinox.simpleconfigurator/.baseBundlesInfoTimestamp"); |
| } |
| |
| protected File getUserProfileRegistryFolder() { |
| return new File(userBase, "p2/org.eclipse.equinox.p2.engine/profileRegistry/"); |
| } |
| |
| protected File getUserProfileFolder() { |
| return new File(getUserProfileRegistryFolder(), profileId + ".profile"); |
| } |
| |
| protected File getBaseProfileRegistryFolder() { |
| return new File(output, getRootFolder() + "p2/org.eclipse.equinox.p2.engine/profileRegistry/"); |
| } |
| |
| protected long[] getProfileTimestampsFromUser() { |
| return new SimpleProfileRegistry(getAgent(), getUserProfileRegistryFolder()).listProfileTimestamps(profileId); |
| } |
| |
| protected long getMostRecentProfileTimestamp(File profileFolder) { |
| long[] ts = new SimpleProfileRegistry(getAgent(), profileFolder).listProfileTimestamps(profileId); |
| return ts[ts.length - 1]; |
| } |
| |
| protected long getMostRecentProfileTimestampFromBase() { |
| return getMostRecentProfileTimestamp(getBaseProfileRegistryFolder()); |
| } |
| |
| protected void assertProfileStatePropertiesHasValue(File profileFolder, String value) { |
| try { |
| Properties p = loadProperties(new File(profileFolder, "state.properties")); |
| Collection<Object> values = p.values(); |
| for (Object v : values) { |
| if (((String) v).contains(value)) { |
| return; |
| } |
| } |
| fail("Value: " + value + " not found."); |
| } catch (IOException e) { |
| fail("exception while loading profile state properties in " + profileFolder.getAbsolutePath()); |
| } |
| |
| } |
| |
| protected File getConfigIniTimestamp() { |
| return new File(userBase, "configuration/.baseConfigIniTimestamp"); |
| } |
| |
| protected void assertProfileStatePropertiesHasKey(File profileFolder, String key) { |
| try { |
| Properties p = loadProperties(new File(profileFolder, "state.properties")); |
| Set<Object> keys = p.keySet(); |
| for (Object k : keys) { |
| if (((String) k).contains(key)) { |
| return; |
| } |
| } |
| fail("Key: " + key + " not found."); |
| } catch (IOException e) { |
| fail("exception while loading profile state properties in " + profileFolder.getAbsolutePath()); |
| } |
| |
| } |
| |
| protected void installFeature1AndVerifierInUser() { |
| //TODO Install something into eclipse - make sure that this can be done in an automated setup |
| runEclipse("Installing in user", output, new String[] {"-configuration", userBase.getAbsolutePath() + java.io.File.separatorChar + "configuration", "-application", "org.eclipse.equinox.p2.director", "-installIU", "p2TestFeature1.feature.group,Verifier.feature.group", "-repository", getTestRepo()}); |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| if (readOnlyBase != null && readOnlyBase.exists()) { |
| setReadOnly(readOnlyBase, false); |
| } |
| delete(readOnlyBase); |
| delete(userBase); |
| super.tearDown(); |
| } |
| |
| protected void installFeature1InUser() { |
| runEclipse("user2", output, new String[] {"-configuration", userBase.getAbsolutePath() + java.io.File.separatorChar + "configuration", "-application", "org.eclipse.equinox.p2.director", "-installIU", "p2TestFeature1.feature.group", "-repository", getTestRepo()}); |
| } |
| |
| protected void installFeature1InUserWithoutSpecifyingConfiguration() { |
| runEclipse("user2", output, new String[] {"-application", "org.eclipse.equinox.p2.director", "-installIU", "p2TestFeature1.feature.group", "-repository", getTestRepo()}); |
| } |
| |
| protected void installFeature2InUser() { |
| runEclipse("user2", output, new String[] {"-configuration", userBase.getAbsolutePath() + java.io.File.separatorChar + "configuration", "-application", "org.eclipse.equinox.p2.director", "-installIU", "p2TestFeature2.feature.group", "-repository", getTestRepo()}); |
| } |
| |
| protected void installVerifierInBase() { |
| setReadOnly(readOnlyBase, false); |
| runEclipse("Running eclipse", output, new String[] {"-application", "org.eclipse.equinox.p2.director", "-installIU", "Verifier.feature.group", "-repository", getTestRepo()}); |
| setReadOnly(readOnlyBase, true); |
| } |
| |
| protected void installVerifierAndFeature1InBase() { |
| setReadOnly(readOnlyBase, false); |
| runEclipse("Running eclipse", output, new String[] {"-application", "org.eclipse.equinox.p2.director", "-installIU", "Verifier.feature.group,p2TestFeature1.feature.group", "-repository", getTestRepo()}); |
| setReadOnly(readOnlyBase, true); |
| } |
| |
| protected void uninstallFeature1InBase() { |
| setReadOnly(readOnlyBase, false); |
| runEclipse("Running eclipse", output, new String[] {"-application", "org.eclipse.equinox.p2.director", "-uninstallIU", "p2TestFeature1.feature.group", "-repository", getTestRepo()}); |
| setReadOnly(readOnlyBase, true); |
| } |
| |
| protected void installFeature2InBase() { |
| setReadOnly(readOnlyBase, false); |
| runEclipse("Running eclipse", output, new String[] {"-application", "org.eclipse.equinox.p2.director", "-installIU", "p2TestFeature2.feature.group", "-repository", getTestRepo()}); |
| setReadOnly(readOnlyBase, true); |
| } |
| |
| protected boolean isInUserBundlesInfo(String bundleId) { |
| try { |
| return isInBundlesInfo(getUserBundlesInfo(), bundleId, null, null); |
| } catch (IOException e) { |
| fail("Problem reading bundles.info"); |
| } |
| //should never be reached |
| return false; |
| } |
| |
| protected File getUserBundlesInfo() { |
| return new File(userBase, "configuration/org.eclipse.equinox.simpleconfigurator/bundles.info"); |
| } |
| |
| protected void startEclipseAsUser() { |
| runEclipse("Running eclipse", output, new String[] {"-configuration", userBase.getAbsolutePath() + java.io.File.separatorChar + "configuration", "-application", "org.eclipse.equinox.p2.director", "-listInstalledRoots"}); |
| } |
| |
| protected void executeVerifierWithoutSpecifyingConfiguration(Properties verificationProperties) { |
| realExecuteVerifier(verificationProperties, false); |
| } |
| |
| protected void realExecuteVerifier(Properties verificationProperties, boolean withConfigFlag) { |
| File verifierConfig = new File(getTempFolder(), "verification.properties"); |
| try { |
| writeProperties(verifierConfig, verificationProperties); |
| } catch (IOException e) { |
| fail("Failing to write out properties to configure verifier", e); |
| } |
| |
| String[] args = null; |
| if (withConfigFlag) |
| args = new String[] {"-configuration", userBase.getAbsolutePath() + java.io.File.separatorChar + "configuration", "-application", "org.eclipse.equinox.p2.tests.verifier.application", "-verifier.properties", verifierConfig.getAbsolutePath(), "-consoleLog"}; |
| else |
| args = new String[] {"-application", "org.eclipse.equinox.p2.tests.verifier.application", "-verifier.properties", verifierConfig.getAbsolutePath(), "-consoleLog"}; |
| |
| assertEquals(0, runEclipse("Running verifier", output, args)); |
| } |
| |
| protected void executeVerifier(Properties verificationProperties) { |
| realExecuteVerifier(verificationProperties, true); |
| } |
| |
| public static void reallyReadOnly(File folder, boolean recurse) { |
| reallyReadOnly(folder); |
| if (folder.exists() && recurse) { |
| File[] dirs = folder.listFiles((FileFilter) File::isDirectory); |
| for (File dir : dirs) { |
| reallyReadOnly(dir, true); |
| } |
| } |
| } |
| |
| public static void reallyReadOnly(File folder) { |
| if (!Platform.getOS().equals(Platform.OS_WIN32)) |
| return; |
| |
| try { |
| Path path = folder.toPath(); |
| AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class); |
| AclEntry newEntry = AclEntry.newBuilder().setFlags(AclEntryFlag.FILE_INHERIT, AclEntryFlag.DIRECTORY_INHERIT).setPermissions(AclEntryPermission.WRITE_DATA, AclEntryPermission.APPEND_DATA, AclEntryPermission.WRITE_NAMED_ATTRS, AclEntryPermission.WRITE_ATTRIBUTES).setPrincipal(view.getOwner()).setType(AclEntryType.DENY).build(); |
| |
| List<AclEntry> acl = view.getAcl(); |
| acl.add(0, newEntry); // insert before any DENY entries |
| view.setAcl(acl); |
| } catch (IOException e) { |
| fail("can't mark the folder " + folder + " read-only."); |
| } |
| } |
| |
| public static void removeReallyReadOnly(File folder, boolean recurse) { |
| removeReallyReadOnly(folder); |
| if (folder.exists() && recurse) { |
| File[] dirs = folder.listFiles((FileFilter) File::isDirectory); |
| for (File dir : dirs) { |
| removeReallyReadOnly(dir, true); |
| } |
| } |
| } |
| |
| public static void removeReallyReadOnly(File folder) { |
| if (!Platform.getOS().equals(Platform.OS_WIN32)) |
| return; |
| |
| try { |
| Path path = folder.toPath(); |
| AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class); |
| |
| List<AclEntry> acl = view.getAcl(); |
| acl.remove(0); |
| view.setAcl(acl); |
| } catch (IOException e) { |
| fail("oh shit"); |
| } |
| } |
| |
| public static Properties loadProperties(File inputFile) throws FileNotFoundException, IOException { |
| Properties props = new Properties(); |
| try (InputStream is = new FileInputStream(inputFile)) { |
| props.load(is); |
| } |
| return props; |
| } |
| |
| public static void setupReadOnlyInstall() { |
| readOnlyBase = new File(output, getRootFolder()); |
| readOnlyBase.mkdirs(); |
| assertTrue(readOnlyBase.canWrite()); |
| setReadOnly(readOnlyBase, true); |
| userBase = new File(output, "user"); |
| userBase.mkdir(); |
| String[] files = new File(readOnlyBase, "p2/org.eclipse.equinox.p2.engine/profileRegistry/").list(); |
| if (files.length > 1 || files.length == 0) |
| fail("The profile for the read only install located at: " + output + "could not be determined"); |
| else |
| profileId = files[0].substring(0, files[0].indexOf('.')); |
| } |
| |
| public static void setReadOnly(File target, boolean readOnly) { |
| if (WINDOWS) { |
| String targetPath = target.getAbsolutePath(); |
| String[] command = new String[] {"attrib", readOnly ? "+r" : "-r", targetPath, "/s", "/d"}; |
| run("setReadOnly " + readOnly + " failed on" + target.getAbsolutePath(), command); |
| if (target.isDirectory()) { |
| targetPath += "\\*.*"; |
| command = new String[] {"attrib", readOnly ? "+r" : "-r", targetPath, "/s", "/d"}; |
| run("setReadOnly " + readOnly + " failed on" + target.getAbsolutePath(), command); |
| } |
| } else { |
| String[] command = new String[] {"chmod", "-R", readOnly ? "a-w" : "a+w", target.getAbsolutePath()}; |
| run("setReadOnly " + readOnly + " failed on" + target.getAbsolutePath(), command); |
| } |
| } |
| |
| public AbstractSharedInstallTest(String name) { |
| super(name); |
| } |
| |
| public void replaceDotEclipseProductFile(File base, String id, String version) { |
| File eclipseProductFile = new File(base, ".eclipseproduct"); |
| eclipseProductFile.delete(); |
| |
| Properties newProps = new Properties(); |
| newProps.put("id", id); |
| newProps.put("version", version); |
| try (OutputStream os = new FileOutputStream(eclipseProductFile)) { |
| newProps.store(os, "file generated for tests " + getName()); |
| } catch (IOException e) { |
| fail("Failing setting up the .eclipseproduct file at:" + eclipseProductFile.getAbsolutePath()); |
| } |
| } |
| |
| } |