001/*
002 *  jDTAUS Core Test Suite
003 *  Copyright (C) 2005 Christian Schulte
004 *  <cs@schulte.it>
005 *
006 *  This library is free software; you can redistribute it and/or
007 *  modify it under the terms of the GNU Lesser General Public
008 *  License as published by the Free Software Foundation; either
009 *  version 2.1 of the License, or any later version.
010 *
011 *  This library is distributed in the hope that it will be useful,
012 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 *  Lesser General Public License for more details.
015 *
016 *  You should have received a copy of the GNU Lesser General Public
017 *  License along with this library; if not, write to the Free Software
018 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
019 *
020 */
021package org.jdtaus.core.monitor.spi.it;
022
023import java.util.Iterator;
024import java.util.LinkedList;
025import java.util.List;
026import java.util.Locale;
027import junit.framework.Assert;
028import org.jdtaus.core.monitor.TaskEvent;
029import org.jdtaus.core.monitor.TaskEventSource;
030import org.jdtaus.core.monitor.TaskListener;
031import org.jdtaus.core.monitor.it.TaskEventSourceTest;
032import org.jdtaus.core.monitor.spi.Task;
033import org.jdtaus.core.monitor.spi.TaskMonitor;
034import org.jdtaus.core.text.Message;
035
036/**
037 * Testcase for {@code TaskMonitor} implementations.
038 *
039 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
040 * @version $JDTAUS: TaskMonitorTest.java 8743 2012-10-07 03:06:20Z schulte $
041 */
042public class TaskMonitorTest extends TaskEventSourceTest
043{
044    //--TaskEventSourceTest-----------------------------------------------------
045
046    /**
047     * {@inheritDoc}
048     * @see #getTaskMonitor()
049     */
050    public final TaskEventSource getTaskEventSource()
051    {
052        return this.monitor;
053    }
054
055    //-----------------------------------------------------TaskEventSourceTest--
056    //--TaskMonitorTest---------------------------------------------------------
057
058    /** Implementation to test. */
059    private TaskMonitor monitor;
060
061    /** Creates a new {@code TaskMonitorTest} instance. */
062    public TaskMonitorTest()
063    {
064        super();
065    }
066
067    /**
068     * Gets the {@code TaskMonitor} implementation tests are performed with.
069     *
070     * @return the {@code TaskMonitor} implementation tests are performed
071     * with.
072     */
073    public TaskMonitor getTaskMonitor()
074    {
075        return this.monitor;
076    }
077
078    /**
079     * Sets the {@code TaskMonitor} implementation tests are performed with.
080     *
081     * @param value the {@code TaskMonitor} implementation to perform tests
082     * with.
083     */
084    public final void setTaskMonitor( final TaskMonitor value )
085    {
086        this.monitor = value;
087        this.setTaskEventSource( value );
088    }
089
090    /** {@code Task} implementation monitoring is tested with. */
091    public static final class TestMessage extends Message
092    {
093
094        /** @serial */
095        private String text = TaskMonitorTest.class.getName();
096
097        public TestMessage()
098        {
099            super();
100        }
101
102        public Object[] getFormatArguments( final Locale locale )
103        {
104            return new Object[ 0 ];
105        }
106
107        public String getText( final Locale locale )
108        {
109            return this.text;
110        }
111
112        public void setText( final String value )
113        {
114            this.text = value;
115        }
116
117    }
118
119    /** {@code TaskListener} implementation monitoring is tested with. */
120    public static final class TestTaskListener implements TaskListener
121    {
122
123        /** The instance of the tested task. */
124        private Task task;
125
126        /** The timestamp the tested task started. */
127        private long startTime;
128
129        /** The timestamp the tested task ended. */
130        private long endTime;
131
132        /** Flag indicating that the tested task changed its state. */
133        private boolean changedState;
134
135        /**
136         * Creates a new {@code TestTaskListener} instance taking the tested
137         * task.
138         *
139         * @param task the tested task.
140         */
141        public TestTaskListener( final Task task )
142        {
143            if ( task == null )
144            {
145                throw new NullPointerException( "task" );
146            }
147
148            this.task = task;
149            this.reset();
150        }
151
152        /**
153         * Gets the timestamp the tested task started.
154         *
155         * @return the timestamp the tested task started or {@code -1} if no
156         * corresponding event got fired.
157         */
158        public long getStartTime()
159        {
160            return this.startTime;
161        }
162
163        /**
164         * Sets the timestamp the tested task ended.
165         *
166         * @return the timestamp the tested task ended or {@code -1} if no
167         * corresponding event got fired.
168         */
169        public long getEndTime()
170        {
171            return this.endTime;
172        }
173
174        /**
175         * Flag indicating that corresponding events caused by the task
176         * changing its state were fired.
177         *
178         * @return {@code true} if corresponding event got fired indicating
179         * the task having changed state; {@code false} if no corresponding
180         * events got fired.
181         */
182        public boolean getChangedState()
183        {
184            return this.changedState;
185        }
186
187        /** Resets the state of the listener. */
188        public void reset()
189        {
190            this.startTime = -1L;
191            this.endTime = -1L;
192            this.changedState = false;
193        }
194
195        public void onTaskEvent( final TaskEvent taskEvent )
196        {
197            if ( taskEvent.getTask().equals( this.task ) )
198            {
199                final int type = taskEvent.getType();
200                if ( type == TaskEvent.STARTED )
201                {
202                    assert this.startTime == -1;
203                    this.startTime = System.currentTimeMillis();
204                }
205                else if ( type == TaskEvent.ENDED )
206                {
207                    assert this.endTime == -1;
208                    this.endTime = System.currentTimeMillis();
209                }
210                else if ( type == TaskEvent.CHANGED_STATE )
211                {
212                    this.changedState = true;
213                }
214                else
215                {
216                    throw new IllegalStateException( Integer.toString( type ) );
217                }
218            }
219        }
220
221    }
222
223    //---------------------------------------------------------TaskMonitorTest--
224    //--Tests-------------------------------------------------------------------
225
226    /**
227     * Tests the {@link TaskMonitor#monitor(Task)} and
228     * {@link TaskMonitor#finish(Task)} implementation to handle illegal
229     * arguments correctly by throwing a corresponding
230     * {@code NullPointerException}.
231     */
232    public void testIllegalArguments() throws Exception
233    {
234        assert this.getTaskMonitor() != null;
235
236        try
237        {
238            this.getTaskMonitor().monitor( null );
239            throw new AssertionError();
240        }
241        catch ( final NullPointerException e )
242        {
243            Assert.assertNotNull( e.getMessage() );
244            System.out.println( e.toString() );
245        }
246
247        try
248        {
249            this.getTaskMonitor().finish( null );
250            throw new AssertionError();
251        }
252        catch ( final NullPointerException e )
253        {
254            Assert.assertNotNull( e.getMessage() );
255            System.out.println( e.toString() );
256        }
257
258
259    }
260
261    /**
262     * Tests the {@link TaskMonitor#monitor(Task)} and
263     * {@link TaskMonitor#finish(Task)} implementation to fire corresponding
264     * events during task monitoring.
265     */
266    public void testMonitoring() throws Exception
267    {
268        assert this.getTaskMonitor() != null;
269
270        final Task task = new Task();
271        final TestTaskListener listener = new TestTaskListener( task );
272
273        task.setDescription( new TestMessage() );
274
275        this.getTaskEventSource().addTaskListener( listener );
276
277        task.setIndeterminate( false );
278        task.setMinimum( 0 );
279        task.setMaximum( 10 );
280        task.setProgress( 0 );
281
282        this.getTaskMonitor().monitor( task );
283
284        for ( int i = 10; i > 0; i-- )
285        {
286            task.setProgress( i );
287            Thread.currentThread().sleep( 1000 );
288        }
289
290        this.getTaskMonitor().finish( task );
291
292        Assert.assertTrue( listener.getStartTime() > 0 );
293        Assert.assertTrue( listener.getEndTime() > 0 );
294        Assert.assertTrue( listener.getChangedState() );
295    }
296
297    /**
298     * Tests the {@link TaskMonitor#monitor(Task)} and
299     * {@link TaskMonitor#finish(Task)} implementation to fire corresponding
300     * events during task monitoring for property {@code progressDescription}.
301     */
302    public void testProgressDescriptionMonitoring() throws Exception
303    {
304        assert this.getTaskMonitor() != null;
305
306        final Task task = new Task();
307        final TestTaskListener listener = new TestTaskListener( task );
308        final TestMessage progressDescription = new TestMessage();
309
310        task.setDescription( new TestMessage() );
311        task.setProgressDescription( progressDescription );
312
313        this.getTaskEventSource().addTaskListener( listener );
314
315        task.setIndeterminate( true );
316
317        this.getTaskMonitor().monitor( task );
318
319        for ( int i = 2; i > 0; i-- )
320        {
321            Thread.currentThread().sleep( 1000 );
322            progressDescription.setText( Integer.toString( i ) );
323        }
324
325        this.getTaskMonitor().finish( task );
326
327        Assert.assertTrue( listener.getStartTime() > 0 );
328        Assert.assertTrue( listener.getEndTime() > 0 );
329        Assert.assertTrue( listener.getChangedState() );
330    }
331
332    /**
333     * Tests the {@link TaskMonitor#monitor(Task)} and
334     * {@link TaskMonitor#finish(Task)} implementation to fire corresponding
335     * events during task monitoring when an application updates property
336     * {@code cancelled}.
337     */
338    public void testCancelable() throws Exception
339    {
340        assert this.getTaskMonitor() != null;
341
342        final Task task = new Task();
343        final TestTaskListener listener = new TestTaskListener( task );
344
345        this.getTaskEventSource().addTaskListener( listener );
346
347        task.setCancelable( true );
348        task.setDescription( new TestMessage() );
349
350        this.getTaskMonitor().monitor( task );
351
352        for ( int i = 10; i > 0; i-- )
353        {
354            if ( i == 10 )
355            {
356                task.setCancelled( true );
357            }
358
359            Thread.currentThread().sleep( 1000 );
360        }
361
362        this.getTaskMonitor().finish( task );
363
364        Assert.assertTrue( listener.getStartTime() > 0 );
365        Assert.assertTrue( listener.getEndTime() > 0 );
366        Assert.assertTrue( listener.getChangedState() );
367    }
368
369    /**
370     * Tests the {@link TaskMonitor#monitor(Task)} and
371     * {@link TaskMonitor#finish(Task)} implementation to not throw any
372     * exceptions for parallel accessing tasks.
373     */
374    public void testSynchronization() throws Exception
375    {
376        final List threads = new LinkedList();
377        for ( int i = 10; i > 0; i-- )
378        {
379            final Thread thread = new Thread()
380            {
381
382                public void run()
383                {
384                    try
385                    {
386                        final Task task = new Task();
387                        task.setIndeterminate( true );
388                        task.setDescription( new TestMessage() );
389
390                        getTaskMonitor().monitor( task );
391                        for ( int j = 10; j > 0; j-- )
392                        {
393                            Thread.sleep( 1000 );
394                        }
395                        getTaskMonitor().finish( task );
396                    }
397                    catch ( final InterruptedException e )
398                    {
399                        throw new AssertionError( e );
400                    }
401                }
402
403            };
404
405            threads.add( thread );
406            thread.start();
407        }
408
409        for ( final Iterator it = threads.iterator(); it.hasNext();)
410        {
411            ( ( Thread ) it.next() ).join();
412        }
413    }
414
415    //-------------------------------------------------------------------Tests--
416}