コード例 #1
0
def run_test(ctx):
    print('running test: {}'.format(os.path.basename(__file__)[:-3]))
    remoteHosts = ['beta', 'gamma']
    srv_params = {}
    clt_params = {}
    supported_protocols = [
        "tcp-throughput",
        "tcp-tls-throughput",
        "quic-throughput"]
    # TODO maybe as program parameters
    
    
    '''
    use: start, stop interval or predefined msmt points 
    start_rate = 2
    stop_rate = 60
    step_rate = 2
    analyzing_rates = list(range(start_rate, stop_rate + step_rate, step_rate))
    '''
    print("analyzing rates: ", analyzing_rates)
    num_iterations = 10

    iterations = list(range(num_iterations))

    for host in remoteHosts:
        avail = shared.host_alive(ctx, host)

        if not avail:
            raise Exception("Host {} not available".format(host))

    beta_iface_to_alpha = ctx.config['beta']['netem-interfaces-to-alpha']
    beta_iface_to_gamma = ctx.config['beta']['netem-interfaces-to-gamma']
    interfaces = [beta_iface_to_alpha, beta_iface_to_gamma]

    srv_params['-uc-listen-addr'] = '192.186.23.3'
    srv_params['-port'] = '64321'

    clt_params['-control-addr'] = '192.186.23.3'
    clt_params['-control-protocol'] = 'tcp'
    clt_params['-streams'] = '1'
    clt_params['-addr'] = '192.186.25.2'
    clt_params['-deadline'] = '60'
    clt_params['-buffer-length'] = '1400'
    clt_params['-update-interval'] = '1'
    total_results = {}

    for protocol in supported_protocols:
        print("\n-------- analyzing: {} --------".format(protocol))

        x = []
        y = []

        for rate in analyzing_rates:
            print("\n------ configuring rate to: {} --------".format(rate))

            clt_bytes = int(shared.calc_clt_bytes(rate))
            print("\nclt sends: {} bytes".format(clt_bytes))
            clt_params['-bytes'] = str(clt_bytes)

            success_total = []
            measurements_succeeded = 0

            for iteration in iterations:
                print("\n -------- {}. iteration -------".format(iteration))

                # ensures we dont get stuck in a popen.wait(deadline) deadlock
                timeout_ctr = 0
                timeout_ctr_limit = 10

                # reset queue at netem middlebox and configure
                shared.netem_reset(ctx, 'beta', interfaces=interfaces)
                
                shared.netem_configure(
                ctx, 'beta', interfaces=interfaces, netem_params={
                    'rate': '{}kbit'.format(rate)})
 
                # ensure server is running "fresh" per iter => no saved crypto cookies
                # note: using this we cant get "ssh" debug data
                # due to background cmd
                # we could implement a logging routine in mapago writing to a log file on srv...
                shared.mapago_reset(ctx, 'gamma')
                shared.prepare_server(ctx, srv_params)

                # ensures client mapago creation does not happen before server is ready
                sleep(5)

                clt_params['-module'] = '{}'.format(protocol)
                print("\n starting module: {}".format(clt_params['-module']))
               
                msmt_results = []

                while len(msmt_results) < 1 and timeout_ctr < timeout_ctr_limit:
                    print("\nIssueing prepare_client!\n")
                    msmt_results = shared.prepare_client(ctx, clt_params)
                    
                    if len(msmt_results) < 1:
                        print("\nClient NOT terminated! reissue until client terminates!")
                        timeout_ctr += 1

                if timeout_ctr >= timeout_ctr_limit:
                    print("\nTimeout ctr limit reached! Iteration failed")
                    success_iter = 0
                else:
                    success_iter = analyze_data(msmt_results, protocol, clt_bytes)

                # add success_value to list
                success_total.append(success_iter)
           
            # future x axis (rates)
            x.append(rate)

            # calculate "success value"
            if len(success_total) != num_iterations:
                raise Exception("list of success values does not math number of iterations!")

            for success_value in success_total:
                if success_value == 1:
                    measurements_succeeded += 1

            print("From {} finished {} successfully: ".format(num_iterations, measurements_succeeded))
            success_rate = int(float(measurements_succeeded / num_iterations) * 100)

            # future y axis (throughput)
            y.append(success_rate)

        # we are with this protocol finished add to total results
        total_results[protocol] = (x, y)
        shared.save_raw_data(os.path.basename(__file__)[:-3], total_results)   

        print(total_results)

        print("\nsleeping")
        sleep(5)
        print("\n next protocol")

    plot_data(total_results)
