| <!-- |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| --> |
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
| <html> |
| <head> |
| <title>OData Long Haul Tests</title> |
| <meta http-equiv="cache-control" content="no-cache" /> |
| <meta http-equiv="pragma" content="no-cache" /> |
| <meta http-equiv="expires" content="-1" /> |
| <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js"></script> |
| <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.js"></script> |
| <script type="text/javascript" src="../build/odatajs-4.0.0-beta-01.js"></script> |
| <script type="text/javascript" src="common/common.js"></script> |
| <script type="text/javascript" src="common/djstest.js"></script> |
| <script type="text/javascript" src="common/Instrument.js"></script> |
| <script type="text/javascript"> |
| var cache; |
| var clearBetweenReads; |
| var currentRunTimeMS; |
| var failureCount; |
| var hourMS = 60 * 60 * 1000; |
| var goalRunTimeMS = hourMS; |
| var isTotalIncreaseHigh; |
| var itemsInCollection = 16; |
| var iterationsRun; |
| var memoryDelta = 5000000; |
| var getBrowserMemorySize; |
| var startMemorySize; |
| var startTimeMs = 0; |
| var testFeed = "http://odata.netflix.com/Catalog/Titles"; |
| |
| var makeUnexpectedErrorHandler = function () { |
| return function (err) { |
| failureCount++; |
| if (failureCount < 50) { |
| $("#errors").append("<p>Iteration: " + iterationsRun + " Error reading cache: " + err.message + "<p>"); |
| } |
| }; |
| }; |
| |
| var checkMemoryIncrease = function (memorySizeBefore) { |
| getBrowserMemorySize(function (memorySizeAfter) { |
| var incrementalIncreaseInMemory = memorySizeAfter - memorySizeBefore; |
| var totalIncreaseInMemory = memorySizeAfter - startMemorySize; |
| if (incrementalIncreaseInMemory > memoryDelta) { |
| failureCount++; |
| if (failureCount < 50) { |
| $("#errors").append("<p>Iteration: " + iterationsRun + " Memory usage increase in read: " + incrementalIncreaseInMemory + "<p>"); |
| } |
| } |
| |
| if (totalIncreaseInMemory > memoryDelta && !isTotalIncreaseHigh) { |
| isTotalIncreaseHigh = true; |
| failureCount++; |
| if (failureCount < 50) { |
| $("#errors").append("<p>Iteration: " + iterationsRun + " Total memory usage increase over duration: " + totalIncreaseInMemory + "<p>"); |
| } |
| } |
| |
| iterationsRun++; |
| nextIteration(); |
| }); |
| }; |
| |
| var readRangePrefetchTest = function () { |
| var readPage = 6; |
| |
| getBrowserMemorySize(function (memorySizeBefore) { |
| callReadRangeRepeatedly(0, readPage, function () { checkMemoryIncrease(memorySizeBefore) }); |
| }); |
| }; |
| |
| var callReadRangeRepeatedly = function (index, count, done) { |
| /** Calls readRange over the whole collection and done when all items have been read. |
| * @param {Integer} index - Index to start the read. |
| * @param {String} count - The count of each readRange. |
| * @param {Function} done - Function to be called when all items in collection have been read. |
| var cacheRead = function () { |
| cache.readRange(index, count).then(function () { |
| if (index < itemsInCollection) { |
| index += count; |
| callReadRangeRepeatedly(index, count, done); |
| } |
| else { |
| done(); |
| } |
| }, makeUnexpectedErrorHandler(cache)); |
| }; |
| |
| if (clearBetweenReads) { |
| cache.clear().then(cacheRead(), makeUnexpectedErrorHandler(cache)); |
| } |
| else { |
| cacheRead(); |
| } |
| } |
| |
| function startTest() { |
| var prefetchSize = |
| $('input[name=PrefetchEnabled]').attr('checked') ? -1 : 0; |
| clearBetweenReads = $('input[name=ClearBetweenReads]').attr('checked'); |
| var inputHours = parseFloat($('#time').val()); |
| |
| if (inputHours !== undefined && typeof inputHours === "number" && !isNaN(inputHours) && isFinite(inputHours) && inputHours > 0) { |
| goalRunTimeMS = hourMS * inputHours; |
| } |
| OData.defaultHttpClient.enableJsonpCallback = true; |
| cache = datajs.cache.createDataCache({ name: "cache" + new Date().valueOf(), source: testFeed, pageSize: 5, prefetchSize: prefetchSize }); |
| failureCount = 0; |
| iterationsRun = 0; |
| currentRunTimeMS = 0; |
| isTotalIncreaseHigh = false; |
| $("#errors").empty(); |
| getBrowserMemorySize = Instrument.getBrowserMemorySize; |
| getBrowserMemorySize(function (memorySizeStart) { |
| startMemorySize = memorySizeStart; |
| $("#starting-memory").text("Starting memory size: " + startMemorySize); |
| }); |
| startTimeMs = new Date().getTime(); |
| |
| nextIteration(); |
| } |
| |
| function nextIteration() { |
| currentRunTimeMS = new Date().getTime() - startTimeMs; |
| if (currentRunTimeMS > goalRunTimeMS) { |
| getBrowserMemorySize(function (memorySizeAfter) { |
| $("#stress-status").text("Tests complete. Iterations: " + iterationsRun + " Failures: " + failureCount + |
| " Start memory: " + startMemorySize + " End memory: " + memorySizeAfter); |
| }); |
| |
| cache.clear(); |
| return; |
| } |
| |
| if (iterationsRun % 100 === 0) { |
| getBrowserMemorySize(function (memorySizeAfter) { |
| var text = "Running tests (iterationsRun=" + iterationsRun; |
| text += ", Time run: " + currentRunTimeMS + "ms"; |
| text += ", Remaining time: " + (goalRunTimeMS - currentRunTimeMS) + "ms"; |
| text += "). Failures: " + failureCount; |
| text += " Current memory size: " + memorySizeAfter; |
| $("#stress-status").text(text); |
| }); |
| } |
| |
| readRangePrefetchTest(); |
| } |
| |
| $(document).ready(function () { |
| $("#start-button").click(startTest); |
| }); |
| </script> |
| </head> |
| <body> |
| <h1> |
| OData Long Haul</h1> |
| <p> |
| Repeatedly runs an action and checks the memory usage. |
| </p> |
| <p> |
| <input name="time" id="time" type="text" />Length of time to run test</p> |
| <p> |
| <input type="checkbox" name="PrefetchEnabled" value="false" />Prefetch Enabled</p> |
| <p> |
| <input type="checkbox" name="ClearBetweenReads" value="false" />Clear Between Reads</p> |
| <button id='start-button'> |
| Start</button> |
| <p id='errors'> |
| </p> |
| <p id='stress-status'> |
| </p> |
| <p id='starting-memory'> |
| </p> |
| </body> |
| </html> |