#!/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


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