package org.dcache.gplazma.loader;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.dcache.gplazma.plugins.GPlazmaPlugin;
import static org.junit.Assert.*;
public class XmlParserTests {
private static final DocumentBuilderFactory BUILDER_FACTORY =
DocumentBuilderFactory.newInstance();
private Document _emptyDocument;
private PluginXmlGenerator _pluginXml;
private Set<PluginMetadata> _plugins;
@Before
public void setUp() throws ParserConfigurationException {
DocumentBuilder builder = BUILDER_FACTORY.newDocumentBuilder();
_emptyDocument = builder.newDocument();
_pluginXml = new PluginXmlGenerator();
}
@Test
public void testEmpty() {
// Note: as the XML is not well-formed, the support library generates
// output on stderr. It's unclear how to suppress this.
parseAndGetPlugins( _emptyDocument);
assertEquals( "check plugins empty", _plugins, Collections.emptySet());
}
@Test
public void testBrokenXml() {
// Note: as the XML is not well-formed, the support library generates
// output on stderr. It's unclear how to suppress this.
parseAndGetPlugins( "<plugins>");
assertEquals( "check plugins empty", _plugins, Collections.emptySet());
}
@Test
public void testXmlWithExtraField() {
parseAndGetPlugins( "<plugins><plugin><class>org.dcache.gplazma.loader.XmlParserTests$DummyPlugin</class><name>test</name><fruit>banana</fruit></plugin></plugins>");
assertEquals( "check plugin count", 1, _plugins.size());
PluginMetadata plugin = _plugins.iterator().next();
assertPluginMetadata( plugin, Collections.singleton( "test"),
DummyPlugin.class, "test", null);
}
@Test
public void testOnlyRoot() {
parseAndGetPlugins();
assertEquals( "check plugins empty", _plugins, Collections.emptySet());
}
@Test
public void testPluginsAndEmptyPlugin() {
_pluginXml.addEmptyPlugin();
parseAndGetPlugins();
assertEquals( "check plugins empty", _plugins, Collections.emptySet());
}
@Test
public void testPluginsAndValidPluginWithSingleName() {
String pluginName = "foo";
Set<String> names = Collections.singleton( pluginName);
_pluginXml.addPlugin( names, DummyPlugin.class);
parseAndGetPlugins();
assertEquals( "check plugin count", 1, _plugins.size());
PluginMetadata plugin = _plugins.iterator().next();
assertPluginMetadata( plugin, names, DummyPlugin.class, pluginName,
null);
}
@Test
public void testPluginsAndValidPluginWithMultipleNames() {
String pluginShortestName = "foo";
Set<String> names =
new HashSet<>( Arrays.asList( pluginShortestName,
"foo-o-matic", "original-foo"));
_pluginXml.addPlugin( names, DummyPlugin.class);
parseAndGetPlugins();
assertEquals( "check plugin count", 1, _plugins.size());
PluginMetadata plugin = _plugins.iterator().next();
assertPluginMetadata( plugin, names, DummyPlugin.class,
pluginShortestName, null);
}
@Test
public void testPluginsAndTwoValidPlugins() {
String plugin1Name = "foo";
Set<String> plugin1Names = Collections.singleton( plugin1Name);
_pluginXml.addPlugin( plugin1Names, DummyPlugin.class);
String plugin2Name = "bar";
Set<String> plugin2Names = Collections.singleton( plugin2Name);
_pluginXml.addPlugin( plugin2Names, AnotherDummyPlugin.class);
parseAndGetPlugins();
assertEquals( "check plugin count", 2, _plugins.size());
Map<String, PluginMetadata> results =
new HashMap<>();
for( PluginMetadata plugin : _plugins) {
results.put( plugin.getShortestName(), plugin);
}
PluginMetadata plugin1Result = results.get( plugin1Name);
assertPluginMetadata( plugin1Result, plugin1Names, DummyPlugin.class,
plugin1Name, null);
PluginMetadata plugin2Result = results.get( plugin2Name);
assertPluginMetadata( plugin2Result, plugin2Names,
AnotherDummyPlugin.class, plugin2Name, null);
}
@Test
public void testPluginWithDefaultControl() {
String pluginName = "foo";
Set<String> names = Collections.singleton( pluginName);
String defaultControl = "required";
_pluginXml.addPlugin( names, DummyPlugin.class.getName(), defaultControl);
parseAndGetPlugins();
assertEquals( "check plugin count", 1, _plugins.size());
PluginMetadata plugin = _plugins.iterator().next();
assertPluginMetadata( plugin, names, DummyPlugin.class, pluginName,
defaultControl);
}
@Test
public void testTwoPluginsWithSameClassAcceptsNeither() {
String className = DummyPlugin.class.getName();
String plugin1Name = "foo";
Set<String> plugin1Names = Collections.singleton( plugin1Name);
_pluginXml.addPlugin( plugin1Names, className);
String plugin2Name = "bar";
Set<String> plugin2Names = Collections.singleton( plugin2Name);
_pluginXml.addPlugin( plugin2Names, className);
parseAndGetPlugins();
assertEquals( "check plugin count", 0, _plugins.size());
}
@Test
public void testThreePluginsWithSameClassAcceptsNone() {
String className = DummyPlugin.class.getName();
String plugin1Name = "foo";
Set<String> plugin1Names = Collections.singleton( plugin1Name);
_pluginXml.addPlugin( plugin1Names, className);
String plugin2Name = "bar";
Set<String> plugin2Names = Collections.singleton( plugin2Name);
_pluginXml.addPlugin( plugin2Names, className);
String plugin3Name = "baz";
Set<String> plugin3Names = Collections.singleton( plugin3Name);
_pluginXml.addPlugin( plugin3Names, className);
parseAndGetPlugins();
assertEquals( "check plugin count", 0, _plugins.size());
}
@Test
public void testPluginWithTwoClassesNotAccepted() {
String class1Name = DummyPlugin.class.getName();
String class2Name = AnotherDummyPlugin.class.getName();
String xmlData = String.format( "<plugins><plugin>"
+ "<name>test</name>"
+ "<class>%s</class>"
+ "<class>%s</class>"
+ "</plugin></plugins>",
class1Name, class2Name);
parseAndGetPlugins( xmlData);
assertEquals( "check plugin count", 0, _plugins.size());
}
/*
* COMPOUND ASSERTIONS
*/
private void assertPluginMetadata( PluginMetadata plugin,
Set<String> assignedNames,
Class<?> expectedClass,
String expectedShortestName,
String expectedDefaultControl) {
assertNotNull( plugin);
assertTrue( plugin.isValid());
// We always add the class name to the list of names
Set<String> expectedNames = new HashSet<>( assignedNames);
expectedNames.add( expectedClass.getName());
assertEquals( expectedNames, plugin.getPluginNames());
assertEquals( expectedClass, plugin.getPluginClass());
assertEquals( expectedShortestName, plugin.getShortestName());
assertEquals( expectedDefaultControl, plugin.getDefaultControl());
}
/*
* SUPPORT METHODS
*/
private void parseAndGetPlugins() {
String xmlData = _pluginXml.toString();
parseAndGetPlugins( xmlData);
}
private void parseAndGetPlugins( Document document) {
String xmlData = PluginXmlGenerator.documentAsString( document);
parseAndGetPlugins( xmlData);
}
private void parseAndGetPlugins( String xmlData) {
Reader xmlSrc = new StringReader( xmlData);
XmlParser parser = new XmlParser( xmlSrc);
parser.parse();
_plugins = parser.getPlugins();
}
/**
* Dummy implementation of a GPlazmaPlugin
*/
public static final class DummyPlugin implements GPlazmaPlugin {
// no content as the class isn't meant to be used.
}
/**
* Another dummy implementation of a GPlazmaPlugin
*/
public static final class AnotherDummyPlugin implements GPlazmaPlugin {
// no content as the class isn't meant to be used.
}
}