js/src/tests/ecma/Date/shell.js

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:da7ab04a7f8d
1
2 var BUGNUMBER;
3 var summary;
4
5 function runDSTOffsetCachingTestsFraction(part, parts)
6 {
7 BUGNUMBER = 563938;
8 summary = 'Cache DST offsets to improve SunSpider score';
9
10 print(BUGNUMBER + ": " + summary);
11
12 var MAX_UNIX_TIMET = 2145859200;
13 var RANGE_EXPANSION_AMOUNT = 30 * 24 * 60 * 60;
14
15 /**
16 * Computes the time zone offset in minutes at the given timestamp.
17 */
18 function tzOffsetFromUnixTimestamp(timestamp)
19 {
20 var d = new Date(NaN);
21 d.setTime(timestamp); // local slot = NaN, UTC slot = timestamp
22 return d.getTimezoneOffset(); // get UTC, calculate local => diff in minutes
23 }
24
25 /**
26 * Clear the DST offset cache, leaving it initialized to include a timestamp
27 * completely unlike the provided one (i.e. one very, very far away in time
28 * from it). Thus an immediately following lookup for the provided timestamp
29 * will cache-miss and compute a clean value.
30 */
31 function clearDSTOffsetCache(undesiredTimestamp)
32 {
33 var opposite = (undesiredTimestamp + MAX_UNIX_TIMET / 2) % MAX_UNIX_TIMET;
34
35 // Generic purge to known, but not necessarily desired, state
36 tzOffsetFromUnixTimestamp(0);
37 tzOffsetFromUnixTimestamp(MAX_UNIX_TIMET);
38
39 // Purge to desired state. Cycle 2x in case opposite or undesiredTimestamp
40 // is close to 0 or MAX_UNIX_TIMET.
41 tzOffsetFromUnixTimestamp(opposite);
42 tzOffsetFromUnixTimestamp(undesiredTimestamp);
43 tzOffsetFromUnixTimestamp(opposite);
44 tzOffsetFromUnixTimestamp(undesiredTimestamp);
45 }
46
47 function computeCanonicalTZOffset(timestamp)
48 {
49 clearDSTOffsetCache(timestamp);
50 return tzOffsetFromUnixTimestamp(timestamp);
51 }
52
53 var TEST_TIMESTAMPS_SECONDS =
54 [
55 // Special-ish timestamps
56 0,
57 RANGE_EXPANSION_AMOUNT,
58 MAX_UNIX_TIMET,
59 ];
60
61 var ONE_DAY = 24 * 60 * 60;
62 var EIGHTY_THREE_HOURS = 83 * 60 * 60;
63 var NINETY_EIGHT_HOURS = 98 * 60 * 60;
64 function nextIncrement(i)
65 {
66 return i === EIGHTY_THREE_HOURS ? NINETY_EIGHT_HOURS : EIGHTY_THREE_HOURS;
67 }
68
69 // Now add a long sequence of non-special timestamps, from a fixed range, that
70 // overlaps a DST change by "a bit" on each side. 67 days should be enough
71 // displacement that we can occasionally exercise the implementation's
72 // thirty-day expansion and the DST-offset-change logic. Use two different
73 // increments just to be safe and catch something a single increment might not.
74 var DST_CHANGE_DATE = 1268553600; // March 14, 2010
75 for (var t = DST_CHANGE_DATE - 67 * ONE_DAY,
76 i = nextIncrement(NINETY_EIGHT_HOURS),
77 end = DST_CHANGE_DATE + 67 * ONE_DAY;
78 t < end;
79 i = nextIncrement(i), t += i)
80 {
81 TEST_TIMESTAMPS_SECONDS.push(t);
82 }
83
84 var TEST_TIMESTAMPS =
85 TEST_TIMESTAMPS_SECONDS.map(function(v) { return v * 1000; });
86
87 /**************
88 * BEGIN TEST *
89 **************/
90
91 // Compute the correct time zone offsets for all timestamps to be tested.
92 var CORRECT_TZOFFSETS = TEST_TIMESTAMPS.map(computeCanonicalTZOffset);
93
94 // Intentionally and knowingly invoking every single logic path in the cache
95 // isn't easy for a human to get right (and know he's gotten it right), so
96 // let's do it the easy way: exhaustively try all possible four-date sequences
97 // selecting from our array of possible timestamps.
98
99 var sz = TEST_TIMESTAMPS.length;
100 var start = Math.floor((part - 1) / parts * sz);
101 var end = Math.floor(part / parts * sz);
102
103 print("Exhaustively testing timestamps " +
104 "[" + start + ", " + end + ") of " + sz + "...");
105
106 try
107 {
108 for (var i = start; i < end; i++)
109 {
110 print("Testing timestamp " + i + "...");
111
112 var t1 = TEST_TIMESTAMPS[i];
113 for (var j = 0; j < sz; j++)
114 {
115 var t2 = TEST_TIMESTAMPS[j];
116 for (var k = 0; k < sz; k++)
117 {
118 var t3 = TEST_TIMESTAMPS[k];
119 for (var w = 0; w < sz; w++)
120 {
121 var t4 = TEST_TIMESTAMPS[w];
122
123 clearDSTOffsetCache(t1);
124
125 var tzo1 = tzOffsetFromUnixTimestamp(t1);
126 var tzo2 = tzOffsetFromUnixTimestamp(t2);
127 var tzo3 = tzOffsetFromUnixTimestamp(t3);
128 var tzo4 = tzOffsetFromUnixTimestamp(t4);
129
130 assertEq(tzo1, CORRECT_TZOFFSETS[i]);
131 assertEq(tzo2, CORRECT_TZOFFSETS[j]);
132 assertEq(tzo3, CORRECT_TZOFFSETS[k]);
133 assertEq(tzo4, CORRECT_TZOFFSETS[w]);
134 }
135 }
136 }
137 }
138 }
139 catch (e)
140 {
141 assertEq(true, false,
142 "Error when testing with timestamps " +
143 i + ", " + j + ", " + k + ", " + w +
144 " (" + t1 + ", " + t2 + ", " + t3 + ", " + t4 + ")!");
145 }
146
147 reportCompare(true, true);
148 print("All tests passed!");
149 }

mercurial