[Libguestfs] [PATCH v2 3/3] v2v: -o rhv-upload: Add a test.
Nir Soffer
nsoffer at redhat.com
Tue Oct 9 11:28:10 UTC 2018
On Thu, Sep 20, 2018 at 11:51 AM Richard W.M. Jones <rjones at redhat.com>
wrote:
> Previously this output method was almost completely untested.
>
> This commit adds a fake ovirtsdk4 module so we can test the
> -o rhv-upload method fairly completely without needing an actual
> oVirt instance around.
> ---
> v2v/Makefile.am | 4 +
> .../ovirtsdk4/__init__.py | 146 ++++++++++++++++++
> .../ovirtsdk4/types.py | 125 +++++++++++++++
> v2v/test-v2v-o-rhv-upload.sh | 51 ++++++
> 4 files changed, 326 insertions(+)
>
> diff --git a/v2v/Makefile.am b/v2v/Makefile.am
> index 14183572b..aab356637 100644
> --- a/v2v/Makefile.am
> +++ b/v2v/Makefile.am
> @@ -382,6 +382,7 @@ TESTS += \
> test-v2v-o-openstack.sh \
> test-v2v-o-qemu.sh \
> test-v2v-o-rhv.sh \
> + test-v2v-o-rhv-upload.sh \
> test-v2v-o-vdsm-options.sh \
> test-v2v-oa-option.sh \
> test-v2v-of-option.sh \
> @@ -539,6 +540,9 @@ EXTRA_DIST += \
> test-v2v-o-qemu.sh \
> test-v2v-o-rhv.ovf.expected \
> test-v2v-o-rhv.sh \
> + test-v2v-o-rhv-upload.sh \
> + test-v2v-o-rhv-upload-module/ovirtsdk4/__init__.py \
> + test-v2v-o-rhv-upload-module/ovirtsdk4/types.py \
> test-v2v-o-rhv-upload-oo-query.sh \
> test-v2v-o-vdsm-oo-query.sh \
> test-v2v-o-vdsm-options.ovf.expected \
> diff --git a/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/__init__.py
> b/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/__init__.py
> new file mode 100644
> index 000000000..2ddb950ea
> --- /dev/null
> +++ b/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/__init__.py
> @@ -0,0 +1,146 @@
> +# -*- python -*-
> +# Copyright (C) 2018 Red Hat Inc.
> +#
> +# 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
> +# the Free Software Foundation; either version 2 of the License, or
> +# (at your option) any later version.
> +#
> +# 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.
> +
> +# Fake ovirtsdk4 module used as a test harness.
> +# See v2v/test-v2v-o-rhv-upload.sh
> +
> +class Error(Exception):
> + pass
> +class NotFoundError(Error):
> + pass
> +
> +class Connection(object):
> + def __init__(
> + self,
> + url = None,
> + username = None,
> + password = None,
> + ca_file = None,
> + log = None,
> + insecure = False,
> + ):
> + pass
> +
> + def system_service(self):
> + return SystemService()
> +
> +class SystemService(object):
> + def data_centers_service(self):
> + return DataCentersService()
> +
> + def disks_service(self):
> + return DisksService()
> +
> + def image_transfers_service(self):
> + return ImageTransfersService()
> +
> + def storage_domains_service(self):
> + return StorageDomainsService()
> +
> + def vms_service(self):
> + return VmsService()
> +
> +class DataCentersService(object):
> + def list(self, search=None, case_sensitive=False):
> + return []
> +
> +class DiskService(object):
> + def __init__(self, disk_id):
> + self._disk_id = disk_id
> +
> + def get(self):
> + return types.Disk()
> +
> + def remove(self):
> + pass
> +
> +class DisksService(object):
> + def add(self, disk=None):
> + return disk
> +
> + def disk_service(self, disk_id):
> + return DiskService(disk_id)
> +
> +class ImageTransferService(object):
> + def __init__(self):
> + self._finalized = False
> +
> + def get(self):
> + if self._finalized:
> + raise NotFoundError
> + else:
> + return types.ImageTransfer()
> +
> + def finalize(self):
> + self._finalized = True
> +
> +class ImageTransfersService(object):
> + def add(self, transfer):
> + return transfer
> +
> + def image_transfer_service(self, id):
> + return ImageTransferService()
> +
> +class StorageDomain(object):
> + id = "ba87af68-b630-4211-a73a-694c1a689405"
> +
> +class StorageDomainsService(object):
> + def list(self, search=None):
> + return [ StorageDomain() ]
> +
> +class VmsService(object):
> + def add(self, vm):
> + return vm
> +
> + def list(self, search=None):
> + return []
> +
> +# Create a background thread running a web server which is
> +# simulating the imageio server.
>
This functionality should be separated from the fake SDK module, since it is
not part of the SDK, and may be replaced by real imageio server later.
> +
> +from http.server import HTTPServer, BaseHTTPRequestHandler
> +import random
> +import threading
> +
> +# Choose a random port number in range [50000,59999]
> +imageio_port = random.randint(50000,60000)
> +
> +class RequestHandler(BaseHTTPRequestHandler):
>
This request handler is using HTTP/1.0, and will close the connection after
every request. This is not a good implementation of the imageio server, and
also
hides bugs in this code.
Should be fixed by adding:
protocol_version = "HTTP/1.1"
> + def do_OPTIONS(self):
+ self.send_response(200)
> + self.send_header("Content-type", "application/json;
> charset=UTF-8")
> + self.end_headers()
> + # Advertize only zero support.
> + self.wfile.write(b'''{ "features": [ "zero" ] }''')
> +
> + # eg. zero request. Just ignore it.
> + def do_PATCH(self):
>
This must read content-length bytes from self.rfile.
> + self.send_response(200)
> + self.end_headers()
> +
> + # Flush request. Ignore it.
> + def do_PUT(self):
>
This must read content-length bytes from self.rfile.
Both bugs are hidden by the fact that this server close the connection at
the end
of the request.
> + self.send_response(200)
> + self.end_headers()
> +
> +def server():
> + server_address = ("", imageio_port)
> + httpd = HTTPServer(server_address, RequestHandler)
> + httpd.serve_forever()
>
Using HTTP instead of HTTPS is not a good idea. We are not testing the same
code
on the client side.
It is easy to run HTTPS server using pre-created certificate, if we disable
certificate
verification on the client side (e.g. --insecure).
Nir
> +
> +thread = threading.Thread(target = server, args = [], daemon = True)
> +thread.start()
> diff --git a/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/types.py
> b/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/types.py
> new file mode 100644
> index 000000000..9b3f557ee
> --- /dev/null
> +++ b/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/types.py
> @@ -0,0 +1,125 @@
> +# -*- python -*-
> +# Copyright (C) 2018 Red Hat Inc.
> +#
> +# 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
> +# the Free Software Foundation; either version 2 of the License, or
> +# (at your option) any later version.
> +#
> +# 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.
> +
> +# Fake ovirtsdk4 module used as a test harness.
> +# See v2v/test-v2v-o-rhv-upload.sh
> +
> +from enum import Enum
> +from ovirtsdk4 import imageio_port
> +
> +class Cluster(object):
> + def __init__(self, name):
> + pass
> +
> +class Configuration(object):
> + def __init__(self, type=None, data=None):
> + pass
> +class ConfigurationType(Enum):
> + OVA = 'ova'
> + OVF = 'ovf'
> +
> + def __init__(self, image):
> + self._image = image
> +
> + def __str__(self):
> + return self._image
> +
> +class DiskFormat(Enum):
> + COW = "cow"
> + RAW = "raw"
> +
> + def __init__(self, image):
> + self._image = image
> +
> + def __str__(self):
> + return self._image
> +
> +class DiskStatus(Enum):
> + ILLEGAL = "illegal"
> + LOCKED = "locked"
> + OK = "ok"
> +
> + def __init__(self, image):
> + self._image = image
> +
> + def __str__(self):
> + return self._image
> +
> +class Disk(object):
> + def __init__(
> + self,
> + id = None,
> + name = None,
> + description = None,
> + format = None,
> + initial_size = None,
> + provisioned_size = None,
> + sparse = False,
> + storage_domains = None
> + ):
> + pass
> +
> + id = 123
> + status = DiskStatus.OK
> +
> +class ImageTransferPhase(Enum):
> + CANCELLED = 'cancelled'
> + FINALIZING_FAILURE = 'finalizing_failure'
> + FINALIZING_SUCCESS = 'finalizing_success'
> + FINISHED_FAILURE = 'finished_failure'
> + FINISHED_SUCCESS = 'finished_success'
> + INITIALIZING = 'initializing'
> + PAUSED_SYSTEM = 'paused_system'
> + PAUSED_USER = 'paused_user'
> + RESUMING = 'resuming'
> + TRANSFERRING = 'transferring'
> + UNKNOWN = 'unknown'
> +
> + def __init__(self, image):
> + self._image = image
> +
> + def __str__(self):
> + return self._image
> +
> +class ImageTransfer(object):
> + def __init__(
> + self,
> + disk = None,
> + host = None,
> + inactivity_timeout = None,
> + ):
> + pass
> +
> + id = 456
> + phase = ImageTransferPhase.TRANSFERRING
> + transfer_url = "http://localhost:" + str(imageio_port) + "/"
> +
> +class Initialization(object):
> + def __init__(self, configuration):
> + pass
> +
> +class StorageDomain(object):
> + def __init__(self, name = None):
> + pass
> +
> +class Vm(object):
> + def __init__(
> + self,
> + cluster = None,
> + initialization = None
> + ):
> + pass
> diff --git a/v2v/test-v2v-o-rhv-upload.sh b/v2v/test-v2v-o-rhv-upload.sh
> new file mode 100755
> index 000000000..8bda7cc0b
> --- /dev/null
> +++ b/v2v/test-v2v-o-rhv-upload.sh
> @@ -0,0 +1,51 @@
> +#!/bin/bash -
> +# libguestfs virt-v2v test script
> +# Copyright (C) 2018 Red Hat Inc.
> +#
> +# 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
> +# the Free Software Foundation; either version 2 of the License, or
> +# (at your option) any later version.
> +#
> +# 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.
> +
> +# Test -o rhv-upload.
> +#
> +# These uses a test harness (see
> +# v2v/test-v2v-o-rhv-upload-module/ovirtsdk4) to fake responses from
> +# oVirt.
> +
> +set -e
> +set -x
> +
> +$TEST_FUNCTIONS
> +skip_if_skipped
> +skip_if_backend uml
> +skip_unless_phony_guest windows.img
> +
> +libvirt_uri="test://$abs_top_builddir/test-data/phony-guests/guests.xml"
> +f=$top_builddir/test-data/phony-guests/windows.img
> +
> +export VIRT_TOOLS_DATA_DIR="$top_srcdir/test-data/fake-virt-tools"
> +export VIRTIO_WIN="$top_srcdir/test-data/fake-virtio-win"
> +export PYTHONPATH=$srcdir/test-v2v-o-rhv-upload-module:$PYTHONPATH
> +
> +# Run virt-v2v -o rhv-upload.
> +#
> +# The fake ovirtsdk4 module doesn't care about most of the options
> +# like -oc, -oo rhv-cafile, -op etc. Any values may be used.
> +$VG virt-v2v --debug-gc -v -x \
> + -i libvirt -ic "$libvirt_uri" windows \
> + -o rhv-upload \
> + -oc https://example.com/ovirt-engine/api \
> + -oo rhv-cafile=/dev/null \
> + -oo rhv-direct \
> + -op /dev/null \
> + -os .
> --
> 2.19.0.rc0
>
> _______________________________________________
> Libguestfs mailing list
> Libguestfs at redhat.com
> https://www.redhat.com/mailman/listinfo/libguestfs
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/libguestfs/attachments/20181009/4ea64e4f/attachment.htm>
More information about the Libguestfs
mailing list