Case1
Description
A concurrency error of this example occurs when two network events are executed in unexpected order. The function image134Loaded in line 9 of case1.html is called when image1.jpg, image3.jpg or image4.jpg is downloaded. The function image134Loaded assigns an object to imagesList. The function image2Loaded in line 12 of case1.html is called when image2.jpg is downloaded. The function image2Loaded reads imagesList. If image2.jpg is downloaded before image1.jpg, image3.jpg and image4.jpg, imagesList is not initialized yet and the bug occurs.
Example
http://pswlab.kaist.ac.kr:81/case1.html
Reference
"Ajax race conditions create erroneous error messages" in Drupal, https://drupal.org/node/830386
"Relying on the order of asynchronous operations" in "Avoiding intermittent oranges", https://developer.mozilla.org/en-US/docs/Mozilla/QA/Avoiding_intermittent_oranges
Source code
case1.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Case1</title>
</head>
<body>
<script>
function image134Loaded(elem) {
imagesList = {width:elem.width};
}
function image2Loaded() {
document.getElementById("outputImage2").innerHTML = "Width of images : " + imagesList.width;
}
function button1Clicked() {
document.getElementById("outputButton1").innerHTML = "Button 1 is clicked";
}
function button2Clicked() {
document.getElementById("outputButton2").innerHTML = "Button 2 is clicked";
}
</script>
<div id="outputImage2"></div>
<img id="image1" src="image1.jpg" onload="image134Loaded(this)" width="100px" height="75px" />
<img id="image2" src="image2.jpg" onload="image2Loaded()" width="100px" height="75px" />
<script src='dummy.js'></script><br />
<img id="image3" src="image3.jpg" onload="image134Loaded(this)" width="100px" height="75px" />
<img id="image4" src="image4.jpg" onload="image134Loaded(this)" width="100px" height="75px" /><br />
<button id="button1" onclick="button1Clicked()" >Button 1</button>
<button id="button2" onclick="button2Clicked()" >Button 2</button>
<div id="outputButton1" ></div>
<div id="outputButton2" ></div>
</body>
</html>
dummy.js
// dummy. works noting.
// dummy. works noting.
// dummy. works noting.
Execution Model
Operations and an Inital Test Case
There are 8 operations in this example.
- p1: parsing operation, parse line 1~24 of case1.html
- p2: parsing operation, parse dummy.js and line 25~33 of case1.html
- n1: network operation, trigger onload event of image1.jpg
- n2: network operation, trigger onload event of image2.jpg
- n3: network operation, trigger onload event of image3.jpg
- n4: network operation, trigger onload event of image4.jpg
- u1: user event operation, trigger onclick event of button1
- u2: user event operation, trigger onclick event of button2
The inital test case: p1 - p2 - n1 - n2 - n3 - n4 - u1 - u2
Happens-before Relations
- For two parsing operations: (p1, p2)
- For two user event operations: (u1, u2)
- For a parsing operation and a user event operation: (p2, u1), (p2, u2)
- For a network operation: (p1, n1), (p1, n2), (p2, n3), (p2, n4)
Generated Possible Test Cases
504 test cases are generated and 162 test cases of them are buggy because they contains (n2, n1), (n2, n3) and (n2, n4).