Skip to content

Commit

Permalink
Adds a simple CLI to client_wrapper
Browse files Browse the repository at this point in the history
This adds a simple command line interface to client_wrapper

This also makes a slight change to NdtHtml5SeleniumDriver's semantics in
that now the perform_test() call has no arguments. This allows us to use
a consistent perform_test() call across different drivers (including
browserless clients).
  • Loading branch information
mtlynch committed Mar 25, 2016
1 parent 28c98de commit 9df633f
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 57 deletions.
48 changes: 40 additions & 8 deletions client_wrapper/client_wrapper.py
Expand Up @@ -12,17 +12,49 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import argparse

import html5_driver

NDT_HTML5_CLIENT = 'ndt_js'


def main(args):
if args.client == NDT_HTML5_CLIENT:
driver = html5_driver.NdtHtml5SeleniumDriver(args.browser,
args.client_url,
timeout=20)
else:
raise ValueError('unsupported NDT client: %s' % args.client)

def main():
selenium_driver = html5_driver.NdtHtml5SeleniumDriver()
test_results = selenium_driver.perform_test(
url='http://ndt.iupui.mlab4.nuq1t.measurement-lab.org:7123/',
browser='firefox',
timeout=20)
print(test_results)
for i in range(args.iterations):
print 'starting iteration %d...' % (i + 1)
result = driver.perform_test()
print '\tc2s_throughput: %s Mbps' % result.c2s_throughput
print '\ts2c_throughput: %s Mbps' % result.s2c_throughput
if result.errors:
print '\terrors:'
for error in result.errors:
print '\t * %s: %s' % (
error.timestamp.strftime('%y-%m-%d %H:%M:%S'),
error.message)


if __name__ == '__main__':
main()
parser = argparse.ArgumentParser(
prog='NDT E2E Testing Client Wrapper',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--client',
help='NDT client implementation to run',
choices=(NDT_HTML5_CLIENT,),
required=True)
parser.add_argument('--browser',
help='Browser to run under (for browser-based client)',
choices=('chrome', 'firefox', 'safari', 'edge'))
parser.add_argument('--client_url',
help='URL of NDT client (for server-hosted clients)')
parser.add_argument('--iterations',
help='Number of iterations to run',
type=int,
default=1)
main(parser.parse_args())
25 changes: 15 additions & 10 deletions client_wrapper/html5_driver.py
Expand Up @@ -26,17 +26,21 @@

class NdtHtml5SeleniumDriver(object):

def perform_test(self, url, browser, timeout):
"""Performs an NDT test with the HTML5 client in the specified browser.
Performs a full NDT test (both s2c and c2s) using the specified
browser.
def __init__(self, browser, url, timeout):
"""Creates a NDT HTML5 client driver for the given URL and browser.
Args:
url: The URL of an NDT server to test against.
browser: Can be one of 'firefox', 'chrome', 'edge', or 'safari'.
timeout: The number of seconds that the driver will wait for
each element to become visible before timing out.
timeout: The number of seconds that the driver will wait for each
element to become visible before timing out.
"""
self._browser = browser
self._url = url
self._timeout = timeout

def perform_test(self):
"""Performs a full NDT test (both s2c and c2s) with the HTML5 client.
Returns:
A populated NdtResult object.
Expand All @@ -47,14 +51,15 @@ def perform_test(self, url, browser, timeout):
s2c_start_time=None,
errors=[])

with contextlib.closing(_create_browser(browser)) as driver:
with contextlib.closing(_create_browser(self._browser)) as driver:

if not _load_url(driver, url, result):
if not _load_url(driver, self._url, result):
return result

_click_start_button(driver, result)

if not _record_test_in_progress_values(result, driver, timeout):
if not _record_test_in_progress_values(result, driver,
self._timeout):
return result

if not _populate_metric_values(result, driver):
Expand Down
76 changes: 37 additions & 39 deletions tests/test_html5_driver.py
Expand Up @@ -44,10 +44,10 @@ def test_invalid_URL_throws_error(self):
self.mock_browser.get.side_effect = exceptions.WebDriverException(
u'Failed to load test UI.')

selenium_driver = html5_driver.NdtHtml5SeleniumDriver()
test_results = selenium_driver.perform_test(url='invalid_url',
browser='firefox',
timeout=1)
test_results = html5_driver.NdtHtml5SeleniumDriver(
browser='firefox',
url='invalid_url',
timeout=1).perform_test()

