/*******************************************************************************
* Copyright (c) 2008, 2011 Thomas Holland (thomas@innot.de) 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:
* Thomas Holland - initial API and implementation
*******************************************************************************/
package de.innot.avreclipse.core.targets;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.IPath;
import org.junit.Before;
import org.junit.Test;
import org.osgi.service.prefs.BackingStoreException;
import de.innot.avreclipse.AVRPlugin;
import de.innot.avreclipse.core.avrdude.AVRDudeException;
import de.innot.avreclipse.core.toolinfo.AVRDude;
/**
* @author Thomas Holland
* @since
*
*/
public class TargetConfigurationTest implements ITargetConfigConstants {
/**
* Extension of {@link TargetConfiguration} to get access to the protected constructors.
*
*/
private class MyTargetConfiguration extends TargetConfiguration {
protected MyTargetConfiguration(IPath file) throws IOException {
super(file);
}
protected MyTargetConfiguration(TargetConfiguration config) {
super(config);
}
}
private TargetConfiguration tc;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
IPath testfile = getTestFile();
tc = new MyTargetConfiguration(testfile);
assertNotNull("Config is null", tc);
}
/**
* Test method for
* {@link de.innot.avreclipse.core.targets.TargetConfiguration#TargetConfiguration(de.innot.avreclipse.core.targets.TargetConfiguration)}
* .
*
* @throws IOException
*/
@Test
public void testTargetConfigurationTargetConfiguration() throws IOException {
ITargetConfigChangeListener faillistener = new ITargetConfigChangeListener() {
public void attributeChange(ITargetConfiguration config, String attribute,
String oldvalue, String newvalue) {
fail("Changing an attribute of the copy caused a attributeChange event of the original");
}
};
// Change a few settings in the standard target configuration
tc.setName("testName");
tc.setDescription("testDescription");
tc.setMCU("testMCU");
tc.setFCPU(12345678);
tc.setAttribute("testattr1", "foo");
tc.setAttribute("testattr2", "bar");
tc.addPropertyChangeListener(faillistener);
// Now clone this target config
TargetConfiguration wc = new MyTargetConfiguration(tc);
assertNotNull("Copy is null", wc);
// Check that all changes were propagated
assertEquals(tc.getId(), wc.getId());
assertEquals(tc.getName(), wc.getName());
assertEquals(tc.getDescription(), wc.getDescription());
assertEquals(tc.getMCU(), wc.getMCU());
assertEquals(tc.getFCPU(), wc.getFCPU());
assertEquals("foo", wc.getAttribute("testattr1"));
assertEquals("bar", wc.getAttribute("testattr2"));
// Check that the listener was not copied
wc.setAttribute("testattr1", "baz");
// and that the copy is separate
assertEquals("foo", tc.getAttribute("testattr1"));
// but on safe the change should propagate to the original config
tc.removePropertyChangeListener(faillistener);
wc.doSave();
assertEquals("baz", tc.getAttribute("testattr1"));
}
/**
* Test method for {@link de.innot.avreclipse.core.targets.TargetConfiguration#getId()}.
*
* @throws IOException
*/
@Test
public void testGetId() throws Exception {
IPath testfile = getTestFile();
TargetConfiguration test = new MyTargetConfiguration(testfile);
assertNotNull(test);
assertEquals(testfile.lastSegment(), test.getId());
}
/**
* Test method for {@link de.innot.avreclipse.core.targets.TargetConfiguration#getName()}.
*/
@Test
public void testName() {
String[] testnames = new String[] { "foo", "bar", "" };
for (String name : testnames) {
tc.setName(name);
assertEquals(name, tc.getName());
assertEquals(name, tc.getAttribute(ATTR_NAME));
}
}
/**
* Test method for {@link de.innot.avreclipse.core.targets.TargetConfiguration#getDescription()}
* .
*/
@Test
public void testDescription() {
String[] testdescriptions = new String[] { "foo", "bar", "" };
for (String desc : testdescriptions) {
tc.setDescription(desc);
assertEquals(desc, tc.getDescription());
assertEquals(desc, tc.getAttribute(ATTR_DESCRIPTION));
}
}
/**
* Test method for {@link de.innot.avreclipse.core.targets.TargetConfiguration#getMCU()}.
*/
@Test
public void testMCUId() {
String[] testmcus = new String[] { "foo", "bar", "" };
for (String mcu : testmcus) {
tc.setMCU(mcu);
assertEquals(mcu, tc.getMCU());
assertEquals(mcu, tc.getAttribute(ATTR_MCU));
}
}
/**
* Test method for {@link de.innot.avreclipse.core.targets.TargetConfiguration#getFCPU()}.
*/
@Test
public void testFCPU() {
int[] testvalues = new int[] { 1234, 123, 0 };
for (int fcpu : testvalues) {
tc.setFCPU(fcpu);
assertEquals(fcpu, tc.getFCPU());
assertEquals(fcpu, Integer.parseInt(tc.getAttribute(ATTR_FCPU)));
}
}
/**
* Test method for {@link de.innot.avreclipse.core.targets.TargetConfiguration#doSave()}.
*
* @throws BackingStoreException
* @throws IOException
*/
@Test
public void testDoSave() throws BackingStoreException, IOException {
// Make a "working copy"
TargetConfiguration wc = new MyTargetConfiguration(tc);
// Change a few settings in the standard target configuration
wc.setName("testNameCopy");
wc.setDescription("testDescriptionCopy");
wc.setMCU("testMCUCopy");
wc.setFCPU(12345678);
// pre-check the dirty flags
assertTrue("Workingcopy should be dirty", wc.isDirty());
assertFalse("Original should be clean", tc.isDirty());
// save the config.
wc.doSave();
// check the dirty flags
assertFalse("Workingcopy should be clean", wc.isDirty());
assertFalse("Original should be clean", tc.isDirty());
// check that the changes were propagated to the original
assertEquals("testNameCopy", tc.getName());
assertEquals("testDescriptionCopy", tc.getDescription());
assertEquals("testMCUCopy", tc.getMCU());
assertEquals(12345678, tc.getFCPU());
// Now reload the save config from the preference storage area with the help of the target
// configuration manager
ITargetConfiguration tc2 = TargetConfigurationManager.getDefault().getConfig(tc.getId());
// and do the same checks
assertEquals("testNameCopy", tc2.getName());
assertEquals("testDescriptionCopy", tc2.getDescription());
assertEquals("testMCUCopy", tc2.getMCU());
assertEquals(12345678, tc2.getFCPU());
}
/**
* Test method for {@link de.innot.avreclipse.core.targets.TargetConfiguration#restoreDefaults()}.
*/
@Test
public void testSetDefaults() {
String id = tc.getId();
// Change a few settings in the standard target configuration
tc.setName("testName");
tc.setDescription("testDescription");
tc.setMCU("testMCU");
tc.setFCPU(12345678);
// Now set the defaults and check that they have been applied
tc.restoreDefaults();
// Check that all changes were propagated
assertEquals(id, tc.getId());
assertEquals(DEF_NAME, tc.getName());
assertEquals(DEF_DESCRIPTION, tc.getDescription());
assertEquals(DEF_MCU, tc.getMCU());
assertEquals(DEF_FCPU, tc.getFCPU());
}
/**
* Test method for
* {@link de.innot.avreclipse.core.targets.TargetConfiguration#getAttribute(java.lang.String)}.
*
* @throws BackingStoreException
*/
@Test
public void testAttribute() throws BackingStoreException {
assertFalse(tc.isDirty());
tc.setAttribute("foo", "bar");
assertTrue(tc.isDirty());
assertEquals("bar", tc.getAttribute("foo"));
// Test failures
try {
tc.setAttribute(null, "bar");
fail("setAttribute(null, xxx) did not throw assertion error");
} catch (Exception e) {
// Exception expected
}
try {
tc.setAttribute("foo", null);
fail("setAttribute(xxx, null) did not throw assertion error");
} catch (Exception e) {
// Exception expected
}
}
/**
* Test method for {@link de.innot.avreclipse.core.targets.TargetConfiguration#getAttributes()}.
*/
@Test
public void testGetAttributes() {
// Add one more custom attribute
tc.setAttribute("foo", "bar");
// now get the list of all attributes and check that the standard attributes + the custom
// attr are in the list
Map<String, String> attrmap = tc.getAttributes();
assertNotNull(attrmap);
assertTrue(attrmap.size() > 0);
assertTrue(attrmap.containsKey(ATTR_NAME));
assertTrue(attrmap.containsKey(ATTR_DESCRIPTION));
assertTrue(attrmap.containsKey(ATTR_MCU));
assertTrue(attrmap.containsKey(ATTR_FCPU));
assertTrue(attrmap.containsKey("foo"));
assertFalse(attrmap.containsKey(null));
// Test failures
try {
tc.getAttribute(null);
fail("getAttribute(null) did not throw assertion error");
} catch (Exception e) {
// Exception expected
}
}
/**
* Test method for {@link de.innot.avreclipse.core.targets.TargetConfiguration#dispose()}.
*/
@Test
public void testDispose() {
ITargetConfigChangeListener faillistener = new ITargetConfigChangeListener() {
public void attributeChange(ITargetConfiguration config, String attribute,
String oldvalue, String newvalue) {
fail("Change event generated after dispose()");
}
};
tc.addPropertyChangeListener(faillistener);
tc.dispose();
// the next line will cause a change event, but the listener should be disposed
tc.setName("foobar");
}
private String fAttribute;
private String fOldValue;
private String fNewValue;
/**
* Test method for
* {@link de.innot.avreclipse.core.targets.TargetConfiguration#addPropertyChangeListener(de.innot.avreclipse.core.targets.TargetConfiguration.ITargetConfigChangeListener)}
* .
*/
@Test
public void testAddPropertyChangeListener() {
ITargetConfigChangeListener listener = new ITargetConfigChangeListener() {
public void attributeChange(ITargetConfiguration config, String attribute,
String oldvalue, String newvalue) {
assertSame(tc, config);
fAttribute = attribute;
fOldValue = oldvalue;
fNewValue = newvalue;
}
};
tc.addPropertyChangeListener(listener);
tc.setName("testname");
assertEquals(ATTR_NAME, fAttribute);
assertEquals("testname", fNewValue);
tc.setName("testname2");
assertEquals(ATTR_NAME, fAttribute);
assertEquals("testname", fOldValue);
assertEquals("testname2", fNewValue);
}
/**
* Test method for
* {@link de.innot.avreclipse.core.targets.TargetConfiguration#removePropertyChangeListener(de.innot.avreclipse.core.targets.TargetConfiguration.ITargetConfigChangeListener)}
* .
*/
@Test
public void testRemovePropertyChangeListener() {
ITargetConfigChangeListener faillistener = new ITargetConfigChangeListener() {
public void attributeChange(ITargetConfiguration config, String attribute,
String oldvalue, String newvalue) {
fail("Change event generated after listener has been removed");
}
};
tc.addPropertyChangeListener(faillistener);
tc.removePropertyChangeListener(faillistener);
// the next line will cause a change event, but the listener should be removed
tc.setName("foobar");
}
/**
* This is not a test but just a small utility to dump all information about all programmers to
* the console.
*
* @throws AVRDudeException
*/
// @Test
public void dumpProgrammers() throws AVRDudeException {
List<IProgrammer> allprogrammers = AVRDude.getDefault().getProgrammersList();
Collections.sort(allprogrammers, new Comparator<IProgrammer>() {
public int compare(IProgrammer o1, IProgrammer o2) {
return o1.getDescription().compareToIgnoreCase(o2.getDescription());
}
});
for (IProgrammer programmer : allprogrammers) {
StringBuilder sb = new StringBuilder();
sb.append(programmer.getDescription());
sb.append("\t");
sb.append(programmer.getId());
sb.append("\t");
// find the type by looking for "type = xxx" in the info text
Pattern typePat = Pattern.compile(".*type\\s*=\\s*(\\w*);.*", Pattern.DOTALL);
Matcher m = typePat.matcher(programmer.getAdditionalInfo());
if (m.matches()) {
sb.append(m.group(1));
sb.append("\t");
} else {
sb.append("type not found;\t");
}
HostInterface[] allhis = programmer.getHostInterfaces();
for (HostInterface hi : allhis) {
sb.append(hi.name());
sb.append(" ");
}
sb.append("\t");
sb.append(programmer.getTargetInterface().name());
System.out.println(sb.toString());
}
}
private IPath getTestFile() throws Exception {
IPath folder = getConfigFolder();
return folder.append("targetconfig.test");
}
private IPath getConfigFolder() throws IOException {
IPath location = AVRPlugin.getDefault().getStateLocation().append("hardwareconfigs");
File folder = location.toFile();
if (!folder.exists()) {
if (!folder.mkdirs()) {
throw new IOException("Could not create hardware config storage folder '"
+ folder.toString() + "'");
}
}
return location;
}
}