Commit 280738fc authored by gmantele's avatar gmantele
Browse files

[ALL] Update ANT build scripts to test all existings JUnit tests before...

[ALL] Update ANT build scripts to test all existings JUnit tests before compiling. In case of error, the compilation does not complete.
parent 2b16274c
Loading
Loading
Loading
Loading
+38 −2
Original line number Diff line number Diff line
@@ -22,14 +22,33 @@
	
	<property name="adqlParserLink" value="adqlParser.jar" />
	
	<property name="testsDir" value="test" />
	<property name="junitReportsDir" value="reports/adql" />
	
	<fail message="The property POSTGRES must be set! It provides the path toward a directory or a JAR which contains all classes inside org.postgresql.">
		<condition><not><isset property="POSTGRES"/></not></condition>
	</fail>
	
	<fail message="The property SERVLET-API must be set! It provides the path toward a directory or a JAR which contains all classes inside javax.servlet.">
		<condition><not><isset property="SERVLET-API"/></not></condition>
	</fail>
	
	<fail message="The property JUNIT-API must be set! It provides the path toward a directory or a JAR which contains all classes needed to use JUnit.">
		<condition><not><isset property="JUNIT-API"/></not></condition>
	</fail>
	
	<!-- CLASSPATHS -->
	<path id="adql.classpath">
		<pathelement location="${POSTGRES}" />
	</path>
	
	<path id="junit.class.path">
		<path refid="adql.classpath" />
		<pathelement path="${JUNIT-API}" />
		<pathelement location="bin" />
	</path>
	
	<!-- START -->
	<echo>ADQL LIBRARY VERSION = ${version}</echo>
	
	<!-- BUILD ALL TASK -->
@@ -38,7 +57,24 @@
		<antcall target="cleanJavadocBuild" />
	</target>
	
	<target name="cleanAll" depends="clean,cleanJavadoc" description="Delete all files generated by this ANT file for the set version." />
	<target name="cleanAll" depends="clean,cleanJUnitReports,cleanJavadoc" description="Delete all files generated by this ANT file for the set version." />
	
	<!-- JUNIT VALIDATION -->
	<target name="cleanJUnitReports" description="Clean the JUnit reports directory of the ADQL library ONLY.">
			<delete dir="${junitReportsDir}" failonerror="false" />
	</target>
	
	<target name="junitValidation" depends="cleanJUnitReports" description="Executes all JUnit tests before building the library and stop ANT at any error.">
		<mkdir dir="${junitReportsDir}"/>
		<junit errorproperty="adqlTestsFailure" failureproperty="adqlTestsFailure">
			<classpath refid="junit.class.path" />
			<formatter type="brief" usefile="yes" />
			<batchtest todir="${junitReportsDir}">
				<fileset dir="${testsDir}" includes="adql/**/Test*.java" />
			</batchtest>
		</junit>
		<fail if="${adqlTestsFailure}" message="Failed JUnit validation for ADQL Lib.!" />
	</target>
			
	<!-- LIB & SOURCES -->
	<target name="clean" description="Delete the JARs for the library (classes), the runnable ADQL parser and for its sources for the set version.">
@@ -49,7 +85,7 @@
		<delete dir="${compileDir}" failonerror="false" />
	</target>
	
	<target name="compileLib" depends="clean" description="Build all the classes of the ADQL library. This target is particularly usefull because it lets highlighting missing dependencies.">
	<target name="compileLib" depends="clean,junitValidation" description="Build all the classes of the ADQL library. This target is particularly usefull because it lets highlighting missing dependencies.">
		<mkdir dir="${compileDir}" />
		<javac destdir="${compileDir}" srcdir="${srcDir}" includes="${includesList}" includeantruntime="false">
			<classpath refid="adql.classpath" />
+43 −19
Original line number Diff line number Diff line
@@ -26,6 +26,11 @@
	<property name="srcJarFile" value="${jarDest}/tap_src_${version}.jar" />
	<property name="javadocJarFile" value="${jarDest}/tap_javadoc_${version}.jar" />
	
	<property name="testsDir" value="test" />
	<property name="adqlJunitReportsDir" value="reports/adql" />
	<property name="uwsJunitReportsDir" value="reports/uws" />
	<property name="tapJunitReportsDir" value="reports/tap" />
	
	<fail message="The property POSTGRES must be set! It provides the path toward a directory or a JAR which contains all classes inside org.postgresql.">
		<condition><not><isset property="POSTGRES"/></not></condition>
	</fail>