def run_test(ctx):
    print('running test: {}'.format(os.path.basename(__file__)[:-3]))
    remoteHosts = ['beta', 'gamma']
    srv_params = {}
    clt_params = {}

    supported_protocols = [
        "tcp-throughput", "tcp-tls-throughput", "quic-throughput"
    ]

    num_iterations = 10
    timeout_ctr_limit = 3

    sim_dur = shared.calc_simulation_time(supported_protocols, num_iterations,
                                          timeout_ctr_limit, analyzing_rates,
                                          analyzing_delay)
    print("simulation duration is: {}".format(sim_dur))

    iterations = list(range(num_iterations))

    for host in remoteHosts:
        avail = shared.host_alive(ctx, host)

        if not avail:
            raise Exception("Host {} not available".format(host))

    beta_iface_to_alpha = ctx.config['beta']['netem-interfaces-to-alpha']
    beta_iface_to_gamma = ctx.config['beta']['netem-interfaces-to-gamma']
    interfaces = [beta_iface_to_alpha, beta_iface_to_gamma]

    srv_params['-uc-listen-addr'] = '192.186.23.3'
    srv_params['-port'] = '64321'

    clt_params['-control-addr'] = '192.186.23.3'
    clt_params['-control-protocol'] = 'tcp'
    clt_params['-streams'] = '1'
    clt_params['-addr'] = '192.186.25.2'
    clt_params['-deadline'] = '120'
    clt_params['-buffer-length'] = '1400'
    clt_params['-update-interval'] = '1'

    # goodput_rate_avg for all protocols
    total_goodput_rate_avg = {}
    total_results_debug = {}

    # 1. iterate over protocols
    for protocol in supported_protocols:
        print("\n-------- analyzing: {} --------".format(protocol))

        visited_rate = []
        visited_delay = []
        quotients_all_rates_over_delays = []
        kbits_normalized = []

        # 2. iterate over rate
        for rate in analyzing_rates:
            print("\n------ configuring rate to: {} --------".format(rate))

            # 3. determine bytes for transmission regarding rate
            clt_bytes = int(shared.calc_clt_bytes(rate))
            clt_params['-bytes'] = str(clt_bytes)

            quotients_single_rate_over_delays = []
            analyzed_delay_per_rate = []

            # 4. deepest for loop: iterate over delay
            for delay in analyzing_delay:
                print(
                    "\n------ configuring delay to: {} --------".format(delay))

                # holds results of ALL iters per single delay and rate tuple
                kbits_per_delay = []

                for iteration in iterations:
                    print(
                        "\n -------- {}. iteration -------".format(iteration))

                    # ensures we dont get stuck in a popen.wait(deadline) deadlock
                    timeout_ctr = 0

                    # reset queue at netem middlebox
                    shared.netem_reset(ctx, 'beta', interfaces=interfaces)

                    # 5. we know everything: so configure!
                    shared.netem_configure(ctx,
                                           'beta',
                                           interfaces=interfaces,
                                           netem_params={
                                               'rate': '{}kbit'.format(rate),
                                               'delay': '{}'.format(delay)
                                           })

                    # ensure server is running "fresh" per iter => no saved crypto cookies
                    # note: using this we cant get "ssh" debug data
                    # due to background cmd
                    # we could implement a logging routine in mapago writing to a log file on srv...
                    shared.mapago_reset(ctx, 'gamma')
                    shared.prepare_server(ctx, srv_params)

                    # ensures client mapago creation does not happen before server is ready
                    sleep(5)

                    clt_params['-module'] = '{}'.format(protocol)
                    print("\n starting module: {}".format(
                        clt_params['-module']))

                    msmt_results = []

                    while len(msmt_results
                              ) < 1 and timeout_ctr < timeout_ctr_limit:
                        print("\nIssueing prepare_client!\n")
                        msmt_results = shared.prepare_client(ctx, clt_params)

                        # check if client not terminated
                        if len(msmt_results) < 1:
                            print(
                                "\n!!!!!!Error!!!!!! Client NOT terminated! reissue until client terminates!"
                            )
                            timeout_ctr += 1

                    if timeout_ctr >= timeout_ctr_limit:
                        print("\nTimeout ctr limit reached! Iteration failed")
                        kbits_iter = 0
                    else:
                        kbits_iter = analyze_data(msmt_results, protocol,
                                                  clt_bytes)

                    kbits_per_delay.append(kbits_iter)

                kbits_per_delay_normalized = 0

                # account all iters
                for kbits_iter in kbits_per_delay:
                    kbits_per_delay_normalized += kbits_iter

                kbits_per_delay_normalized = kbits_per_delay_normalized / num_iterations
                print("\n mean kbits per delay: {}".format(
                    kbits_per_delay_normalized))

                # 6. calculate for single delay and rate tuple our goodput_rate_quotient
                # i.e. rate  = 5, delay = 2; rate = 5, delay = 5; rate = 5, delay = 10
                # "red"
                goodput_rate_quotient_avg = kbits_per_delay_normalized / rate

                # 7. add to list of quietnts for single rate iver losses
                quotients_single_rate_over_delays.append(
                    goodput_rate_quotient_avg)

                # 7.5 add los to list
                analyzed_delay_per_rate.append(delay)

            # 8. ok: we got all quoient for a given SINGLE rate and all LOSSES
            # add it to the list: where we store all RATES and the corresponding list
            # for the SINGLE rate and all LOSSES
            quotients_all_rates_over_delays.append(
                quotients_single_rate_over_delays)
            visited_rate.append(rate)
            visited_delay.append(analyzed_delay_per_rate)

        # 9. we got the list of lists for a single protocol complete: add it
        total_goodput_rate_avg[protocol] = (visited_rate, visited_delay,
                                            quotients_all_rates_over_delays)
        shared.save_raw_data(
            os.path.basename(__file__)[:-3], total_goodput_rate_avg)

        print("\n visited_rate: ", visited_rate)
        print("\n visited_delay: ", visited_delay)
        print("\n total_goodput_rate_avg: ", total_goodput_rate_avg)

        print("\nsleeping")
        sleep(5)
        print("\n next protocol")
    '''
    QUIC thesis results:
    - These results were obtained in the context of the measurement
    - Used this line for verifying the result

    total_goodput_rate_avg = {"tcp-throughput": [[5, 50, 250, 500], [[0, 10, 50, 250], [0, 10, 50, 250], [0, 10, 50, 250], [0, 10, 50, 250]], [[0.8987872192411489, 0.7823267454919813, 0.8717731267708974, 0.9449281470690319], [0.8914808616112653, 0.9393961996215485, 0.9553501262186983, 0.9014234459920567], [0.9502326564667469, 0.9542850021635289, 0.9561571123219293, 0.9509310693945888], [0.9563853871451465, 0.9563302765309082, 0.9564144806993923, 0.9553549476575104]]], "tcp-tls-throughput": [[5, 50, 250, 500], [[0, 10, 50, 250], [0, 10, 50, 250], [0, 10, 50, 250], [0, 10, 50, 250]], [[0.7915266722574326, 0.7601227070334426, 0.7381980505336566, 0.8927837899522644], [0.915011005190392, 0.9349899435998139, 0.7538226523850817, 0.7739993436101752], [0.8963259250550947, 0.9095146161880139, 0.9074419480214088, 0.8893709701924917], [0.9146203613669235, 0.9309780058311868, 0.8878567577638666, 0.8991129060391729]]], "quic-throughput": [[5, 50, 250, 500], [[0, 10, 50, 250], [0, 10, 50, 250], [0, 10, 50, 250], [0, 10, 50, 250]], [[0.0, 0.0, 0.0, 0.0], [0.3006895781631222, 0.13806085691509123, 0.30098765980594716, 0.44843030517187144], [0.9044825487791093, 0.8881095657532313, 0.901846031337234, 0.8991592469774472], [0.9027135581514798, 0.9059463999240039, 0.9052832465014307, 0.8994225971623447]]]}
    '''

    plot_data(total_goodput_rate_avg)
