package org.iplantc.phyloviewer.server; import static org.junit.Assert.*; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.zip.GZIPInputStream; import javax.sql.DataSource; import org.iplantc.phyloviewer.viewer.client.model.RemoteNode; import org.iplantc.phyloviewer.shared.model.Tree; import org.iplantc.phyloviewer.viewer.server.DatabaseTreeData; import org.iplantc.phyloviewer.viewer.server.db.ConnectionUtil; import org.iplantc.phyloviewer.viewer.server.db.ImportTree; import org.iplantc.phyloviewer.viewer.server.db.ImportTreeData; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; public class TestDatabaseTreeData { static final String DB = "testdb"; static DataSource pool; static DatabaseTreeData treeData; static RemoteNode child0; static RemoteNode child1; static RemoteNode parent; static Tree tree; @BeforeClass public static void classSetUp() throws ClassNotFoundException, SQLException { { Class.forName("org.postgresql.Driver"); Connection conn = DriverManager.getConnection("jdbc:postgresql:phyloviewer", "phyloviewer", "phyloviewer"); conn.createStatement().execute("DROP DATABASE IF EXISTS " + DB); conn.createStatement().execute("CREATE DATABASE " + DB + " WITH TEMPLATE phyloviewer_template;"); conn.close(); } { pool = new MockDataSource(); treeData = new DatabaseTreeData(pool); child0 = new RemoteNode(0, "", 0, 1, 1, 1, 0, 2, 3); //note: IDs will be changed when the node is inserted into the DB child1 = new RemoteNode(1, "", 0, 1, 1, 1, 0, 4, 5); RemoteNode[] children = new RemoteNode[] { child0, child1 }; parent = new RemoteNode(2, "", 2, 3, 2, 0, 1, 1, 6); parent.setChildren(children); tree = new Tree(); tree.setId(0); tree.setRootNode(parent); Connection conn2 = pool.getConnection(); ImportTree it = new ImportTree(conn2); it.addTree(tree,""); it.close(); conn2.close(); } } @AfterClass public static void classTearDown() throws SQLException { Connection conn = DriverManager.getConnection("jdbc:postgresql:phyloviewer", "phyloviewer", "phyloviewer"); conn.createStatement().execute("DROP DATABASE IF EXISTS " + DB); conn.close(); } @Test public void testGetRemoteNode() { RemoteNode returned = treeData.getSubtree(parent.getId(),1); assertNotNull(returned); assertEquals(parent.getNumberOfChildren(), returned.getNumberOfChildren()); assertEquals(parent.getNumberOfLeafNodes(), returned.getNumberOfLeafNodes()); assertEquals(parent.getNumberOfNodes(), returned.getNumberOfNodes()); assertEquals(parent.findMaximumDepthToLeaf(), returned.findMaximumDepthToLeaf()); } @Test public void testGetChildren() { RemoteNode[] returnedChildren = treeData.getChildren(parent.getId()); assertNotNull(returnedChildren); assertEquals(2, returnedChildren.length); assertTrue(arrayContains(child0, returnedChildren)); assertTrue(arrayContains(child1, returnedChildren)); returnedChildren = treeData.getChildren(child0.getId()); assertNull(returnedChildren); returnedChildren = treeData.getChildren(child1.getId()); assertNull(returnedChildren); } private <T> boolean arrayContains(T obj, T[] array) { for (T element : array) { if (element.equals(obj)){ return true; } } return false; } @Test public void testGetTree() { Tree returnedTree = treeData.getTree(tree.getId(), 1); assertEquals(tree, returnedTree); } @Test public void testGetSubtree() { RemoteNode subtree = treeData.getSubtree(parent.getId(), 0); assertNull(subtree.getChildren()); assertEquals(2, subtree.getNumberOfChildren()); subtree = treeData.getSubtree(parent.getId(), 1); assertTrue(arrayContains(child0, subtree.getChildren())); assertTrue(arrayContains(child1, subtree.getChildren())); assertNull(subtree.getChild(0).getChildren()); assertEquals(0, subtree.getChild(0).getNumberOfChildren()); assertNull(subtree.getChild(1).getChildren()); assertEquals(0, subtree.getChild(1).getNumberOfChildren()); } public static void main(String[] args) throws SQLException, ClassNotFoundException, FileNotFoundException, IOException { // classSetUp(); //creates new empty testdb database // Tree tree = loadBenchmarkTree(); //loads NCBI tree MockDataSource pool = new MockDataSource(); DatabaseTreeData treeData = new DatabaseTreeData(pool); Connection connection = pool.getConnection(); Statement statement = connection.createStatement(); ResultSet rs = statement.executeQuery("select * from tree where name = 'ncbi'"); rs.next(); int rootID = rs.getInt("root_id"); ConnectionUtil.close(rs); ConnectionUtil.close(statement); ConnectionUtil.close(connection); System.out.println("depth\tnodes\t2Q\tRec"); for (int depth = 1; depth <= 10; depth += 1) { System.gc(); long t00 = System.currentTimeMillis(); RemoteNode subtree = treeData.getSubtreeInTwoQueries(rootID, depth); long t01 = System.currentTimeMillis(); System.gc(); long t10 = System.currentTimeMillis(); treeData.getSubtreeRecursive(rootID, depth); long t11 = System.currentTimeMillis(); int nodeCount = subtree.getNumberOfLocalNodes(); System.out.println(depth + "\t" + nodeCount + "\t" + (t01 - t00) + "\t" + (t11 - t10)); } } private Tree loadBenchmarkTree() throws FileNotFoundException, IOException, SQLException { File file = new File("./src/test/resources/data/ncbi-taxonomy.nwk.gz"); BufferedReader in = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(file)))); StringBuffer newick = new StringBuffer(); String line; while((line = in.readLine()) != null) { newick.append(line); } RemoteNode root = ImportTreeData.rootNodeFromNewick(newick.toString(), "ncbi"); Tree tree = new Tree(); tree.setRootNode(root); Connection conn = pool.getConnection(); conn.setAutoCommit(false); ImportTree it = new ImportTree(conn); it.addTree(tree, "ncbi"); conn.commit(); it.close(); conn.close(); return tree; } private static class MockDataSource implements DataSource { public MockDataSource() throws SQLException, ClassNotFoundException { Class.forName("org.postgresql.Driver"); } @Override public Connection getConnection() throws SQLException { return DriverManager.getConnection("jdbc:postgresql:" + DB, "phyloviewer", "phyloviewer"); } @Override public Connection getConnection(String username, String password) throws SQLException { return DriverManager.getConnection("jdbc:postgresql:" + DB, "phyloviewer", "phyloviewer"); } @Override public PrintWriter getLogWriter() throws SQLException { return null; } @Override public int getLoginTimeout() throws SQLException { return 0; } @Override public void setLogWriter(PrintWriter out) throws SQLException {} @Override public void setLoginTimeout(int seconds) throws SQLException {} @Override public boolean isWrapperFor(Class<?> iface) throws SQLException { return false; } @Override public <T> T unwrap(Class<T> iface) throws SQLException { return null; } } }