From: fredrik <fre...@us...> - 2005-04-28 11:51:15
|
Update of /cvsroot/test-manager/main/src/testmanager/database/tables In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14164/src/testmanager/database/tables Added Files: Attachment.java TestCaseArea.java Bug.java BugLink.java package.html LoggedIn.java TestCase.java Tester.java History.java Log Message: Reorganizing servlets & adding bug tracking --- NEW FILE: package.html --- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <html> <body> Provides classes that models the problem domain. </body> </html> --- NEW FILE: LoggedIn.java --- package testmanager.database.tables; /** * @author Fredrik Fornwall */ public abstract class LoggedIn { public static final String createTableStatement = "CREATE TABLE LoggedIn (TesterID INTEGER NOT NULL)"; } --- NEW FILE: Bug.java --- package testmanager.database.tables; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; /** * @author Fredrik Fornwall */ public class Bug { public static void addDummyData(Connection connection) throws SQLException { addNew(connection, 41514, 1, STATUS_OPEN); addNew(connection, 33, 1, STATUS_OPEN); addNew(connection, 44, 1, STATUS_OPEN); } public static int getTestCaseID(Connection connection, int bugID) throws SQLException { ResultSet resultSet = connection.createStatement().executeQuery( "SELECT TestCaseID FROM Bug WHERE BugID = " + bugID); resultSet.next(); return resultSet.getInt(1); } public static final String createTableStatement = "CREATE TABLE Bug (" + "BugID INT NOT NULL, " + "TestCaseID INT NOT NULL, " + "BugStatus INT NOT NULL, " + "PRIMARY KEY (BugID, TestCaseID)" + ")"; public static interface RowHandler { public void noRows(); public void start(); public void finish(); public void handleRow(int bugID, int bugStatus); } public static void useRowHandler(Connection connection, int testCaseID, RowHandler rowHandler) throws SQLException { ResultSet resultSet = connection.createStatement().executeQuery( "SELECT BugID, BugStatus FROM Bug WHERE TestCaseID = " + testCaseID); if (!resultSet.next()) { rowHandler.noRows(); return; } rowHandler.start(); do { rowHandler.handleRow(resultSet.getInt(1), resultSet.getInt(2)); } while (resultSet.next()); rowHandler.finish(); } public static final int STATUS_OPEN = 1; public static final int STATUS_RESOLVED = 1 << 1; public static final int STATUS_VERIFIED_BY_TEST = 1 << 2; public static final String[] STATUS_MARKS = { "", "R", "V" }; public static void remove(Connection connection, int bugID, int testCaseID) throws SQLException { connection.createStatement().executeUpdate( "DELETE FROM Bug WHERE BugID = " + bugID + " AND TestCaseID = " + testCaseID); } public static void addNew(Connection connection, int bugID, int testCaseID, int bugStatus) throws SQLException { connection.createStatement().executeUpdate( "INSERT INTO Bug (BugID, TestCaseID, BugStatus) VALUES (" + bugID + ", " + testCaseID + ", " + bugStatus + ")"); } } --- NEW FILE: Tester.java --- package testmanager.database.tables; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import testmanager.database.Database; import testmanager.database.jdbc.Utilities; /** * A user of the test manager framework. * * @author Fredrik Fornwall */ public class Tester { public static void addDummyData(Connection connection) throws IllegalArgumentException, SQLException, AlreadyExistsException { addNew("admin", "mellon", "Joe Admin", "jo...@ad...", ROLE_ADMIN); addNew("fredrik", "mellon", "Fredrik Fornwall", "fre...@gm...", ROLE_TESTER); addNew("faina", "mellon", "Faina Barknell", "bar...@ho...", ROLE_TESTER); addNew("goran", "mellon", "Goran Soderman", "gor...@ch...", ROLE_TESTER); addNew("czeslaw", "mellon", "Czeslaw Kolodziejski", "cz...@ch...", ROLE_TESTER); } public static String getFullName(Connection connection, int testerID) throws SQLException { return Utilities.stringQuery(connection, "SELECT FullName FROM Tester WHERE ID = " + testerID); } public static class AlreadyExistsException extends Exception { } public boolean isLoggedIn() { try { Connection connection = Database.getConnection(); ResultSet result = connection.createStatement().executeQuery( "SELECT COUNT(*) FROM LoggedIn WHERE TesterID = " + getID()); result.next(); return (result.getInt(1) == 1); } catch (SQLException e) { e.printStackTrace(); //TODO: Handle return true; } } public void login() { try { Connection connection = Database.getConnection(); connection.createStatement().executeUpdate( "INSERT INTO LoggedIn VALUES (" + getID() + ")"); } catch (SQLException e) { e.printStackTrace(); } } public void logout() { try { Connection connection = Database.getConnection(); connection.createStatement().executeUpdate( "DELETE FROM LoggedIn WHERE TesterID = " + getID()); } catch (SQLException e) { e.printStackTrace(); } } public static final int MAX_FULLNAME_LENGTH = 40; public static final int MAX_MAILADDRESS_LENGTH = 30; public static final int MAX_PASSWORD_LENGTH = 15; public static final int MAX_USERNAME_LENGTH = 18; public static final int ROLE_ADMIN = 0; public static final int ROLE_TESTER = 1; public static final String[] roleNames = { "Administrator", "Tester" }; /** * The SQL statement to create the Tester database table. */ public static final String createTableStatement = "CREATE TABLE Tester (" + "ID INTEGER PRIMARY KEY NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), " + "Role INT NOT NULL, " + "UserName VARCHAR(" + MAX_USERNAME_LENGTH + ") UNIQUE NOT NULL, " + "Password VARCHAR(" + MAX_PASSWORD_LENGTH + ") NOT NULL, " + "FullName VARCHAR(" + MAX_FULLNAME_LENGTH + "), " + "MailAddress VARCHAR(" + MAX_MAILADDRESS_LENGTH + ") NOT NULL" + ")"; /** * Add a new Tester into the database and return the generated id from him. * * @param userName * The userName of the new tester. * @param password * The password of the new tester. * @param fullName * The full name of the new tester. * @param mailAddress * The mail address of the new tester. * * @return The generated ID of the inserted Tester. * @throws SQLException * If one occurs while adding the Tester to the database * @throws IllegalArgumentException * If any of the arguments are of the wrong size or format * @throws AlreadyExistsException * If a tester with the supplied username already exists. */ public static int addNew(String userName, String password, String fullName, String mailAddress, int role) throws SQLException, IllegalArgumentException, AlreadyExistsException { if (userName.length() < 4 || userName.length() > MAX_USERNAME_LENGTH) { throw new IllegalArgumentException( "User name must be between four and twelve characters long"); } else if (password.length() < 6 || password.length() > MAX_PASSWORD_LENGTH) { throw new IllegalArgumentException( "Password must be between six and fifteen characters long"); } else if (fullName.length() < 6 || fullName.length() > MAX_FULLNAME_LENGTH) { throw new IllegalArgumentException( "Full name must be between six and forty characters long"); } else if (mailAddress.length() < 6 || mailAddress.length() > MAX_MAILADDRESS_LENGTH) { throw new IllegalArgumentException( "Mail address must be between six and forty characters long"); } else if (!mailAddress .matches("^([a-zA-Z0-9_\\.\\-])+\\@(([a-zA-Z0-9\\-])+\\.)+([a-zA-Z0-9]{2,4})+$")) { throw new IllegalArgumentException("The supplied mail address \"" + mailAddress + "\" does not seem to be valid!"); } else if (role != ROLE_ADMIN && role != ROLE_TESTER) { throw new IllegalArgumentException("Invalid role: " + role); } Connection connection = Database.getConnection(); // Check that no user with the supplied user name already exists PreparedStatement statement = connection .prepareStatement("SELECT COUNT(*) FROM Tester WHERE UserName = ?"); statement.setString(1, userName); ResultSet countResult = statement.executeQuery(); countResult.next(); if (countResult.getInt(1) != 0) { throw new AlreadyExistsException(); } statement = connection .prepareStatement( "INSERT INTO Tester (UserName, Password, FullName, MailAddress, Role) VALUES (?, ?, ? , ?, ?)", Statement.RETURN_GENERATED_KEYS); statement.setString(1, userName); statement.setString(2, password); statement.setString(3, fullName); statement.setString(4, mailAddress); statement.setInt(5, role); statement.executeUpdate(); ResultSet generatedKeys = statement.getGeneratedKeys(); generatedKeys.next(); return generatedKeys.getInt(1); } /** * Get a tester by his id; * * @param id * The id of the wanted tester. * @return The tester with the specified id or null if none exists. */ public static Tester getById(int id) throws SQLException { Connection connection = Database.getConnection(); try { // We only assure that there is a user with this name PreparedStatement statement = connection .prepareStatement("SELECT * FROM Tester WHERE ID = ?"); statement.setInt(1, id); ResultSet result = statement.executeQuery(); if (result.next()) { return new Tester(result.getInt("ID"), result.getString("UserName"), result .getString("Password"), result.getString("FullName"), result .getString("MailAddress"), result.getInt("Role")); } else { return null; } } catch (SQLException e) { System.out.println("SQLException in getByUserName: " + e.getMessage()); } finally { connection.close(); } return null; } /** * Get a tester by name. * * @param userName * The user name of the wanted tester. * @return The tester with the specified name or null if no tester with the specified name * exists. */ public static Tester getByUserName(String userName) throws SQLException { Connection connection = Database.getConnection(); try { // We only assure that there is a user with this name PreparedStatement statement = connection .prepareStatement("SELECT * FROM Tester WHERE userName = ?"); statement.setString(1, userName); ResultSet result = statement.executeQuery(); if (result.next()) { return new Tester(result.getInt("id"), result.getString("userName"), result .getString("password"), result.getString("fullName"), result .getString("mailAddress"), result.getInt("role")); } else { return null; } } catch (SQLException e) { System.out.println("SQLException in getByUserName: " + e.getMessage()); } finally { connection.close(); } return null; } private String fullName; private int id; private String mailAddress; private String password; private String userName; private int role; private Tester() { } private Tester(int id, String userName, String password, String fullName, String mailAddress, int role) { this.id = id; this.userName = userName; this.password = password; this.fullName = fullName; this.mailAddress = mailAddress; this.role = role; } public String getFullName() { return fullName; } public int getID() { return id; } public String getMailAddress() throws SQLException { return mailAddress; } public String getPassword() throws SQLException { return password; } public String getUserName() { return userName; } public void setPassword(String password) { } /** * @return Returns the role. */ public int getRole() { return role; } } --- NEW FILE: BugLink.java --- package testmanager.database.tables; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * @author Fredrik Fornwall */ public abstract class BugLink { public static void addDummyData(Connection connection) throws SQLException { changeTo(connection, "http://good.old.bugzilla/show_bug.cgi?id="); } public static final int MAX_LENGTH = 80; public static final String createTableStatement = "CREATE TABLE BugLink (Link VARCHAR(" + MAX_LENGTH + ") NOT NULL)"; public static void initialize(Connection connection) throws SQLException { connection.createStatement().execute("INSERT INTO BugLink VALUES ('')"); } public static String get(Connection connection) throws SQLException { ResultSet resultSet = connection.createStatement().executeQuery("SELECT * FROM BugLink"); resultSet.next(); return resultSet.getString(1); } public static void changeTo(Connection connection, String newLink) throws SQLException { PreparedStatement statement = connection.prepareStatement("UPDATE BugLink SET Link = ?"); statement.setString(1, newLink); statement.executeUpdate(); } } --- NEW FILE: Attachment.java --- package testmanager.database.tables; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; /** * File attachments to test cases. * * @author Fredrik Fornwall */ public class Attachment { public static void remove(Connection connection, int attachmentID) throws SQLException { connection.createStatement().executeUpdate( "DELETE FROM Attachment WHERE ID = " + attachmentID); } public static int getTestCaseID(Connection connection, int attachmentID) throws SQLException { ResultSet resultSet = connection.createStatement().executeQuery( "SELECT TestCaseID FROM Attachment WHERE ID = " + attachmentID); resultSet.next(); return resultSet.getInt(1); } public static String getName(Connection connection, int attachmentID) throws SQLException { ResultSet resultSet = connection.createStatement().executeQuery( "SELECT Name FROM Attachment WHERE ID = " + attachmentID); resultSet.next(); return resultSet.getString(1); } public static final String createTableStatement = "CREATE TABLE Attachment (" + "ID INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), " + "TestCaseID INTEGER NOT NULL, " + // ID of TestCase that this is // an attachment to "Name VARCHAR(60) NOT NULL, " + "Contents BLOB(32M) NOT NULL" + ")"; } --- NEW FILE: History.java --- package testmanager.database.tables; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /** * A History item is connected to a TestCase. Each time a Tester changes something on a TestCase a * History item is created. * * @author Fredrik Fornwall */ public class History { public static void addDummyData(Connection connection) throws SQLException { /* addNew(connection, 1, 2, ) statement .addBatch("INSERT INTO History (TestCaseID, ResponsibleID, CreationTimestamp, Description, Comment) " + "VALUES (1, 1, CURRENT_TIMESTAMP, 'Changed test status to fail\n', 'Application crashes at startup')"); statement .addBatch("INSERT INTO History (TestCaseID, ResponsibleID, CreationTimestamp, Description, Comment) " + "VALUES (1, 2, CURRENT_TIMESTAMP, 'Changed test status to pass\n', 'I fixed it yesterday, updating the status.')"); */ } /** * Append a history item id. * * @param testCaseID * @param creatorID * @param description * @throws SQLException */ public static void addNew(Connection connection, int testCaseID, int creatorID, String description, String comment) throws SQLException { PreparedStatement statement = connection.prepareStatement("INSERT INTO History " + "(TestCaseID, CreationTimestamp, ResponsibleID, Description, Comment) VALUES " + "(?, CURRENT_TIMESTAMP, ?, ?, ?)"); statement.setInt(1, testCaseID); statement.setInt(2, creatorID); statement.setString(3, description); statement.setString(4, comment); statement.executeUpdate(); } public static final String createTableStatement = "Create TABLE History (" + "ID INT NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), " // ID of the test case this history item is attached to + "TestCaseID INTEGER NOT NULL, " // ID of the responsible tester of this history item. + "ResponsibleID INTEGER NOT NULL, " // The time at which this history item was created + "CreationTimestamp TIMESTAMP NOT NULL, " // A description of what was made such as "Changed test status to // pass" + "Description LONG VARCHAR," // A commment entered by the user + "Comment LONG VARCHAR" + ")"; } --- NEW FILE: TestCase.java --- package testmanager.database.tables; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import testmanager.database.jdbc.Utilities; /** * A single test case. * * @author Fredrik Fornwall */ public class TestCase { public static final int MIN_TITLE_LENGTH = 6; public static final int MAX_TITLE_LENGTH = 60; public static void setNewDueDate(Connection connection, int testCaseID, int newYear, int newMonth, int newDay) throws SQLException { PreparedStatement statement = connection .prepareStatement("UPDATE TestCase SET DueDate = ? WHERE ID = ?"); statement.setDate(1, Utilities.createSQLDate(newYear, newMonth, newDay)); statement.setInt(2, testCaseID); statement.executeUpdate(); } public static String getSpecification(Connection connection, int testCaseID) throws SQLException { return Utilities.stringQuery(connection, "SELECT DESCRIPTION FROM TestCase WHERE ID = " + testCaseID); } public static void setNewSpecification(Connection connection, int testCaseID, String newSpecification) throws SQLException { PreparedStatement statement = connection .prepareStatement("UPDATE TestCase SET Description = ? WHERE ID = ?"); statement.setString(1, newSpecification); statement.setInt(2, testCaseID); statement.executeUpdate(); } public static void addDummyData(Connection connection) throws SQLException { addNew(connection, "Verify that the Acid2 page renders correctly", 1, 2, 1, "This test case tests that the browser HTML rendering capability is standards compliant.\n" + "Environment: Windows XP\n" + "Test Execution:\n" + "1. Open your browser.\n" + "2. Open the acid2 test\n" + "3. Compare rendering with reference image\n" + "Expected Result: The reference image and the actual rendering should match", 2006, 5, 12, TestCase.STATUS_PASS, TestCase.ACCEPTANCE_CRITERIA); addNew(connection, "Verify that applications launches correctly", 1, 2, 1, "Functionality tested: The ability to launch the program through java web start.\n" + "Environment: Any modern browser\n" + "Test Execution:\n" + "1. Open your browse\n" + "2. Go to http://test-manager.sf.net/\n" + "3. Click on the \"Launch\" \n" + "Expected Result: Java web start should launch normally and give a security warning", 2007, 5, 1, TestCase.STATUS_PASS, TestCase.ACCEPTANCE_CRITERIA); } public static final String createTableStatement = "CREATE TABLE TestCase (" + "ID INT NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), " + "Title VARCHAR(" + MAX_TITLE_LENGTH + ") NOT NULL, " + "AuthorID INTEGER NOT NULL, " + "ResponsibleID INTEGER NOT NULL, " + "Type INTEGER NOT NULL, " + "Status INTEGER NOT NULL, " + "AreaID INTEGER NOT NULL, " + "CreationDate DATE NOT NULL, " + "ExecutionDate DATE NOT NULL, " + "DueDate DATE NOT NULL, " + "Description LONG VARCHAR" + ")"; /** * Add a new test case to the database. The parameters are checked * * @param connection * @param title * @param authorID * @param responsibleID * @param areaID * @param description * @param dueDate * @param status * @param typeID * @return The generated ID of the inserted Tester. * * @throws IllegalArgumentException * if any invalid arguments are given and checked before database calls. * @throws SQLException */ public static int addNew(Connection connection, String title, int authorID, int responsibleID, int areaID, String description, int dueDateYear, int dueDateMonth, int dueDateDay, int status, int typeID) throws SQLException { if (title.length() < MIN_TITLE_LENGTH || title.length() > MAX_TITLE_LENGTH) { throw new IllegalArgumentException( "Test case title must be between six and sixty characters long"); } PreparedStatement statement = connection.prepareStatement( "INSERT INTO TestCase (Title, AuthorId, ResponsibleID, AreaID, " + "ExecutionDate, CreationDate, DueDate, Status, Type, Description) " + "VALUES (?, ?, ?, ?, CURRENT_DATE, CURRENT_DATE, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS); int index = 1; statement.setString(index++, title); statement.setInt(index++, authorID); statement.setInt(index++, responsibleID); statement.setInt(index++, areaID); statement.setDate(index++, Utilities.createSQLDate(dueDateYear, dueDateMonth, dueDateDay)); statement.setInt(index++, status); statement.setInt(index++, typeID); statement.setString(index++, description); statement.executeUpdate(); ResultSet generatedKeys = statement.getGeneratedKeys(); generatedKeys.next(); return generatedKeys.getInt(1); } /** * A possible level. These test cases are run when Testing first receives a new build of an * application. They verify that further testing is possible. These must all pass for a build to * be considered TESTABLE. Less than 5% of your test cases should be smoke tests. You should * have at least a few standard tests that you run through every build to ensure it is testable. */ public static final int SMOKE_TEST = 0; /** * These test cases are run on every build that Testing certifies as testable (has passed the * smoke tests). They verify that core functionality works exactly as */ public static final int CRITICAL_PATH = 1; /** * These test cases need to be run at least once during the entire test cycle for this release. * These cases are run once, and do not need to be repeated. They verify the minimum * requirements for the application to be released. These test cases (plus the smoke test and * critical path cases) must all pass for a build to be */ public static final int ACCEPTANCE_CRITERIA = 2; /** * These are Test Cases that would be nice to execute, but may be omitted due to time * constraints. Typically, these test cases would have a low visibility of occurrence to users. * Roughly 0-30% of your test cases should be smoke tests; the more thoroughly */ public static final int SUGGESTED = 3; /** * Textual description of the different types that a TestCase can be. */ public static final String[] typeNames = { "Smoke Test", "Critical Path", "Acceptance Criteria", "Suggested" }; /** * This is never used to indicate a real status. This is for instance passed to indicate no * change. */ public static final int STATUS_NOT_USED = -1; public static final int STATUS_NOT_TESTED = 0; public static final int STATUS_FAIL = 1; public static final int STATUS_PASS = 2; public static final int STATUS_POSTPONED = 3; public static final String[] statusNames = { "Not Tested", "Fail", "Pass", "Postponed" }; } --- NEW FILE: TestCaseArea.java --- package testmanager.database.tables; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import testmanager.database.jdbc.Utilities; /** * Test case area to which a test case belongs. * * @author Fredrik Fornwall */ public class TestCaseArea { public static String getName(Connection connection, int testCaseAreaID) throws SQLException { return Utilities.stringQuery(connection, "SELECT Name FROM TestCaseArea WHERE ID = " + testCaseAreaID); } public static final int MAX_NAME_LENGTH = 40; public static final String createTableStatement = "CREATE TABLE TestCaseArea (" + "ID INTEGER PRIMARY KEY NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), " + "Name VARCHAR(" + MAX_NAME_LENGTH + ") UNIQUE NOT NULL, " + "Description LONG VARCHAR NOT NULL" + ")"; /** * Add a new test case area into the database. * * @param name * The name of the test case area to add. * @param description * The description of the test case area to add. * @return The ID of the newly inserted TestCaseArea. * @throws SQLException * If one occurs while inserting the area into the database. */ public static int addNew(Connection connection, String name, String description) throws SQLException { if (name.length() < 2 || name.length() > MAX_NAME_LENGTH) { throw new IllegalArgumentException( "Area name must be between two and forty characters long"); } PreparedStatement statement = connection .prepareStatement("SELECT COUNT(*) FROM TestCaseArea WHERE Name = ?"); statement.setString(1, name); ResultSet countResult = statement.executeQuery(); countResult.next(); if (countResult.getInt(1) > 0) { throw new IllegalArgumentException( "An area with the specified area name already exists"); } statement = connection.prepareStatement( "INSERT INTO TestCaseArea (Name, Description) VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS); statement.setString(1, name); statement.setString(2, description); statement.executeUpdate(); ResultSet generatedKeys = statement.getGeneratedKeys(); generatedKeys.next(); return generatedKeys.getInt(1); } } |