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 8641 2012-09-27 06:45:17Z 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    /**
062     * Gets the {@code TaskMonitor} implementation tests are performed with.
063     *
064     * @return the {@code TaskMonitor} implementation tests are performed
065     * with.
066     */
067    public TaskMonitor getTaskMonitor()
068    {
069        return this.monitor;
070    }
071
072    /**
073     * Sets the {@code TaskMonitor} implementation tests are performed with.
074     *
075     * @param value the {@code TaskMonitor} implementation to perform tests
076     * with.
077     */
078    public final void setTaskMonitor( final TaskMonitor value )
079    {
080        this.monitor = value;
081        this.setTaskEventSource( value );
082    }
083
084    /** {@code Task} implementation monitoring is tested with. */
085    public static final class TestMessage extends Message
086    {
087
088        /** @serial */
089        String text = TaskMonitorTest.class.getName();
090
091        public Object[] getFormatArguments( final Locale locale )
092        {
093            return new Object[ 0 ];
094        }
095
096        public String getText( final Locale locale )
097        {
098            return this.text;
099        }
100
101        public void setText( final String value )
102        {
103            this.text = value;
104        }
105
106    }
107
108    /** {@code TaskListener} implementation monitoring is tested with. */
109    public static final class TestTaskListener implements TaskListener
110    {
111
112        /** The instance of the tested task. */
113        private Task task;
114
115        /** The timestamp the tested task started. */
116        private long startTime;
117
118        /** The timestamp the tested task ended. */
119        private long endTime;
120
121        /** Flag indicating that the tested task changed its state. */
122        private boolean changedState;
123
124        /**
125         * Creates a new {@code TestTaskListener} instance taking the tested
126         * task.
127         *
128         * @param task the tested task.
129         */
130        public TestTaskListener( final Task task )
131        {
132            if ( task == null )
133            {
134                throw new NullPointerException( "task" );
135            }
136
137            this.task = task;
138            this.reset();
139        }
140
141        /**
142         * Gets the timestamp the tested task started.
143         *
144         * @return the timestamp the tested task started or {@code -1} if no
145         * corresponding event got fired.
146         */
147        public long getStartTime()
148        {
149            return this.startTime;
150        }
151
152        /**
153         * Sets the timestamp the tested task ended.
154         *
155         * @return the timestamp the tested task ended or {@code -1} if no
156         * corresponding event got fired.
157         */
158        public long getEndTime()
159        {
160            return this.endTime;
161        }
162
163        /**
164         * Flag indicating that corresponding events caused by the task
165         * changing its state were fired.
166         *
167         * @return {@code true} if corresponding event got fired indicating
168         * the task having changed state; {@code false} if no corresponding
169         * events got fired.
170         */
171        public boolean getChangedState()
172        {
173            return this.changedState;
174        }
175
176        /** Resets the state of the listener. */
177        public void reset()
178        {
179            this.startTime = -1L;
180            this.endTime = -1L;
181            this.changedState = false;
182        }
183
184        public void onTaskEvent( final TaskEvent taskEvent )
185        {
186            if ( taskEvent.getTask().equals( this.task ) )
187            {
188                final int type = taskEvent.getType();
189                if ( type == TaskEvent.STARTED )
190                {
191                    assert this.startTime == -1;
192                    this.startTime = System.currentTimeMillis();
193                }
194                else if ( type == TaskEvent.ENDED )
195                {
196                    assert this.endTime == -1;
197                    this.endTime = System.currentTimeMillis();
198                }
199                else if ( type == TaskEvent.CHANGED_STATE )
200                {
201                    this.changedState = true;
202                }
203                else
204                {
205                    throw new IllegalStateException( Integer.toString( type ) );
206                }
207            }
208        }
209
210    }
211
212    //---------------------------------------------------------TaskMonitorTest--
213    //--Tests-------------------------------------------------------------------
214
215    /**
216     * Tests the {@link TaskMonitor#monitor(Task)} and
217     * {@link TaskMonitor#finish(Task)} implementation to handle illegal
218     * arguments correctly by throwing a corresponding
219     * {@code NullPointerException}.
220     */
221    public void testIllegalArguments() throws Exception
222    {
223        assert this.getTaskMonitor() != null;
224
225        try
226        {
227            this.getTaskMonitor().monitor( null );
228            throw new AssertionError();
229        }
230        catch ( NullPointerException e )
231        {
232            Assert.assertNotNull( e.getMessage() );
233            System.out.println( e.toString() );
234        }
235
236        try
237        {
238            this.getTaskMonitor().finish( null );
239            throw new AssertionError();
240        }
241        catch ( NullPointerException e )
242        {
243            Assert.assertNotNull( e.getMessage() );
244            System.out.println( e.toString() );
245        }
246
247
248    }
249
250    /**
251     * Tests the {@link TaskMonitor#monitor(Task)} and
252     * {@link TaskMonitor#finish(Task)} implementation to fire corresponding
253     * events during task monitoring.
254     */
255    public void testMonitoring() throws Exception
256    {
257        assert this.getTaskMonitor() != null;
258
259        final Task task = new Task();
260        final TestTaskListener listener = new TestTaskListener( task );
261
262        task.setDescription( new TestMessage() );
263
264        this.getTaskEventSource().addTaskListener( listener );
265
266        task.setIndeterminate( false );
267        task.setMinimum( 0 );
268        task.setMaximum( 10 );
269        task.setProgress( 0 );
270
271        this.getTaskMonitor().monitor( task );
272
273        for ( int i = 10; i > 0; i-- )
274        {
275            task.setProgress( i );
276            Thread.currentThread().sleep( 1000 );
277        }
278
279        this.getTaskMonitor().finish( task );
280
281        Assert.assertTrue( listener.getStartTime() > 0 );
282        Assert.assertTrue( listener.getEndTime() > 0 );
283        Assert.assertTrue( listener.getChangedState() );
284    }
285
286    /**
287     * Tests the {@link TaskMonitor#monitor(Task)} and
288     * {@link TaskMonitor#finish(Task)} implementation to fire corresponding
289     * events during task monitoring for property {@code progressDescription}.
290     */
291    public void testProgressDescriptionMonitoring() throws Exception
292    {
293        assert this.getTaskMonitor() != null;
294
295        final Task task = new Task();
296        final TestTaskListener listener = new TestTaskListener( task );
297        final TestMessage progressDescription = new TestMessage();
298
299        task.setDescription( new TestMessage() );
300        task.setProgressDescription( progressDescription );
301
302        this.getTaskEventSource().addTaskListener( listener );
303
304        task.setIndeterminate( true );
305
306        this.getTaskMonitor().monitor( task );
307
308        for ( int i = 2; i > 0; i-- )
309        {
310            Thread.currentThread().sleep( 1000 );
311            progressDescription.setText( Integer.toString( i ) );
312        }
313
314        this.getTaskMonitor().finish( task );
315
316        Assert.assertTrue( listener.getStartTime() > 0 );
317        Assert.assertTrue( listener.getEndTime() > 0 );
318        Assert.assertTrue( listener.getChangedState() );
319    }
320
321    /**
322     * Tests the {@link TaskMonitor#monitor(Task)} and
323     * {@link TaskMonitor#finish(Task)} implementation to fire corresponding
324     * events during task monitoring when an application updates property
325     * {@code cancelled}.
326     */
327    public void testCancelable() throws Exception
328    {
329        assert this.getTaskMonitor() != null;
330
331        final Task task = new Task();
332        final TestTaskListener listener = new TestTaskListener( task );
333
334        this.getTaskEventSource().addTaskListener( listener );
335
336        task.setCancelable( true );
337        task.setDescription( new TestMessage() );
338
339        this.getTaskMonitor().monitor( task );
340
341        for ( int i = 10; i > 0; i-- )
342        {
343            if ( i == 10 )
344            {
345                task.setCancelled( true );
346            }
347
348            Thread.currentThread().sleep( 1000 );
349        }
350
351        this.getTaskMonitor().finish( task );
352
353        Assert.assertTrue( listener.getStartTime() > 0 );
354        Assert.assertTrue( listener.getEndTime() > 0 );
355        Assert.assertTrue( listener.getChangedState() );
356    }
357
358    /**
359     * Tests the {@link TaskMonitor#monitor(Task)} and
360     * {@link TaskMonitor#finish(Task)} implementation to not throw any
361     * exceptions for parallel accessing tasks.
362     */
363    public void testSynchronization() throws Exception
364    {
365        final List threads = new LinkedList();
366        for ( int i = 10; i > 0; i-- )
367        {
368            final Thread thread = new Thread()
369            {
370
371                public void run()
372                {
373                    try
374                    {
375                        final Task task = new Task();
376                        task.setIndeterminate( true );
377                        task.setDescription( new TestMessage() );
378
379                        getTaskMonitor().monitor( task );
380                        for ( int j = 10; j > 0; j-- )
381                        {
382                            Thread.sleep( 1000 );
383                        }
384                        getTaskMonitor().finish( task );
385                    }
386                    catch ( InterruptedException e )
387                    {
388                        throw new AssertionError( e );
389                    }
390                }
391
392            };
393
394            threads.add( thread );
395            thread.start();
396        }
397
398        for ( Iterator it = threads.iterator(); it.hasNext();)
399        {
400            ( ( Thread ) it.next() ).join();
401        }
402    }
403
404    //-------------------------------------------------------------------Tests--
405}