@@ -38,6 +43,12 @@
		<condition><not><isset property="JUNIT-API"/></not></condition>
	</fail>

	<fail message="The property JNDI-API must be set! It provides the path toward a directory or a JAR which contains all classes needed to use Simple-JNDI.">
		<condition><not><isset property="JNDI-API"/></not></condition>
	</fail>
	

	<!-- CLASSPATHS -->
	<path id="tap.classpath">
		<pathelement location="${cosJar}" />
		<pathelement location="${jsonJar}" />
@@ -46,14 +57,9 @@
		<pathelement location="${SERVLET-API}" />
	</path>
	
	<!-- Define the classpath which includes the junit.jar and the classes after compiling-->
	<path id="junit.class.path">
		<pathelement location="${cosJar}" />
		<pathelement location="${jsonJar}" />
		<pathelement location="${stilJar}" />
		<pathelement location="${POSTGRES}" />
		<pathelement location="${SERVLET-API}" />
		
		<path refid="tap.classpath" />
		<pathelement path="${JNDI-API}" />
		<pathelement path="${JUNIT-API}" />
		<pathelement location="bin" />
	</path>
@@ -66,25 +72,43 @@
		<antcall target="cleanJavadocBuild" />
	</target>
	
	<target name="cleanAll" depends="clean,cleanJavadoc" description="Delete all files generated by this ANT file for the set version." />
	<target name="cleanAll" depends="clean,cleanJavadoc,cleanJUnitReports" description="Delete all files generated by this ANT file for the set version." />
	
	<!-- LIB & SOURCES -->
	<target name="junitValidation" description="Executes all JUnit tests before building the library and stop ANT at any error.">
			<junit printsummary="on" fork="yes" haltonfailure="yes">
	<!-- JUNIT VALIDATION -->
	<target name="cleanJUnitReports" description="Clean the JUnit reports directory of the ADQL, UWS and TAP library ONLY.">
		<delete dir="${adqlJunitReportsDir}" failonerror="false" />
		<delete dir="${uwsJunitReportsDir}" failonerror="false" />
		<delete dir="${tapJunitReportsDir}" failonerror="false" />
	</target>
	
	<target name="junitValidation" depends="cleanJUnitReports" description="Executes all JUnit tests before building the library and stop ANT at any error.">
		<mkdir dir="${adqlJunitReportsDir}"/>
		<mkdir dir="${uwsJunitReportsDir}"/>
		<mkdir dir="${tapJunitReportsDir}"/>
		<junit errorproperty="testsFailure" failureproperty="testsFailure">
			<classpath refid="junit.class.path" />
				<test name="tap.config.AllTests" outfile="testReports">
					<formatter type="plain" usefile="yes" />
				</test>
			<formatter type="brief" usefile="yes" />
			<batchtest todir="${adqlJunitReportsDir}">
				<fileset dir="${testsDir}" includes="adql/**/Test*.java" />
			</batchtest>
			<batchtest todir="${uwsJunitReportsDir}">
				<fileset dir="${testsDir}" includes="uws/**/Test*.java" />
			</batchtest>
			<batchtest todir="${tapJunitReportsDir}">
				<fileset dir="${testsDir}" includes="tap/**/Test*.java" />
			</batchtest>
		</junit>
		<fail if="${testsFailure}" message="Failed JUnit validation for ADQL, UWS or TAP Lib.!" />
	</target>
			
	<!-- LIB & SOURCES -->
	<target name="clean" depends="junitValidation" description="Delete the JARs for the library (classes) and for its sources for the set version.">
		<delete file="${libJarFile}" failonerror="false" />
		<delete file="${srcJarFile}" failonerror="false" />
		<delete dir="${compileDir}" failonerror="false" />
	</target>
	
	<target name="compileLib" depends="clean" description="Build all the classes of the TAP library. This target is particularly usefull because it lets highlighting missing dependencies.">
	<target name="compileLib" depends="clean,junitValidation" description="Build all the classes of the TAP library. This target is particularly usefull because it lets highlighting missing dependencies.">
		<mkdir dir="${compileDir}" />
		<javac destdir="${compileDir}" srcdir="${srcDir}" includes="${includesList}" includeantruntime="false">
			<classpath refid="tap.classpath" />
