Clover icon

Coverage Report

  1. Project Clover database Thu Nov 7 2024 10:11:34 GMT
  2. Package jalview.datamodel

File ConcurrentModificationTest.java

 

Code metrics

18
64
8
1
244
145
18
0.28
8
8
2.25

Classes

Class Line # Actions
ConcurrentModificationTest 39 64 18
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.datamodel;
22   
23    import static org.testng.Assert.assertEquals;
24    import static org.testng.Assert.assertNotSame;
25    import static org.testng.Assert.fail;
26   
27    import java.util.ArrayList;
28    import java.util.ConcurrentModificationException;
29    import java.util.List;
30   
31    import org.testng.annotations.BeforeMethod;
32    import org.testng.annotations.Test;
33   
34    /**
35    * Not a test of code specific to Jalview, but some tests to verify Java
36    * behaviour under certain scenarios of concurrent modification of iterated
37    * lists or arrays
38    */
 
39    public class ConcurrentModificationTest
40    {
41    static int MAX = 10;
42   
43    int[] intArray;
44   
45    List<Integer> intList;
46   
47    /**
48    * Setup: populate array and list with values 0,...,9
49    */
 
50  0 toggle @BeforeMethod()
51    public void setUp()
52    {
53  0 intArray = new int[MAX];
54  0 intList = new ArrayList<Integer>();
55  0 for (int i = 0; i < MAX; i++)
56    {
57  0 intArray[i] = i;
58  0 intList.add(i);
59    }
60    }
61   
62    /**
63    * Sanity check of values if no 'interference'
64    */
 
65  0 toggle @Test
66    public void test_nullCase()
67    {
68    /*
69    * array iteration
70    */
71  0 int j = 0;
72  0 for (int i : intArray)
73    {
74  0 assertEquals(i, j);
75  0 j++;
76    }
77   
78    /*
79    * list iteration
80    */
81  0 j = 0;
82  0 for (int i : intList)
83    {
84  0 assertEquals(i, j);
85  0 j++;
86    }
87    }
88   
89    /**
90    * Test for the case where the array is reallocated and enlarged during the
91    * iteration. The for loop iteration is not affected.
92    */
 
93  0 toggle @Test
94    public void testEnhancedForLoop_arrayExtended()
95    {
96  0 int j = 0;
97  0 for (int i : intArray)
98    {
99  0 if (j == 5)
100    {
101  0 intArray = new int[MAX + 1];
102    }
103  0 assertEquals(i, j);
104  0 j++;
105    }
106  0 assertEquals(j, MAX);
107    }
108   
109    /**
110    * Test for the case where the array is nulled during the iteration. The for
111    * loop iteration is not affected.
112    */
 
113  0 toggle @Test
114    public void testEnhancedForLoop_arrayNulled()
115    {
116  0 int j = 0;
117  0 for (int i : intArray)
118    {
119  0 if (j == 5)
120    {
121  0 intArray = null;
122    }
123  0 assertEquals(i, j);
124  0 j++;
125    }
126  0 assertEquals(j, MAX);
127    }
128   
129    /**
130    * Test for the case where a value is changed before the iteration reaches it.
131    * The iteration reads the new value.
132    * <p>
133    * This is analagous to Jalview's consensus thread modifying entries in the
134    * AlignmentAnnotation.annotations array of Annotation[] while it is being
135    * read.
136    */
 
137  0 toggle @Test
138    public void testEnhancedForLoop_arrayModified()
139    {
140  0 int j = 0;
141  0 for (int i : intArray)
142    {
143  0 if (j == 5)
144    {
145  0 intArray[5] = -1;
146  0 intArray[6] = -2;
147    }
148    /*
149    * the value 'just read' by the for loop is not affected;
150    * the next value read is affected
151    */
152  0 int expected = j == 6 ? -2 : j;
153  0 assertEquals(i, expected);
154  0 j++;
155    }
156  0 assertEquals(j, MAX);
157    }
158   
159    /**
160    * Test for the case where a list entry is added during the iteration.
161    */
 
162  0 toggle @Test
163    public void testEnhancedForLoop_listExtended()
164    {
165  0 int j = 0;
166  0 try
167    {
168  0 for (int i : intList)
169    {
170  0 if (j == 5)
171    {
172  0 intList.add(MAX + 1);
173    }
174  0 assertEquals(i, j);
175  0 j++;
176    }
177    } catch (ConcurrentModificationException e)
178    {
179    /*
180    * exception occurs on next loop iteration after 'concurrent'
181    * modification
182    */
183  0 assertEquals(j, 6);
184  0 return;
185    }
186  0 fail("Expected exception");
187    }
188   
189    /**
190    * Test for the case where a list entry is modified during the iteration. No
191    * exception occurs.
192    */
 
193  0 toggle @Test
194    public void testEnhancedForLoop_listModified()
195    {
196  0 int j = 0;
197  0 for (int i : intList)
198    {
199  0 if (j == 5)
200    {
201  0 intList.set(5, -1);
202  0 intList.set(6, -2);
203    }
204   
205    /*
206    * the value 'just read' is not affected, the next value
207    * is read as modified, no exception
208    */
209  0 int expected = j == 6 ? -2 : j;
210  0 assertEquals(i, expected);
211  0 j++;
212    }
213  0 assertEquals(j, MAX);
214    }
215   
216    /**
217    * Test for the case where the list is recreated during the iteration.
218    */
 
219  0 toggle @Test
220    public void testEnhancedForLoop_listRenewed()
221    {
222  0 Object theList = intList;
223  0 int j = 0;
224  0 for (int i : intList)
225    {
226  0 if (j == 5)
227    {
228    /*
229    * recreate a new List object
230    */
231  0 setUp();
232  0 assertNotSame(theList, intList);
233    }
234  0 assertEquals(i, j);
235  0 j++;
236    }
237   
238    /*
239    * no exception in the for loop; changing the object intList refers to
240    * does not affect the loop's iteration over the original object
241    */
242  0 assertEquals(j, MAX);
243    }
244    }