コード例 #3
0
def run_test(ctx):
    print('running test: {}'.format(os.path.basename(__file__)[:-3]))
    remoteHosts = ['beta', 'gamma']
    srv_params = {}
    clt_params = {}

    supported_protocols = [
        "tcp-throughput", "tcp-tls-throughput", "quic-throughput"
    ]

    print("rate: ", analyzing_rates)
    print("delay: ", analyzing_delay)

    num_iterations = 10
    timeout_ctr_limit = 3

    sim_dur = shared.calc_simulation_time(supported_protocols, num_iterations,
                                          timeout_ctr_limit, analyzing_rates,
                                          analyzing_delay)
    print("simulation duration is: {}".format(sim_dur))

    iterations = list(range(num_iterations))

    for host in remoteHosts:
        avail = shared.host_alive(ctx, host)

        if not avail:
            raise Exception("Host {} not available".format(host))

    beta_iface_to_alpha = ctx.config['beta']['netem-interfaces-to-alpha']
    beta_iface_to_gamma = ctx.config['beta']['netem-interfaces-to-gamma']
    interfaces = [beta_iface_to_alpha, beta_iface_to_gamma]

    srv_params['-uc-listen-addr'] = '192.186.23.3'
    srv_params['-port'] = '64321'

    clt_params['-control-addr'] = '192.186.23.3'
    clt_params['-control-protocol'] = 'tcp'
    clt_params['-streams'] = '1'
    clt_params['-addr'] = '192.186.25.2'
    clt_params['-deadline'] = '120'
    clt_params['-buffer-length'] = '1400'
    clt_params['-update-interval'] = '1'

    # goodput_rate_avg for all protocols
    total_goodput_rate_avg = {}
    total_results_debug = {}

    # 1. iterate over protocols
    for protocol in supported_protocols:
        print("\n-------- analyzing: {} --------".format(protocol))

        visited_rate = []
        visited_delay = []
        quotients_all_rates_over_delays = []
        kbits_normalized = []

        # 2. iterate over rate
        for rate in analyzing_rates:
            print("\n------ configuring rate to: {} --------".format(rate))

            # 3. determine bytes for transmission regarding rate
            clt_bytes = int(shared.calc_clt_bytes(rate))
            clt_params['-bytes'] = str(clt_bytes)

            quotients_single_rate_over_delays = []
            analyzed_delay_per_rate = []

            # 4. deepest for loop: iterate over delay
            for delay in analyzing_delay:
                # holds results of ALL iters per single delay and rate tuple
                kbits_per_delay = []
                jitter = (float(delay) / 100) * jitter_ratio
                print("\nsetting jitter to: ", jitter)

                print(
                    "\n------ configuring delay and jitter to: {}, {} --------"
                    .format(delay, jitter))

                for iteration in iterations:
                    print(
                        "\n -------- {}. iteration -------".format(iteration))

                    # ensures we dont get stuck in a popen.wait(deadline) deadlock
                    timeout_ctr = 0

                    # reset queue at netem middlebox
                    shared.netem_reset(ctx, 'beta', interfaces=interfaces)

                    # 5. we know everything: so configure!
                    shared.netem_configure(ctx,
                                           'beta',
                                           interfaces=interfaces,
                                           netem_params={
                                               'rate':
                                               '{}kbit'.format(rate),
                                               'delay+jitter':
                                               '{}ms {}ms'.format(
                                                   delay, jitter)
                                           })

                    # ensure server is running "fresh" per iter => no saved crypto cookies
                    # note: using this we cant get "ssh" debug data
                    # due to background cmd
                    # we could implement a logging routine in mapago writing to a log file on srv...
                    shared.mapago_reset(ctx, 'gamma')
                    shared.prepare_server(ctx, srv_params)

                    # ensures client mapago creation does not happen before server is ready
                    sleep(5)

                    clt_params['-module'] = '{}'.format(protocol)
                    print("\n starting module: {}".format(
                        clt_params['-module']))

                    msmt_results = []

                    while len(msmt_results
                              ) < 1 and timeout_ctr < timeout_ctr_limit:
                        print("\nIssueing prepare_client!\n")
                        msmt_results = shared.prepare_client(ctx, clt_params)

                        # check if client not terminated
                        if len(msmt_results) < 1:
                            print(
                                "\n!!!!!!Error!!!!!! Client NOT terminated! reissue until client terminates!"
                            )
                            timeout_ctr += 1

                    if timeout_ctr >= timeout_ctr_limit:
                        print("\nTimeout ctr limit reached! Iteration failed")
                        kbits_iter = 0
                    else:
                        kbits_iter = analyze_data(msmt_results, protocol,
                                                  clt_bytes)

                    kbits_per_delay.append(kbits_iter)

                kbits_per_delay_normalized = 0

                # account all iters
                for kbits_iter in kbits_per_delay:
                    kbits_per_delay_normalized += kbits_iter

                kbits_per_delay_normalized = kbits_per_delay_normalized / num_iterations
                print("\n mean kbits per delay: {}".format(
                    kbits_per_delay_normalized))

                # 6. calculate for single delay and rate tuple our goodput_rate_quotient
                # i.e. rate  = 5, delay = 2; rate = 5, delay = 5; rate = 5, delay = 10
                # "red"
                goodput_rate_quotient_avg = kbits_per_delay_normalized / rate

                # 7. add to list of quietnts for single rate iver losses
                quotients_single_rate_over_delays.append(
                    goodput_rate_quotient_avg)

                # 7.5 add los to list
                analyzed_delay_per_rate.append(delay)

            # 8. ok: we got all quoient for a given SINGLE rate and all LOSSES
            # add it to the list: where we store all RATES and the corresponding list
            # for the SINGLE rate and all LOSSES
            quotients_all_rates_over_delays.append(
                quotients_single_rate_over_delays)
            visited_rate.append(rate)
            visited_delay.append(analyzed_delay_per_rate)

        # 9. we got the list of lists for a single protocol complete: add it
        total_goodput_rate_avg[protocol] = (visited_rate, visited_delay,
                                            quotients_all_rates_over_delays)
        shared.save_raw_data(
            os.path.basename(__file__)[:-3], total_goodput_rate_avg)

        print("\n visited_rate: ", visited_rate)
        print("\n visited_delay: ", visited_delay)
        print("\n total_goodput_rate_avg: ", total_goodput_rate_avg)

        print("\nsleeping")
        sleep(5)
        print("\n next protocol")
    '''
    QUIC thesis results:
    - These results were obtained in the context of the measurement
    - Used this line for verifying the result

    total_goodput_rate_avg = {"quic-throughput": [[5, 50, 250, 500], [[0, 10, 50, 250, 1000, 10000], [0, 10, 50, 250, 1000, 10000], [0, 10, 50, 250, 1000, 10000], [0, 10, 50, 250, 1000, 10000]], [[0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.80161227838563056, 0.8040652428144947, 0.8041416107786962, 0.7940765487525084, 0.7444791929425141, 0.0], [0.8949120673581473, 0.8681223437939265, 0.8227633821170063, 0.0, 0.0, 0.0], [0.9020158717586202, 0.8678721881786707, 0.7935316913337243, 0.0, 0.0, 0.0]]], "tcp-throughput": [[5, 50, 250, 500], [[0, 10, 50, 250, 1000, 10000], [0, 10, 50, 250, 1000, 10000], [0, 10, 50, 250, 1000, 10000], [0, 10, 50, 250, 1000, 10000]], [[0.8947504090914252, 0.6525793098184648, 0.7649036420047517, 0.8389996637955015, 0.7478415226187547, 0.4889345563833384], [0.9368367623192994, 0.7945618978868387, 0.8481709831094519, 0.8196944154301594, 0.622114906545979, 0.18108507164912754], [0.9544446957447422, 0.9316989097856575, 0.924426515051143, 0.8985641638385886, 0.8391914638969366, 0.0], [0.9563714427147644, 0.9561166758797403, 0.954858844154299, 0.9530127448208954, 0.8657837061661853, 0.0]]], "tcp-tls-throughput": [[5, 50, 250, 500], [[0, 10, 50, 250, 1000, 10000], [0, 10, 50, 250, 1000, 10000], [0, 10, 50, 250, 1000, 10000], [0, 10, 50, 250, 1000, 10000]], [[0.905965133648742, 0.625319284545624, 0.6197808646068161, 0.7395122680163873, 0.7086336896330845, 0.48219699140931727], [0.7789134555766118, 0.7740938538514139, 0.9094230363344891, 0.6078073032754268, 0.6734109346990803, 0.18402407325358308], [0.920490309867192, 0.7166749984938212, 0.7119296816954054, 0.8449847624341839, 0.7851837084388277, 0.0], [0.8985949229726562, 0.8379584627409254, 0.7977987060452126, 0.7697167567685701, 0.7220478414231848, 0.0]]]}
    '''

    plot_data(total_goodput_rate_avg)