+30 −3
Original line number Diff line number Diff line
@@ -24,15 +24,25 @@
	<property name="srcJarFile" value="${jarDest}/uws_src_${version}.jar" />
	<property name="javadocJarFile" value="${jarDest}/uws_javadoc_${version}.jar" />
	
	<property name="testsDir" value="test" />
	<property name="junitReportsDir" value="reports/uws" />
	
	<fail message="The property SERVLET-API must be set! It provides the path toward a directory or a JAR which contains all classes inside javax.servlet.">
		<condition><not><isset property="SERVLET-API"/></not></condition>
	</fail>

	<!-- CLASSPATHS -->
	<path id="uws.classpath">
		<pathelement location="${cosJar}" />
		<pathelement location="${SERVLET-API}" />
	</path>
	
	<path id="junit.class.path">
		<path refid="uws.classpath" />
		<pathelement path="${JUNIT-API}" />
		<pathelement location="bin" />
	</path>
	
	<echo>UWS LIBRARY VERSION = ${version}</echo>
	
	<!-- BUILD ALL TASK -->
@@ -41,7 +51,24 @@
		<antcall target="cleanJavadocBuild" />
	</target>
	
	<target name="cleanAll" depends="clean,cleanJavadoc" description="Delete all files generated by this ANT file for the set version." />
	<target name="cleanAll" depends="clean,cleanJavadoc,cleanJUnitReports" description="Delete all files generated by this ANT file for the set version." />
	
	<!-- JUNIT VALIDATION -->
	<target name="cleanJUnitReports" description="Clean the JUnit reports directory of the UWS library ONLY.">
			<delete dir="${junitReportsDir}" failonerror="false" />
	</target>
	
	<target name="junitValidation" depends="cleanJUnitReports" description="Executes all JUnit tests before building the library and stop ANT at any error.">
		<mkdir dir="${junitReportsDir}"/>
		<junit errorproperty="uwsTestsFailure" failureproperty="uwsTestsFailure">
			<classpath refid="junit.class.path" />
			<formatter type="brief" usefile="yes" />
			<batchtest todir="${junitReportsDir}">
				<fileset dir="${testsDir}" includes="uws/**/Test*.java" />
			</batchtest>
		</junit>
		<fail if="${uwsTestsFailure}" message="Failed JUnit validation for UWS Lib.!" />
	</target>
			
	<!-- LIB & SOURCES -->
	<target name="clean" description="Delete the JARs for the library (classes) and for its sources for the set version.">
@@ -50,7 +77,7 @@
		<delete dir="${compileDir}" failonerror="false" />
	</target>
	
	<target name="compileLib" depends="clean" description="Build all the classes of the UWS library. This target is particularly usefull because it lets highlighting missing dependencies.">
	<target name="compileLib" depends="clean,junitValidation" description="Build all the classes of the UWS library. This target is particularly usefull because it lets highlighting missing dependencies.">
		<mkdir dir="${compileDir}" />
		<javac destdir="${compileDir}" srcdir="${srcDir}" includes="${includesList}" includeantruntime="false">
			<classpath refid="uws.classpath" />
+3 −3
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ package tap.resource;
 * You should have received a copy of the GNU Lesser General Public License
 * along with TAPLibrary.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 *                       Astronomisches Rechen Institut (ARI)
 */

@@ -38,7 +38,7 @@ import uk.ac.starlink.votable.VOSerializer;
 * <p>This resource just return an XML document giving a description of the TAP service and list all its VOSI resources.</p>
 * 
 * @author Gr&eacute;gory Mantelet (CDS;ARI)
 * @version 2.0 (09/2014)
 * @version 2.0 (02/2015)
 */
