<%@ page language="java" import="java.util.Date,java.sql.Connection,java.sql.DriverManager,java.sql.ResultSet,java.sql.Statement"%> Build Stats <% String dbUsername = "SET_ME"; String dbPassword = "SET_ME"; String url = "jdbc:mysql://SET_ME/teamcity"; String requestedProjectID = request.getParameter("projectID") != null? request.getParameter("projectID") : "project2"; // trunk String requestedBuildID = request.getParameter("buildID"); String requestedStartTime = request.getParameter("startTime") != null? request.getParameter("startTime") : String.valueOf(new Date().getTime()); long requestedInterval = Long.valueOf(request.getParameter("interval") != null? request.getParameter("interval") : "7"); // 7 days out.print("Requested project id: " + requestedProjectID + "
"); out.print("Requested build id: " + requestedBuildID + "
"); out.print("Requested start time: " + requestedStartTime + "
"); out.print("Requested interval: " + requestedInterval + "days

"); if (request.getParameter("debug") != null && request.getParameter("debug").toLowerCase().equals("true")) { debug = true; } String DRIVER = "org.gjt.mm.mysql.Driver"; Class.forName(DRIVER).newInstance(); Connection connection = null; Statement statement = null; Statement statement2 = null; String projectSQL = "select distinct project_name, project_id " + "from projects " + "order by project_name"; String buildSQL = "select distinct build_type_name, build_type_id " + "from projects " + "where project_id like '@projectID@' "; String statusSQL = "select history.status, history.status_text, " + "projects.project_name, projects.build_type_name, projects.build_type_id " + "from history, projects " + "where projects.project_id = history.project_id " + "and build_start_time_server > @interval@ " + "and projects.build_type_id = history.build_type_id " + "and build_start_time_server < @startTime@ "; ResultSet projectResults = null; ResultSet buildResults = null; ResultSet statusResults = null; connection = DriverManager.getConnection(url, dbUsername, dbPassword); statement = connection.createStatement(); statement2 = connection.createStatement(); projectResults = statement.executeQuery(projectSQL); %>
<% String updatedBuildSQL = buildSQL.replace("@projectID@", requestedProjectID); if (requestedBuildID != null && ! requestedBuildID.trim().equals("")) { updatedBuildSQL += " and build_type_id = '" + requestedBuildID + "' "; } updatedBuildSQL += " order by build_type_name"; buildResults = statement.executeQuery(updatedBuildSQL); %>
<% buildResults.beforeFirst(); while (buildResults.next()) { float totalRuns = 0f; float totalSuccesses = 0f; float totalCompilationFailures = 0f; float totalPassingTests = 0f; float totalFailingTests = 0f; // LOOP over build types? String updatedSQL = statusSQL + " and history.build_type_id = '" + buildResults.getString(2) + "' "; if (requestedProjectID != null) { updatedSQL += " and history.project_id = '" + requestedProjectID + "' "; } long intervalMillis = requestedInterval * 24l * 60l * 60l * 1000l; updatedSQL = updatedSQL.replace("@interval@", String.valueOf(Long.valueOf(requestedStartTime) - intervalMillis)); updatedSQL = updatedSQL.replace("@startTime@", requestedStartTime); updatedSQL += " order by projects.build_type_name"; debug(updatedSQL); statusResults = statement2.executeQuery(updatedSQL); while (statusResults.next()){ BuildResult parsedResult = parseStatus(statusResults.getString(2), statusResults.getInt(1)); totalRuns++; if (parsedResult.success) { totalSuccesses++; } else if (parsedResult.compilationFailed) { totalCompilationFailures++; } totalPassingTests += parsedResult.passingTests; totalFailingTests += parsedResult.failingTests; } float testDivisor = totalPassingTests + totalFailingTests > 0? totalPassingTests + totalFailingTests : 1; %> <% statusResults.close(); } %>
Build Total Runs Total Success % Success Total Comp Failures % Comp Failure Tests Passing Tests Failing % Passing
<%= buildResults.getString(1) %> <%= (new Float(totalRuns)).intValue() %> <%= (new Float(totalSuccesses)).intValue() %> <%= round((totalSuccesses / totalRuns) * 100f, 3) %> <%= (new Float(totalCompilationFailures)).intValue() %> <%= round((totalCompilationFailures / totalRuns) * 100f, 3)%> <%= (new Float(totalPassingTests)).intValue() %> <%= (new Float(totalFailingTests)).intValue() %> <%= round((totalPassingTests / testDivisor) * 100f, 3) %>
<% projectResults.close(); buildResults.close(); statement.close(); statement2.close(); connection.close(); %> <%! private boolean debug=false; private BuildResult parseStatus(String status, int code) { BuildResult result = new BuildResult(); String originalStatus = status; switch (code) { case 4: // Compilation failed result.compilationFailed = true; break; case 0: // cancelled result.cancelled = true; break; case 1: // success, do not break - need to parse results result.success = true; case 3: // failed if (status.contains("Tests ")) { status = status.substring(status.indexOf("Tests ") + 6); } if (status.contains("(")) { status = status.substring(0, status.indexOf("(") -1) + status.substring(status.indexOf(")") + 1); } String[] results = status.split(","); for (int i=0; i < results.length; i++) { String currentResultString = results[i].trim(); String[] resultParts = currentResultString.split(":"); if (resultParts[0].trim().equals("passed")) { result.passingTests = Integer.valueOf(resultParts[1].trim()); } else if (resultParts[0].trim().equals("failed")) { result.failingTests = Integer.valueOf(resultParts[1].trim()); } } //System.out.println(code + " - " + originalStatus); //System.out.println(result); break; } return result; } private float round(float value, int places) { float multiplier = (float)Math.pow(10, places); float result = value * multiplier; result = Math.round(result); return (float)result/multiplier; } private void debug(String message) { if (debug) { System.out.println(message); } } class BuildResult { boolean success = false; boolean compilationFailed = false; boolean cancelled = false; int passingTests = 0; int failingTests = 0; public String toString() { return "Success? " + success + " Compilation Failed? " + compilationFailed + " Passed: " + passingTests + " Failed: " + failingTests; } } %>