1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/tests/ecma/Date/shell.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,149 @@ 1.4 + 1.5 +var BUGNUMBER; 1.6 +var summary; 1.7 + 1.8 +function runDSTOffsetCachingTestsFraction(part, parts) 1.9 +{ 1.10 + BUGNUMBER = 563938; 1.11 + summary = 'Cache DST offsets to improve SunSpider score'; 1.12 + 1.13 + print(BUGNUMBER + ": " + summary); 1.14 + 1.15 + var MAX_UNIX_TIMET = 2145859200; 1.16 + var RANGE_EXPANSION_AMOUNT = 30 * 24 * 60 * 60; 1.17 + 1.18 + /** 1.19 + * Computes the time zone offset in minutes at the given timestamp. 1.20 + */ 1.21 + function tzOffsetFromUnixTimestamp(timestamp) 1.22 + { 1.23 + var d = new Date(NaN); 1.24 + d.setTime(timestamp); // local slot = NaN, UTC slot = timestamp 1.25 + return d.getTimezoneOffset(); // get UTC, calculate local => diff in minutes 1.26 + } 1.27 + 1.28 + /** 1.29 + * Clear the DST offset cache, leaving it initialized to include a timestamp 1.30 + * completely unlike the provided one (i.e. one very, very far away in time 1.31 + * from it). Thus an immediately following lookup for the provided timestamp 1.32 + * will cache-miss and compute a clean value. 1.33 + */ 1.34 + function clearDSTOffsetCache(undesiredTimestamp) 1.35 + { 1.36 + var opposite = (undesiredTimestamp + MAX_UNIX_TIMET / 2) % MAX_UNIX_TIMET; 1.37 + 1.38 + // Generic purge to known, but not necessarily desired, state 1.39 + tzOffsetFromUnixTimestamp(0); 1.40 + tzOffsetFromUnixTimestamp(MAX_UNIX_TIMET); 1.41 + 1.42 + // Purge to desired state. Cycle 2x in case opposite or undesiredTimestamp 1.43 + // is close to 0 or MAX_UNIX_TIMET. 1.44 + tzOffsetFromUnixTimestamp(opposite); 1.45 + tzOffsetFromUnixTimestamp(undesiredTimestamp); 1.46 + tzOffsetFromUnixTimestamp(opposite); 1.47 + tzOffsetFromUnixTimestamp(undesiredTimestamp); 1.48 + } 1.49 + 1.50 + function computeCanonicalTZOffset(timestamp) 1.51 + { 1.52 + clearDSTOffsetCache(timestamp); 1.53 + return tzOffsetFromUnixTimestamp(timestamp); 1.54 + } 1.55 + 1.56 + var TEST_TIMESTAMPS_SECONDS = 1.57 + [ 1.58 + // Special-ish timestamps 1.59 + 0, 1.60 + RANGE_EXPANSION_AMOUNT, 1.61 + MAX_UNIX_TIMET, 1.62 + ]; 1.63 + 1.64 + var ONE_DAY = 24 * 60 * 60; 1.65 + var EIGHTY_THREE_HOURS = 83 * 60 * 60; 1.66 + var NINETY_EIGHT_HOURS = 98 * 60 * 60; 1.67 + function nextIncrement(i) 1.68 + { 1.69 + return i === EIGHTY_THREE_HOURS ? NINETY_EIGHT_HOURS : EIGHTY_THREE_HOURS; 1.70 + } 1.71 + 1.72 + // Now add a long sequence of non-special timestamps, from a fixed range, that 1.73 + // overlaps a DST change by "a bit" on each side. 67 days should be enough 1.74 + // displacement that we can occasionally exercise the implementation's 1.75 + // thirty-day expansion and the DST-offset-change logic. Use two different 1.76 + // increments just to be safe and catch something a single increment might not. 1.77 + var DST_CHANGE_DATE = 1268553600; // March 14, 2010 1.78 + for (var t = DST_CHANGE_DATE - 67 * ONE_DAY, 1.79 + i = nextIncrement(NINETY_EIGHT_HOURS), 1.80 + end = DST_CHANGE_DATE + 67 * ONE_DAY; 1.81 + t < end; 1.82 + i = nextIncrement(i), t += i) 1.83 + { 1.84 + TEST_TIMESTAMPS_SECONDS.push(t); 1.85 + } 1.86 + 1.87 + var TEST_TIMESTAMPS = 1.88 + TEST_TIMESTAMPS_SECONDS.map(function(v) { return v * 1000; }); 1.89 + 1.90 + /************** 1.91 + * BEGIN TEST * 1.92 + **************/ 1.93 + 1.94 + // Compute the correct time zone offsets for all timestamps to be tested. 1.95 + var CORRECT_TZOFFSETS = TEST_TIMESTAMPS.map(computeCanonicalTZOffset); 1.96 + 1.97 + // Intentionally and knowingly invoking every single logic path in the cache 1.98 + // isn't easy for a human to get right (and know he's gotten it right), so 1.99 + // let's do it the easy way: exhaustively try all possible four-date sequences 1.100 + // selecting from our array of possible timestamps. 1.101 + 1.102 + var sz = TEST_TIMESTAMPS.length; 1.103 + var start = Math.floor((part - 1) / parts * sz); 1.104 + var end = Math.floor(part / parts * sz); 1.105 + 1.106 + print("Exhaustively testing timestamps " + 1.107 + "[" + start + ", " + end + ") of " + sz + "..."); 1.108 + 1.109 + try 1.110 + { 1.111 + for (var i = start; i < end; i++) 1.112 + { 1.113 + print("Testing timestamp " + i + "..."); 1.114 + 1.115 + var t1 = TEST_TIMESTAMPS[i]; 1.116 + for (var j = 0; j < sz; j++) 1.117 + { 1.118 + var t2 = TEST_TIMESTAMPS[j]; 1.119 + for (var k = 0; k < sz; k++) 1.120 + { 1.121 + var t3 = TEST_TIMESTAMPS[k]; 1.122 + for (var w = 0; w < sz; w++) 1.123 + { 1.124 + var t4 = TEST_TIMESTAMPS[w]; 1.125 + 1.126 + clearDSTOffsetCache(t1); 1.127 + 1.128 + var tzo1 = tzOffsetFromUnixTimestamp(t1); 1.129 + var tzo2 = tzOffsetFromUnixTimestamp(t2); 1.130 + var tzo3 = tzOffsetFromUnixTimestamp(t3); 1.131 + var tzo4 = tzOffsetFromUnixTimestamp(t4); 1.132 + 1.133 + assertEq(tzo1, CORRECT_TZOFFSETS[i]); 1.134 + assertEq(tzo2, CORRECT_TZOFFSETS[j]); 1.135 + assertEq(tzo3, CORRECT_TZOFFSETS[k]); 1.136 + assertEq(tzo4, CORRECT_TZOFFSETS[w]); 1.137 + } 1.138 + } 1.139 + } 1.140 + } 1.141 + } 1.142 + catch (e) 1.143 + { 1.144 + assertEq(true, false, 1.145 + "Error when testing with timestamps " + 1.146 + i + ", " + j + ", " + k + ", " + w + 1.147 + " (" + t1 + ", " + t2 + ", " + t3 + ", " + t4 + ")!"); 1.148 + } 1.149 + 1.150 + reportCompare(true, true); 1.151 + print("All tests passed!"); 1.152 +}