blob: a6741178df4638cd2f99934ade508f7d43951d51 [file] [log] [blame]
# Lint as: python2, python3
# Copyright 2013 The ChromiumOS Authors
# 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')