コード例 #4
0
def run_test(ctx):
    print('running test: {}'.format(os.path.basename(__file__)[:-3]))
    remoteHosts = ['beta', 'gamma']
    srv_params = {}
    clt_params = {}
    supported_protocols = [
        "tcp-throughput",
        "tcp-tls-throughput",
        "udp-throughput",
        "quic-throughput"]
    # TODO maybe as program parameters
    
    start_rate = 10
    stop_rate = 1000
    step_rate = 10
    analyzing_rates = list(range(start_rate, stop_rate + step_rate, step_rate))
    num_iterations = 10

    iterations = list(range(num_iterations))

    for host in remoteHosts:
        avail = shared.host_alive(ctx, host)

        if not avail:
            raise Exception("Host {} not available".format(host))

    beta_iface_to_alpha = ctx.config['beta']['netem-interfaces-to-alpha']
    beta_iface_to_gamma = ctx.config['beta']['netem-interfaces-to-gamma']
    interfaces = [beta_iface_to_alpha, beta_iface_to_gamma]

    srv_params['-uc-listen-addr'] = '192.186.23.3'
    srv_params['-port'] = '64321'

    clt_params['-control-addr'] = '192.186.23.3'
    clt_params['-control-protocol'] = 'tcp'
    clt_params['-streams'] = '1'
    clt_params['-addr'] = '192.186.25.2'
    clt_params['-deadline'] = '60'
    clt_params['-buffer-length'] = '1400'
    clt_params['-update-interval'] = '1'

    total_results = {}

    for protocol in supported_protocols:
        print("\n-------- analyzing: {} --------".format(protocol))
        # TODO: move mapago_reset, prepare_server, netem_reset up
        shared.mapago_reset(ctx, 'gamma')
        shared.prepare_server(ctx, srv_params)

        x = []
        y = []

        for rate in analyzing_rates:
            ''' We need to reset the netem server and reconfigure'''
            print("\n------ configuring rate to: {} --------".format(rate))

            shared.netem_reset(ctx, 'beta', interfaces=interfaces)
            shared.netem_configure(
                ctx, 'beta', interfaces=interfaces, netem_params={
                    'rate': '{}kbit'.format(rate)})

            clt_bytes = int(shared.calc_clt_bytes(rate))
            # print("\nclt sends: {} bytes".format(clt_bytes))
            clt_params['-bytes'] = str(clt_bytes)


            # stores all iteration results regarding a specific rate
            kbits_per_rate = []

            for iteration in iterations:
                print("\n -------- {}. iteration -------".format(iteration))

                clt_params['-module'] = '{}'.format(protocol)
                print("\n starting module: {}".format(clt_params['-module']))
                msmt_results = shared.prepare_client(ctx, clt_params)
                kbits_iter = analyze_data(msmt_results, protocol, clt_bytes)

                kbits_per_rate.append(kbits_iter)

            kbits_per_rate_normalized = 0

            # account all iters
            for kbits_iter in kbits_per_rate:
                kbits_per_rate_normalized += kbits_iter
            #
            kbits_per_rate_normalized = kbits_per_rate_normalized / num_iterations
            print("\n mean kbits per rate: {}".format(
                kbits_per_rate_normalized))

            # future x axis (rates)
            x.append(rate)

            # future y axis (throughput)
            y.append(kbits_per_rate_normalized)

        # we are with this protocol finished add to total results
        total_results[protocol] = (x, y)
        print(total_results)

        print("\nsleeping")
        sleep(5)
        print("\n next protocol")

    plot_data(total_results)
