%description:
Testing Ethernet communication from a source host to a sink host on full duplex gigabit ethernet connection.
The hosts have same ethernet configurations in pairs.

variations:
 - queue: internal / external
 - implementation: EtherMAC / EtherMACFullDuplex

compare results of variations and checks:
 - the number of sent packets are equals (one packet different is acceptable, because the first event of endtime is processed.)
 - the idle state of rx is smaller or equals than 2% in all sink hosts
 - the utilization state of rx is more tan or equals to 98% in all sink hosts

%#--------------------------------------------------------------------------------------------------------------
%testprog: opp_run

%#--------------------------------------------------------------------------------------------------------------
%file: test.ned

import ned.DatarateChannel;
import inet.node.ethernet.EtherHost;

network CompareMACs
{
    types:
        channel C extends DatarateChannel
        {
            delay = 0s;
            datarate = 1000Mbps;
        }

    submodules:
        host_iq_1_F_A: EtherHost {
            parameters:
                @display("p=70,70");
        }
        host_iq_1_F_B: EtherHost {
            parameters:
                @display("p=210,70");
        }
        host_eq_1_F_A: EtherHost {
            parameters:
                queueType = "DropTailQueue";
                @display("p=70,140");
        }
        host_eq_1_F_B: EtherHost {
            parameters:
                queueType = "DropTailQueue";
                @display("p=210,140");
        }
        host_iq_2_F_A: EtherHost {
            parameters:
                macType = "EtherMACFullDuplex";
                @display("p=70,210");
        }
        host_iq_2_F_B: EtherHost {
            parameters:
                macType = "EtherMACFullDuplex";
                @display("p=210,210");
        }
        host_eq_2_F_A: EtherHost {
            parameters:
                queueType = "DropTailQueue";
                macType = "EtherMACFullDuplex";
                @display("p=70,280");
        }
        host_eq_2_F_B: EtherHost {
            parameters:
                queueType = "DropTailQueue";
                macType = "EtherMACFullDuplex";
                @display("p=210,280");
        }

    connections:
        host_iq_1_F_A.ethg <--> C <--> host_iq_1_F_B.ethg;
        host_eq_1_F_A.ethg <--> C <--> host_eq_1_F_B.ethg;
        host_iq_2_F_A.ethg <--> C <--> host_iq_2_F_B.ethg;
        host_eq_2_F_A.ethg <--> C <--> host_eq_2_F_B.ethg;
}

%#--------------------------------------------------------------------------------------------------------------
%inifile: omnetpp.ini

[General]
sim-time-limit = 1s

tkenv-plugin-path = ../../../etc/plugins
#record-eventlog = true
**.vector-recording = false

network = CompareMACs


*.host_iq_1_F_A.cli.destAddress = "host_iq_1_F_B"
*.host_iq_1_F_B.cli.destAddress = "host_iq_1_F_A"

*.host_eq_1_F_A.cli.destAddress = "host_eq_1_F_B"
*.host_eq_1_F_B.cli.destAddress = "host_eq_1_F_A"

*.host_iq_2_F_A.cli.destAddress = "host_iq_2_F_B"
*.host_iq_2_F_B.cli.destAddress = "host_iq_2_F_A"

*.host_eq_2_F_A.cli.destAddress = "host_eq_2_F_B"
*.host_eq_2_F_B.cli.destAddress = "host_eq_2_F_A"

**.cli.reqLength = 1250B       # 10.000 bit
**.cli.respLength = 0B      # no response

*.host_*_A.cli.startTime = 0s
*.host_*_B.cli.startTime = 10000s # out of simulation time

*.host_*_F_*.mac.duplexMode = true

*.host_*_F_*.cli.sendInterval = 0.009ms       # 1000Mbps 10.000 / speed [ / 2 when halfduplex]

**.mac.address = "auto"
*.host_iq_*.mac.txQueueLimit = 100000
*.host_eq_*.queue.dataQueue.frameCapacity = 100

%#--------------------------------------------------------------------------------------------------------------
%postrun-command: Rscript check.r
%#--------------------------------------------------------------------------------------------------------------
%file: check.r
#!/usr/bin/env Rscript

options(echo=FALSE)
options(width=160)
library("omnetpp", warn.conflicts=FALSE)

#TEST parameters
scafile <- 'results/General-#0.sca'
linecount <- 4
idlelimit <- 2.0
usedlimit <- 98.0

# begin TEST:

dataset <- loadDataset(scafile)

cat("\nOMNETPP TEST RESULT:\n")

cat("\nCHECK SENT PACKETS:\n")

x <- dataset$scalars[dataset$scalars$name == "sentPk:count",]
xx <- x[grep("_F_A.cli$",x$module)==1,]

if(length(xx$value) != linecount)
{
    cat("LINECOUNT INCORRECT\n")
    print(xx)
} else {
    cat("LINECOUNT CORRECT\n")

#   one packet different is acceptable, because the first event of endtime is processed.
    if( 1 >= (max(xx$value) - min(xx$value)))
    {
        cat("NUMBER OF SENT PACKETS ARE EQUALS\n")
    } else {
        cat("NUMBER OF SENT PACKETS ARE DIFFERS\n")
        print(xx)
    }
}

x <- dataset$scalars[grep("_F_B.mac$",dataset$scalars$module),]

cat("\nCHECK RX CHANNEL IDLE RATES:\n")

xx <- x[x$name == "rx channel idle (%)",]

if(length(xx$value) != linecount)
{
    cat("LINECOUNT INCORRECT\n")
    print(xx)
} else {
    cat("LINECOUNT CORRECT\n")
    if(max(xx$value) <= idlelimit)
    {
        cat("IDLE OK\n")
    } else {
        cat("IDLE BAD:\n")
        print(xx[xx$value > idlelimit,])
    }
}

cat("\nCHECK RX CHANNEL UTILIZATION RATES:\n")

xx <- x[x$name == "rx channel utilization (%)",]

if(length(xx$value) != linecount)
{
    cat("LINECOUNT INCORRECT\n")
    print(xx)
} else {
    cat("LINECOUNT CORRECT\n")
    if(min(xx$value) >= usedlimit)
    {
        cat("USED OK\n")
    } else {
        cat("USED BAD:\n")
        print(xx[xx$value < usedlimit,])
    }
}

cat("\n")

%#--------------------------------------------------------------------------------------------------------------
%contains: postrun-command(1).out

OMNETPP TEST RESULT:

CHECK SENT PACKETS:
LINECOUNT CORRECT
NUMBER OF SENT PACKETS ARE EQUALS

CHECK RX CHANNEL IDLE RATES:
LINECOUNT CORRECT
IDLE OK

CHECK RX CHANNEL UTILIZATION RATES:
LINECOUNT CORRECT
USED OK

%#--------------------------------------------------------------------------------------------------------------
