/*******************************************************************************
* Copyright (c) 2009, 2013 Broadcom Corp. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* James Blackburn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.envvar;
import java.io.ByteArrayInputStream;
import java.util.Arrays;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
import org.eclipse.cdt.core.testplugin.ResourceHelper;
import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager;
import org.eclipse.cdt.utils.envvar.IEnvironmentChangeEvent;
import org.eclipse.cdt.utils.envvar.IEnvironmentChangeListener;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
public class IEnvironmentVariableManagerTests extends TestCase {
/**
* Mock listener to listen to environment variable change events.
*/
private class MockEnvironmentListener implements IEnvironmentChangeListener {
private int count = 0;
private IEnvironmentChangeEvent lastEvent = null;
public int getCount() {
return count;
}
public void resetCount() {
count = 0;
lastEvent = null;
}
public IEnvironmentChangeEvent getLastEvent() {
return lastEvent;
}
@Override
public void handleEvent(IEnvironmentChangeEvent event) {
count++;
lastEvent = event;
}
}
@Override
protected void setUp() throws Exception {
super.setUp();
}
@Override
protected void tearDown() throws Exception {
ResourceHelper.cleanUp(getName());
}
public static Test suite() {
TestSuite suite = new TestSuite(IEnvironmentVariableManagerTests.class);
return suite;
}
/**
* Create a project with 2 configurations. Set an environment variable on one of
* the configurations. Close and reopen the project. Check persistence
* @throws Exception
*/
public void testSimpleVar() throws Exception {
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProject");
// Add another, derived configuration
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
final String id1 = desc.getId(); // Config 1's ID
final String id2 = CDataUtil.genId(id1); // Config 2's ID
prjDesc.createConfiguration(id2, "config2", desc);
CoreModel.getDefault().setProjectDescription(project, prjDesc);
// Get all the configurations
prjDesc = CoreModel.getDefault().getProjectDescription(project);
ICConfigurationDescription[] descs = prjDesc.getConfigurations();
assertTrue(descs.length == 2);
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
assertFalse(descs[0].isModified());
assertFalse(descs[1].isModified());
// Try setting an environment variable
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR");
contribEnv.addVariable(var, prjDesc.getConfigurationById(id1));
assertTrue(prjDesc.getConfigurationById(id1).isModified());
assertFalse(prjDesc.getConfigurationById(id2).isModified());
// Check that the variable exists on the config1 & not in config2:
IEnvironmentVariable var2 = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var2, var);
var2 = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id2), true);
assertNull(var2);
CoreModel.getDefault().setProjectDescription(project, prjDesc);
// Close and reopen, variables should still exist
project.close(null);
project.open(null);
prjDesc = CoreModel.getDefault().getProjectDescription(project);
var2 = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var2, var);
var2 = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id2), true);
assertNull(var2);
assertFalse(prjDesc.getConfigurationById(id1).isModified());
assertFalse(prjDesc.getConfigurationById(id2).isModified());
}
/**
* Tests that we can load the environment stored as a single (old-style) long XML string
* Also tests that an an external change to the settings file is correctly picked up.
* @throws Exception
*/
public void testOldStyleLoad() throws Exception {
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProjectOldStyleLoad");
// Add another, derived configuration
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
final String id1 = desc.getId(); // Config 1's ID
final String id2 = "712427638"; // Config 2's ID
prjDesc.createConfiguration(id2, "config2", desc);
CoreModel.getDefault().setProjectDescription(project, prjDesc);
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
final IEnvironmentVariable varOrig = new EnvironmentVariable("FOO", "ZOO");
contribEnv.addVariable(varOrig, prjDesc.getConfigurationById(id2));
CoreModel.getDefault().setProjectDescription(project, prjDesc);
final String env = "#Mon Nov 16 21:47:46 GMT 2009\n" +
"eclipse.preferences.version=1\n" +
"environment/project/712427638=<?xml version\\=\"1.0\" encoding\\=\"UTF-8\" standalone\\=\"no\"?>\\n" +
"<environment append\\=\"true\" appendContributed\\=\"true\">\\n" +
"<variable delimiter\\=\"\\:\" name\\=\"FOO1\" operation\\=\"replace\" value\\=\"BAR1\"/>\\n" +
"<variable delimiter\\=\"\\:\" name\\=\"FOO2\" operation\\=\"replace\" value\\=\"BAR2\"/>\\n" +
"<variable delimiter\\=\"\\;\" name\\=\"FOO\" operation\\=\"append\" value\\=\"BAR\"/>\\n</environment>\n";
project.getFile(".settings/org.eclipse.cdt.core.prefs").setContents(new ByteArrayInputStream(env.getBytes("UTF-8")), true, false, null);
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR", IEnvironmentVariable.ENVVAR_APPEND, ";");
final IEnvironmentVariable var1 = new EnvironmentVariable("FOO1", "BAR1", ":");
final IEnvironmentVariable var2 = new EnvironmentVariable("FOO2", "BAR2", ":");
prjDesc = CoreModel.getDefault().getProjectDescription(project);
assertEquals(var, envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id2), true));
assertEquals(var1, envManager.getVariable(var1.getName(), prjDesc.getConfigurationById(id2), true));
assertEquals(var2, envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id2), true));
}
/**
* Tests we can load an old-style preferences while an incompatible scheduling rule is held.
* @throws Exception
*/
public void testOldStyleLoadConflictingSchedulingRule() throws Exception {
final IProject project = ResourceHelper.createCDTProjectWithConfig("incompatibleSchedRule");
// Add another, derived configuration
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
final String id1 = desc.getId(); // Config 1's ID
final String id2 = "712427638"; // Config 2's ID
prjDesc.createConfiguration(id2, "config2", desc);
CoreModel.getDefault().setProjectDescription(project, prjDesc);
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
final IEnvironmentVariable varOrig = new EnvironmentVariable("FOO", "ZOO");
contribEnv.addVariable(varOrig, prjDesc.getConfigurationById(id2));
CoreModel.getDefault().setProjectDescription(project, prjDesc);
final String env = "#Mon Nov 16 21:47:46 GMT 2009\n" +
"eclipse.preferences.version=1\n" +
"environment/project/712427638=<?xml version\\=\"1.0\" encoding\\=\"UTF-8\" standalone\\=\"no\"?>\\n" +
"<environment append\\=\"true\" appendContributed\\=\"true\">\\n" +
"<variable delimiter\\=\"\\:\" name\\=\"FOO1\" operation\\=\"replace\" value\\=\"BAR1\"/>\\n" +
"<variable delimiter\\=\"\\:\" name\\=\"FOO2\" operation\\=\"replace\" value\\=\"BAR2\"/>\\n" +
"<variable delimiter\\=\"\\;\" name\\=\"FOO\" operation\\=\"append\" value\\=\"BAR\"/>\\n</environment>\n";
project.getFile(".settings/org.eclipse.cdt.core.prefs").setContents(new ByteArrayInputStream(env.getBytes("UTF-8")), true, false, null);
ISchedulingRule incompatibleRule = new ISchedulingRule() {
@Override
public boolean isConflicting(ISchedulingRule rule) {
return rule == this || rule instanceof IResource;
}
@Override
public boolean contains(ISchedulingRule rule) {
return rule == this;
}
};
try {
Job.getJobManager().beginRule(incompatibleRule, new NullProgressMonitor());
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR", IEnvironmentVariable.ENVVAR_APPEND, ";");
final IEnvironmentVariable var1 = new EnvironmentVariable("FOO1", "BAR1", ":");
final IEnvironmentVariable var2 = new EnvironmentVariable("FOO2", "BAR2", ":");
prjDesc = CoreModel.getDefault().getProjectDescription(project);
assertEquals(var, envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id2), true));
assertEquals(var1, envManager.getVariable(var1.getName(), prjDesc.getConfigurationById(id2), true));
assertEquals(var2, envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id2), true));
} finally {
Job.getJobManager().endRule(incompatibleRule);
}
// Change back to FOO => ZOO , close and re-open the project and check its still there
prjDesc = CoreModel.getDefault().getProjectDescription(project);
contribEnv.addVariable(varOrig, prjDesc.getConfigurationById(id2));
CoreModel.getDefault().setProjectDescription(project, prjDesc);
project.close(null);
project.open(null);
prjDesc = CoreModel.getDefault().getProjectDescription(project);
assertEquals(varOrig, envManager.getVariable(varOrig.getName(), prjDesc.getConfigurationById(id2), true));
}
/**
* Test that an ovewrite of new style preferences is loaded correctly
* @throws Exception
*/
public void testNewStyleOverwrite() throws Exception {
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProjectNewStyleLoad");
// Add another, derived configuration
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
final String id1 = desc.getId(); // Config 1's ID
final String id2 = "712427638"; // Config 2's ID
prjDesc.createConfiguration(id2, "config2", desc);
CoreModel.getDefault().setProjectDescription(project, prjDesc);
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
// Variable which will be overwritten
final IEnvironmentVariable varOrig = new EnvironmentVariable("FOO", "ZOO");
contribEnv.addVariable(varOrig, prjDesc.getConfigurationById(id2));
CoreModel.getDefault().setProjectDescription(project, prjDesc);
final String env = "environment/project/712427638/FOO/delimiter=;\n" +
"environment/project/712427638/FOO/operation=append\n" +
"environment/project/712427638/FOO/value=BAR\n" +
"environment/project/712427638/FOO1/delimiter=\\:\n" +
"environment/project/712427638/FOO1/operation=replace\n" +
"environment/project/712427638/FOO1/value=BAR1\n" +
"environment/project/712427638/FOO2/delimiter=\\:\n" +
"environment/project/712427638/FOO2/operation=replace\n" +
"environment/project/712427638/FOO2/value=BAR2\n" +
"environment/project/712427638/append=true\n" +
"environment/project/712427638/appendContributed=true\n";
project.getFile(".settings/org.eclipse.cdt.core.prefs").setContents(new ByteArrayInputStream(env.getBytes("UTF-8")), true, false, null);
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR", IEnvironmentVariable.ENVVAR_APPEND, ";");
final IEnvironmentVariable var1 = new EnvironmentVariable("FOO1", "BAR1", ":");
final IEnvironmentVariable var2 = new EnvironmentVariable("FOO2", "BAR2", ":");
prjDesc = CoreModel.getDefault().getProjectDescription(project);
assertEquals(var, envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id2), true));
assertEquals(var1, envManager.getVariable(var1.getName(), prjDesc.getConfigurationById(id2), true));
assertEquals(var2, envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id2), true));
}
public void testNoChangeToOneVariable() throws Exception {
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProject");
// Add another, derived configuration
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
final String id1 = desc.getId();
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
// Try setting an environment variable
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR");
final IEnvironmentVariable var1 = new EnvironmentVariable("FOO1", "BAR1");
final IEnvironmentVariable var2 = new EnvironmentVariable("FOO2", "BAR2");
contribEnv.addVariable(var, prjDesc.getConfigurationById(id1));
contribEnv.addVariable(var1, prjDesc.getConfigurationById(id1));
contribEnv.addVariable(var2, prjDesc.getConfigurationById(id1));
// Check that the variable exists on config1
IEnvironmentVariable readVar = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var, readVar);
readVar = envManager.getVariable(var1.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var1, readVar);
readVar = envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var2, readVar);
// Save the project description
CoreModel.getDefault().setProjectDescription(project, prjDesc);
// Close and open the project
project.close(null);
project.open(null);
prjDesc = CoreModel.getDefault().getProjectDescription(project);
final IEnvironmentVariable var3 = new EnvironmentVariable("FOO", "BAZ");
contribEnv.addVariable(var3, prjDesc.getConfigurationById(id1));
readVar = envManager.getVariable(var3.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var3, readVar);
readVar = envManager.getVariable(var1.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var1, readVar);
// Save the project description
CoreModel.getDefault().setProjectDescription(project, prjDesc);
// Close and open the project
project.close(null);
project.open(null);
prjDesc = CoreModel.getDefault().getProjectDescription(project);
readVar = envManager.getVariable(var3.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var3, readVar);
readVar = envManager.getVariable(var1.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var1, readVar);
readVar = envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var2, readVar);
}
/**
* tests the get / set append persisting
*/
public void testGetSetAppend() throws Exception {
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProject");
// Add another, derived configuration
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
final String id1 = desc.getId(); // Config 1's ID
final String id2 = CDataUtil.genId(id1); // Config 2's ID
prjDesc.createConfiguration(id2, "config2", desc);
CoreModel.getDefault().setProjectDescription(project, prjDesc);
// Get all the configurations
prjDesc = CoreModel.getDefault().getProjectDescription(project);
ICConfigurationDescription[] descs = prjDesc.getConfigurations();
assertEquals(2, descs.length);
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
assertFalse(descs[0].isModified());
assertFalse(descs[1].isModified());
// Set append & append contributed on the 2 configs respectively
final boolean append = contribEnv.appendEnvironment(prjDesc.getConfigurationById(id2));
contribEnv.setAppendEnvironment(!append, prjDesc.getConfigurationById(id2));
assertEquals(!append, contribEnv.appendEnvironment(prjDesc.getConfigurationById(id2)));
assertFalse(prjDesc.getConfigurationById(id1).isModified());
assertTrue(prjDesc.getConfigurationById(id2).isModified());
CoreModel.getDefault().setProjectDescription(project, prjDesc);
// Close and reopen, variables should still exist
project.close(null);
project.open(null);
prjDesc = CoreModel.getDefault().getProjectDescription(project);
assertEquals(!append, contribEnv.appendEnvironment(prjDesc.getConfigurationById(id2)));
assertFalse(prjDesc.getConfigurationById(id1).isModified());
assertFalse(prjDesc.getConfigurationById(id2).isModified());
}
/**
* Tests file system change of the settings file
*/
public void testSettingsOverwrite() throws Exception {
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProject");
// Add another, derived configuration
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
final String id1 = desc.getId(); // Config 1's ID
final String id2 = CDataUtil.genId(id1); // Config 2's ID
prjDesc.createConfiguration(id2, "config2", desc);
CoreModel.getDefault().setProjectDescription(project, prjDesc);
// Get all the configurations
prjDesc = CoreModel.getDefault().getProjectDescription(project);
ICConfigurationDescription[] descs = prjDesc.getConfigurations();
assertTrue(descs.length == 2);
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
assertFalse(descs[0].isModified());
assertFalse(descs[1].isModified());
// Try setting an environment variable
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR");
contribEnv.addVariable(var, prjDesc.getConfigurationById(id1));
assertTrue(prjDesc.getConfigurationById(id1).isModified());
assertFalse(prjDesc.getConfigurationById(id2).isModified());
CoreModel.getDefault().setProjectDescription(project, prjDesc);
// Backup the settings file
project.getFile(".settings/org.eclipse.cdt.core.prefs.bak").create(
project.getFile(".settings/org.eclipse.cdt.core.prefs").getContents(), true, null);
// Change the environment variable
final IEnvironmentVariable var2 = new EnvironmentVariable("FOO", "BOO");
contribEnv.addVariable(var2, prjDesc.getConfigurationById(id1));
assertEquals(var2, envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id1), true));
CoreModel.getDefault().setProjectDescription(project, prjDesc);
// Replace the settings with it's backup
project.getFile(".settings/org.eclipse.cdt.core.prefs").setContents(
project.getFile(".settings/org.eclipse.cdt.core.prefs.bak").getContents(), true, false, null);
prjDesc = CoreModel.getDefault().getProjectDescription(project);
assertEquals(var, envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true));
}
/**
* Tests file system change of the settings file without recreating the project description
*/
public void testSettingsOverwriteBug295436() throws Exception {
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProject");
// Add another, derived configuration
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
final String id1 = desc.getId(); // Config 1's ID
final String id2 = CDataUtil.genId(id1); // Config 2's ID
prjDesc.createConfiguration(id2, "config2", desc);
CoreModel.getDefault().setProjectDescription(project, prjDesc);
// Get all the configurations
prjDesc = CoreModel.getDefault().getProjectDescription(project);
ICConfigurationDescription[] descs = prjDesc.getConfigurations();
assertTrue(descs.length == 2);
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
assertFalse(descs[0].isModified());
assertFalse(descs[1].isModified());
// Try setting an environment variable
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR");
contribEnv.addVariable(var, prjDesc.getConfigurationById(id1));
assertTrue(prjDesc.getConfigurationById(id1).isModified());
assertFalse(prjDesc.getConfigurationById(id2).isModified());
CoreModel.getDefault().setProjectDescription(project, prjDesc);
// Backup the settings file
project.getFile(".settings/org.eclipse.cdt.core.prefs.bak").create(
project.getFile(".settings/org.eclipse.cdt.core.prefs").getContents(), true, null);
// Change the environment variable
final IEnvironmentVariable var2 = new EnvironmentVariable("FOO", "BOO");
contribEnv.addVariable(var2, prjDesc.getConfigurationById(id1));
assertEquals(var2, envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id1), true));
CoreModel.getDefault().setProjectDescription(project, prjDesc);
// clean desc should be updated when the preference file is overwritten
final ICProjectDescription cleanDesc = CoreModel.getDefault().getProjectDescription(project);
assertEquals(contribEnv.getVariable(var.getName(), cleanDesc.getConfigurationById(id1)).getValue(), var2.getValue());
// Replace the settings with it's backup
project.getFile(".settings/org.eclipse.cdt.core.prefs").setContents(
project.getFile(".settings/org.eclipse.cdt.core.prefs.bak").getContents(), true, false, null);
// check that cleanDesc has been updated
assertEquals(contribEnv.getVariable(var.getName(), cleanDesc.getConfigurationById(id1)).getValue(), var.getValue());
assertEquals(var, envManager.getVariable(var.getName(), cleanDesc.getConfigurationById(id1), true));
}
/**
* Test that on deleting and recreating the project variables haven't persisted
* @throws Exception
*/
public void testBrokenCaching() throws Exception {
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProject");
// Add another, derived configuration
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
final String id1 = desc.getId();
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
// At the moment 0 variables are set
assertEquals(0, contribEnv.getVariables(desc).length);
// Try setting an environment variable
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR");
contribEnv.addVariable(var, prjDesc.getConfigurationById(id1));
assertEquals(1, contribEnv.getVariables(desc).length);
// Check that the variable exists on config1
IEnvironmentVariable readVar = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var, readVar);
// Save the project description
CoreModel.getDefault().setProjectDescription(project, prjDesc);
ResourceHelper.cleanUp(getName());
assertFalse(project.exists());
ResourceHelper.createCDTProjectWithConfig("envProject");
assertTrue(project.exists());
// Fetch the current configuration
prjDesc = CoreModel.getDefault().getProjectDescription(project);
desc = prjDesc.getActiveConfiguration();
assertEquals(0, contribEnv.getVariables(desc).length);
}
/**
* This bug checks for an environment load race during project open / import.
*
* This occurs because environment is stored using platform Preferences (persisted in
* the .settings directory) and, when background refresh is enabled this is loaded
* asynchronously.
*
* The model shouldn't cache incorrect variables / values in the project description
* @throws Exception
*/
public void testBug265282() throws Exception {
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProject");
// Add another, derived configuration
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
final String id1 = desc.getId();
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
// Try setting an environment variable
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR");
final IEnvironmentVariable var1 = new EnvironmentVariable("FOO1", "BAR1");
final IEnvironmentVariable var2 = new EnvironmentVariable("FOO2", "BAR2");
contribEnv.addVariable(var, prjDesc.getConfigurationById(id1));
// Check that the variable exists on config1
IEnvironmentVariable readVar = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var, readVar);
// Save the project description
CoreModel.getDefault().setProjectDescription(project, prjDesc);
// Delete and reimport the project, environment should persist...
project.close(null);
project.delete(false, null);
IJobManager jm = Job.getJobManager();
ISchedulingRule root = ResourcesPlugin.getWorkspace().getRoot();
// Var 3 is to overwrite var2
final IEnvironmentVariable var3 = new EnvironmentVariable("FOO2", "BAR3");
try {
// lock the workspace preventing any asynchronous refresh job from detecting new environment
jm.beginRule(root, null);
project.create(null);
project.open(IResource.BACKGROUND_REFRESH, null);
prjDesc = CoreModel.getDefault().getProjectDescription(project);
readVar = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
// At this point readVar will be null -- we've locked the resource tree, so async refresh can't proceed
assertNull(readVar);
// Remove one variable
envManager.getContributedEnvironment().removeVariable(var2.getName(), prjDesc.getConfigurationById(id1));
// repalce one with another
envManager.getContributedEnvironment().addVariable(var3, prjDesc.getConfigurationById(id1));
} finally {
jm.endRule(root);
}
// Make everything up to date
project.refreshLocal(IResource.DEPTH_INFINITE, null);
// Environment should now be correct
readVar = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var, readVar);
readVar = envManager.getVariable(var1.getName(), prjDesc.getConfigurationById(id1), true);
assertNull(readVar);
readVar = envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var3, readVar);
// Get project description should only have the persisted envvar
prjDesc = CoreModel.getDefault().getProjectDescription(project);
readVar = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
assertEquals(var, readVar);
readVar = envManager.getVariable(var1.getName(), prjDesc.getConfigurationById(id1), true);
assertNull(readVar);
readVar = envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id1), true);
assertNull(readVar);
}
/**
* This test checks if an environment variable is only processed as a list
* if it matches a certain pattern. ([^:]+:)+[^:]* (; on Windows)
*
* If a variable is a list, it is split into a String array depending on the
* delimiter given. At some point, this array is used to build a new
* String representing the list, separated by the delimiter. This should
* only happen when the variable matches the pattern. For example, if a
* variable has a value of ':' without the quotes, it shouldn't processed as
* a list even if it contains a delimiter because if it was, it would give
* an empty string when built since there are no items in the list.
*
* @throws Exception
*/
public void testBug284843() throws Exception{
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProject");
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
ICConfigurationDescription confDesc = prjDesc.getActiveConfiguration();
String delimiter = System.getProperty("path.separator");
// Create the test variables
IEnvironmentVariable varDelim = new EnvironmentVariable("DELIM",
delimiter);
String varListValue = "value1" + delimiter + "value2" + delimiter + "value3";
IEnvironmentVariable varList = new EnvironmentVariable("LIST", varListValue);
IEnvironmentVariable varListDelim = new EnvironmentVariable("LISTDELIM",
"value1" + delimiter);
IEnvironmentVariable varListDelims = new EnvironmentVariable("LISTDELIMS",
varListValue + delimiter);
String varInvalidListValue = delimiter + "value1" + delimiter + "value2" + delimiter + delimiter + "value3" + delimiter;
IEnvironmentVariable varInvalidList = new EnvironmentVariable("INVALIDLIST", varInvalidListValue);
// Add the variables to the contributed environment
contribEnv.addVariable(varDelim, confDesc);
contribEnv.addVariable(varList, confDesc);
contribEnv.addVariable(varListDelim, confDesc);
contribEnv.addVariable(varListDelims, confDesc);
contribEnv.addVariable(varInvalidList, confDesc);
// Get the processed variables
varDelim = envManager.getVariable(varDelim.getName(), confDesc, true);
varList = envManager.getVariable(varList.getName(), confDesc, true);
varListDelim = envManager.getVariable(varListDelim.getName(), confDesc, true);
varListDelims = envManager.getVariable(varListDelims.getName(), confDesc, true);
varInvalidList = envManager.getVariable(varInvalidList.getName(), confDesc, true);
// Should keep the same value, not a list
assertEquals(delimiter, varDelim.getValue());
// Should keep the same value, processed as a list
assertEquals(varListValue, varList.getValue());
// The delimiter will be trimmed, processed as a list
assertEquals("value1", varListDelim.getValue());
// The last delimiter will be trimmed, processed as a list
assertEquals(varListValue, varListDelims.getValue());
// Should keep the same value, not a list
assertEquals(varInvalidListValue,varInvalidList.getValue());
}
/**
* Test case to test environment variable change notifications
*
* @throws Exception
*/
public void testEnvironmentChangeListener() throws Exception {
// Register environment event listener
MockEnvironmentListener envListener = new MockEnvironmentListener();
EnvironmentVariableManager.fUserSupplier.registerEnvironmentChangeListener(envListener);
assertEquals(0, envListener.getCount());
// Define sample environment variable name
String variableName = "VAR";
// Test adding a variable
IEnvironmentVariable[] varsAdded = { new EnvironmentVariable(variableName, "value") };
{
// Reset the listener
envListener.resetCount();
assertEquals(0, envListener.getCount());
// Add environment variable
EnvironmentVariableManager.fUserSupplier.setVariables(varsAdded, null);
EnvironmentVariableManager.fUserSupplier.storeWorkspaceEnvironment(true);
// Doublecheck that variable added
IEnvironmentVariable[] actualVars = EnvironmentVariableManager.fUserSupplier.getVariables(null);
assertTrue(((Arrays.equals(varsAdded, actualVars))));
// Check event received by the listener
assertEquals(1, envListener.getCount());
IEnvironmentChangeEvent event = envListener.getLastEvent();
assertTrue(Arrays.equals(new IEnvironmentVariable[0], event.getOldVariables()));
assertTrue(Arrays.equals(varsAdded, event.getNewVariables()));
}
// Test changing a variable
IEnvironmentVariable[] varsChanged = { new EnvironmentVariable(variableName, "value-changed") };
{
// Reset the listener
envListener.resetCount();
assertEquals(0, envListener.getCount());
// Add environment variable
EnvironmentVariableManager.fUserSupplier.setVariables(varsChanged, null);
EnvironmentVariableManager.fUserSupplier.storeWorkspaceEnvironment(true);
// Doublecheck that variable added
IEnvironmentVariable[] actualVars = EnvironmentVariableManager.fUserSupplier.getVariables(null);
assertTrue(Arrays.equals(varsChanged, actualVars));
// Check event received by the listener
assertEquals(1, envListener.getCount());
IEnvironmentChangeEvent event = envListener.getLastEvent();
assertTrue(Arrays.equals(varsAdded, event.getOldVariables()));
assertTrue(Arrays.equals(varsChanged, event.getNewVariables()));
}
// Test removing a variable
IEnvironmentVariable[] varsRemoved = {};
{
// Reset the listener
envListener.resetCount();
assertEquals(0, envListener.getCount());
// Add environment variable
EnvironmentVariableManager.fUserSupplier.setVariables(varsRemoved, null);
EnvironmentVariableManager.fUserSupplier.storeWorkspaceEnvironment(true);
// Doublecheck that variable added
IEnvironmentVariable[] actualVars = EnvironmentVariableManager.fUserSupplier.getVariables(null);
assertTrue(Arrays.equals(varsRemoved, actualVars));
// Check event received by the listener
assertEquals(1, envListener.getCount());
IEnvironmentChangeEvent event = envListener.getLastEvent();
assertTrue(Arrays.equals(varsChanged, event.getOldVariables()));
assertTrue(Arrays.equals(varsRemoved, event.getNewVariables()));
}
// Release environment event listener
EnvironmentVariableManager.fUserSupplier.unregisterEnvironmentChangeListener(envListener);
}
}