#!/usr/bin/env python
#
# Test NBD client reconnection
#
# Copyright (c) 2019 Virtuozzo International GmbH
#
# 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, see <http://www.gnu.org/licenses/>.
#

import os
import subprocess
import iotests
from iotests import file_path, log


nbd_sock, conf_file = file_path('nbd-sock', 'nbd-fault-injector.conf')


def make_conf_file(event):
    """
    Create configuration file for the nbd-fault-injector.py

    :param event: which event the server should close a connection on
    """
    with open(conf_file, 'w') as conff:
        conff.write('[inject-error]\nevent={}\nwhen=after'.format(event))


def start_server_NBD(event):
    make_conf_file(event)

    srv = subprocess.Popen(['nbd-fault-injector.py', '--classic-negotiation',
                           nbd_sock, conf_file], stdout=subprocess.PIPE,
                           stderr=subprocess.STDOUT, universal_newlines=True)
    line = srv.stdout.readline()
    if 'Listening on ' in line:
        log('NBD server: started')
    else:
        log('NBD server: ' + line.rstrip())

    return srv


def start_client_NBD():
    log('NBD client: QEMU-IO write')
    args = iotests.qemu_io_args_no_fmt + \
        ['-c', 'write -P 0x7 0 3M', '--image-opts',
         'driver=nbd,server.type=unix,server.path={},'
         'reconnect-delay=7'.format(nbd_sock)]
    clt = subprocess.Popen(args, stdout=subprocess.PIPE,
                           stderr=subprocess.STDOUT,
                           universal_newlines=True)
    return clt


def check_proc_NBD(proc, connector):
    try:
        outs, errs = proc.communicate(timeout=10)

        if proc.returncode < 0:
            log('NBD {}: EXIT SIGNAL {}\n'.format(connector, proc.returncode))
            log(outs)
        else:
            msg = outs.split('\n', 1)
            log('NBD {}: {}'.format(connector, msg[0]))

    except subprocess.TimeoutExpired:
        proc.kill()
        log('NBD {}: ERROR timeout expired'.format(connector))
    finally:
        if connector == 'server':
            os.remove(nbd_sock)
            os.remove(conf_file)


srv = start_server_NBD('data')
clt = start_client_NBD()
# The server should close the connection after a client write request
check_proc_NBD(srv, 'server')
# Start the NBD server again
srv = start_server_NBD('reply')
# The client should reconnect and complete the write operation
check_proc_NBD(clt, 'client')
# Make it sure that server terminated
check_proc_NBD(srv, 'server')