コード例 #5
0
def run_test(ctx):
    print('running test: {}'.format(os.path.basename(__file__)[:-3]))
    remoteHosts = ['beta', 'gamma']
    srv_params = {}
    clt_params = {}

    supported_protocols = [
        "tcp-throughput", "tcp-tls-throughput", "quic-throughput"
    ]

    print("rate: ", analyzing_rates)
    num_iterations = 10

    iterations = list(range(num_iterations))

    for host in remoteHosts:
        avail = shared.host_alive(ctx, host)

        if not avail:
            raise Exception("Host {} not available".format(host))

    beta_iface_to_alpha = ctx.config['beta']['netem-interfaces-to-alpha']
    beta_iface_to_gamma = ctx.config['beta']['netem-interfaces-to-gamma']
    interfaces = [beta_iface_to_alpha, beta_iface_to_gamma]

    srv_params['-uc-listen-addr'] = '192.186.23.3'
    srv_params['-port'] = '64321'

    clt_params['-control-addr'] = '192.186.23.3'
    clt_params['-control-protocol'] = 'tcp'
    clt_params['-streams'] = '1'
    clt_params['-addr'] = '192.186.25.2'
    clt_params['-deadline'] = '60'
    #clt_params['-buffer-length'] = '1400'
    clt_params['-buffer-length'] = '1400'
    clt_params['-update-interval'] = '1'

    total_goodput_rate_avg = {}
    total_goodput_rate_max = {}
    total_goodput_rate_min = {}
    total_results_debug = {}

    for protocol in supported_protocols:
        print("\n-------- analyzing: {} --------".format(protocol))

        x = []
        # goodput_rate_avg
        goodput_rate_avg = []

        # goodput_rate_max
        goodput_rate_max = []

        # goodput_rate_min
        goodput_rate_min = []

        kbits_normalized = []

        for rate in analyzing_rates:
            print("\n------ configuring rate to: {} --------".format(rate))

            clt_bytes = int(shared.calc_clt_bytes(rate))
            clt_params['-bytes'] = str(clt_bytes)

            kbits_per_rate = []
            kbits_min = 0
            kbits_max = 0
            kbits_min_rate = 0
            kbits_max_rate = 0

            for iteration in iterations:
                print("\n -------- {}. iteration -------".format(iteration))

                # ensures we dont get stuck in a popen.wait(deadline) deadlock
                timeout_ctr = 0
                timeout_ctr_limit = 10

                shared.netem_reset(ctx, 'beta', interfaces=interfaces)
                shared.netem_configure(
                    ctx,
                    'beta',
                    interfaces=interfaces,
                    netem_params={'rate': '{}kbit'.format(rate)})

                # ensure server is running "fresh" per iter => no saved crypto cookies
                # note: using this we cant get "ssh" debug data
                # due to background cmd
                # we could implement a logging routine in mapago writing to a log file on srv...
                shared.mapago_reset(ctx, 'gamma')
                shared.prepare_server(ctx, srv_params)

                # ensures client mapago creation does not happen before server is ready
                sleep(5)

                clt_params['-module'] = '{}'.format(protocol)
                print("\n starting module: {}".format(clt_params['-module']))

                msmt_results = []

                while len(
                        msmt_results) < 1 and timeout_ctr < timeout_ctr_limit:
                    print("\nIssueing prepare_client!\n")
                    msmt_results = shared.prepare_client(ctx, clt_params)

                    if len(msmt_results) < 1:
                        print(
                            "\n!!!!!!Error!!!!!! Client NOT terminated! reissue until client terminates!"
                        )
                        timeout_ctr += 1

                # debug print("Debug output: Throughput_critical / msmt_results {}".format(msmt_results))
                if timeout_ctr >= timeout_ctr_limit:
                    print("\nTimeout ctr limit reached! Iteration failed")
                    kbits_iter = 0
                else:
                    kbits_iter = analyze_data(msmt_results, protocol,
                                              clt_bytes)

                # 1. used to calculate AVG
                kbits_per_rate.append(kbits_iter)

                # 2. MAX: evaluate if current kbits_iter > max value until now
                if kbits_max == 0 and kbits_max_rate == 0:
                    kbits_max = kbits_iter
                    kbits_max_rate = rate

                if kbits_iter > kbits_max:
                    kbits_max = kbits_iter
                    kbits_max_rate = rate

                # 3. MIN: evaluate if current kbits_iter < min value until now
                if kbits_min == 0 and kbits_min_rate == 0:
                    kbits_min = kbits_iter
                    kbits_min_rate = rate

                if kbits_iter < kbits_min:
                    kbits_min = kbits_iter
                    kbits_min_rate = rate

            kbits_per_rate_normalized = 0

            # 4. Calculate AVG
            for kbits_iter in kbits_per_rate:
                kbits_per_rate_normalized += kbits_iter
            #
            kbits_per_rate_normalized = kbits_per_rate_normalized / num_iterations
            print(
                "\n mean kbits per rate: {}".format(kbits_per_rate_normalized))

            goodput_rate_quotient_avg = float(kbits_per_rate_normalized / rate)

            # future x axis (rates)
            x.append(rate)

            # future goodput_rate_avg axis (throughput)
            goodput_rate_avg.append(goodput_rate_quotient_avg)

            # 5. Calculate / add MAX
            goodput_rate_quotient_max = kbits_max / kbits_max_rate
            goodput_rate_max.append(goodput_rate_quotient_max)

            # 6. Calculate / add MIN
            goodput_rate_quotient_min = kbits_min / kbits_min_rate
            goodput_rate_min.append(goodput_rate_quotient_min)

            # debug stuff
            kbits_normalized.append(kbits_per_rate_normalized)

        # we are with this protocol finished add to total results
        total_goodput_rate_avg[protocol] = (x, goodput_rate_avg)
        total_results_debug[protocol] = (x, kbits_normalized)

        total_goodput_rate_max[protocol] = (x, goodput_rate_max)
        total_goodput_rate_min[protocol] = (x, goodput_rate_min)

        print("goodput quotient avg for protocol: ", goodput_rate_avg)
        print("goodput quotient max for protocol: ", goodput_rate_max)
        print("goodput quotient min for protocol: ", goodput_rate_min)
        print("\ntotal_results_debug: ", total_results_debug)

        print("\nsleeping")
        sleep(5)
        print("\n next protocol")

    # plot_data(goodput_rate_avg, goodput_rate_max, goodput_rate_min)
    shared.save_raw_data(
        os.path.basename(__file__)[:-3], total_goodput_rate_avg)
    shared.save_raw_data(
        os.path.basename(__file__)[:-3], total_goodput_rate_max)
    shared.save_raw_data(
        os.path.basename(__file__)[:-3], total_goodput_rate_min)
    '''
    QUIC thesis results:
    - These results were obtained in the context of the measurement
    - Used this line for verifying the result

    total_goodput_rate_avg = {"tcp-tls-throughput": [[2, 5, 10, 15, 20, 25, 30], [0.7186825957845191, 0.8932157611588828, 0.6142883147484908, 0.8045267518836788, 0.8655885974573809, 0.8394469967342978, 0.8797297303945656]], "quic-throughput": [[2, 5, 10, 15, 20, 25, 30], [0.0, 0.0, 0.0, 0.522877412171877, 0.25292588532657634, 0.7711127312597503, 0.823867531780582]], "tcp-throughput": [[2, 5, 10, 15, 20, 25, 30], [0.7672585409263191, 0.8088174144187545, 0.748441507650644, 0.8224449735488463, 0.9519106591951555, 0.9216265351742691, 0.9262570230098345]]}
    total_goodput_rate_max = {"tcp-tls-throughput": [[2, 5, 10, 15, 20, 25, 30], [0.917836572986393, 0.8991376812040397, 0.9167717297982965, 0.924438219306823, 0.9323932711275507, 0.9333336288889825, 0.9340772168608876]], "quic-throughput": [[2, 5, 10, 15, 20, 25, 30], [0.0, 0.0, 0.0, 0.8750718105804558, 0.8792202503326887, 0.8877729019845608, 0.8906314304881492]], "tcp-throughput": [[2, 5, 10, 15, 20, 25, 30], [0.7958230997232995, 0.906555460371729, 0.9385343229585598, 0.9447708712159038, 0.9530005242779224, 0.9537388786595662, 0.9540895190165545]]}
    total_goodput_rate_min = {"tcp-tls-throughput": [[2, 5, 10, 15, 20, 25, 30], [0.0, 0.8904898978492799, 0.0, 0.0, 0.7120009088183029, 0.0, 0.7214568248833293]], "quic-throughput": [[2, 5, 10, 15, 20, 25, 30], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.78]], "tcp-throughput": [[2, 5, 10, 15, 20, 25, 30], [0.6964525103179906, 0.0, 0.0, 0.0, 0.9500101358447484, 0.6399255784835811, 0.6825403574382192]]}
    '''
    plot_data(total_goodput_rate_avg, total_goodput_rate_max,
              total_goodput_rate_min)
