001 package org.hackystat.dailyprojectdata.resource.codeissue; 002 003 import static org.junit.Assert.assertEquals; 004 005 import java.util.HashMap; 006 import java.util.List; 007 import java.util.Map; 008 import java.util.Map.Entry; 009 010 import javax.xml.datatype.XMLGregorianCalendar; 011 012 import org.hackystat.dailyprojectdata.client.DailyProjectDataClient; 013 import org.hackystat.dailyprojectdata.client.DailyProjectDataClientException; 014 import org.hackystat.dailyprojectdata.resource.codeissue.jaxb.CodeIssueDailyProjectData; 015 import org.hackystat.dailyprojectdata.resource.codeissue.jaxb.CodeIssueData; 016 import org.hackystat.dailyprojectdata.test.DailyProjectDataTestHelper; 017 import org.hackystat.sensorbase.client.SensorBaseClient; 018 import org.hackystat.sensorbase.resource.sensordata.jaxb.Properties; 019 import org.hackystat.sensorbase.resource.sensordata.jaxb.Property; 020 import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorData; 021 import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorDatas; 022 import org.hackystat.utilities.tstamp.Tstamp; 023 import org.junit.Before; 024 import org.junit.Test; 025 026 /** 027 * Tests the CodeIssue portion of the DailyProjectData REST API. 028 * 029 * @author Philip Johnson, Julie Sakuda. 030 */ 031 public class TestCodeIssueRestApi extends DailyProjectDataTestHelper { 032 private static final String PREFIX = "Type_"; 033 private static final String CORRECTNESS_RV = "CORRECTNESS_RV_RETURN_VALUE_IGNORED"; 034 private static final String LINE_LENGTH = "LineLength"; 035 private static final String PACKAGE_HTML = "PackageHtml"; 036 private static final String AVOID_STAR_IMPORT = "AvoidStarImport"; 037 /** Constant for Project. */ 038 private static final String PROJECT = "Default"; 039 /** Constant to make PMD happy. */ 040 private static final String CHECKSTYLE = "Checkstyle"; 041 /** The user for this test case. */ 042 private String user = "TestCodeIssue@hackystat.org"; 043 044 private DailyProjectDataClient dpdClient; 045 046 private XMLGregorianCalendar tstamp; 047 048 049 /** 050 * Create data and send to server if we haven't done it already. 051 * @throws Exception If problems occur. 052 */ 053 @Before 054 public void setUp () throws Exception { 055 // First, create some 'counts' for Checkstyle, FindBugs, and PMD. 056 Map<String, Integer> checkstyleCounts = new HashMap<String, Integer>(); 057 checkstyleCounts.put(AVOID_STAR_IMPORT, 2); 058 checkstyleCounts.put(PACKAGE_HTML, 1); 059 checkstyleCounts.put(LINE_LENGTH, 2); 060 checkstyleCounts.put(CORRECTNESS_RV, 6); 061 Map<String, Integer> findbugsCounts = new HashMap<String, Integer>(); 062 findbugsCounts.put(CORRECTNESS_RV, 8); 063 Map<String, Integer> pmdCounts = new HashMap<String, Integer>(); 064 065 String runtime = "2007-10-30T02:00:00"; 066 SensorDatas batchData = new SensorDatas(); 067 batchData.getSensorData().add( 068 makeCodeIssue("2007-10-30T02:00:00", user, runtime, "PMD", pmdCounts)); 069 batchData.getSensorData().add( 070 makeCodeIssue("2007-10-30T02:10:00", user, runtime, CHECKSTYLE, checkstyleCounts)); 071 batchData.getSensorData().add( 072 makeCodeIssue("2007-10-30T02:15:00", user, runtime, "FindBugs", findbugsCounts)); 073 074 // Connect to the sensorbase and register the DailyProjectDataCodeIssue user. 075 SensorBaseClient.registerUser(getSensorBaseHostName(), user); 076 SensorBaseClient client = new SensorBaseClient(getSensorBaseHostName(), user, user); 077 client.authenticate(); 078 // Send the sensor data to the SensorBase. 079 client.putSensorDataBatch(batchData); 080 081 // Now connect to the DPD server and make the client. 082 dpdClient = new DailyProjectDataClient(getDailyProjectDataHostName(), user, user); 083 dpdClient.authenticate(); 084 tstamp = Tstamp.makeTimestamp("2007-10-30"); 085 } 086 087 /** 088 * Test that GET {host}/codeissue/{user}/default/{starttime} works properly with no 089 * type and tool parameters. 090 * 091 * @throws Exception If problems occur. 092 */ 093 @Test 094 public void testAnyQuery() throws Exception { 095 // Test query with no tool or type, so get everything. 096 CodeIssueDailyProjectData codeIssue = dpdClient.getCodeIssue(user, PROJECT, tstamp, null, null); 097 // There should be 5 entries, one for each tool and type combination. 098 assertEquals("Checking for 6 code issue entries.", 6, codeIssue.getCodeIssueData().size()); 099 } 100 101 /** 102 * Tests DPD query where type is specified. 103 * 104 * @throws DailyProjectDataClientException Thrown if an error occurs. 105 */ 106 @Test 107 public void testTypeQuery() throws DailyProjectDataClientException { 108 CodeIssueDailyProjectData codeIssue = 109 dpdClient.getCodeIssue(user, PROJECT, tstamp, null, CORRECTNESS_RV); 110 List<CodeIssueData> issueList = codeIssue.getCodeIssueData(); 111 assertEquals("Checking for 2 entries, checkstyle and findbugs.", 2, issueList.size()); 112 CodeIssueData data = issueList.get(0); 113 assertEquals("Tool should be FindBugs.", "FindBugs", data.getTool()); 114 assertEquals("Issue should be CORRECTNESS_RV.", CORRECTNESS_RV, data.getIssueType()); 115 assertEquals("Count should be 8", 8, data.getNumIssues()); 116 } 117 118 /** 119 * Tests DPD query with tool and type. 120 * 121 * @throws DailyProjectDataClientException Thrown if an error occurs. 122 */ 123 @Test 124 public void testToolTypeQuery() throws DailyProjectDataClientException { 125 CodeIssueDailyProjectData codeIssue = 126 dpdClient.getCodeIssue(user, PROJECT, tstamp, CHECKSTYLE, AVOID_STAR_IMPORT); 127 List<CodeIssueData> issueList = codeIssue.getCodeIssueData(); 128 assertEquals("Checking for 1 Checkstyle entry.", 1, issueList.size()); 129 } 130 131 /** 132 * Tests DPD query with only tool. 133 * 134 * @throws DailyProjectDataClientException Thrown if an error occurs. 135 */ 136 @Test 137 public void testToolQuery() throws DailyProjectDataClientException { 138 CodeIssueDailyProjectData codeIssue 139 = dpdClient.getCodeIssue(user, PROJECT, tstamp, "PMD", null); 140 List<CodeIssueData> issueList = codeIssue.getCodeIssueData(); 141 assertEquals("Checking for 0 PMD member data instance.", 1, issueList.size()); 142 } 143 144 /** 145 * Creates a sample SensorData CodeIssue instance. 146 * 147 * @param tstampString The timestamp as a string 148 * @param user The user. 149 * @param runtimeString The runtime. 150 * @param tool The tool. 151 * @param typeCounts A mapping of types for the given tool to the number of occurrences of 152 * that error type. 153 * @return The new SensorData CodeIssue instance. 154 * @throws Exception If problems occur. 155 */ 156 private SensorData makeCodeIssue(String tstampString, String user, String runtimeString, 157 String tool, Map<String, Integer> typeCounts) throws Exception { 158 XMLGregorianCalendar tstamp = Tstamp.makeTimestamp(tstampString); 159 XMLGregorianCalendar runtime = Tstamp.makeTimestamp(runtimeString); 160 SensorData data = new SensorData(); 161 data.setSensorDataType("CodeIssue"); 162 data.setOwner(user); 163 data.setTimestamp(tstamp); 164 data.setTool(tool); 165 data.setResource("file://foo/bar/baz.txt"); 166 data.setRuntime(runtime); 167 168 data.setProperties(new Properties()); 169 Properties properties = data.getProperties(); 170 List<Property> propertyList = properties.getProperty(); 171 for (Entry<String, Integer> entry : typeCounts.entrySet()) { 172 Property property = new Property(); 173 property.setKey(PREFIX + entry.getKey()); 174 property.setValue(entry.getValue().toString()); 175 propertyList.add(property); 176 } 177 178 return data; 179 } 180 }