public class Capabilities implements TAPResource, VOSIResource {

@@ -128,7 +128,7 @@ public class Capabilities implements TAPResource, VOSIResource {
		out.print(tap.getCapability());

		// Write the capabilities of all VOSI resources:
		Iterator<TAPResource> it = tap.getTAPResources();
		Iterator<TAPResource> it = tap.getResources();
		while(it.hasNext()){
			TAPResource res = it.next();
			if (res instanceof VOSIResource){
+0 −243
Original line number Diff line number Diff line
package adql;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import tap.metadata.TAPColumn;
import tap.metadata.TAPSchema;
import tap.metadata.TAPTable;
import tap.metadata.TAPTable.TableType;
import adql.db.DBColumn;
import adql.db.DBCommonColumn;
import adql.db.DBTable;
import adql.db.DBType;
import adql.db.SearchColumnList;
import adql.db.DBType.DBDatatype;
import adql.db.exception.UnresolvedJoin;
import adql.parser.ParseException;
import adql.query.IdentifierField;
import adql.query.operand.ADQLColumn;

public class SearchColumnListTest {

	public static void main(String[] args) throws ParseException{

		/* SET THE TABLES AND COLUMNS NEEDED FOR THE TEST */
		// Describe the available table:
		TAPTable tableA = new TAPTable("A", TableType.table, "NATURAL JOIN Test table", null);
		TAPTable tableB = new TAPTable("B", TableType.table, "NATURAL JOIN Test table", null);
		TAPTable tableC = new TAPTable("C", TableType.table, "NATURAL JOIN Test table", null);
		TAPTable tableD = new TAPTable("D", TableType.table, "NATURAL JOIN Test table", null);

		// Describe its columns:
		tableA.addColumn(new TAPColumn("id", new DBType(DBDatatype.VARCHAR), "Object ID"));
		tableA.addColumn(new TAPColumn("txta", new DBType(DBDatatype.VARCHAR), "Text of table A"));
		tableB.addColumn(new TAPColumn("id", new DBType(DBDatatype.VARCHAR), "Object ID"));
		tableB.addColumn(new TAPColumn("txtb", new DBType(DBDatatype.VARCHAR), "Text of table B"));
		tableC.addColumn(new TAPColumn("Id", new DBType(DBDatatype.VARCHAR), "Object ID"));
		tableC.addColumn(new TAPColumn("txta", new DBType(DBDatatype.VARCHAR), "Text of table A"));
		tableC.addColumn(new TAPColumn("txtc", new DBType(DBDatatype.VARCHAR), "Text of table C"));
		tableD.addColumn(new TAPColumn("id", new DBType(DBDatatype.VARCHAR), "Object ID"));
		tableD.addColumn(new TAPColumn("txta", new DBType(DBDatatype.VARCHAR), "Text of table A"));
		tableD.addColumn(new TAPColumn("txtd", new DBType(DBDatatype.VARCHAR), "Text of table D"));

		// List all available tables:
		TAPSchema schema = new TAPSchema("public");
		schema.addTable(tableA);
		schema.addTable(tableB);
		schema.addTable(tableC);
		schema.addTable(tableD);

		// Build the corresponding SearchColumnList:
		SearchColumnList listA = new SearchColumnList();
		for(DBColumn col : tableA)
			listA.add(col);
		SearchColumnList listB = new SearchColumnList();
		for(DBColumn col : tableB)
			listB.add(col);
		SearchColumnList listC = new SearchColumnList();
		for(DBColumn col : tableC)
			listC.add(col);
		SearchColumnList listD = new SearchColumnList();
		for(DBColumn col : tableD)
			listD.add(col);

		/* TEST OF NATURAL JOIN */
		System.out.println("### CROSS JOIN ###");
		SearchColumnList crossJoin = join(listA, listB, false, null);

		// DEBUG
		for(DBColumn dbCol : crossJoin){
			if (dbCol instanceof DBCommonColumn){
				System.out.print("\t- " + dbCol.getADQLName() + " in " + ((dbCol.getTable() == null) ? "<NULL>" : dbCol.getTable().getADQLName()) + " (= " + dbCol.getDBName() + " in ");
				Iterator<DBTable> it = ((DBCommonColumn)dbCol).getCoveredTables();
				DBTable table;
				while(it.hasNext()){
					table = it.next();
					System.out.print((table == null) ? "<NULL>" : table.getDBName() + ", ");
				}
				System.out.println(")");
			}else
				System.out.println("\t- " + dbCol.getADQLName() + " in " + ((dbCol.getTable() == null) ? "<NULL>" : dbCol.getTable().getADQLName()) + " (= " + dbCol.getDBName() + " in " + ((dbCol.getTable() == null) ? "<NULL>" : dbCol.getTable().getDBName()) + ")");
		}
		System.out.println();

		/* TEST OF NATURAL JOIN */
		System.out.println("### NATURAL JOIN ###");
		SearchColumnList join1 = join(listA, listB, true, null);
		SearchColumnList join2 = join(listC, listD, true, null);
		//SearchColumnList join3 = join(join1, join2, true, null);

		// DEBUG
		for(DBColumn dbCol : join2){
			if (dbCol instanceof DBCommonColumn){
				System.out.print("\t- " + dbCol.getADQLName() + " in " + ((dbCol.getTable() == null) ? "<NULL>" : dbCol.getTable().getADQLName()) + " (= " + dbCol.getDBName() + " in ");
				Iterator<DBTable> it = ((DBCommonColumn)dbCol).getCoveredTables();
				DBTable table;
				while(it.hasNext()){
					table = it.next();
					System.out.print((table == null) ? "<NULL>" : table.getDBName() + ", ");
				}
				System.out.println(")");
			}else
				System.out.println("\t- " + dbCol.getADQLName() + " in " + ((dbCol.getTable() == null) ? "<NULL>" : dbCol.getTable().getADQLName()) + " (= " + dbCol.getDBName() + " in " + ((dbCol.getTable() == null) ? "<NULL>" : dbCol.getTable().getDBName()) + ")");
		}
		System.out.println();

		/* TEST OF JOIN USING 1 */
		System.out.println("\n### USING JOIN 1 ###");
		ArrayList<ADQLColumn> usingList = new ArrayList<ADQLColumn>();
		usingList.add(new ADQLColumn("id"));
		SearchColumnList joinUsing1 = join(join1, join2, false, usingList);

		// DEBUG
		for(DBColumn dbCol : joinUsing1){
			if (dbCol instanceof DBCommonColumn){
				System.out.print("\t- " + dbCol.getADQLName() + " in " + ((dbCol.getTable() == null) ? "<NULL>" : dbCol.getTable().getADQLName()) + " (= " + dbCol.getDBName() + " in ");
				Iterator<DBTable> it = ((DBCommonColumn)dbCol).getCoveredTables();
				DBTable table;
				while(it.hasNext()){
					table = it.next();
					System.out.print((table == null) ? "<NULL>" : table.getDBName() + ", ");
				}
				System.out.println(")");
			}else
				System.out.println("\t- " + dbCol.getADQLName() + " in " + ((dbCol.getTable() == null) ? "<NULL>" : dbCol.getTable().getADQLName()) + " (= " + dbCol.getDBName() + " in " + ((dbCol.getTable() == null) ? "<NULL>" : dbCol.getTable().getDBName()) + ")");
		}
		System.out.println();

		/* TEST OF JOIN USING 1 *
			System.out.println("\n### USING JOIN 2 ###");
			usingList.clear();
			usingList.add(new TAPColumn("id"));
			SearchColumnList joinUsing2 = joinUsing(listA, join3, usingList);
			
		// DEBUG
			for(DBColumn dbCol : joinUsing2){
				System.out.println("\t- "+dbCol.getADQLName()+" in "+((dbCol.getTable()==null)?"<NULL>":dbCol.getTable().getADQLName())+" (= "+dbCol.getDBName()+" in "+((dbCol.getTable()==null)?"<NULL>":dbCol.getTable().getDBName())+")");
			}
			System.out.println();*/

	}

	public static final SearchColumnList join(final SearchColumnList leftList, final SearchColumnList rightList, final boolean natural, final ArrayList<ADQLColumn> usingList) throws UnresolvedJoin{

		SearchColumnList list = new SearchColumnList();
		/*SearchColumnList leftList = leftTable.getDBColumns();
		SearchColumnList rightList = rightTable.getDBColumns();*/

		/* 1. Figure out duplicated columns */
		HashMap<String,DBCommonColumn> mapDuplicated = new HashMap<String,DBCommonColumn>();
		// CASE: NATURAL
		if (natural){
			// Find duplicated items between the two lists and add one common column in mapDuplicated for each
			DBColumn rightCol;
			for(DBColumn leftCol : leftList){
				// search for at most one column with the same name in the RIGHT list
				// and throw an exception is there are several matches:
				rightCol = findAtMostOneColumn(leftCol.getADQLName(), (byte)0, rightList, false);
				// if there is one...
				if (rightCol != null){
					// ...check there is only one column with this name in the LEFT list,
					// and throw an exception if it is not the case:
					findExactlyOneColumn(leftCol.getADQLName(), (byte)0, leftList, true);
					// ...create a common column:
					mapDuplicated.put(leftCol.getADQLName().toLowerCase(), new DBCommonColumn(leftCol, rightCol));
				}
			}

		}
		// CASE: USING
		else if (usingList != null && !usingList.isEmpty()){
			// For each columns of usingList, check there is in each list exactly one matching column, and then, add it in mapDuplicated
			DBColumn leftCol, rightCol;
			for(ADQLColumn usingCol : usingList){
				// search for exactly one column with the same name in the LEFT list
				// and throw an exception if there is none, or if there are several matches:
				leftCol = findExactlyOneColumn(usingCol.getColumnName(), usingCol.getCaseSensitive(), leftList, true);
				// idem in the RIGHT list:
				rightCol = findExactlyOneColumn(usingCol.getColumnName(), usingCol.getCaseSensitive(), rightList, false);
				// create a common column:
				mapDuplicated.put((usingCol.isCaseSensitive(IdentifierField.COLUMN) ? ("\"" + usingCol.getColumnName() + "\"") : usingCol.getColumnName().toLowerCase()), new DBCommonColumn(leftCol, rightCol));
			}

		}
		// CASE: NO DUPLICATION TO FIGURE OUT
		else{
			// Return the union of both lists:
			list.addAll(leftList);
			list.addAll(rightList);
			return list;
		}

		/* 2. Add all columns of the left list except the ones identified as duplications */
		addAllExcept(leftList, list, mapDuplicated);

		/* 3. Add all columns of the right list except the ones identified as duplications */
		addAllExcept(rightList, list, mapDuplicated);

		/* 4. Add all common columns of mapDuplicated */
		list.addAll(mapDuplicated.values());

		return list;

	}

	public final static void addAllExcept(final SearchColumnList itemsToAdd, final SearchColumnList target, final Map<String,DBCommonColumn> exception){
		for(DBColumn col : itemsToAdd){
			if (!exception.containsKey(col.getADQLName().toLowerCase()) && !exception.containsKey("\"" + col.getADQLName() + "\""))
				target.add(col);
		}
	}

	public final static DBColumn findExactlyOneColumn(final String columnName, final byte caseSensitive, final SearchColumnList list, final boolean leftList) throws UnresolvedJoin{
		DBColumn result = findAtMostOneColumn(columnName, caseSensitive, list, leftList);
		if (result == null)
			throw new UnresolvedJoin("Column \"" + columnName + "\" specified in USING clause does not exist in " + (leftList ? "left" : "right") + " table!");
		else
			return result;
	}

	public final static DBColumn findAtMostOneColumn(final String columnName, final byte caseSensitive, final SearchColumnList list, final boolean leftList) throws UnresolvedJoin{
		ArrayList<DBColumn> result = list.search(null, null, null, columnName, caseSensitive);
		if (result.isEmpty())
			return null;
		else if (result.size() > 1)
			throw new UnresolvedJoin("Common column name \"" + columnName + "\" appears more than once in " + (leftList ? "left" : "right") + " table!");
		else
			return result.get(0);
	}

	/**
	 * Tells whether the given column is a common column (that's to say, a unification of several columns of the same name).
	 * 
	 * @param col	A DBColumn.
	 * @return		true if the given column is a common column, false otherwise (particularly if col = null).
	 */
	public static final boolean isCommonColumn(final DBColumn col){
		return (col != null && col instanceof DBCommonColumn);
	}

}
Loading