2013-10-28 00:59:46 +04:00
# Copyright (C) 2013 Red Hat, Inc.
2013-03-18 01:06:52 +04:00
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
2013-10-28 00:59:47 +04:00
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
2013-03-18 01:06:52 +04:00
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
import unittest
import time
import logging
import platform
2016-04-08 00:13:17 +03:00
import traceback
2013-09-26 02:52:41 +04:00
2013-09-27 02:32:50 +04:00
from tests import URLTEST_LOCAL_MEDIA
2013-04-11 03:48:07 +04:00
from tests import utils
2013-09-26 02:52:41 +04:00
from virtinst import Guest
2013-08-09 05:42:44 +04:00
from virtinst import urlfetcher
2015-09-06 21:26:50 +03:00
from virtinst import util
2013-08-09 05:42:44 +04:00
from virtinst . urlfetcher import FedoraDistro
from virtinst . urlfetcher import SuseDistro
from virtinst . urlfetcher import DebianDistro
from virtinst . urlfetcher import CentOSDistro
from virtinst . urlfetcher import SLDistro
from virtinst . urlfetcher import UbuntuDistro
from virtinst . urlfetcher import MandrivaDistro
2013-03-18 01:06:52 +04:00
2014-04-03 02:39:43 +04:00
# pylint: disable=protected-access
2013-04-12 00:32:00 +04:00
# Access to protected member, needed to unittest stuff
2014-12-10 21:39:18 +03:00
ARCHIVE_FEDORA_URL = " https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/ %s /Fedora/ %s /os/ "
2016-04-07 23:46:37 +03:00
DEVFEDORA_URL = " http://dl.fedoraproject.org/pub/fedora/linux/development/ %s /Server/ %s /os/ "
2014-12-10 21:39:18 +03:00
FEDORA_URL = " http://dl.fedoraproject.org/pub/fedora/linux/releases/ %s /Server/ %s /os/ "
2013-03-18 01:06:52 +04:00
2013-09-26 18:24:28 +04:00
OLD_CENTOS_URL = " http://vault.centos.org/ %s /os/ %s "
2014-09-06 23:35:30 +04:00
CENTOS_URL = " http://mirrors.mit.edu/centos/ %s /os/ %s / "
2013-09-26 22:47:08 +04:00
OLD_SCIENTIFIC_URL = " http://ftp.scientificlinux.org/linux/scientific/ %s / %s / "
SCIENTIFIC_URL = " http://ftp.scientificlinux.org/linux/scientific/ %s / %s /os "
2013-03-18 01:06:52 +04:00
2013-09-26 18:24:28 +04:00
OPENSUSE10 = " http://ftp.hosteurope.de/mirror/ftp.opensuse.org/discontinued/10.0 "
OLD_OPENSUSE_URL = " http://ftp5.gwdg.de/pub/opensuse/discontinued/distribution/ %s /repo/oss "
OPENSUSE_URL = " http://download.opensuse.org/distribution/ %s /repo/oss/ "
2016-06-07 20:23:01 +03:00
OPENSUSE_TUMBLEWEED = " http://download.opensuse.org/tumbleweed/repo/oss/ "
2013-03-18 01:06:52 +04:00
2013-09-26 18:24:28 +04:00
OLD_UBUNTU_URL = " http://old-releases.ubuntu.com/ubuntu/dists/ %s /main/installer- %s "
2016-03-24 23:15:21 +03:00
UBUNTU_URL = " http://us.archive.ubuntu.com:80/ubuntu/dists/ %s /main/installer- %s "
2013-09-26 18:24:28 +04:00
OLD_DEBIAN_URL = " http://archive.debian.org/debian/dists/ %s /main/installer- %s / "
DAILY_DEBIAN_URL = " http://d-i.debian.org/daily-images/ %s / "
2016-12-13 22:36:24 +03:00
DEBIAN_URL = " ftp://ftp.us.debian.org/debian/dists/ %s /main/installer- %s / "
2013-09-26 18:24:28 +04:00
2016-03-24 22:57:14 +03:00
MAGEIA_URL = " http://distro.ibiblio.org/mageia/distrib/ %s / %s "
2013-03-18 01:06:52 +04:00
2013-04-13 22:34:52 +04:00
2013-09-26 22:40:52 +04:00
urls = { }
_distro = None
2013-09-26 02:52:41 +04:00
2013-09-26 22:47:08 +04:00
2013-09-26 18:24:28 +04:00
class _DistroURL ( object ) :
2016-04-08 00:43:53 +03:00
def __init__ ( self , x86_64 , detectdistro = None , i686 = None ,
2013-09-27 01:44:30 +04:00
hasxen = True , hasbootiso = True , name = None ,
testshortcircuit = False ) :
2013-09-26 18:24:28 +04:00
self . x86_64 = x86_64
self . i686 = i686
self . detectdistro = detectdistro
self . hasxen = hasxen
self . hasbootiso = hasbootiso
self . name = name or self . detectdistro
2013-09-26 22:40:52 +04:00
self . distroclass = _distro
2013-09-26 18:24:28 +04:00
2013-09-27 01:44:30 +04:00
# If True, pass in the expected distro value to getDistroStore
# so it can short circuit the lookup checks
self . testshortcircuit = testshortcircuit
2013-09-26 22:47:08 +04:00
2013-09-26 22:40:52 +04:00
def _set_distro ( _d ) :
# Saves us from having to pass distro class to ever _add invocation
global _distro
_distro = _d
2013-09-26 18:24:28 +04:00
2013-09-26 22:47:08 +04:00
2013-09-26 18:24:28 +04:00
def _add ( * args , * * kwargs ) :
_d = _DistroURL ( * args , * * kwargs )
if _d . name in urls :
raise RuntimeError ( " distro= %s url= %s collides with entry in urls, "
" set a unique name " % ( _d . name , _d . x86_64 ) )
urls [ _d . name ] = _d
# Goal here is generally to cover all tree variants for each distro,
# where feasible. Don't exhaustively test i686 trees since most people
# aren't using it and it slows down the test, only use it in a couple
# places. Follow the comments for what trees to keep around
2013-09-26 22:40:52 +04:00
_set_distro ( FedoraDistro )
2013-09-26 18:24:28 +04:00
# One old Fedora
2014-12-10 21:39:18 +03:00
_add ( ARCHIVE_FEDORA_URL % ( " 14 " , " x86_64 " ) , " fedora14 " ,
i686 = ARCHIVE_FEDORA_URL % ( " 14 " , " i386 " ) )
2013-09-26 18:24:28 +04:00
# 2 Latest releases
2016-12-13 22:36:24 +03:00
_add ( FEDORA_URL % ( " 24 " , " x86_64 " ) , " fedora24 " , name = " fedora24 " )
2017-05-17 00:16:59 +03:00
_add ( FEDORA_URL % ( " 25 " , " x86_64 " ) , " fedora25 " , name = " fedora25 " )
2016-04-07 23:46:37 +03:00
# Any Dev release
2016-08-17 03:04:08 +03:00
# _add(DEVFEDORA_URL % ("25", "x86_64"), "fedora23", name="fedora25")
2017-05-17 00:16:59 +03:00
_add ( DEVFEDORA_URL % ( " rawhide " , " x86_64 " ) , " fedora25 " , name = " fedora-rawhide " )
2013-09-26 18:24:28 +04:00
2013-09-26 22:40:52 +04:00
_set_distro ( CentOSDistro )
2013-09-26 18:24:28 +04:00
# One old and new centos 4. No distro detection since there's no treeinfo
_add ( OLD_CENTOS_URL % ( " 4.0 " , " x86_64 " ) , hasxen = False , name = " centos-4.0 " )
_add ( OLD_CENTOS_URL % ( " 4.9 " , " x86_64 " ) , name = " centos-4.9 " )
# One old centos 5
_add ( OLD_CENTOS_URL % ( " 5.0 " , " x86_64 " ) , name = " centos-5.0 " )
# Latest centos 5 w/ i686
2017-05-17 00:16:59 +03:00
_add ( OLD_CENTOS_URL % ( " 5.11 " , " x86_64 " ) , " rhel5.11 " , name = " centos-5.11 " ,
i686 = OLD_CENTOS_URL % ( " 5.11 " , " i386 " ) )
2013-09-26 18:24:28 +04:00
# Latest centos 6 w/ i686
2017-05-17 00:16:59 +03:00
_add ( CENTOS_URL % ( " 6 " , " x86_64 " ) , " centos6.9 " , name = " centos-6-latest " ,
2013-09-26 18:24:28 +04:00
i686 = CENTOS_URL % ( " 6 " , " i386 " ) )
2014-09-06 23:35:30 +04:00
# Latest centos 7, but no i686 as of 2014-09-06
2015-04-04 22:41:13 +03:00
_add ( CENTOS_URL % ( " 7 " , " x86_64 " ) , " centos7.0 " , name = " centos-7-latest " )
2016-08-17 01:52:09 +03:00
# Centos 7 ppc64le
_add ( " http://mirror.centos.org/altarch/7/os/ppc64le/ " ,
" centos7.0 " , name = " centos-7-ppc64 " , hasbootiso = False , hasxen = False )
2013-09-26 18:24:28 +04:00
2013-09-26 22:40:52 +04:00
_set_distro ( SLDistro )
2013-09-26 18:24:28 +04:00
# Latest scientific 6
2017-05-17 00:16:59 +03:00
_add ( SCIENTIFIC_URL % ( " 6 " , " x86_64 " ) , " rhel6.9 " , name = " sl-6latest " )
# Latest scientific 7
_add ( SCIENTIFIC_URL % ( " 7 " , " x86_64 " ) , " rhel7.3 " , name = " sl-7latest " )
2013-09-26 18:24:28 +04:00
2013-09-26 22:40:52 +04:00
_set_distro ( SuseDistro )
2013-09-26 18:24:28 +04:00
# Latest 10 series
2014-09-06 23:35:30 +04:00
_add ( OLD_OPENSUSE_URL % ( " 10.3 " ) , " opensuse10.3 " , hasbootiso = False )
2013-09-26 18:24:28 +04:00
# Latest 11 series
2014-09-06 23:35:30 +04:00
_add ( OLD_OPENSUSE_URL % ( " 11.4 " ) , " opensuse11.4 " , hasbootiso = False )
2013-09-26 18:24:28 +04:00
# Latest 12 series
# Only keep i686 for the latest opensuse
2017-05-17 00:16:59 +03:00
_add ( OLD_OPENSUSE_URL % ( " 12.2 " ) , " opensuse12.2 " ,
i686 = OPENSUSE_URL % ( " 12.2 " ) , hasbootiso = False , testshortcircuit = True )
2015-05-29 11:51:50 +03:00
# Latest 13.x releases
_add ( OPENSUSE_URL % ( " 13.1 " ) , " opensuse13.1 " , hasbootiso = False )
_add ( OPENSUSE_URL % ( " 13.2 " ) , " opensuse13.2 " , hasbootiso = False )
2016-06-07 20:23:01 +03:00
# tumbleweed (rolling distro)
_add ( OPENSUSE_TUMBLEWEED , " opensusetumbleweed " , hasbootiso = False )
2013-09-26 18:24:28 +04:00
2013-09-26 22:40:52 +04:00
_set_distro ( DebianDistro )
2013-09-26 18:24:28 +04:00
# Debian releases rarely enough that we can just do every release since lenny
2014-09-06 23:35:30 +04:00
_add ( OLD_DEBIAN_URL % ( " lenny " , " amd64 " ) , " debian5 " , hasxen = False ,
2013-09-27 01:44:30 +04:00
testshortcircuit = True )
2014-09-06 23:35:30 +04:00
_add ( DEBIAN_URL % ( " wheezy " , " amd64 " ) , " debian7 " )
2013-09-26 18:24:28 +04:00
# And daily builds, since we specially handle that URL
2016-12-13 22:36:24 +03:00
_add ( DAILY_DEBIAN_URL % ( " amd64 " ) , " debiantesting " , name = " debiandaily " )
_add ( DAILY_DEBIAN_URL % ( " arm64 " ) , " debiantesting " ,
2015-03-27 20:06:26 +03:00
name = " debiandailyarm64 " , hasxen = False )
2013-09-26 18:24:28 +04:00
2013-09-26 22:40:52 +04:00
_set_distro ( UbuntuDistro )
2013-09-26 18:24:28 +04:00
# One old ubuntu
2014-09-06 23:35:30 +04:00
_add ( OLD_UBUNTU_URL % ( " hardy " , " amd64 " ) , " ubuntu8.04 " ,
2013-09-27 01:44:30 +04:00
i686 = OLD_UBUNTU_URL % ( " hardy " , " i386 " ) , hasxen = False ,
testshortcircuit = True )
2013-09-26 18:24:28 +04:00
# Latest LTS
2014-09-06 23:35:30 +04:00
_add ( UBUNTU_URL % ( " precise " , " amd64 " ) , " ubuntu12.04 " )
2013-09-26 18:24:28 +04:00
# Latest release
2016-03-24 22:57:14 +03:00
_add ( UBUNTU_URL % ( " wily " , " amd64 " ) , " ubuntu15.10 " )
2013-09-26 18:24:28 +04:00
2013-09-26 22:40:52 +04:00
_set_distro ( MandrivaDistro )
2016-04-08 00:43:53 +03:00
_add ( MAGEIA_URL % ( " 5 " , " x86_64 " ) , name = " mageia5 " , hasxen = False )
2013-03-18 01:06:52 +04:00
2013-07-05 16:59:58 +04:00
testconn = utils . open_testdefault ( )
2013-09-26 21:04:28 +04:00
hvmguest = Guest ( testconn )
hvmguest . os . os_type = " hvm "
xenguest = Guest ( testconn )
xenguest . os . os_type = " xen "
2015-09-06 21:26:50 +03:00
meter = util . make_meter ( quiet = not utils . get_debug ( ) )
2013-03-18 01:06:52 +04:00
2013-04-13 22:34:52 +04:00
2013-09-26 21:04:28 +04:00
def _storeForDistro ( fetcher , guest ) :
2013-09-26 19:49:16 +04:00
"""
Helper to lookup the Distro store object , basically detecting the
URL . Handle occasional proxy errors
"""
for ignore in range ( 0 , 10 ) :
2013-03-18 01:06:52 +04:00
try :
2013-09-26 21:04:28 +04:00
return urlfetcher . getDistroStore ( guest , fetcher )
2017-05-05 19:47:21 +03:00
except Exception as e :
2013-09-26 19:49:16 +04:00
if str ( e ) . count ( " 502 " ) :
logging . debug ( " Caught proxy error: %s " , str ( e ) )
time . sleep ( .5 )
2013-03-18 01:06:52 +04:00
continue
2013-09-26 19:49:16 +04:00
raise
2016-04-18 23:42:12 +03:00
raise # pylint: disable=misplaced-bare-raise
2013-03-18 01:06:52 +04:00
2013-09-26 21:04:28 +04:00
def _testURL ( fetcher , distname , arch , distroobj ) :
2013-09-26 19:49:16 +04:00
"""
Test that our URL detection logic works for grabbing kernel , xen
kernel , and boot . iso
"""
2016-03-24 21:55:27 +03:00
import sys
sys . stdout . write ( " \n Testing %-25s " % ( " %s - %s : " % ( distname , arch ) ) )
sys . stdout . flush ( )
2013-09-26 21:04:28 +04:00
hvmguest . os . arch = arch
xenguest . os . arch = arch
2013-09-27 01:44:30 +04:00
if distroobj . testshortcircuit :
hvmguest . os_variant = distroobj . detectdistro
xenguest . os_variant = distroobj . detectdistro
2013-03-18 01:06:52 +04:00
2016-04-08 00:13:17 +03:00
try :
hvmstore = _storeForDistro ( fetcher , hvmguest )
xenstore = None
if distroobj . hasxen :
xenstore = _storeForDistro ( fetcher , xenguest )
2017-07-24 11:26:48 +03:00
except Exception :
2016-04-08 00:13:17 +03:00
raise AssertionError ( " \n Failed to detect URLDistro class: \n "
" name = %s \n "
" url = %s \n \n %s " %
( distname , fetcher . location , " " . join ( traceback . format_exc ( ) ) ) )
2013-03-18 01:06:52 +04:00
2013-09-26 19:49:16 +04:00
for s in [ hvmstore , xenstore ] :
2013-09-27 02:32:50 +04:00
if ( s and distroobj . distroclass and
not isinstance ( s , distroobj . distroclass ) ) :
2016-03-24 21:55:27 +03:00
raise AssertionError ( " Unexpected URLDistro class: \n "
" found = %s \n "
" expect = %s \n "
" name = %s \n "
" url = %s " %
( s . __class__ , distroobj . distroclass , distname ,
fetcher . location ) )
2013-03-18 01:06:52 +04:00
# Make sure the stores are reporting correct distro name/variant
2013-09-27 02:32:50 +04:00
if ( s and distroobj . detectdistro and
distroobj . detectdistro != s . os_variant ) :
2015-11-25 05:59:26 +03:00
raise AssertionError (
2016-03-24 21:55:27 +03:00
" Detected OS did not match expected values: \n "
" found = %s \n "
" expect = %s \n "
" name = %s \n "
" url = %s \n "
" store = %s " %
( s . os_variant , distroobj . detectdistro ,
distname , fetcher . location , distroobj . distroclass ) )
2013-09-26 19:49:16 +04:00
# Do this only after the distro detection, since we actually need
# to fetch files for that part
2013-09-26 21:04:28 +04:00
def fakeAcquireFile ( filename ) :
2013-09-26 19:49:16 +04:00
logging . debug ( " Fake acquiring %s " , filename )
return fetcher . hasFile ( filename )
fetcher . acquireFile = fakeAcquireFile
# Fetch boot iso
2013-09-26 18:24:28 +04:00
if not distroobj . hasbootiso :
2013-09-26 19:49:16 +04:00
logging . debug ( " Known lack of boot.iso in %s tree. Skipping. " ,
distname )
else :
2013-09-26 21:04:28 +04:00
boot = hvmstore . acquireBootDisk ( hvmguest )
2013-09-26 19:49:16 +04:00
logging . debug ( " acquireBootDisk: %s " , str ( boot ) )
if boot is not True :
raise AssertionError ( " %s - %s : bootiso fetching failed " %
( distname , arch ) )
# Fetch regular kernel
2013-09-26 21:04:28 +04:00
kern = hvmstore . acquireKernel ( hvmguest )
2013-09-26 19:49:16 +04:00
logging . debug ( " acquireKernel (hvm): %s " , str ( kern ) )
if kern [ 0 ] is not True or kern [ 1 ] is not True :
AssertionError ( " %s - %s : hvm kernel fetching failed " %
( distname , arch ) )
# Fetch xen kernel
2013-09-26 18:24:28 +04:00
if not xenstore :
logging . debug ( " acquireKernel (xen): Hardcoded skipping. " )
else :
2013-09-26 21:04:28 +04:00
kern = xenstore . acquireKernel ( xenguest )
2013-09-26 19:49:16 +04:00
logging . debug ( " acquireKernel (xen): %s " , str ( kern ) )
if kern [ 0 ] is not True or kern [ 1 ] is not True :
raise AssertionError ( " %s - %s : xen kernel fetching " %
( distname , arch ) )
def _fetch_wrapper ( url , cb , * args ) :
2013-09-26 21:04:28 +04:00
fetcher = urlfetcher . fetcherForURI ( url , " /tmp " , meter )
2013-09-26 19:49:16 +04:00
try :
fetcher . prepareLocation ( )
return cb ( fetcher , * args )
finally :
fetcher . cleanupLocation ( )
2013-09-27 02:32:50 +04:00
def _make_test_wrapper ( url , args ) :
2013-09-26 19:49:16 +04:00
def cmdtemplate ( ) :
2013-09-27 02:32:50 +04:00
return _fetch_wrapper ( url , _testURL , * args )
2013-09-26 19:49:16 +04:00
return lambda _self : cmdtemplate ( )
# Register tests to be picked up by unittest
# If local ISO tests requested, skip all other URL tests
class URLTests ( unittest . TestCase ) :
pass
def _make_tests ( ) :
2013-09-27 02:32:50 +04:00
global urls
if URLTEST_LOCAL_MEDIA :
urls = { }
2013-09-26 19:49:16 +04:00
newidx = 0
2013-09-27 02:32:50 +04:00
arch = platform . machine ( )
for p in URLTEST_LOCAL_MEDIA :
2013-09-26 19:49:16 +04:00
newidx + = 1
2013-09-27 02:32:50 +04:00
d = _DistroURL ( p , None , hasxen = False , hasbootiso = False ,
name = " path %s " % newidx )
d . distroclass = None
urls [ d . name ] = d
keys = urls . keys ( )
keys . sort ( )
for key in keys :
distroobj = urls [ key ]
for arch , url in [ ( " i686 " , distroobj . i686 ) ,
( " x86_64 " , distroobj . x86_64 ) ] :
if not url :
continue
args = ( key , arch , distroobj )
testfunc = _make_test_wrapper ( url , args )
setattr ( URLTests , " testURL %s %s " % ( key , arch ) , testfunc )
2013-03-18 01:06:52 +04:00
2013-09-26 19:49:16 +04:00
_make_tests ( )