# We have one error
self.assertEqual(len(test_results.errors), 1)
Expand All @@ -62,11 +62,10 @@ def test_timeout_throws_error(self):
'WebDriverWait',
side_effect=exceptions.TimeoutException,
autospec=True):
selenium_driver = html5_driver.NdtHtml5SeleniumDriver()
test_results = selenium_driver.perform_test(
url='http://ndt.mock-server.com:7123/',
test_results = html5_driver.NdtHtml5SeleniumDriver(
browser='firefox',
timeout=1)
url='http://ndt.mock-server.com:7123/',
timeout=1).perform_test()

# We have one error
self.assertEqual(len(test_results.errors), 1)
Expand All @@ -76,38 +75,41 @@ def test_timeout_throws_error(self):
'Test did not complete within timeout period.')

def test_unimplemented_browsers_raise_error(self):
selenium_driver = html5_driver.NdtHtml5SeleniumDriver()

with self.assertRaises(NotImplementedError):
selenium_driver.perform_test(url='http://ndt.mock-server.com:7123',
browser='chrome',
timeout=1)
html5_driver.NdtHtml5SeleniumDriver(
browser='chrome',
url='http://ndt.mock-server.com:7123',
timeout=1).perform_test()
with self.assertRaises(NotImplementedError):
selenium_driver.perform_test(url='http://ndt.mock-server.com:7123',
browser='edge',
timeout=1)
html5_driver.NdtHtml5SeleniumDriver(
browser='edge',
url='http://ndt.mock-server.com:7123',
timeout=1).perform_test()
with self.assertRaises(NotImplementedError):
selenium_driver.perform_test(url='http://ndt.mock-server.com:7123',
browser='safari',
timeout=1)
html5_driver.NdtHtml5SeleniumDriver(
browser='safari',
url='http://ndt.mock-server.com:7123',
timeout=1).perform_test()

def test_unrecognized_browser_raises_error(self):
selenium_driver = html5_driver.NdtHtml5SeleniumDriver()
selenium_driver = html5_driver.NdtHtml5SeleniumDriver(
browser='not_a_browser',
url='http://ndt.mock-server.com:7123',
timeout=1)
with self.assertRaises(ValueError):
selenium_driver.perform_test(url='http://ndt.mock-server.com:7123',
browser='not_a_browser',
timeout=1)
selenium_driver.perform_test()

@freezegun.freeze_time('2016-01-01', tz_offset=0)
def test_ndt_test_results_records_todays_times(self):
# When we patch datetime so it shows our current date as 2016-01-01
self.assertEqual(datetime.datetime.now(), datetime.datetime(2016, 1, 1))

with mock.patch.object(html5_driver.ui, 'WebDriverWait', autospec=True):
selenium_driver = html5_driver.NdtHtml5SeleniumDriver()
test_results = selenium_driver.perform_test(
url='http://ndt.mock-server.com:7123/',
test_results = html5_driver.NdtHtml5SeleniumDriver(
browser='firefox',
timeout=1)
url='http://ndt.mock-server.com:7123/',
timeout=1).perform_test()

# Then the readings for our test start and end times occur within
# today's date
Expand All @@ -134,12 +136,10 @@ def test_ndt_test_results_increments_time_correctly(self):
autospec=True) as mocked_datetime:

mocked_datetime.now.side_effect = dates
selenium_driver = html5_driver.NdtHtml5SeleniumDriver()

test_results = selenium_driver.perform_test(
url='http://ndt.mock-server.com:7123/',
test_results = html5_driver.NdtHtml5SeleniumDriver(
browser='firefox',
timeout=1)
url='http://ndt.mock-server.com:7123/',
timeout=1).perform_test()

# And the sequence of returned values follows the expected timeline
# that the readings are taken in.
Expand Down Expand Up @@ -224,11 +224,10 @@ def find_elements_by_xpath(self, xpath):
autospec=True,
return_value=NewDriver()):

selenium_driver = html5_driver.NdtHtml5SeleniumDriver()
test_results = selenium_driver.perform_test(
url='http://ndt.mock-server.com:7123/',
test_results = html5_driver.NdtHtml5SeleniumDriver(
browser='firefox',
timeout=1000)
url='http://ndt.mock-server.com:7123/',
timeout=1000).perform_test()

# And the appropriate error objects are contained in
# the list
Expand Down Expand Up @@ -272,11 +271,10 @@ def find_elements_by_xpath(self, xpath):
autospec=True,
return_value=NewDriver()):

selenium_driver = html5_driver.NdtHtml5SeleniumDriver()
test_results = selenium_driver.perform_test(
url='http://ndt.mock-server.com:7123/',
test_results = html5_driver.NdtHtml5SeleniumDriver(
browser='firefox',
timeout=1000)
url='http://ndt.mock-server.com:7123/',
timeout=1000).perform_test()

self.assertEqual(test_results.latency, '72')
# And an error object is not contained in the list
Expand Down

0 comments on commit 9df633f

Please sign in to comment.