Download webpagetest data in facets, rather than the full matrix.

Summary:
Make it so we don't do a full MxNxP test for browser_locations x
urls_to_test x connectivity.  Instead, we only do one facet: test all
the browser-locations for urls_to_test[0] + connectivity[0], and all
the urls for browser_locations[0] + connectivity[0], and all the
connectivities for browser_locations[0] and urls_to_test[0].  (We
always test both cached and uncached though, for the moment.)  This
keeps the number of requests down, letting us focus on more runs per
day.

The goal with this change is to get smoother data, because we can
afford 9 runs per test rather than just 2.

In order to keep the size of the requested data down, instead of
fetching the har file for each of the 9 runs (for a given
url/browser/etc), we just pick the most 'representative' of those runs
and fetch the har file for that.

Rewrite a comment to be less confusing.

Oops, I was passing the wrong index for the median-run to webpagetest.org.

(The kind of error we might never have noticed except via reading the
code.)

Test Plan:
I ran run_webpagetest.MainRunTests() manually, with all the default
args except num_runs_per_url=1, and verified it correctly fetched all
the facets (20 requests total).

I then ran the next block of main(), that assigns to mongo_dicts, with
verbose=True, and verified that it successfully finished and printed
out reasonable values.  Since my test had num_runs=1, I couldn't test
that it actually correctly found the median, but at least it didn't
croak.

To test the sorting, I ran this modified version of the 'next block'
in main():
---
mongo_dicts = []
for ((browser_location, connectivity_type, url),
     (test_id, csv_output)) in results.iteritems():
    reader = csv.DictReader(csv_output)
    mongo_dicts_for_this_test_id = []
    for dict_output in reader:
        mongo_dict = ConvertToDict(browser_location, connectivity_type,
                                   url, dict_output)
        mongo_dicts_for_this_test_id.append(mongo_dict)
	d2 = mongo_dict.copy()
	d2['Run'] = 2
	d2['Doc Complete Time (ms)'] += 2
        mongo_dicts_for_this_test_id.append(d2)
	d3 = mongo_dict.copy()
	d3['Run'] = 3
	d3['Doc Complete Time (ms)'] += 1
        mongo_dicts_for_this_test_id.append(d3)
    DownloadHARFile(test_id, mongo_dicts_for_this_test_id, True)
    mongo_dicts.extend(mongo_dicts_for_this_test_id)
---

I verified that DownloadHARFile() emitted messages like:
   Downloaded HAR file for run 3 of http://www.khanacademy.org/ / Dulles_IE8 / DSL / True (11/30/2012)
showing that it correctly sorted run 3 to the middle.

Ran the following artificial test in python to visually verify.  The
first line ('runs = ...') is the artificial part; the rest of the code
is verbatim from above.

>>> runs = [{'Doc Complete Time (ms)': 4}, {'Doc Complete Time (ms)': 3}, {'Doc Complete Time (ms)': 11}, {'Doc Complete Time (ms)': 26}, {'Doc Complete Time (ms)': 7}]
>>> sorted_runs = sorted(runs, key=lambda d: d['Doc Complete Time (ms)'])
>>> median_run = sorted_runs[len(sorted_runs) / 2]
>>> median_run_index = runs.index(median_run)
>>> print '\n\n'.join(map(str, (runs, sorted_runs, median_run, median_run_index)))
[{'Doc Complete Time (ms)': 4}, {'Doc Complete Time (ms)': 3}, {'Doc Complete Time (ms)': 11}, {'Doc Complete Time (ms)': 26}, {'Doc Complete Time (ms)': 7}]

[{'Doc Complete Time (ms)': 3}, {'Doc Complete Time (ms)': 4}, {'Doc Complete Time (ms)': 7}, {'Doc Complete Time (ms)': 11}, {'Doc Complete Time (ms)': 26}]

{'Doc Complete Time (ms)': 7}

4

Reviewers: chris

Reviewed By: chris

Differential Revision: http://phabricator.khanacademy.org/D959