2013-10-28 00:59:46 +04:00
# Copyright (C) 2013 Red Hat, Inc.
2013-03-18 01:06:52 +04:00
#
2018-03-20 22:00:02 +03:00
# This work is licensed under the GNU GPLv2.
# See the COPYING file in the top-level directory.
2013-03-18 01:06:52 +04:00
import logging
2018-01-05 23:49:53 +03:00
import os
2018-03-28 21:56:52 +03:00
import re
2018-01-02 22:58:57 +03:00
import sys
2018-01-05 23:49:53 +03:00
import time
2016-04-08 00:13:17 +03:00
import traceback
2018-01-05 23:49:53 +03:00
import unittest
2013-09-26 02:52:41 +04:00
2013-04-11 03:48:07 +04:00
from tests import utils
2013-09-26 02:52:41 +04:00
from virtinst import Guest
2018-03-28 21:56:52 +03:00
from virtinst import OSDB
2018-03-29 01:46:07 +03:00
from virtinst import urldetect
2013-08-09 05:42:44 +04:00
from virtinst import urlfetcher
2015-09-06 21:26:50 +03:00
from virtinst import util
2018-03-29 01:46:07 +03:00
from virtinst . urldetect import ALTLinuxDistro
from virtinst . urldetect import CentOSDistro
from virtinst . urldetect import DebianDistro
from virtinst . urldetect import FedoraDistro
2018-03-29 02:37:19 +03:00
from virtinst . urldetect import GenericTreeinfoDistro
2018-03-29 01:46:07 +03:00
from virtinst . urldetect import MandrivaDistro
from virtinst . urldetect import RHELDistro
from virtinst . urldetect import SuseDistro
from virtinst . urldetect import UbuntuDistro
2013-09-26 02:52:41 +04:00
2013-09-26 22:47:08 +04:00
2018-03-28 21:39:40 +03:00
class _URLTestData ( object ) :
"""
Class that tracks all data needed for a single URL test case .
Data is stored in test_urls . ini
"""
2018-01-02 22:58:57 +03:00
def __init__ ( self , name , url , detectdistro ,
2018-04-02 23:50:41 +03:00
testxen , testbootiso , testshortcircuit , kernelarg ) :
2018-01-02 22:58:57 +03:00
self . name = name
2017-08-29 18:04:57 +03:00
self . url = url
2013-09-26 18:24:28 +04:00
self . detectdistro = detectdistro
2018-01-02 22:58:57 +03:00
self . arch = self . _find_arch ( )
self . distroclass = self . _distroclass_for_name ( self . name )
2018-04-02 23:50:41 +03:00
self . kernelarg = kernelarg
2018-01-02 22:58:57 +03:00
self . testxen = testxen
self . testbootiso = testbootiso
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
2018-01-02 22:58:57 +03:00
# so it can short circuit the lookup checks. Speeds up the tests
# and exercises the shortcircuit infrastructure
2013-09-27 01:44:30 +04:00
self . testshortcircuit = testshortcircuit
2018-01-02 22:58:57 +03:00
def _distroclass_for_name ( self , name ) :
2018-03-29 01:46:07 +03:00
# Map the test case name to the expected urldetect distro
2018-01-02 22:58:57 +03:00
# class we should be detecting
if " fedora " in name :
return FedoraDistro
if " centos " in name :
return CentOSDistro
if " rhel " in name :
return RHELDistro
if " suse " in name :
return SuseDistro
if " debian " in name :
return DebianDistro
if " ubuntu " in name :
return UbuntuDistro
if " mageia " in name :
return MandrivaDistro
if " altlinux " in name :
return ALTLinuxDistro
if " generic " in name :
2018-03-29 02:37:19 +03:00
return GenericTreeinfoDistro
2018-01-02 22:58:57 +03:00
raise RuntimeError ( " name= %s didn ' t map to any distro class. Extend "
" _distroclass_for_name " % name )
def _find_arch ( self ) :
if ( " i686 " in self . url or
" i386 " in self . url or
" i586 " in self . url ) :
return " i686 "
if ( " arm64 " in self . url or
" aarch64 " in self . url ) :
return " aarch64 "
if ( " ppc64el " in self . url or
" ppc64le " in self . url ) :
return " ppc64le "
if " s390 " in self . url :
return " s390x "
if ( " x86_64 " in self . url or
" amd64 " in self . url ) :
return " x86_64 "
return " x86_64 "
2013-03-18 01:06:52 +04:00
2018-02-22 22:57:10 +03:00
testconn = utils . URIs . open_testdefault_cached ( )
2013-09-26 21:04:28 +04:00
hvmguest = Guest ( testconn )
hvmguest . os . os_type = " hvm "
xenguest = Guest ( testconn )
xenguest . os . os_type = " xen "
2018-02-22 21:46:24 +03:00
meter = util . make_meter ( quiet = not utils . clistate . 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 :
2018-03-29 01:46:07 +03:00
return urldetect . getDistroStore ( guest , fetcher )
2017-05-05 19:47:21 +03:00
except Exception as e :
2018-02-14 03:04:08 +03:00
if " 502 " in str ( e ) :
2013-09-26 19:49:16 +04:00
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
2018-03-28 21:56:52 +03:00
def _sanitize_osdict_name ( detectdistro ) :
"""
Try to handle working with out of date osinfo - db data . Like if
checking distro FedoraXX but osinfo - db latest Fedora is
FedoraXX - 1 , convert to use that
"""
if not detectdistro :
return detectdistro
if detectdistro == " testsuite-fedora-rawhide " :
# Special value we use in the test suite to always return the latest
# fedora when checking rawhide URL
return OSDB . latest_fedora_version ( )
if re . match ( " fedora[0-9]+ " , detectdistro ) :
if not OSDB . lookup_os ( detectdistro ) :
ret = OSDB . latest_fedora_version ( )
print ( " \n Converting detectdistro= %s to latest value= %s " %
( detectdistro , ret ) )
return ret
return detectdistro
2018-03-28 21:39:40 +03:00
def _testURL ( fetcher , testdata ) :
2013-09-26 19:49:16 +04:00
"""
Test that our URL detection logic works for grabbing kernel , xen
kernel , and boot . iso
"""
2018-03-28 21:39:40 +03:00
distname = testdata . name
arch = testdata . arch
2018-03-28 21:56:52 +03:00
detectdistro = _sanitize_osdict_name ( testdata . detectdistro )
2013-09-26 21:04:28 +04:00
hvmguest . os . arch = arch
xenguest . os . arch = arch
2018-03-28 21:39:40 +03:00
if testdata . testshortcircuit :
2018-03-28 21:56:52 +03:00
hvmguest . os_variant = detectdistro
xenguest . os_variant = detectdistro
2018-01-02 22:58:57 +03:00
else :
hvmguest . os_variant = None
xenguest . os_variant = None
2013-03-18 01:06:52 +04:00
2016-04-08 00:13:17 +03:00
try :
hvmstore = _storeForDistro ( fetcher , hvmguest )
xenstore = None
2018-03-28 21:39:40 +03:00
if testdata . testxen :
2016-04-08 00:13:17 +03:00
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 ] :
2018-03-28 21:39:40 +03:00
if ( s and testdata . distroclass and
not isinstance ( s , testdata . 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 " %
2018-03-28 21:39:40 +03:00
( s . __class__ , testdata . distroclass , distname ,
2016-03-24 21:55:27 +03:00
fetcher . location ) )
2013-03-18 01:06:52 +04:00
# Make sure the stores are reporting correct distro name/variant
2018-03-28 21:56:52 +03:00
if ( s and detectdistro and
detectdistro != s . get_osdict_info ( ) ) :
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 " %
2018-03-28 21:56:52 +03:00
( s . os_variant , detectdistro ,
2018-03-28 21:39:40 +03:00
distname , fetcher . location , testdata . 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
2018-03-28 21:39:40 +03:00
if testdata . testbootiso :
2018-03-29 23:14:08 +03:00
boot = hvmstore . acquireBootISO ( )
logging . debug ( " acquireBootISO: %s " , str ( boot ) )
2013-09-26 19:49:16 +04:00
if boot is not True :
raise AssertionError ( " %s - %s : bootiso fetching failed " %
( distname , arch ) )
# Fetch regular kernel
2018-04-02 23:50:41 +03:00
kernel , initrd , kernelargs = hvmstore . acquireKernel ( )
if kernel is not True or initrd is not True :
2013-09-26 19:49:16 +04:00
AssertionError ( " %s - %s : hvm kernel fetching failed " %
( distname , arch ) )
2018-04-02 23:50:41 +03:00
if testdata . kernelarg == " None " :
if bool ( kernelargs ) :
raise AssertionError ( " kernelargs= ' %s ' but testdata.kernelarg= ' %s ' "
% ( kernelargs , testdata . kernelarg ) )
elif testdata . kernelarg :
if not kernelargs . startswith ( testdata . kernelarg ) :
raise AssertionError ( " kernelargs= ' %s ' but testdata.kernelarg= ' %s ' "
% ( kernelargs , testdata . kernelarg ) )
2013-09-26 19:49:16 +04:00
# Fetch xen kernel
2018-01-02 22:58:57 +03:00
if xenstore :
2018-04-02 23:50:41 +03:00
kernel , initrd , kernelargs = xenstore . acquireKernel ( )
if kernel is not True or initrd is not True :
2013-09-26 19:49:16 +04:00
raise AssertionError ( " %s - %s : xen kernel fetching " %
( distname , arch ) )
2018-03-30 02:22:28 +03:00
def _fetchWrapper ( url , cb ) :
fetcher = urlfetcher . fetcherForURI ( url , " /tmp " , meter )
try :
fetcher . prepareLocation ( )
return cb ( fetcher )
finally :
fetcher . cleanupLocation ( )
2018-03-28 21:39:40 +03:00
def _testURLWrapper ( testdata ) :
2018-01-27 22:49:43 +03:00
os . environ . pop ( " VIRTINST_TEST_SUITE " , None )
logging . debug ( " Testing for media arch= %s distroclass= %s " ,
2018-03-28 21:39:40 +03:00
testdata . arch , testdata . distroclass )
2018-01-27 22:49:43 +03:00
2018-03-28 21:39:40 +03:00
sys . stdout . write ( " \n Testing %-25s " % testdata . name )
2018-01-27 22:49:43 +03:00
sys . stdout . flush ( )
2018-03-30 02:22:28 +03:00
def cb ( fetcher ) :
2018-03-28 21:39:40 +03:00
return _testURL ( fetcher , testdata )
2018-03-30 02:22:28 +03:00
return _fetchWrapper ( testdata . url , cb )
2013-09-26 19:49:16 +04:00
# Register tests to be picked up by unittest
class URLTests ( unittest . TestCase ) :
2018-03-30 02:22:28 +03:00
def test001BadURL ( self ) :
badurl = " http://aksdkakskdfa-idontexist.com/foo/tree "
def cb ( fetcher ) :
return _storeForDistro ( fetcher , hvmguest )
try :
_fetchWrapper ( badurl , cb )
raise AssertionError ( " Expected URL failure " )
except ValueError as e :
self . assertTrue ( " maybe you mistyped " in str ( e ) )
2013-09-26 19:49:16 +04:00
def _make_tests ( ) :
2017-10-11 14:35:39 +03:00
import configparser
cfg = configparser . ConfigParser ( )
2018-01-02 22:58:57 +03:00
cfg . read ( " tests/test_urls.ini " )
2018-04-03 22:29:03 +03:00
manualpath = " ~/.config/virt-manager/test_urls_manual.ini "
2018-01-05 23:49:53 +03:00
cfg . read ( manualpath )
2018-04-03 22:29:03 +03:00
if not os . path . exists ( os . path . expanduser ( manualpath ) ) :
2018-01-05 23:49:53 +03:00
print ( " NOTE: Pass in manual data with %s " % manualpath )
2018-01-02 22:58:57 +03:00
urls = { }
for name in cfg . sections ( ) :
vals = dict ( cfg . items ( name ) )
2018-03-28 21:39:40 +03:00
d = _URLTestData ( name , vals [ " url " ] ,
vals . get ( " distro " , None ) ,
vals . get ( " testxen " , " 0 " ) == " 1 " ,
vals . get ( " testbootiso " , " 0 " ) == " 1 " ,
2018-04-02 23:50:41 +03:00
vals . get ( " testshortcircuit " , " 0 " ) == " 1 " ,
vals . get ( " kernelarg " , None ) )
2018-01-02 22:58:57 +03:00
urls [ d . name ] = d
2013-09-27 02:32:50 +04:00
2017-10-11 14:35:46 +03:00
keys = list ( urls . keys ( ) )
2013-09-27 02:32:50 +04:00
keys . sort ( )
for key in keys :
2018-03-28 21:39:40 +03:00
testdata = urls [ key ]
2018-01-02 22:58:57 +03:00
def _make_wrapper ( d ) :
return lambda _self : _testURLWrapper ( d )
setattr ( URLTests , " testURL %s " % key . replace ( " - " , " _ " ) ,
2018-03-28 21:39:40 +03:00
_make_wrapper ( testdata ) )
2013-03-18 01:06:52 +04:00
2013-09-26 19:49:16 +04:00
_make_tests ( )