blob: b2f4af6b1fec97be77f6e630ee023880cde8e7b6 [file] [log] [blame]
# 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
import time
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
from autotest_lib.server import test
# 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'
# File size of the shared file in KB.
P2P_FILE_SIZE_KB = 20 * 1000
# 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 = 600
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_KB * 1000, file_temp_name))
dut.run('mv %s %s' % (file_temp_name, file_shared_name))
# Generate part of the files total file fize.
first_part_size_kb = P2P_FILE_SIZE_KB / 3
dut.run('dd if=/dev/urandom of=%s bs=1000 count=%d' %
(file_shared_name, first_part_size_kb))
# This small sleep is to ensure that the new file size is updated
# by avahi daemon.
time.sleep(5)
# 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/urandom of=%s bs=1000 count=%d'
' conv=notrunc oflag=append' %
(file_shared_name, P2P_FILE_SIZE_KB - first_part_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')