def run_test(ctx):

    print('running test: {}'.format(os.path.basename(__file__)[:-3]))
    remoteHosts = ['beta', 'gamma']
    srv_params = {}
    clt_params = {}

    supported_protocols = [
        "quic-throughput", "tcp-tls-throughput", "tcp-throughput"
    ]

    num_iterations = 10
    timeout_ctr_limit = 1

    sim_dur = shared.calc_simulation_time(supported_protocols, num_iterations,
                                          timeout_ctr_limit, analyzing_rates,
                                          analyzing_mean_loss_bursts)
    print("simulation duration for single per is: {}".format(sim_dur))
    print("simulation duration for {} pers is: {}".format(
        len(analyzing_mean_pers), 4 * sim_dur[0]))

    iterations = list(range(num_iterations))

    for host in remoteHosts:
        avail = shared.host_alive(ctx, host)

        if not avail:
            raise Exception("Host {} not available".format(host))

    beta_iface_to_alpha = ctx.config['beta']['netem-interfaces-to-alpha']
    beta_iface_to_gamma = ctx.config['beta']['netem-interfaces-to-gamma']
    interfaces = [beta_iface_to_alpha, beta_iface_to_gamma]

    srv_params['-uc-listen-addr'] = '192.186.23.3'
    srv_params['-port'] = '64321'

    clt_params['-control-addr'] = '192.186.23.3'
    clt_params['-control-protocol'] = 'tcp'
    clt_params['-streams'] = '1'
    clt_params['-addr'] = '192.186.25.2'
    #clt_params['-deadline'] = '60'
    clt_params['-deadline'] = '90'

    clt_params['-buffer-length'] = '1400'
    clt_params['-update-interval'] = '1'

    # goodput_rate_avg for all protocols
    total_goodput_rate_avg = {}
    total_results_debug = {}
    total_goodput_rate_avg_over_mean_per = {}

    # to do add a variable to saved results per mean_per_rate

    # ok here must go 0. mean_per_rate
    for mean_per in analyzing_mean_pers:
        print("\n-------- analyzing mean_per: {} --------".format(mean_per))

        #total_goodput_rate_avg_over_mean_per = {}
        # that is {"quic" : []} ....{"quic" : [], "tcp" : []} .... {"quic" : [], "tcp" : [], "tls" : []}
        total_goodput_rate_avg = {}

        # 1. iterate over protocols
        for protocol in supported_protocols:
            print("\n-------- analyzing: {} --------".format(protocol))

            visited_rate = []
            visited_loss = []
            quotients_all_rates_over_losses = []
            kbits_normalized = []

            # 2. iterate over rate
            for rate in analyzing_rates:
                print("\n------ configuring rate to: {} --------".format(rate))

                # 3. determine bytes for transmission regarding rate
                clt_bytes = int(shared.calc_clt_bytes(rate))
                clt_params['-bytes'] = str(clt_bytes)

                quotients_single_rate_over_losses = []
                analyzed_loss_per_rate = []

                # 4. deepest for-loop: iterate over mean_loss_burst
                for mean_loss_burst in analyzing_mean_loss_bursts:
                    print(
                        "\n------ configuring mean_loss_burst to: {} --------".
                        format(mean_loss_burst))

                    # holds results of ALL iters per single mean_loss_burst and rate tuple
                    kbits_per_loss = []

                    r = 1 / mean_loss_burst

                    # p is related to r an mean_per
                    p_mean_per = mean_per / 100
                    print("configuring p_mean_per to: {}".format(p_mean_per))

                    p = (r * p_mean_per) / (1 - p_mean_per)

                    print("configuring p to: {}".format(p))
                    print("configuring r to: {}".format(r))

                    good_state_holding_time = 1 / p
                    print(
                        "handling on average {} packets in good before going to bad"
                        .format(good_state_holding_time))
                    print(
                        "handling on average {} packets in bad before going to good"
                        .format(mean_loss_burst))

                    for iteration in iterations:
                        print("\n -------- {}. iteration -------".format(
                            iteration))

                        # ensures we dont get stuck in a popen.wait(deadline) deadlock
                        timeout_ctr = 0

                        # reset queue at netem middlebox
                        shared.netem_reset(ctx, 'beta', interfaces=interfaces)

                        # 5. we know everything: so configure!
                        shared.netem_configure(ctx,
                                               'beta',
                                               interfaces=interfaces,
                                               netem_params={
                                                   'rate':
                                                   '{}kbit'.format(rate),
                                                   'simpleGilbertLoss':
                                                   '{}% {}%'.format(
                                                       p * 100, r * 100)
                                               })

                        # ensure server is running "fresh" per iter => no saved crypto cookies
                        # note: using this we cant get "ssh" debug data
                        # due to background cmd
                        # we could implement a logging routine in mapago writing to a log file on srv...
                        shared.mapago_reset(ctx, 'gamma')
                        shared.prepare_server(ctx, srv_params)

                        # ensures client mapago creation does not happen before server is ready
                        sleep(5)

                        clt_params['-module'] = '{}'.format(protocol)
                        print("\n starting module: {}".format(
                            clt_params['-module']))

                        msmt_results = []

                        while len(msmt_results
                                  ) < 1 and timeout_ctr < timeout_ctr_limit:
                            print("\nIssueing prepare_client!\n")
                            msmt_results = shared.prepare_client(
                                ctx, clt_params)

                            if len(msmt_results) < 1:
                                print(
                                    "\n!!!!!!Error!!!!!! Client NOT terminated! reissue until client terminates!"
                                )
                                timeout_ctr += 1

                        if timeout_ctr >= timeout_ctr_limit:
                            print(
                                "\nTimeout ctr limit reached! Iteration failed"
                            )
                            kbits_iter = 0
                        else:
                            kbits_iter = analyze_data(msmt_results, protocol,
                                                      clt_bytes)

                        # kbits results of each iteration
                        kbits_per_loss.append(kbits_iter)

                    kbits_per_loss_normalized = 0

                    # account all iters
                    for kbits_iter in kbits_per_loss:
                        kbits_per_loss_normalized += kbits_iter

                    kbits_per_loss_normalized = kbits_per_loss_normalized / num_iterations
                    print("\n mean kbits per mean_loss_burst: {}".format(
                        kbits_per_loss_normalized))

                    # 6. calculate for single mean_loss_burst and rate tuple our goodput_rate_quotient
                    # i.e. rate  = 5, mean_loss_burst = 2; rate = 5, mean_loss_burst = 5; rate = 5, mean_loss_burst = 10
                    # "red"
                    goodput_rate_quotient_avg = kbits_per_loss_normalized / rate

                    # 7. add to list of quietnts for single rate iver losses
                    # for rate = 10 this holds the quotient values obtained for mean_loss_burst = [0,2,5,10 etc.]
                    quotients_single_rate_over_losses.append(
                        goodput_rate_quotient_avg)

                    # 7.5 add los to list
                    analyzed_loss_per_rate.append(mean_loss_burst)

                # 8. ok: we got all quoient for a given SINGLE rate and all LOSSES
                # add it to the list: where we store all RATES and the corresponding list
                # for the SINGLE rate and all LOSSES
                quotients_all_rates_over_losses.append(
                    quotients_single_rate_over_losses)
                visited_rate.append(rate)
                visited_loss.append(analyzed_loss_per_rate)

            # 9. we got the list of lists for a single protocol complete: add it
            total_goodput_rate_avg[protocol] = (
                visited_rate, visited_loss, quotients_all_rates_over_losses)

            # save current version of total_goodput_rate_avg
            # that is {"quic" : []} ....{"quic" : [], "tcp" : []} .... {"quic" : [], "tcp" : [], "tls" : []}
            interim_msmt_result = os.path.basename(__file__)[:-3] + "Interim"
            shared.save_raw_data(interim_msmt_result, total_goodput_rate_avg)

            print("\n visited_rate: ", visited_rate)
            print("\n visited_loss: ", visited_loss)
            print("\n total_goodput_rate_avg: ", total_goodput_rate_avg)

            print("\nsleeping")
            sleep(5)
            print("\n next protocol")

        total_goodput_rate_avg_over_mean_per[mean_per] = total_goodput_rate_avg
        shared.save_raw_data(
            os.path.basename(__file__)[:-3],
            total_goodput_rate_avg_over_mean_per)
    '''
    QUIC thesis results:
    - These results were obtained in the context of the measurement
    - Used this line for verifying the result

    # mean-PER = 10%
    total_goodput_rate_avg_over_mean_per = {"10": {"tcp-tls-throughput": [[500, 250, 50, 5], [[2, 4, 8, 16], [2, 4, 8, 16], [2, 4, 8, 16], [2, 4, 8, 16]], [[0.0, 0.0, 0.0, 0.0], [0.1796758624402684, 0.09681631223578252, 0.0, 0.22547596905631857], [0.8538951302118121, 0.3725531491798668, 0.44610610364628095, 0.30402388355520105], [0.4337156612991152, 0.11559839449667024, 0.1543480211862107, 0.15041069037363763]]], "tcp-throughput": [[500, 250, 50, 5], [[2, 4, 8, 16], [2, 4, 8, 16], [2, 4, 8, 16], [2, 4, 8, 16]], [[0.0, 0.0, 0.0, 0.0], [0.18610042911192348, 0.0, 0.0, 0.13809595676961314], [0.7979374626906224, 0.6951387544139145, 0.7686291354056989, 0.1446643184561609], [0.45938173370385604, 0.4278040667088546, 0.5455886715930053, 0.3027597371671452]]], "quic-throughput": [[500, 250, 50, 5], [[2, 4, 8, 16], [2, 4, 8, 16], [2, 4, 8, 16], [2, 4, 8, 16]], [[0.7386721300700039, 0.6911498543832674, 0.3453532850225947, 0.0], [0.8794329718993402, 0.6977864005464235, 0.5757086137437306, 0.594549969721013], [0.898514861402809, 0.7420622226960838, 0.7350185376835979, 0.7517594174868713], [0.0, 0.0, 0.0, 0.0]]]}} 
    
    # mean-PER = 20%
    total_goodput_rate_avg_over_mean_per = {"20": {"tcp-tls-throughput": [[500, 250, 50, 5], [[2, 4, 8, 16], [2, 4, 8, 16], [2, 4, 8, 16], [2, 4, 8, 16]], [[0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [0.13424765923599835, 0.0, 0.2654570601010148, 0.15136688707590124]]], "tcp-throughput": [[500, 250, 50, 5], [[2, 4, 8, 16], [2, 4, 8, 16], [2, 4, 8, 16], [2, 4, 8, 16]], [[0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [0.08773547601322287, 0.09807980582160043, 0.0, 0.0], [0.2586507599749574, 0.26229089447621, 0.0, 0.31272853696807]]], "quic-throughput": [[500, 250, 50, 5], [[2, 4, 8, 16], [2, 4, 8, 16], [2, 4, 8, 16], [2, 4, 8, 16]], [[0.6552915924410667, 0.0, 0.0, 0.0], [0.5323270522190142, 0.0, 0.0, 0.0], [0.85228504351984, 0.5954838024532209, 0.6005059897673689, 0.30105901991509665], [0.0, 0.0, 0.0, 0.0]]]}}
    '''

    plot_data(total_goodput_rate_avg_over_mean_per)