001 // SECTION-START[License Header] 002 // <editor-fold defaultstate="collapsed" desc=" Generated License "> 003 /* 004 * Copyright (c) 2010 The JOMC Project 005 * Copyright (c) 2005 Christian Schulte <schulte2005@users.sourceforge.net> 006 * All rights reserved. 007 * 008 * Redistribution and use in source and binary forms, with or without 009 * modification, are permitted provided that the following conditions 010 * are met: 011 * 012 * o Redistributions of source code must retain the above copyright 013 * notice, this list of conditions and the following disclaimer. 014 * 015 * o Redistributions in binary form must reproduce the above copyright 016 * notice, this list of conditions and the following disclaimer in 017 * the documentation and/or other materials provided with the 018 * distribution. 019 * 020 * THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS" 021 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 022 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 023 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR 024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 027 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 028 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 029 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 030 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 031 * 032 * $Id: SequenceDirectoryTest.java 2246 2010-06-29 07:59:25Z schulte2005 $ 033 * 034 */ 035 // </editor-fold> 036 // SECTION-END 037 package org.jomc.sequences.it; 038 039 import java.io.IOException; 040 import java.io.InputStream; 041 import java.math.BigInteger; 042 import java.net.URL; 043 import java.util.ArrayList; 044 import java.util.Arrays; 045 import java.util.List; 046 import java.util.Set; 047 import java.util.logging.LogManager; 048 import org.jomc.sequences.ConcurrentModificationException; 049 import org.jomc.sequences.SequenceExistsException; 050 import org.jomc.sequences.SequenceVetoException; 051 import org.jomc.sequences.Sequence; 052 import org.jomc.sequences.SequenceNotFoundException; 053 import org.jomc.sequences.SequencesSystemException; 054 import org.junit.Test; 055 import org.junit.runner.JUnitCore; 056 import static org.junit.Assert.assertEquals; 057 import static org.junit.Assert.assertNotNull; 058 import static org.junit.Assert.fail; 059 060 // SECTION-START[Documentation] 061 // <editor-fold defaultstate="collapsed" desc=" Generated Documentation "> 062 /** 063 * Testcase for SequenceDirectory implementations. 064 * <p><b>Properties</b><ul> 065 * <li>"{@link #getSequenceNameMaxLength sequenceNameMaxLength}" 066 * <blockquote>Property of type {@code int}. 067 * <p>Maximum allowed length of a sequence name.</p> 068 * </blockquote></li> 069 * <li>"{@link #getSequenceNameMinLength sequenceNameMinLength}" 070 * <blockquote>Property of type {@code int}. 071 * <p>Minimum required length of a sequence name.</p> 072 * </blockquote></li> 073 * </ul></p> 074 * <p><b>Dependencies</b><ul> 075 * <li>"{@link #getSequenceDirectory SequenceDirectory}"<blockquote> 076 * Dependency on {@code 'org.jomc.sequences.SequenceDirectory'} {@code (org.jomc.sequences.SequenceDirectory)} at specification level 1.0 bound to an instance.</blockquote></li> 077 * </ul></p> 078 * 079 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a> 1.0 080 * @version $Id: SequenceDirectoryTest.java 2246 2010-06-29 07:59:25Z schulte2005 $ 081 */ 082 // </editor-fold> 083 // SECTION-END 084 // SECTION-START[Annotations] 085 // <editor-fold defaultstate="collapsed" desc=" Generated Annotations "> 086 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" ) 087 // </editor-fold> 088 // SECTION-END 089 public class SequenceDirectoryTest 090 { 091 // SECTION-START[SequenceDirectoryTest] 092 093 /** 094 * Gets a sequence with valid data. 095 * 096 * @return A sequence with valid data. 097 */ 098 public static Sequence getTestSequence() 099 { 100 final Sequence legal = new Sequence(); 101 legal.setIncrement( 1L ); 102 legal.setMaximum( 10L ); 103 legal.setMinimum( 0L ); 104 legal.setName( "TEST" ); 105 legal.setValue( 0L ); 106 107 return legal; 108 } 109 110 /** 111 * Tests all {@link org.jomc.sequences.SequenceDirectory} methods to handle illegal arguments correctly by throwing 112 * a {@code SequencesSystemException} with non-null message. 113 */ 114 @Test public void testIllegalArguments() throws Exception 115 { 116 assert this.getSequenceDirectory() != null; 117 118 try 119 { 120 this.getSequenceDirectory().addSequence( null ); 121 fail( "Expected SequencesSystemException not thrown." ); 122 } 123 catch ( final SequencesSystemException e ) 124 { 125 assertNotNull( e.getMessage() ); 126 System.out.println( e.toString() ); 127 } 128 129 try 130 { 131 this.getSequenceDirectory().deleteSequence( null, 0L ); 132 fail( "Expected SequencesSystemException not thrown." ); 133 } 134 catch ( final SequencesSystemException e ) 135 { 136 assertNotNull( e.getMessage() ); 137 System.out.println( e.toString() ); 138 } 139 140 try 141 { 142 this.getSequenceDirectory().editSequence( null, 0L, null ); 143 fail( "Expected SequencesSystemException not thrown." ); 144 } 145 catch ( final SequencesSystemException e ) 146 { 147 assertNotNull( e.getMessage() ); 148 System.out.println( e.toString() ); 149 } 150 151 try 152 { 153 this.getSequenceDirectory().editSequence( "TEST", 0L, null ); 154 fail( "Expected SequencesSystemException not thrown." ); 155 } 156 catch ( final SequencesSystemException e ) 157 { 158 assertNotNull( e.getMessage() ); 159 System.out.println( e.toString() ); 160 } 161 162 try 163 { 164 this.getSequenceDirectory().editSequence( null, 0L, new Sequence() ); 165 fail( "Expected SequencesSystemException not thrown." ); 166 } 167 catch ( final SequencesSystemException e ) 168 { 169 assertNotNull( e.getMessage() ); 170 System.out.println( e.toString() ); 171 } 172 173 try 174 { 175 this.getSequenceDirectory().getSequence( null ); 176 fail( "Expected SequencesSystemException not thrown." ); 177 } 178 catch ( final SequencesSystemException e ) 179 { 180 assertNotNull( e.getMessage() ); 181 System.out.println( e.toString() ); 182 } 183 184 } 185 186 /** Tests that a valid sequence can get added, edited, searched and removed. */ 187 @Test public void testAddEditSearchDeleteLegalSequence() throws Exception 188 { 189 assert this.getSequenceDirectory() != null; 190 191 this.clearDirectory(); 192 193 Sequence legal = getTestSequence(); 194 195 legal = this.getSequenceDirectory().addSequence( legal ); 196 197 System.out.println( legal ); 198 199 legal.setName( "TEST2" ); 200 201 legal = this.getSequenceDirectory().editSequence( "TEST", legal.getRevision(), legal ); 202 203 System.out.println( legal ); 204 205 assertEquals( legal, this.getSequenceDirectory().getSequence( "TEST2" ) ); 206 207 final Set<Sequence> result = this.getSequenceDirectory().searchSequences( "%TEST%" ); 208 209 assertEquals( 1, result.size() ); 210 assertEquals( legal, result.toArray()[0] ); 211 212 this.getSequenceDirectory().deleteSequence( "TEST2", legal.getRevision() ); 213 214 assertEquals( 0, this.getSequenceDirectory().searchSequences( null ).size() ); 215 assertEquals( BigInteger.ZERO, this.getSequenceDirectory().getSequenceCount() ); 216 } 217 218 /** Tests that a sequence cannot get edited or removed when it got changed concurrently. */ 219 @Test public void testConcurrentModificationException() throws Exception 220 { 221 assert this.getSequenceDirectory() != null; 222 223 this.clearDirectory(); 224 225 final Sequence legal = getTestSequence(); 226 227 final Sequence sequence = this.getSequenceDirectory().addSequence( legal ); 228 229 try 230 { 231 this.getSequenceDirectory().editSequence( "TEST", sequence.getRevision() + 1L, sequence ); 232 fail( "Expected ConcurrentModificationException not thrown." ); 233 } 234 catch ( final ConcurrentModificationException e ) 235 { 236 assertNotNull( e.getMessage() ); 237 System.out.println( e.toString() ); 238 } 239 240 try 241 { 242 this.getSequenceDirectory().deleteSequence( "TEST", sequence.getRevision() + 1L ); 243 fail( "Expected ConcurrentModificationException not thrown." ); 244 } 245 catch ( final ConcurrentModificationException e ) 246 { 247 assertNotNull( e.getMessage() ); 248 System.out.println( e.toString() ); 249 } 250 } 251 252 /** 253 * Tests that adding an illegal sequence or updating an existing sequence with illegal data is prevented by throwing 254 * a corresponding {@code SequenceVetoException}. 255 */ 256 @Test public void testSequenceVetoException() throws Exception 257 { 258 assert this.getSequenceDirectory() != null; 259 260 this.clearDirectory(); 261 262 Sequence legal = getTestSequence(); 263 264 final Sequence illegal = new Sequence(); 265 char[] name = new char[ this.getSequenceNameMaxLength() + 1 ]; 266 Arrays.fill( name, 'T' ); 267 268 illegal.setName( String.valueOf( name ) ); 269 illegal.setMinimum( 100L ); 270 illegal.setMaximum( 1L ); 271 illegal.setValue( 0L ); 272 illegal.setIncrement( -1L ); 273 274 try 275 { 276 this.getSequenceDirectory().addSequence( illegal ); 277 fail( "Expected SequenceVetoException not thrown." ); 278 } 279 catch ( final SequenceVetoException e ) 280 { 281 assertNotNull( e.getMessage() ); 282 System.out.println( e.toString() ); 283 } 284 285 illegal.setName( null ); 286 287 try 288 { 289 this.getSequenceDirectory().addSequence( illegal ); 290 fail( "Expected SequenceVetoException not thrown." ); 291 } 292 catch ( final SequenceVetoException e ) 293 { 294 assertNotNull( e.getMessage() ); 295 System.out.println( e.toString() ); 296 } 297 298 if ( this.getSequenceNameMinLength() - 1 >= 0 ) 299 { 300 try 301 { 302 name = new char[ this.getSequenceNameMinLength() - 1 ]; 303 Arrays.fill( name, 'T' ); 304 illegal.setName( String.valueOf( name ) ); 305 this.getSequenceDirectory().addSequence( illegal ); 306 fail( "Expected SequenceVetoException not thrown." ); 307 } 308 catch ( final SequenceVetoException e ) 309 { 310 assertNotNull( e.getMessage() ); 311 System.out.println( e.toString() ); 312 } 313 } 314 315 legal = this.getSequenceDirectory().addSequence( legal ); 316 317 try 318 { 319 this.getSequenceDirectory().editSequence( legal.getName(), legal.getRevision(), illegal ); 320 fail( "Expected SequenceVetoException not thrown." ); 321 } 322 catch ( final SequenceVetoException e ) 323 { 324 assertNotNull( e.getMessage() ); 325 System.out.println( e.toString() ); 326 } 327 328 this.getSequenceDirectory().deleteSequence( legal.getName(), legal.getRevision() ); 329 } 330 331 /** 332 * Tests that adding a sequence twice is prevented by throwing a corresponding {@code SequenceExistsException}. 333 */ 334 @Test public void testSequenceExistsException() throws Exception 335 { 336 assert this.getSequenceDirectory() != null; 337 338 this.clearDirectory(); 339 340 Sequence legal = getTestSequence(); 341 342 legal = this.getSequenceDirectory().addSequence( legal ); 343 344 try 345 { 346 this.getSequenceDirectory().addSequence( legal ); 347 fail( "Expected SequenceExistsException not thrown." ); 348 } 349 catch ( final SequenceExistsException e ) 350 { 351 assertNotNull( e.getMessage() ); 352 System.out.println( e.toString() ); 353 } 354 } 355 356 /** 357 * Tests that updating or deleting an unknown sequence is prevented by throwing a corresponding 358 * {@code SequenceNotFoundException}. 359 */ 360 @Test public void testSequenceNotFoundException() throws Exception 361 { 362 assert this.getSequenceDirectory() != null; 363 364 this.clearDirectory(); 365 366 final Sequence legal = getTestSequence(); 367 368 try 369 { 370 this.getSequenceDirectory().editSequence( "UNKNOWN", 0L, legal ); 371 fail( "Expected SequenceNotFoundException not thrown." ); 372 } 373 catch ( final SequenceNotFoundException e ) 374 { 375 assertNotNull( e.getMessage() ); 376 System.out.println( e.toString() ); 377 } 378 379 try 380 { 381 this.getSequenceDirectory().deleteSequence( "UNKNOWN", 0L ); 382 fail( "Expected SequenceNotFoundException not thrown." ); 383 } 384 catch ( final SequenceNotFoundException e ) 385 { 386 assertNotNull( e.getMessage() ); 387 System.out.println( e.toString() ); 388 } 389 390 this.clearDirectory(); 391 } 392 393 /** Tests that adding, editing and then removing multiple sequences leaves an empty directory. */ 394 @Test public void testAddEditDeleteMany() throws Exception 395 { 396 assert this.getSequenceDirectory() != null; 397 398 this.clearDirectory(); 399 400 final int count = 15; 401 final List<Sequence> added = new ArrayList<Sequence>( count ); 402 final List<Sequence> updated = new ArrayList<Sequence>( count ); 403 for ( int i = 0; i < count; i++ ) 404 { 405 final Sequence legal = getTestSequence(); 406 legal.setName( legal.getName() + ' ' + i ); 407 final Sequence a = this.getSequenceDirectory().addSequence( legal ); 408 added.add( a ); 409 System.out.println( "ADD: " + a ); 410 } 411 412 for ( Sequence s : added ) 413 { 414 final String oldName = s.getName(); 415 s.setName( oldName + "_UPDATED" ); 416 417 final Sequence u = this.getSequenceDirectory().editSequence( oldName, s.getRevision(), s ); 418 updated.add( u ); 419 420 System.out.println( "EDIT: " + u ); 421 } 422 423 for ( Sequence s : updated ) 424 { 425 final Sequence d = this.getSequenceDirectory().deleteSequence( s.getName(), s.getRevision() ); 426 System.out.println( "DELETE: " + d ); 427 } 428 429 assertEquals( BigInteger.ZERO, this.getSequenceDirectory().getSequenceCount() ); 430 } 431 432 /** Removes all sequences from the directory. */ 433 protected void clearDirectory() throws Exception 434 { 435 // Remove any test entries. 436 for ( Sequence sequence : this.getSequenceDirectory().searchSequences( null ) ) 437 { 438 System.out.println( this.getSequenceDirectory().deleteSequence( 439 sequence.getName(), sequence.getRevision() ) ); 440 441 } 442 443 assertEquals( BigInteger.ZERO, this.getSequenceDirectory().getSequenceCount() ); 444 } 445 446 /** 447 * Test runner entry point. 448 * <p>This method sets up the JDK's {@code LogManager} with properties found at classpath location 449 * {@code "/logging.properties"} and executes {@link JUnitCore#main} passing the given arguments with this classes 450 * name prepended.</p> 451 * 452 * @param args Command line arguments. 453 */ 454 public static void main( final String... args ) 455 { 456 try 457 { 458 final URL loggingProperties = SequenceDirectoryTest.class.getResource( "/logging.properties" ); 459 if ( loggingProperties != null ) 460 { 461 final InputStream in = loggingProperties.openStream(); 462 LogManager.getLogManager().readConfiguration( in ); 463 in.close(); 464 } 465 466 final List<String> l = new ArrayList<String>( Arrays.asList( args ) ); 467 l.add( 0, SequenceDirectoryTest.class.getName() ); 468 JUnitCore.main( l.toArray( new String[ l.size() ] ) ); 469 } 470 catch ( final IOException e ) 471 { 472 e.printStackTrace(); 473 System.exit( 1 ); 474 } 475 } 476 477 // SECTION-END 478 // SECTION-START[Constructors] 479 // <editor-fold defaultstate="collapsed" desc=" Generated Constructors "> 480 481 /** Creates a new {@code SequenceDirectoryTest} instance. */ 482 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" ) 483 public SequenceDirectoryTest() 484 { 485 // SECTION-START[Default Constructor] 486 super(); 487 // SECTION-END 488 } 489 // </editor-fold> 490 // SECTION-END 491 // SECTION-START[Dependencies] 492 // <editor-fold defaultstate="collapsed" desc=" Generated Dependencies "> 493 494 /** 495 * Gets the {@code SequenceDirectory} dependency. 496 * <p>This method returns any available object of the {@code 'org.jomc.sequences.SequenceDirectory'} {@code (org.jomc.sequences.SequenceDirectory)} specification at specification level 1.0.</p> 497 * <p>That specification applies to {@code Singleton} scope. The singleton object is returned whenever requested and bound to this instance.</p> 498 * @return The {@code SequenceDirectory} dependency. 499 * {@code null} if no object is available. 500 * @throws org.jomc.ObjectManagementException if getting the dependency instance fails. 501 */ 502 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" ) 503 private org.jomc.sequences.SequenceDirectory getSequenceDirectory() 504 { 505 return (org.jomc.sequences.SequenceDirectory) org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getDependency( this, "SequenceDirectory" ); 506 } 507 // </editor-fold> 508 // SECTION-END 509 // SECTION-START[Properties] 510 // <editor-fold defaultstate="collapsed" desc=" Generated Properties "> 511 512 /** 513 * Gets the value of the {@code sequenceNameMaxLength} property. 514 * @return Maximum allowed length of a sequence name. 515 * @throws org.jomc.ObjectManagementException if getting the property instance fails. 516 */ 517 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" ) 518 private int getSequenceNameMaxLength() 519 { 520 final java.lang.Integer _p = (java.lang.Integer) org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getProperty( this, "sequenceNameMaxLength" ); 521 assert _p != null : "'sequenceNameMaxLength' property not found."; 522 return _p.intValue(); 523 } 524 525 /** 526 * Gets the value of the {@code sequenceNameMinLength} property. 527 * @return Minimum required length of a sequence name. 528 * @throws org.jomc.ObjectManagementException if getting the property instance fails. 529 */ 530 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" ) 531 private int getSequenceNameMinLength() 532 { 533 final java.lang.Integer _p = (java.lang.Integer) org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getProperty( this, "sequenceNameMinLength" ); 534 assert _p != null : "'sequenceNameMinLength' property not found."; 535 return _p.intValue(); 536 } 537 // </editor-fold> 538 // SECTION-END 539 // SECTION-START[Messages] 540 // SECTION-END 541 }