#!/usr/bin/env python3
#
# 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

iotests.script_initialize()


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')
