138 lines
5.3 KiB
Python
138 lines
5.3 KiB
Python
# Lint as: python2, python3
|
|
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
import logging
|
|
import os
|
|
|
|
from autotest_lib.client.common_lib import error
|
|
from autotest_lib.client.common_lib import utils
|
|
from autotest_lib.server import test
|
|
|
|
DEFAULT_AVAHI_SIZE_UPDATE_DELAY = 10
|
|
|
|
# P2P_PATH is the path where the p2p server expects the sharing files.
|
|
P2P_PATH = '/var/cache/p2p'
|
|
|
|
# Prefix all the test files with P2P_TEST_PREFIX.
|
|
P2P_TEST_PREFIX = 'p2p-test'
|
|
|
|
# Kilobyte.
|
|
KB = 1024
|
|
|
|
# File size of the shared file in MB.
|
|
P2P_FILE_SIZE_MB = 4 * KB * KB
|
|
P2P_FILE_SPLIT_SIZE_KB = P2P_FILE_SIZE_MB // (2 * KB)
|
|
|
|
# After a peer finishes the download we need it to keep serving the file for
|
|
# other peers. This peer will then wait up to P2P_SERVING_TIMEOUT_SECS seconds
|
|
# for the test to conclude.
|
|
P2P_SERVING_TIMEOUT_SECS = 300
|
|
|
|
|
|
class p2p_EndToEndTest(test.test):
|
|
"""Test to check that p2p works."""
|
|
version = 1
|
|
|
|
|
|
def run_once(self, dut, file_id, companions):
|
|
self._dut = dut
|
|
self._companion = companions[0]
|
|
|
|
file_id = '%s-%s' % (P2P_TEST_PREFIX, file_id)
|
|
file_temp_name = os.path.join(P2P_PATH, file_id + '.tmp')
|
|
file_shared_name = os.path.join(P2P_PATH, file_id + '.p2p')
|
|
|
|
logging.info('File ID: %s', file_id)
|
|
|
|
# Setup dut and companion.
|
|
for host in [self._dut, self._companion]:
|
|
# Ensure that p2p is running.
|
|
host.run('start p2p || true')
|
|
host.run('status p2p | grep running')
|
|
|
|
# Prepare an empty file to share and specify its final size via the
|
|
# "user.cros-p2p-filesize" attribute.
|
|
logging.info('All devices setup. Generating a file on main DUT')
|
|
dut.run('touch %s' % file_temp_name)
|
|
dut.run('setfattr -n user.cros-p2p-filesize -v %d %s' %
|
|
(P2P_FILE_SIZE_MB, file_temp_name))
|
|
dut.run('mv %s %s' % (file_temp_name, file_shared_name))
|
|
|
|
# Generate part of the files total file fize.
|
|
dut.run('dd if=/dev/zero of=%s bs=%d count=%d' %
|
|
(file_shared_name, KB, P2P_FILE_SPLIT_SIZE_KB))
|
|
|
|
def _wait_until_avahi_size_update():
|
|
ret = ''
|
|
try:
|
|
ret = self._companion.run(
|
|
'p2p-client --get-url=%s --minimum-size=%d' %
|
|
(file_id, P2P_FILE_SPLIT_SIZE_KB * KB))
|
|
ret = ret.stdout.strip()
|
|
except:
|
|
return False
|
|
return ret != ''
|
|
|
|
err = 'Shared file size did not update in time.'
|
|
# The actual delay is 10 seconds, so triple that to account for flakes.
|
|
utils.poll_for_condition(condition=_wait_until_avahi_size_update,
|
|
timeout=DEFAULT_AVAHI_SIZE_UPDATE_DELAY * 3,
|
|
exception=error.TestFail(err))
|
|
|
|
# Now thhe companion can attempt a p2p file download.
|
|
logging.info('Listing all p2p peers for the companion: ')
|
|
logging.info(self._companion.run('p2p-client --list-all').stdout)
|
|
ret = self._companion.run('p2p-client --get-url=%s' % file_id,
|
|
ignore_status=True)
|
|
url = ret.stdout.strip()
|
|
|
|
if not url:
|
|
raise error.TestFail(
|
|
'p2p-client on companion returned an empty URL.')
|
|
else:
|
|
logging.info('Companion using URL %s.', url)
|
|
logging.info(
|
|
'Companion downloading the file from main DUT via p2p in the background.'
|
|
)
|
|
self._companion.run_background('curl %s -o %s' %
|
|
(url, file_shared_name),
|
|
verbose=True)
|
|
|
|
logging.info(
|
|
'While companion is downloading the file, we will expand it to its full size.'
|
|
)
|
|
dut.run('dd if=/dev/zero of=%s bs=%d count=%d'
|
|
' conv=notrunc oflag=append' %
|
|
(file_shared_name, KB, P2P_FILE_SPLIT_SIZE_KB))
|
|
|
|
# Calculate the SHA1 (160 bits -> 40 characters when
|
|
# hexencoded) of the generated file.
|
|
ret = dut.run('sha1sum %s' % file_shared_name)
|
|
sha1_main = ret.stdout.strip()[0:40]
|
|
logging.info('SHA1 of main is %s', sha1_main)
|
|
sha1_companion = ''
|
|
logging.info(
|
|
'Waiting for companion to finish downloading file so we can compare SHA1 values'
|
|
)
|
|
|
|
def _shas_match():
|
|
"""Returns true when the SHA1 of the file matches on DUT and companion."""
|
|
ret = self._companion.run('sha1sum %s' % file_shared_name)
|
|
sha1_companion = ret.stdout.strip()[0:40]
|
|
logging.debug(sha1_companion)
|
|
return sha1_main == sha1_companion
|
|
|
|
err = "Main DUT's SHA1 (%s) doesn't match companions's SHA1 (%s)." % (
|
|
sha1_main, sha1_companion)
|
|
utils.poll_for_condition(condition=_shas_match,
|
|
timeout=P2P_SERVING_TIMEOUT_SECS,
|
|
exception=error.TestFail(err))
|
|
|
|
def cleanup(self):
|
|
# Clean the test environment and stop sharing this file.
|
|
for host in [self._dut, self._companion]:
|
|
host.run('rm -f %s/%s-*.p2p' % (P2P_PATH, P2P_TEST_PREFIX))
|
|
host.run('stop p2p')
|