// Copyright 2011 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.enterprise.connector.instantiator; import com.google.enterprise.connector.common.PropertiesUtils; import com.google.enterprise.connector.common.StringUtils; import com.google.enterprise.connector.instantiator.InstanceInfo.FactoryCreationFailureException; import com.google.enterprise.connector.instantiator.InstanceInfo.NoBeansFoundException; import com.google.enterprise.connector.instantiator.InstanceInfo.PropertyProcessingFailureException; import com.google.enterprise.connector.instantiator.TypeInfo.TypeInfoException; import com.google.enterprise.connector.spi.Connector; import junit.framework.TestCase; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import java.io.File; import java.io.FileInputStream; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; /** * Base class for InstanceInfoTest and ConnectorInstanceFactoryTest. * Forgive the odd name, but it is not to be confused with a Test Case * at run time. */ public abstract class AbstractTestInstanceInfo extends TestCase { protected Logger logger; protected void setUp() throws Exception { super.setUp(); logger = Logger.getLogger(this.getClass().getName()); } /** * Constructs a new Connector Instance. * * @param connectorName the name of the Connector instance. * @param connectorDir the Connector's on-disk directory. * @param typeInfo the Connector's prototype. * @param connfiguration the Connector Configuration. * @return new Connector instance. */ protected abstract Connector newInstance(String connectorName, String connectorDir, TypeInfo typeInfo, Configuration configuration) throws Exception; /** * Constructs a new Connector Configuration based * upon its on-disk persistently stored configuration. * * @param connectorName the name of the Connector instance. * @param connectorDir the Connector's on-disk directory. * @param typeInfo the Connector's prototype. * @return the Connector Configuration. */ protected Configuration readConfiguration(String connectorName, String connectorDir, TypeInfo typeInfo) throws Exception { // Read the configuration from svn-controlled connectorDir. // Note that this is not the test directory generally used for // persistence, and it shouldn't be. We want to avoid writing // to svn-controlled directories when running the tests. File propFile = new File(connectorDir, connectorName +".properties"); Properties props = PropertiesUtils.loadFromFile(propFile); File xmlFile = new File(connectorDir, TypeInfo.CONNECTOR_INSTANCE_XML); String xml = null; if (xmlFile.exists()) { xml = StringUtils.streamToStringAndThrow(new FileInputStream(xmlFile)); } Configuration configuration = new Configuration(typeInfo.getConnectorTypeName(), PropertiesUtils.toMap(props), xml); assertNotNull(configuration); return configuration; } /** Makes a TypeInfo from the supplied Spring resource. */ protected TypeInfo makeTypeInfo(String resourceName) throws TypeInfoException { Resource r = new FileSystemResource(resourceName); TypeInfo typeInfo = TypeInfo.fromSpringResourceAndThrow(r); assertNotNull(typeInfo); return typeInfo; } /** * Constructs a new Connector Configuration based * upon the supplied Configuration. * * @param connectorName the name of the Connector instance. * @param connfiguration the Connector Configuration. * @param connectorDir the Connector's on-disk directory. * @param typeInfo the Connector's prototype. * @param expectedException Class for expected exception to be thrown. * If null, no exception is expected. * @param expectedMessage Expected message of exception to be thrown. * If null, don't care about the message. * @return the Connector instance. */ protected Connector fromConfigurationTest(String connectorName, String connectorDir, TypeInfo typeInfo, Configuration configuration, Class<? extends Exception> expectedException, String expectedMessage) throws Exception { try { Connector connector = newInstance(connectorName, connectorDir, typeInfo, configuration); assertNull("Expected exception but got none", expectedException); assertNotNull(connector); return connector; } catch (Exception e) { if (e.getClass() == expectedException) { if (expectedMessage != null) { assertTrue("Thrown exception message does not match expected message", e.getMessage().startsWith(expectedMessage)); } logger.log(Level.FINE, "Expected exception thrown", e); } else { logger.log(Level.WARNING, "Unexpected exception during instance info creation", e); throw e; } } return null; } /** * Constructs a new Connector Configuration based * upon its on-disk persistently stored configuration. * * @param connectorName the name of the Connector instance. * @param connectorDir the Connector's on-disk directory. * @param resourceName the ConnectorType Spring resource name. * @param expectedException Class for expected exception to be thrown. * If null, no exception is expected. * @param expectedMessage Expected message of exception to be thrown. * If null, don't care about the message. * @return the Connector instance. */ protected Connector fromDirectoryTest(String connectorName, String connectorDir, String resourceName, Class<? extends Exception> expectedException, String expectedMessage) throws Exception { TypeInfo typeInfo = makeTypeInfo(resourceName); Configuration configuration = readConfiguration(connectorName, connectorDir, typeInfo); return fromConfigurationTest(connectorName, connectorDir, typeInfo, configuration, expectedException, expectedMessage); } /** Test successful Connector Instance creation. */ public final void testFromDirectoryPositive() throws Exception { fromDirectoryTest("fred", "testdata/connectorInstanceTests/positive", "testdata/connectorTypeTests/positive/connectorType.xml", null, null); } /** Test properties file doesn't fill in all properties. */ public final void testInsufficientProperties() throws Exception { fromDirectoryTest("fred", "testdata/connectorInstanceTests/negative3", "testdata/connectorTypeTests/positive/connectorType.xml", PropertyProcessingFailureException.class, null); } /** Test connectorInstance.xml that doesn't implement Connector. */ public final void testNoConnectorBean() throws Exception { fromDirectoryTest("fred", "testdata/connectorInstanceTests/positive", "testdata/connectorInstanceTests/badConnectorType1/connectorType.xml", NoBeansFoundException.class, null); } /** Test custom connectorInstance.xml. */ public final void testCustomInstancePrototype() throws Exception { Connector connector = fromDirectoryTest("fred", "testdata/connectorInstanceTests/custom1", "testdata/connectorTypeTests/positive/connectorType.xml", null, null); assertTrue("Connector should be of type CustomProtoTestConnector", connector instanceof CustomProtoTestConnector); CustomProtoTestConnector c = (CustomProtoTestConnector) connector; assertEquals("oogabooga", c.getCustomProperty()); } /** Test a bad custom connectorInstance.xml. */ public final void testBadCustomInstancePrototype() throws Exception { fromDirectoryTest("fred", "testdata/connectorInstanceTests/custom2", "testdata/connectorTypeTests/positive/connectorType.xml", FactoryCreationFailureException.class, null); } /** Test overspecified properties. */ public final void testOverspecifiedProperties() throws Exception { Connector connector = fromDirectoryTest("fred", "testdata/connectorInstanceTests/overspecifiedProperties", "testdata/connectorTypeTests/positive/connectorType.xml", null, null); assertTrue("Connector should be of type CustomProtoTestConnector", connector instanceof CustomProtoTestConnector); CustomProtoTestConnector c = (CustomProtoTestConnector) connector; assertEquals("hungadunga", c.getCustomProperty()); assertEquals(47, c.getCustomIntProperty()); } /** * Testing case where Connector wants to specify some default properties that * can be overridden. */ public final void testDefaultProperties() throws Exception { Connector connector = fromDirectoryTest("fred", "testdata/connectorInstanceTests/default", "testdata/connectorTypeTests/default/connectorType.xml", null, null); assertTrue("Connector should be of type SimpleTestConnector", connector instanceof SimpleTestConnector); SimpleTestConnector c = (SimpleTestConnector) connector; assertEquals("Checking default - color", "red", c.getColor()); assertEquals("Checking default empty override - repo file", "", c.getRepositoryFileName()); assertEquals("Checking default override - user", "not_default_user", c.getUsername()); assertEquals("Checking setting - work dir name", "/tomcat/webapps/connector-manager/WEB-INF", c.getWorkDirName()); } }