View Javadoc

1   // SECTION-START[License Header]
2   // <editor-fold defaultstate="collapsed" desc=" Generated License ">
3   /*
4    *   Copyright (c) 2010 The JOMC Project
5    *   Copyright (c) 2005 Christian Schulte <schulte2005@users.sourceforge.net>
6    *   All rights reserved.
7    *
8    *   Redistribution and use in source and binary forms, with or without
9    *   modification, are permitted provided that the following conditions
10   *   are met:
11   *
12   *     o Redistributions of source code must retain the above copyright
13   *       notice, this list of conditions and the following disclaimer.
14   *
15   *     o Redistributions in binary form must reproduce the above copyright
16   *       notice, this list of conditions and the following disclaimer in
17   *       the documentation and/or other materials provided with the
18   *       distribution.
19   *
20   *   THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
21   *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22   *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23   *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
24   *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25   *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26   *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27   *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28   *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29   *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30   *   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31   *
32   *   $Id: SequenceDirectoryTest.java 2246 2010-06-29 07:59:25Z schulte2005 $
33   *
34   */
35  // </editor-fold>
36  // SECTION-END
37  package org.jomc.sequences.it;
38  
39  import java.io.IOException;
40  import java.io.InputStream;
41  import java.math.BigInteger;
42  import java.net.URL;
43  import java.util.ArrayList;
44  import java.util.Arrays;
45  import java.util.List;
46  import java.util.Set;
47  import java.util.logging.LogManager;
48  import org.jomc.sequences.ConcurrentModificationException;
49  import org.jomc.sequences.SequenceExistsException;
50  import org.jomc.sequences.SequenceVetoException;
51  import org.jomc.sequences.Sequence;
52  import org.jomc.sequences.SequenceNotFoundException;
53  import org.jomc.sequences.SequencesSystemException;
54  import org.junit.Test;
55  import org.junit.runner.JUnitCore;
56  import static org.junit.Assert.assertEquals;
57  import static org.junit.Assert.assertNotNull;
58  import static org.junit.Assert.fail;
59  
60  // SECTION-START[Documentation]
61  // <editor-fold defaultstate="collapsed" desc=" Generated Documentation ">
62  /**
63   * Testcase for SequenceDirectory implementations.
64   * <p><b>Properties</b><ul>
65   * <li>"{@link #getSequenceNameMaxLength sequenceNameMaxLength}"
66   * <blockquote>Property of type {@code int}.
67   * <p>Maximum allowed length of a sequence name.</p>
68   * </blockquote></li>
69   * <li>"{@link #getSequenceNameMinLength sequenceNameMinLength}"
70   * <blockquote>Property of type {@code int}.
71   * <p>Minimum required length of a sequence name.</p>
72   * </blockquote></li>
73   * </ul></p>
74   * <p><b>Dependencies</b><ul>
75   * <li>"{@link #getSequenceDirectory SequenceDirectory}"<blockquote>
76   * Dependency on {@code 'org.jomc.sequences.SequenceDirectory'} {@code (org.jomc.sequences.SequenceDirectory)} at specification level 1.0 bound to an instance.</blockquote></li>
77   * </ul></p>
78   *
79   * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a> 1.0
80   * @version $Id: SequenceDirectoryTest.java 2246 2010-06-29 07:59:25Z schulte2005 $
81   */
82  // </editor-fold>
83  // SECTION-END
84  // SECTION-START[Annotations]
85  // <editor-fold defaultstate="collapsed" desc=" Generated Annotations ">
86  @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" )
87  // </editor-fold>
88  // SECTION-END
89  public class SequenceDirectoryTest
90  {
91      // SECTION-START[SequenceDirectoryTest]
92  
93      /**
94       * Gets a sequence with valid data.
95       *
96       * @return A sequence with valid data.
97       */
98      public static Sequence getTestSequence()
99      {
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 }