001 package org.hackystat.sensorbase.resource.projects; 002 003 import static org.hackystat.sensorbase.server.ServerProperties.TEST_DOMAIN_KEY; 004 import static org.junit.Assert.assertEquals; 005 import static org.junit.Assert.assertFalse; 006 import static org.junit.Assert.assertTrue; 007 008 import javax.xml.datatype.XMLGregorianCalendar; 009 import org.hackystat.sensorbase.client.SensorBaseClient; 010 import org.hackystat.sensorbase.client.SensorBaseClientException; 011 import org.hackystat.sensorbase.resource.projects.jaxb.MultiDayProjectSummary; 012 import org.hackystat.sensorbase.resource.projects.jaxb.Project; 013 import org.hackystat.sensorbase.resource.projects.jaxb.ProjectIndex; 014 import org.hackystat.sensorbase.resource.projects.jaxb.ProjectRef; 015 import org.hackystat.sensorbase.resource.projects.jaxb.ProjectSummary; 016 import org.hackystat.sensorbase.resource.projects.jaxb.SensorDataSummary; 017 import org.hackystat.sensorbase.resource.projects.jaxb.UriPatterns; 018 import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorData; 019 import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorDataIndex; 020 import org.hackystat.sensorbase.test.SensorBaseRestApiHelper; 021 import org.hackystat.utilities.tstamp.Tstamp; 022 import org.junit.Test; 023 024 /** 025 * Tests the SensorBase REST API for Project resources. 026 * 027 * @author Philip M. Johnson 028 */ 029 public class TestProjectRestApi extends SensorBaseRestApiHelper { 030 031 private String testUser = "TestUser@hackystat.org"; 032 private String testProject = "TestProject"; 033 private String testSdt = "TestSdt"; 034 private String defaultProject = "Default"; 035 private static final String nineAm = "2007-04-30T09:00:00.000"; 036 037 /** 038 * Test that GET host/sensorbase/projects returns an index containing at least one Project. This 039 * is an admin-only request. Probably want to (at)ignore this method on real distributions, 040 * since the returned dataset could be large. 041 * @throws Exception If problems occur. 042 */ 043 @Test 044 public void getProjectIndex() throws Exception { 045 // Create an admin client and check authentication. 046 SensorBaseClient client = new SensorBaseClient(getHostName(), adminEmail, adminPassword); 047 client.authenticate(); 048 // Get the index of all Projects. 049 ProjectIndex index = client.getProjectIndex(); 050 // Make sure that we can iterate through the data and dereference all hrefs. 051 for (ProjectRef ref : index.getProjectRef()) { 052 client.getProject(ref); 053 } 054 assertTrue("Checking for project data", index.getProjectRef().size() > 1); 055 } 056 057 /** 058 * Test that GET host/sensorbase/projects/TestUser@hackystat.org returns an index containing at 059 * least one ProjectRef. 060 * 061 * @throws Exception If problems occur. 062 */ 063 @Test 064 public void getTestUserProjectIndex() throws Exception { 065 // Create the TestUser client and check authentication. 066 SensorBaseClient client = new SensorBaseClient(getHostName(), testUser, testUser); 067 client.authenticate(); 068 // Get the index of this user's Projects. 069 ProjectIndex index = client.getProjectIndex(testUser); 070 // Make sure that we can iterate through the data and dereference all hrefs. 071 for (ProjectRef ref : index.getProjectRef()) { 072 client.getUri(ref.getHref()); 073 } 074 assertTrue("Checking for project data", index.getProjectRef().size() > 1); 075 } 076 077 /** 078 * Test that GET host/sensorbase/projects/TestUser@hackystat.org/TestProject returns a 079 * representation of TestProject. 080 * 081 * @throws Exception If problems occur. 082 */ 083 @Test 084 public void getTestUserProject() throws Exception { 085 // Create the TestUser client and check authentication. 086 SensorBaseClient client = new SensorBaseClient(getHostName(), testUser, testUser); 087 client.authenticate(); 088 // Retrieve the TestProject project and test a field. 089 Project project = client.getProject(testUser, testProject); 090 assertEquals("Checking project name", testProject, project.getName()); 091 } 092 093 /** 094 * Test that GET host/sensorbase/projects/TestUser@hackystat.org/TestProject/sensordata returns an 095 * index of SensorData. 096 * 097 * @throws Exception If problems occur. 098 */ 099 @Test 100 public void getTestUserProjectSensorData() throws Exception { 101 // Create the TestUser client and check authentication. 102 SensorBaseClient client = new SensorBaseClient(getHostName(), testUser, testUser); 103 client.authenticate(); 104 // Retrieve the SensorData for the TestProject project and test a couple of 105 // fields. 106 SensorDataIndex index = client.getProjectSensorData(testUser, testProject); 107 assertTrue("Checking index has entries", index.getSensorDataRef().size() > 1); 108 } 109 110 /** 111 * Test that GET host/sensorbase/projects/TestUser@hackystat.org/TestProject/sensordata? 112 * startTime=2006-04-30T09:00:00.000&endTime=2007-04-30T09:30:00.000 returns an index of 113 * SensorData containing one entry. 114 * 115 * @throws Exception If problems occur. 116 */ 117 @Test 118 public void getTestUserProjectSensorSummary() throws Exception { 119 // Create the TestUser client and check authentication. 120 SensorBaseClient client = new SensorBaseClient(getHostName(), testUser, testUser); 121 client.authenticate(); 122 // Retrieve the SensorData for the TestProject project within the time 123 // interval. 124 XMLGregorianCalendar startTime = Tstamp.makeTimestamp(nineAm); 125 XMLGregorianCalendar endTime = Tstamp.makeTimestamp("2007-04-30T09:30:00.000"); 126 ProjectSummary summary = client.getProjectSummary(testUser, testProject, startTime, endTime); 127 assertEquals("Checking summary size", 1, 128 summary.getSensorDataSummaries().getNumInstances().intValue()); 129 SensorDataSummary dataSummary = summary.getSensorDataSummaries().getSensorDataSummary().get(0); 130 assertEquals("Checking summary tool", "Subversion", dataSummary.getTool()); 131 assertEquals("Checking summary type", testSdt, dataSummary.getSensorDataType()); 132 assertEquals("Checking summary instances", 1, dataSummary.getNumInstances().intValue()); 133 // Now try for multiple days. 134 MultiDayProjectSummary multiSummary = client.getMultiDayProjectSummary(testUser, testProject, 135 startTime, 3); 136 assertEquals("Checking MultiDayProjectSummary", 3, multiSummary.getProjectSummary().size()); 137 } 138 139 /** 140 * Tests the snapshot API. 141 * @throws Exception If problems occur. 142 */ 143 @Test 144 public void getTestUserProjectSnapshot() throws Exception { 145 // Create the TestUser client and check authentication. 146 String snapshotUser = "TestProjectSnapshot@hackystat.org"; 147 SensorBaseClient.registerUser(getHostName(), snapshotUser); 148 SensorBaseClient client = new SensorBaseClient(getHostName(), snapshotUser, snapshotUser); 149 client.authenticate(); 150 // The time interval we'll work in. These will also be our runtimes. 151 XMLGregorianCalendar startTime = Tstamp.makeTimestamp(nineAm); 152 XMLGregorianCalendar endTime = Tstamp.makeTimestamp("2007-04-30T09:30:00.000"); 153 154 XMLGregorianCalendar tstamp1 = Tstamp.incrementMinutes(startTime, 1); 155 XMLGregorianCalendar tstamp2 = Tstamp.incrementMinutes(startTime, 2); 156 XMLGregorianCalendar tstamp3 = Tstamp.incrementMinutes(startTime, 3); 157 String sdt = testSdt; 158 String tool1 = "Tool1"; 159 String tool2 = "Tool2"; 160 client.putSensorData(makeSensorData(tstamp1, tstamp1, snapshotUser, sdt, tool1)); 161 client.putSensorData(makeSensorData(tstamp2, tstamp1, snapshotUser, sdt, tool1)); 162 client.putSensorData(makeSensorData(tstamp3, tstamp3, snapshotUser, sdt, tool2)); 163 164 // We should get the last sensor data item. 165 SensorDataIndex snap1 = 166 client.getProjectSensorDataSnapshot(snapshotUser, defaultProject, startTime, endTime, sdt); 167 assertEquals("Checking snap1 size", 1, snap1.getSensorDataRef().size()); 168 assertEquals("Checking snap1 tstamp", tstamp3, snap1.getSensorDataRef().get(0).getTimestamp()); 169 170 // Now check that we get the other two when we specify the tool. 171 SensorDataIndex snap2 = 172 client.getProjectSensorDataSnapshot(snapshotUser, defaultProject, startTime, endTime, sdt, 173 tool1); 174 assertEquals("Checking snap2 size", 2, snap2.getSensorDataRef().size()); 175 } 176 177 /** 178 * Creates a sample SensorData instance for use in testing snapshots. 179 * @param tstamp The timestamp. 180 * @param runtime The runtime 181 * @param user The user. 182 * @param sdt The sensor data type. 183 * @param tool The tool. 184 * @return The new SensorData instance. 185 */ 186 private SensorData makeSensorData(XMLGregorianCalendar tstamp, XMLGregorianCalendar runtime, 187 String user, String sdt, String tool) { 188 SensorData data = new SensorData(); 189 data.setTool(tool); 190 data.setOwner(user); 191 data.setSensorDataType(sdt); 192 data.setTimestamp(tstamp); 193 data.setResource("file://foo/bar/baz.txt"); 194 data.setRuntime(runtime); 195 return data; 196 } 197 198 /** 199 * Test that GET host/sensorbase/projects/TestUser@hackystat.org/TestProject/sensordata? 200 * startTime=2006-04-30T09:00:00.000&endTime=2007-04-30T09:30:00.000 returns an index of 201 * SensorData containing one entry. 202 * 203 * @throws Exception If problems occur. 204 */ 205 @Test 206 public void getTestUserProjectSensorDataInterval() throws Exception { 207 // Create the TestUser client and check authentication. 208 SensorBaseClient client = new SensorBaseClient(getHostName(), testUser, testUser); 209 client.authenticate(); 210 // Retrieve the SensorData for the TestProject project within the time 211 // interval. 212 XMLGregorianCalendar startTime = Tstamp.makeTimestamp(nineAm); 213 XMLGregorianCalendar endTime = Tstamp.makeTimestamp("2007-04-30T09:30:00.000"); 214 SensorDataIndex index = client.getProjectSensorData(testUser, testProject, startTime, endTime); 215 assertEquals("Checking index contains one entry", 1, index.getSensorDataRef().size()); 216 } 217 218 /** 219 * Test that the GET of a project with the SDT parameter works correctly. 220 * Assumes that the default XML data files are loaded, which result in two sensor data entries 221 * for TestUser@hackystat.org on 2007-04-30, one with SDT=TestSdt and one with SDT=SampleSdt. 222 * 223 * @throws Exception If problems occur. 224 */ 225 @Test 226 public void getTestUserProjectSdtParam() throws Exception { 227 // Create the TestUser client and check authentication. 228 SensorBaseClient client = new SensorBaseClient(getHostName(), testUser, testUser); 229 client.authenticate(); 230 // Retrieve the SensorData for the TestProject project within the time 231 // interval, and make sure we have the two entries that we expect. 232 XMLGregorianCalendar startTime = Tstamp.makeTimestamp(nineAm); 233 XMLGregorianCalendar endTime = Tstamp.makeTimestamp("2007-04-30T10:00:00.000"); 234 SensorDataIndex index = client.getProjectSensorData(testUser, testProject, startTime, endTime); 235 assertEquals("Checking our test data has 2 entries", 2, index.getSensorDataRef().size()); 236 237 // Now test the SDT param call to make sure we get only the SDT of interest. 238 index = client.getProjectSensorData(testUser, testProject, startTime, endTime, testSdt); 239 assertEquals("Checking our test data has 1 entries", 1, index.getSensorDataRef().size()); 240 241 // Now test to see that the tool param works correctly. 242 index = client.getProjectSensorData(testUser, testProject, startTime, endTime, testSdt, 243 "Subversion"); 244 assertEquals("Checking our data has 1 entries", 1, index.getSensorDataRef().size()); 245 index = client.getProjectSensorData(testUser, testProject, startTime, endTime, testSdt, 246 "CVS"); 247 assertEquals("Checking our data has no entries", 0, index.getSensorDataRef().size()); 248 } 249 250 251 /** 252 * Test that the GET of a project with the startIndex/maxInstances parameters work correctly. 253 * Assumes that the default XML data files are loaded, which result in two sensor data entries 254 * for TestUser@hackystat.org on 2007-04-30, one with SDT=TestSdt and one with SDT=SampleSdt. 255 * We'll try a few combinations of startIndex and maxInstances to see that the proper number 256 * of instances are returned. 257 * 258 * @throws Exception If problems occur. 259 */ 260 @Test 261 public void getTestUserProjectStartIndexMaxInstancesParams() throws Exception { 262 // Create the TestUser client and check authentication. 263 SensorBaseClient client = new SensorBaseClient(getHostName(), testUser, testUser); 264 client.authenticate(); 265 // Retrieve the SensorData for the TestProject project within the time 266 // interval, and make sure we have the two entries that we expect. 267 XMLGregorianCalendar startTime = Tstamp.makeTimestamp(nineAm); 268 XMLGregorianCalendar endTime = Tstamp.makeTimestamp("2007-04-30T10:00:00.000"); 269 SensorDataIndex index = client.getProjectSensorData(testUser, testProject, startTime, endTime); 270 assertEquals("Checking our original data has 2 entries", 2, index.getSensorDataRef().size()); 271 272 // Now test the startIndex/maxInstances params. 273 index = client.getProjectSensorData(testUser, testProject, startTime, endTime, 0, 100); 274 assertEquals("Checking startindex 1 is 2", 2, index.getSensorDataRef().size()); 275 276 index = client.getProjectSensorData(testUser, testProject, startTime, endTime, 1, 100); 277 assertEquals("Checking startindex 2 is 1", 1, index.getSensorDataRef().size()); 278 279 index = client.getProjectSensorData(testUser, testProject, startTime, endTime, 0, 1); 280 assertEquals("Checking startindex 3 is 1", 1, index.getSensorDataRef().size()); 281 282 index = client.getProjectSensorData(testUser, testProject, startTime, endTime, 1, 1); 283 assertEquals("Checking startindex 4 is 1", 1, index.getSensorDataRef().size()); 284 285 index = client.getProjectSensorData(testUser, testProject, startTime, endTime, 2, 1); 286 assertEquals("Checking startindex 5 is 0", 0, index.getSensorDataRef().size()); 287 288 289 } 290 291 /** 292 * Test that PUT, rename, and DELETE of host/projects/{user}/{project} works. 293 * 294 * @throws Exception If problems occur. 295 */ 296 @Test 297 public void putProject() throws Exception { 298 // First, create a sample Project. 299 String owner = testUser; 300 String projectName = "TestProject1"; 301 Project project = new Project(); 302 project.setOwner(owner); 303 project.setName(projectName); 304 project.setDescription("Test Project1"); 305 XMLGregorianCalendar tstamp = Tstamp.makeTimestamp(); 306 project.setStartTime(tstamp); 307 project.setEndTime(tstamp); 308 UriPatterns uris = new UriPatterns(); 309 uris.getUriPattern().add("**/test/**"); 310 project.setUriPatterns(uris); 311 312 // Create the TestUser client, check authentication, and post the Project to 313 // the server. 314 SensorBaseClient client = new SensorBaseClient(getHostName(), testUser, testUser); 315 client.authenticate(); 316 client.putProject(project); 317 318 // Check that we can now retrieve it. 319 Project project2 = client.getProject(owner, projectName); 320 assertEquals("Testing for GET TestProject1", projectName, project2.getName()); 321 322 // Check that we can now rename it. 323 String newProjectName = "NewTestProjectName"; 324 client.renameProject(owner, projectName, newProjectName); 325 ProjectIndex index = client.getProjectIndex(testUser); 326 assertTrue("Checking renamed project is in index", hasProjectName(index, newProjectName)); 327 assertFalse("Checking old project name is not in index", hasProjectName(index, projectName)); 328 329 // Test that DELETE gets rid of this Project. 330 client.deleteProject(owner, newProjectName); 331 } 332 333 /** 334 * Returns true if the passed projectName is in the ProjectIndex. 335 * @param index The ProjectIndex. 336 * @param projectName The projectname of interest. 337 * @return True if the projectName is in the index. 338 */ 339 private boolean hasProjectName(ProjectIndex index, String projectName) { 340 for (ProjectRef ref : index.getProjectRef()) { 341 if (ref.getName().equals(projectName)) { 342 return true; 343 } 344 } 345 return false; 346 } 347 348 /** 349 * A helper method to detect HTTP 400 status return values. 350 * Because of intermittent 1001 errors in the sensorbase test suite, this method 351 * will also return true if a 1001 error is returned. 352 * @param e The exception 353 * @return True if the exception message starts with 400 (or 1001). 354 */ 355 private boolean is400(Exception e) { 356 return (e.getMessage().startsWith("400") || e.getMessage().startsWith("1001")); 357 358 } 359 360 /** 361 * Test that PUT of incomplete project definitions causes errors. 362 * 363 * @throws Exception If problems occur. 364 */ 365 @Test 366 public void putBadProjects() throws Exception { 367 // Create the TestUser client, check authentication. 368 SensorBaseClient client = new SensorBaseClient(getHostName(), testUser, testUser); 369 client.authenticate(); 370 371 // First, create a sample Project with no fields. 372 Project project = new Project(); 373 String owner = testUser; 374 project.setOwner(owner); 375 // See if we get the appropriate error 376 try { 377 client.putProject(project); 378 } 379 catch (SensorBaseClientException e) { 380 assertTrue("Test bad project name", is400(e)); 381 } 382 // Fix the project name, try again. 383 String projectName = "TestProject1"; 384 project.setName(projectName); 385 try { 386 client.putProject(project); 387 } 388 catch (SensorBaseClientException e) { 389 assertTrue("Test bad start", is400(e)); 390 } 391 XMLGregorianCalendar tstamp = Tstamp.makeTimestamp(); 392 project.setStartTime(tstamp); 393 394 try { 395 client.putProject(project); 396 } 397 catch (SensorBaseClientException e) { 398 assertTrue("Test bad end", is400(e)); 399 } 400 project.setEndTime(tstamp); 401 // Now this should succeed. 402 client.putProject(project); 403 404 // Check that we can now retrieve it. 405 Project project2 = client.getProject(owner, projectName); 406 assertEquals("Testing for GET TestProject1", projectName, project2.getName()); 407 408 // Test that DELETE gets rid of this Project. 409 client.deleteProject(owner, projectName); 410 } 411 412 /** 413 * Test that PUT multiple times does not cause a problem for getProjectIndex. 414 * 415 * @throws Exception If problems occur. 416 */ 417 //@Ignore 418 @Test 419 public void putMultipleProject() throws Exception { 420 // First, create a sample Project. 421 String owner = testUser; 422 String projectName = "TestProject1"; 423 Project project = new Project(); 424 project.setOwner(owner); 425 project.setName(projectName); 426 project.setDescription("Test Project1"); 427 XMLGregorianCalendar tstamp = Tstamp.makeTimestamp(); 428 project.setStartTime(tstamp); 429 project.setEndTime(tstamp); 430 UriPatterns uris = new UriPatterns(); 431 uris.getUriPattern().add("**/test/**"); 432 project.setUriPatterns(uris); 433 434 // Create the TestUser client. 435 SensorBaseClient client = new SensorBaseClient(getHostName(), adminEmail, adminPassword); 436 client.authenticate(); 437 // Now add a project. 438 client.putProject(project); 439 // Get the size after adding. 440 int before = client.getProjectIndex().getProjectRef().size(); 441 // Now add it again. 442 client.putProject(project); 443 // Get the size after adding. 444 int after = client.getProjectIndex().getProjectRef().size(); 445 // Check that the size hasn't changed. 446 assertEquals("Checking ProjectIndex after adding duplicate Project", before, after); 447 } 448 449 450 451 /** 452 * Tests that after creating a new User, it has a Default Project. 453 * 454 * @throws Exception If problems occur. 455 */ 456 @Test 457 public void newUserTest() throws Exception { 458 // Register a new user. 459 String newUser = "NewUserTest@" + server.getServerProperties().get(TEST_DOMAIN_KEY); 460 SensorBaseClient.registerUser(getHostName(), newUser); 461 // Create a Client for this new user. 462 SensorBaseClient client = new SensorBaseClient(getHostName(), newUser, newUser); 463 client.authenticate(); 464 465 Project project = client.getProject(newUser, defaultProject); 466 assertEquals("Checking default project", defaultProject, project.getName()); 467 468 // Now we delete the user 469 client.deleteUser(newUser); 470 } 471 472 /** 473 * Tests that we can retrieve all data for the TestUser under their Default Project. 474 * 475 * @throws Exception If problems occur. 476 */ 477 @Test 478 public void testUserDefaultProjectData() throws Exception { 479 SensorBaseClient client = new SensorBaseClient(getHostName(), testUser, testUser); 480 client.authenticate(); 481 482 SensorDataIndex index = client.getProjectSensorData(testUser, defaultProject); 483 assertTrue("Checking for testuser sensordata", index.getSensorDataRef().size() >= 3); 484 } 485 }