From: Ondrej Lichtner <olichtne(a)redhat.com>
This commit catches up to the current state of solved bugs on github.
Some closed bugs were skipped since no easy regression test can be
written.
The desc files always contain the link to the corresponding github
issue.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
regression-tests/tests/16/desc | 3 +
regression-tests/tests/16/recipe.xml | 37 +++
regression-tests/tests/16/run.sh | 14 +
regression-tests/tests/17/desc | 3 +
regression-tests/tests/17/recipe.xml | 38 +++
regression-tests/tests/17/run.sh | 14 +
regression-tests/tests/18/desc | 6 +
regression-tests/tests/18/recipe.xml | 26 ++
regression-tests/tests/18/run.sh | 19 ++
regression-tests/tests/19/desc | 3 +
regression-tests/tests/19/recipe.xml | 17 ++
regression-tests/tests/19/run.sh | 19 ++
regression-tests/tests/20/desc | 3 +
regression-tests/tests/20/recipe1.xml | 47 +++
regression-tests/tests/20/recipe2.xml | 31 ++
regression-tests/tests/20/run.sh | 20 ++
regression-tests/tests/21/desc | 3 +
regression-tests/tests/21/lnst-ctl.conf | 3 +
regression-tests/tests/21/recipe.xml | 55 ++++
regression-tests/tests/21/run.sh | 18 ++
.../tests/21/test_modules/TCPConnection.py | 60 ++++
.../tests/21/test_tools/tcp_conn/Makefile | 12 +
.../tests/21/test_tools/tcp_conn/lnst-setup.sh | 3 +
.../tests/21/test_tools/tcp_conn/tcp_connect.c | 281 ++++++++++++++++++
.../tests/21/test_tools/tcp_conn/tcp_listen.c | 330 +++++++++++++++++++++
regression-tests/tests/22/desc | 3 +
regression-tests/tests/22/lnst-ctl.conf | 2 +
regression-tests/tests/22/pool/slave1.xml | 6 +
regression-tests/tests/22/pool/slave2.xml | 6 +
regression-tests/tests/22/recipe.xml | 26 ++
regression-tests/tests/22/run.sh | 18 ++
regression-tests/tests/23/desc | 3 +
regression-tests/tests/23/lnst-ctl.conf | 2 +
regression-tests/tests/23/recipe.xml | 42 +++
regression-tests/tests/23/run.sh | 19 ++
regression-tests/tests/23/test_modules/IcmpPing.py | 71 +++++
regression-tests/tests/24/desc | 6 +
regression-tests/tests/24/recipe_fail.xml | 33 +++
regression-tests/tests/24/recipe_pass.xml | 33 +++
regression-tests/tests/24/run.sh | 22 ++
40 files changed, 1357 insertions(+)
create mode 100644 regression-tests/tests/16/desc
create mode 100644 regression-tests/tests/16/recipe.xml
create mode 100755 regression-tests/tests/16/run.sh
create mode 100644 regression-tests/tests/17/desc
create mode 100644 regression-tests/tests/17/recipe.xml
create mode 100755 regression-tests/tests/17/run.sh
create mode 100644 regression-tests/tests/18/desc
create mode 100644 regression-tests/tests/18/recipe.xml
create mode 100755 regression-tests/tests/18/run.sh
create mode 100644 regression-tests/tests/19/desc
create mode 100644 regression-tests/tests/19/recipe.xml
create mode 100755 regression-tests/tests/19/run.sh
create mode 100644 regression-tests/tests/20/desc
create mode 100644 regression-tests/tests/20/recipe1.xml
create mode 100644 regression-tests/tests/20/recipe2.xml
create mode 100755 regression-tests/tests/20/run.sh
create mode 100644 regression-tests/tests/21/desc
create mode 100644 regression-tests/tests/21/lnst-ctl.conf
create mode 100644 regression-tests/tests/21/recipe.xml
create mode 100755 regression-tests/tests/21/run.sh
create mode 100644 regression-tests/tests/21/test_modules/TCPConnection.py
create mode 100644 regression-tests/tests/21/test_tools/tcp_conn/Makefile
create mode 100755 regression-tests/tests/21/test_tools/tcp_conn/lnst-setup.sh
create mode 100644 regression-tests/tests/21/test_tools/tcp_conn/tcp_connect.c
create mode 100644 regression-tests/tests/21/test_tools/tcp_conn/tcp_listen.c
create mode 100644 regression-tests/tests/22/desc
create mode 100644 regression-tests/tests/22/lnst-ctl.conf
create mode 100644 regression-tests/tests/22/pool/slave1.xml
create mode 100644 regression-tests/tests/22/pool/slave2.xml
create mode 100644 regression-tests/tests/22/recipe.xml
create mode 100755 regression-tests/tests/22/run.sh
create mode 100644 regression-tests/tests/23/desc
create mode 100644 regression-tests/tests/23/lnst-ctl.conf
create mode 100644 regression-tests/tests/23/recipe.xml
create mode 100755 regression-tests/tests/23/run.sh
create mode 100644 regression-tests/tests/23/test_modules/IcmpPing.py
create mode 100644 regression-tests/tests/24/desc
create mode 100644 regression-tests/tests/24/recipe_fail.xml
create mode 100644 regression-tests/tests/24/recipe_pass.xml
create mode 100755 regression-tests/tests/24/run.sh
diff --git a/regression-tests/tests/16/desc b/regression-tests/tests/16/desc
new file mode 100644
index 0000000..a063e3a
--- /dev/null
+++ b/regression-tests/tests/16/desc
@@ -0,0 +1,3 @@
+address tag should accept value in the tag contents or the 'value' attribute
+
+https://github.com/jpirko/lnst/issues/31
diff --git a/regression-tests/tests/16/recipe.xml b/regression-tests/tests/16/recipe.xml
new file mode 100644
index 0000000..3d8887e
--- /dev/null
+++ b/regression-tests/tests/16/recipe.xml
@@ -0,0 +1,37 @@
+<lnstrecipe>
+ <network>
+ <host id="slave1">
+ <interfaces>
+ <eth id="testifc1" label="A">
+ <addresses>
+ <address>fd00::1/64</address>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+
+ <host id="slave2">
+ <interfaces>
+ <eth id="testifc3" label="A">
+ <addresses>
+ <address value="fd00::2/64"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+
+ </network>
+
+ <task>
+ <ctl_wait seconds="5"/>
+ <config host="slave1"
option="/proc/sys/net/ipv4/igmp_max_memberships" value="5"/>
+ <run host="slave1" module="Icmp6Ping">
+ <options>
+ <option name="addr"
value="{ip(slave2,testifc3)}"/>
+ <option name="count" value="20"/>
+ <option name="interval" value="0"/>
+ </options>
+ </run>
+ </task>
+
+</lnstrecipe>
diff --git a/regression-tests/tests/16/run.sh b/regression-tests/tests/16/run.sh
new file mode 100755
index 0000000..6b80eb5
--- /dev/null
+++ b/regression-tests/tests/16/run.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+. ../lib.sh
+
+init_test
+
+lnst-ctl -d run recipe.xml
+rv=$?
+
+print_separator
+
+assert_status "pass" "$rv"
+
+end_test
diff --git a/regression-tests/tests/17/desc b/regression-tests/tests/17/desc
new file mode 100644
index 0000000..af02d5b
--- /dev/null
+++ b/regression-tests/tests/17/desc
@@ -0,0 +1,3 @@
+Unknown options to a test module result in a stack trace
+
+https://github.com/jpirko/lnst/issues/38
diff --git a/regression-tests/tests/17/recipe.xml b/regression-tests/tests/17/recipe.xml
new file mode 100644
index 0000000..56f9216
--- /dev/null
+++ b/regression-tests/tests/17/recipe.xml
@@ -0,0 +1,38 @@
+<lnstrecipe>
+ <network>
+ <host id="slave1">
+ <interfaces>
+ <eth id="testiface" label="A">
+ <addresses>
+ <address value="fd00::1/64"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+
+ <host id="slave2">
+ <interfaces>
+ <eth id="testiface" label="A">
+ <addresses>
+ <address value="fd00::2/64"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+
+ </network>
+
+ <task>
+ <ctl_wait seconds="5"/>
+ <run module="Icmp6Ping" host="slave1"
timeout="30">
+ <options>
+ <option name="addre"
value="{ip(slave2,testiface)}"/> <!-- this is wrong -->
+ <option name="addr"
value="{ip(slave2,testiface)}"/> <!-- this is correct -->
+ <option name="count" value="10"/>
+ <option name="interval" value="0.0"/>
+ <option name="limit_rate" value="95"/>
+ </options>
+ </run>
+ </task>
+
+</lnstrecipe>
diff --git a/regression-tests/tests/17/run.sh b/regression-tests/tests/17/run.sh
new file mode 100755
index 0000000..6b80eb5
--- /dev/null
+++ b/regression-tests/tests/17/run.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+. ../lib.sh
+
+init_test
+
+lnst-ctl -d run recipe.xml
+rv=$?
+
+print_separator
+
+assert_status "pass" "$rv"
+
+end_test
diff --git a/regression-tests/tests/18/desc b/regression-tests/tests/18/desc
new file mode 100644
index 0000000..bca06cc
--- /dev/null
+++ b/regression-tests/tests/18/desc
@@ -0,0 +1,6 @@
+Empty task results in uhandled exception
+
+Instead we should require at least one command or end with an error, but not a
+stack trace.
+
+https://github.com/jpirko/lnst/issues/53
diff --git a/regression-tests/tests/18/recipe.xml b/regression-tests/tests/18/recipe.xml
new file mode 100644
index 0000000..75db68c
--- /dev/null
+++ b/regression-tests/tests/18/recipe.xml
@@ -0,0 +1,26 @@
+<lnstrecipe>
+ <network>
+ <host id="slave1">
+ <interfaces>
+ <eth id="testiface" label="A">
+ <addresses>
+ <address value="fd00::1/64"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+
+ <host id="slave2">
+ <interfaces>
+ <eth id="testiface" label="A">
+ <addresses>
+ <address value="fd00::2/64"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+
+ </network>
+
+ <task/>
+</lnstrecipe>
diff --git a/regression-tests/tests/18/run.sh b/regression-tests/tests/18/run.sh
new file mode 100755
index 0000000..ba19649
--- /dev/null
+++ b/regression-tests/tests/18/run.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+. ../lib.sh
+
+init_test
+
+lnst-ctl -d run recipe.xml | tee test.log
+rv=${PIPESTATUS[0]}
+
+log=`cat test.log`
+
+rm -f test.log
+
+print_separator
+
+assert_status "error" "$rv"
+assert_log "ERROR" "Parser error:" "$log"
+
+end_test
diff --git a/regression-tests/tests/19/desc b/regression-tests/tests/19/desc
new file mode 100644
index 0000000..a704a88
--- /dev/null
+++ b/regression-tests/tests/19/desc
@@ -0,0 +1,3 @@
+undefined interface id in template function
+
+https://github.com/jpirko/lnst/issues/55
diff --git a/regression-tests/tests/19/recipe.xml b/regression-tests/tests/19/recipe.xml
new file mode 100644
index 0000000..4fa9892
--- /dev/null
+++ b/regression-tests/tests/19/recipe.xml
@@ -0,0 +1,17 @@
+<lnstrecipe>
+ <network>
+ <host id="tm1">
+ <interfaces>
+ <eth id="nic1" label="testnet">
+ <addresses>
+ <address value="192.168.131.201/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+
+ <task>
+ <run host="tm1" command="ethtool -i {ip(tm1,nic2)}"/>
+ </task>
+</lnstrecipe>
diff --git a/regression-tests/tests/19/run.sh b/regression-tests/tests/19/run.sh
new file mode 100755
index 0000000..001c35b
--- /dev/null
+++ b/regression-tests/tests/19/run.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+. ../lib.sh
+
+init_test
+
+lnst-ctl -d run recipe.xml | tee test.log
+rv=${PIPESTATUS[0]}
+
+log=`cat test.log`
+
+rm -f test.log
+
+print_separator
+
+assert_status "error" "$rv"
+assert_log "ERROR" "Second parameter of function ip() is invalid"
"$log"
+
+end_test
diff --git a/regression-tests/tests/20/desc b/regression-tests/tests/20/desc
new file mode 100644
index 0000000..c695ab0
--- /dev/null
+++ b/regression-tests/tests/20/desc
@@ -0,0 +1,3 @@
+recipe cannot be run after config_only run of recipe with team/bonding
+
+https://github.com/jpirko/lnst/issues/59
diff --git a/regression-tests/tests/20/recipe1.xml
b/regression-tests/tests/20/recipe1.xml
new file mode 100644
index 0000000..54346e9
--- /dev/null
+++ b/regression-tests/tests/20/recipe1.xml
@@ -0,0 +1,47 @@
+<lnstrecipe>
+ <network>
+ <host id="tm1">
+ <interfaces>
+ <eth id="nic1" label="testnet"/>
+ <bond id="bond">
+ <slaves>
+ <slave id="nic1"/>
+ </slaves>
+ <addresses>
+ <address value="192.168.131.201/24"/>
+ </addresses>
+ </bond>
+ </interfaces>
+ </host>
+ <host id="tm2">
+ <interfaces>
+ <eth id="nic1" label="testnet"/>
+ <team id="team">
+ <options>
+ <option name="teamd_config">
+ {
+ "runner": {"name":
"activebackup"},
+ "link_watch": {"name":
"ethtool"}
+ }
+ </option>
+ </options>
+ <slaves>
+ <slave id="nic1"/>
+ </slaves>
+ <addresses>
+ <address value="192.168.131.202/24"/>
+ </addresses>
+ </team>
+ </interfaces>
+ </host>
+ </network>
+
+ <task>
+ <run host="tm1" module="IcmpPing">
+ <options>
+ <option name="addr" value="{ip(tm2,team)}"/>
+ <option name="count" value="3"/>
+ </options>
+ </run>
+ </task>
+</lnstrecipe>
diff --git a/regression-tests/tests/20/recipe2.xml
b/regression-tests/tests/20/recipe2.xml
new file mode 100644
index 0000000..327c0f3
--- /dev/null
+++ b/regression-tests/tests/20/recipe2.xml
@@ -0,0 +1,31 @@
+<lnstrecipe>
+ <network>
+ <host id="tm1">
+ <interfaces>
+ <eth id="nic1" label="testnet">
+ <addresses>
+ <address value="192.168.131.201/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ <host id="tm2">
+ <interfaces>
+ <eth id="nic1" label="testnet">
+ <addresses>
+ <address value="192.168.131.202/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+
+ <task>
+ <run host="tm1" module="IcmpPing">
+ <options>
+ <option name="addr" value="{ip(tm2,nic1)}"/>
+ <option name="count" value="3"/>
+ </options>
+ </run>
+ </task>
+</lnstrecipe>
diff --git a/regression-tests/tests/20/run.sh b/regression-tests/tests/20/run.sh
new file mode 100755
index 0000000..ca50115
--- /dev/null
+++ b/regression-tests/tests/20/run.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+. ../lib.sh
+
+init_test
+
+lnst-ctl -d run recipe1.xml | tee test.log
+rv1=${PIPESTATUS[0]}
+
+lnst-ctl -d run recipe2.xml | tee test.log
+rv2=${PIPESTATUS[0]}
+
+
+print_separator
+assert_status "pass" "$rv1"
+assert_status "pass" "$rv2"
+
+rm -f test.log
+
+end_test
diff --git a/regression-tests/tests/21/desc b/regression-tests/tests/21/desc
new file mode 100644
index 0000000..e4f5cbc
--- /dev/null
+++ b/regression-tests/tests/21/desc
@@ -0,0 +1,3 @@
+broken tool-module dependency during synchronization
+
+https://github.com/jpirko/lnst/issues/71
diff --git a/regression-tests/tests/21/lnst-ctl.conf
b/regression-tests/tests/21/lnst-ctl.conf
new file mode 100644
index 0000000..9f43732
--- /dev/null
+++ b/regression-tests/tests/21/lnst-ctl.conf
@@ -0,0 +1,3 @@
+[environment]
+test_tool_dirs = ./test_tools
+test_module_dirs = ./test_modules
diff --git a/regression-tests/tests/21/recipe.xml b/regression-tests/tests/21/recipe.xml
new file mode 100644
index 0000000..ee61de1
--- /dev/null
+++ b/regression-tests/tests/21/recipe.xml
@@ -0,0 +1,55 @@
+<lnstrecipe>
+ <network>
+ <host id="tm1">
+ <interfaces>
+ <eth id="nic1" label="testnet">
+ <addresses>
+ <address value="192.168.131.201/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ <host id="tm2">
+ <interfaces>
+ <eth id="nic1" label="testnet">
+ <addresses>
+ <address value="192.168.131.202/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+
+ <task>
+ <define>
+ <alias name="my_range" value="10000-10050" />
+ </define>
+
+ <define>
+ <alias name="debug" value="no"/>
+ </define>
+
+ <run module="TCPConnection" host="tm2"
bg_id="server">
+ <options>
+ <option name="mode" value="server"/>
+ <option name="address"
value="{ip(tm2,nic1)}"/>
+ <option name="portrange" value="{$my_range}"/>
+ <option name="continuous" value="yes"/>
+ <option name="debug" value="{$debug}"/>
+ </options>
+ </run>
+ <ctl_wait seconds="3"/>
+ <run module="TCPConnection" host="tm1"
bg_id="client">
+ <options>
+ <option name="mode" value="client"/>
+ <option name="address"
value="{ip(tm2,nic1)}"/>
+ <option name="portrange" value="{$my_range}"/>
+ <option name="continuous" value="yes"/>
+ <option name="debug" value="{$debug}"/>
+ </options>
+ </run>
+ <ctl_wait seconds="15"/>
+ <intr host="tm1" bg_id="client"/>
+ <intr host="tm2" bg_id="server"/>
+ </task>
+</lnstrecipe>
diff --git a/regression-tests/tests/21/run.sh b/regression-tests/tests/21/run.sh
new file mode 100755
index 0000000..07bd6c0
--- /dev/null
+++ b/regression-tests/tests/21/run.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+. ../lib.sh
+
+init_test
+
+touch test_tools/*
+touch test_modules/*
+
+lnst-ctl -c lnst-ctl.conf -d -r run recipe.xml | tee test.log
+rv=${PIPESTATUS[0]}
+
+print_separator
+assert_status "pass" "$rv"
+
+rm -f test.log
+
+end_test
diff --git a/regression-tests/tests/21/test_modules/TCPConnection.py
b/regression-tests/tests/21/test_modules/TCPConnection.py
new file mode 100644
index 0000000..43b88a9
--- /dev/null
+++ b/regression-tests/tests/21/test_modules/TCPConnection.py
@@ -0,0 +1,60 @@
+"""
+This module defines TCPConnection test,
+a python wrapper for LNST's tcp_conn test tool
+"""
+
+__author__ = """
+jtluka(a)redhat.com (Jan Tluka)
+"""
+
+import re
+import errno
+import logging
+from lnst.Common.TestsCommon import TestGeneric
+from lnst.Common.Utils import bool_it
+
+class TCPConnection(TestGeneric):
+ def run(self):
+ mode = self.get_mopt("mode")
+ address = self.get_mopt("address")
+ portrange = self.get_mopt("portrange")
+
+ continuous = self.get_opt("continuous")
+ debug = self.get_opt("debug")
+ ipv6 = self.get_opt("ipv6")
+
+ cmd = ""
+ if (mode == "server"):
+ logging.debug("TCPConnection: running as server")
+ cmd += "./tcp_listen"
+ elif (mode == "client"):
+ logging.debug("TCPConnection: running as client")
+ cmd += "./tcp_connect"
+ else:
+ raise Exception("Invalid mode value for TCPConnection test
module!")
+
+ cmd += " -a %s -p %s" % (address, portrange)
+
+ if continuous and bool_it(continuous):
+ cmd += " -c"
+
+ if debug and bool_it(debug):
+ cmd += " -d"
+
+ if ipv6 and bool_it(ipv6):
+ cmd += " -6"
+
+ output = self.exec_from("tcp_conn", cmd, die_on_err=False,
log_outputs=True)[0]
+
+ logging.debug("TCPConnection done, inspecting logs ...")
+
+ m = None
+ if (mode == "client"):
+ m = re.search("made [0-9]* connections", output)
+ elif (mode == "server"):
+ m = re.search("handled [0-9]* connections", output)
+
+ if m is None:
+ return self.set_fail({'msg': "Unexpected error"})
+ else:
+ return self.set_pass({'msg': m.group(0)})
diff --git a/regression-tests/tests/21/test_tools/tcp_conn/Makefile
b/regression-tests/tests/21/test_tools/tcp_conn/Makefile
new file mode 100644
index 0000000..a570641
--- /dev/null
+++ b/regression-tests/tests/21/test_tools/tcp_conn/Makefile
@@ -0,0 +1,12 @@
+CC=gcc
+
+all: tcp_listen tcp_connect
+
+tcp_listen: tcp_listen.c
+ $(CC) -o tcp_listen tcp_listen.c -pthread -lrt
+
+tcp_connect: tcp_connect.c
+ $(CC) -o tcp_connect tcp_connect.c -pthread -lrt
+
+clean:
+ rm -f tcp_connect tcp_listen
diff --git a/regression-tests/tests/21/test_tools/tcp_conn/lnst-setup.sh
b/regression-tests/tests/21/test_tools/tcp_conn/lnst-setup.sh
new file mode 100755
index 0000000..2aad486
--- /dev/null
+++ b/regression-tests/tests/21/test_tools/tcp_conn/lnst-setup.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+make
diff --git a/regression-tests/tests/21/test_tools/tcp_conn/tcp_connect.c
b/regression-tests/tests/21/test_tools/tcp_conn/tcp_connect.c
new file mode 100644
index 0000000..3bb4597
--- /dev/null
+++ b/regression-tests/tests/21/test_tools/tcp_conn/tcp_connect.c
@@ -0,0 +1,281 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <semaphore.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define IPCKEY 5678
+
+int connection_handlers[1024];
+int handlers_count;
+int *connection_count;
+
+int debug_on = 0;
+int cont = 0;
+int *term_flag;
+
+sem_t *mutex;
+
+int usage()
+{
+ printf("./tcp_connect -p [port_range] -a [ipaddr] [-d] [-c] [-6]\n");
+ return 0;
+}
+
+#define MSG_MAX 256
+char msg[MSG_MAX];
+
+void debug(char* msg)
+{
+ if (debug_on)
+ {
+ printf("Debug: %s\n", msg);
+ }
+}
+
+void terminate_connections(int p)
+{
+ debug("signalled");
+ *term_flag = 1;
+}
+
+int handle_connections(char* host, int port, int ipv6)
+{
+ int conn_sock;
+ struct sockaddr_in my_addr;
+ struct sockaddr_in6 my_addr6;
+ char data[] = "abcdefghijklmnopqrstuvwxyz0123456789";
+ char buf[21*10*strlen(data)+1];
+ int family;
+
+ snprintf(msg, MSG_MAX, "Starting connection on %s port %i", host, port);
+ debug(msg);
+
+ if (ipv6)
+ {
+ family = my_addr6.sin6_family = AF_INET6;
+ my_addr6.sin6_port = htons(port);
+ if (inet_pton(AF_INET6, host, &my_addr6.sin6_addr) != 1) {
+ perror("fail on inet_pton");
+ return 1;
+ }
+ }
+ else
+ {
+ family = my_addr.sin_family = AF_INET;
+ my_addr.sin_port = htons(port);
+ if (inet_aton(host, &(my_addr.sin_addr)) == 0)
+ {
+ printf("failed on inet_aton()\n");
+ return 1;
+ }
+ }
+
+ do
+ {
+ conn_sock = socket(family, SOCK_STREAM, 0);
+ if (conn_sock == -1)
+ {
+ perror("fail on socket()");
+ return 1;
+ }
+
+ struct sockaddr* sa;
+ socklen_t sa_len;
+ if (ipv6)
+ {
+ sa = (struct sockaddr*) &my_addr6;
+ sa_len = sizeof(struct sockaddr_in6);
+ }
+ else
+ {
+ sa = (struct sockaddr*) &my_addr;
+ sa_len = sizeof(struct sockaddr_in);
+ }
+
+ if (connect(conn_sock, sa, sa_len) == -1)
+ {
+ perror("fail on connect");
+ return 1;
+ }
+
+ sem_wait(mutex);
+ *connection_count += 1;
+ sem_post(mutex);
+
+ int bursts = 5*(random() % 10) + 1;
+ int b;
+ int sum = 0;
+
+ for (b=0; b < bursts; b++)
+ {
+ int parts = 20*(random() % 10) + 1;
+ int j;
+
+ sum += parts*strlen(data);
+ for (j = 0; j < parts; j++)
+ {
+ strncpy(buf + (j*strlen(data)), data, strlen(data));
+ }
+
+ if (write(conn_sock, buf, parts * strlen(data)) == -1)
+ {
+ perror("failed to send data");
+ return 1;
+ }
+ usleep(100*(random()%100));
+ }
+
+ snprintf(msg, MSG_MAX, "sent %i bytes (bursts: %i)", sum, bursts);
+ debug(msg);
+ snprintf(msg, MSG_MAX, "closing connection on port %i", port);
+ debug(msg);
+
+ close(conn_sock);
+ } while (cont && (*term_flag) == 0);
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int rc;
+ int p;
+ char port_str[256];
+ char str_port_start[128];
+ char str_port_end[128];
+ char host_str[16] = "\0";
+ int start_port;
+ int end_port;
+ int opt;
+ char *delimiter;
+ struct sigaction sa;
+ int shm;
+ int ipv6 = 0;
+
+ term_flag = mmap(NULL, sizeof *term_flag, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ *term_flag = 0;
+
+ connection_count = mmap(NULL, sizeof *connection_count, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ *connection_count = 0;
+
+ /* counter synchronization stuff - semaphore and shared memory */
+ if ((shm = shm_open("myshm", O_RDWR | O_CREAT, S_IRWXU)) < 0) {
+ perror("shm_open");
+ exit(1);
+ }
+
+ if ( ftruncate(shm, sizeof(sem_t)) < 0 ) {
+ perror("ftruncate");
+ exit(1);
+ }
+
+ /* place shared mutex into shared memory */
+ if ((mutex = (sem_t*) mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED,
shm, 0)) == MAP_FAILED) {
+ perror("mmap");
+ exit(1);
+ }
+
+ if( sem_init(mutex,1,1) < 0)
+ {
+ perror("semaphore initilization");
+ exit(0);
+ }
+
+ /* signal handling */
+ memset(&sa, 0, sizeof(sa));
+
+ sa.sa_handler = &terminate_connections;
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+
+ handlers_count = 0;
+
+ /* collect program args */
+ while ((opt = getopt(argc, argv, "p:a:dc6")) != -1) {
+ switch (opt) {
+ case 'p':
+ strncpy(port_str, optarg, 256);
+ port_str[256-1]='\0';
+ delimiter = strchr(port_str, '-');
+ if (delimiter == NULL)
+ {
+ usage();
+ return 1;
+ }
+ strncpy(str_port_start, port_str, delimiter - port_str);
+ str_port_start[delimiter - port_str] = '\0';
+ strncpy(str_port_end, delimiter+1, strlen(port_str) -
(delimiter+1-port_str));
+ start_port = atoi(str_port_start);
+ end_port = atoi(str_port_end);
+ break;
+ case 'a':
+ strncpy(host_str, optarg, 64);
+ host_str[16-1] = '\0';
+ break;
+ case 'd':
+ debug_on = 1;
+ break;
+ case 'c':
+ cont = 1;
+ break;
+ case '6':
+ ipv6 = 1;
+ break;
+ }
+ }
+
+ if (strlen(host_str) == 0)
+ {
+ usage();
+ return 1;
+ }
+
+ /* spawn process to handle every port specified */
+ for (p = start_port; p < end_port; p++){
+ if ((rc = fork()) > 0)
+ {
+ /* parent, add pid to the list */
+ connection_handlers[handlers_count++] = rc;
+ }
+ else if (rc == 0)
+ {
+ /* child */
+ sa.sa_handler = SIG_DFL;
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ handle_connections(host_str, p, ipv6);
+ return 0;
+ }
+ }
+
+ /* gather children */
+ int child_status;
+ int i;
+ for (i=0; i < handlers_count; i++)
+ {
+ wait(&child_status);
+ debug("worker finished");
+ }
+
+ debug("tcp_connect finished");
+
+ printf("made %i connections\n", *connection_count);
+
+ return 0;
+}
diff --git a/regression-tests/tests/21/test_tools/tcp_conn/tcp_listen.c
b/regression-tests/tests/21/test_tools/tcp_conn/tcp_listen.c
new file mode 100644
index 0000000..7a292fe
--- /dev/null
+++ b/regression-tests/tests/21/test_tools/tcp_conn/tcp_listen.c
@@ -0,0 +1,330 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <semaphore.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define IPCKEY 5678
+
+int listener_count;
+int listeners[1024];
+int *connection_count;
+
+int debug_on = 0;
+int cont = 0;
+int *term_flag;
+
+sem_t *mutex;
+
+int usage()
+{
+ printf("./tcp_listen -p [port_range] -a [ipaddr] [-d] [-c] [-6]\n");
+ return 0;
+}
+
+void debug(char* msg)
+{
+ if (debug_on)
+ {
+ printf("Debug: %s\n", msg);
+ }
+}
+
+#define MSG_MAX 256
+char msg[MSG_MAX];
+
+void terminate_connections(int p)
+{
+ debug("signal received, killing servers");
+ *term_flag = 1;
+}
+
+int handle_connections(char* host, int port, int ipv6)
+{
+ int listen_sock;
+ struct sockaddr_in my_addr;
+ struct sockaddr_in6 my_addr6;
+ socklen_t my_addr_size = sizeof(my_addr);
+ socklen_t my_addr6_size = sizeof(my_addr6);
+ int remote_sock;
+ struct sockaddr_in remote;
+ struct sockaddr_in6 remote6;
+ socklen_t remote_size = sizeof(remote);
+ socklen_t remote6_size = sizeof(remote6);
+ char data[256];
+ int family;
+
+ snprintf(msg, MSG_MAX, "Starting listener on %s port %i", host, port);
+ debug(msg);
+
+ if (ipv6)
+ {
+ family = AF_INET6;
+ bzero(&my_addr6, my_addr6_size);
+ my_addr6.sin6_family = family;
+ my_addr6.sin6_port = htons(port);
+ if (inet_pton(AF_INET6, host, &(my_addr6.sin6_addr)) != 1)
+ {
+ printf("failed on inet_pton()\n");
+ return 1;
+ }
+ }
+ else
+ {
+ family = AF_INET;
+ bzero(&my_addr, my_addr_size);
+ my_addr.sin_family = family;
+ my_addr.sin_port = htons(port);
+ if (inet_aton(host, &(my_addr.sin_addr)) == 0)
+ {
+ printf("failed on inet_aton()\n");
+ return 1;
+ }
+ }
+
+ if ((listen_sock = socket(family, SOCK_STREAM, 0)) == -1)
+ {
+ perror("fail on socket creation");
+ return 1;
+ }
+
+ int on = 1;
+ if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (const char*) &on,
+ sizeof(on)) == -1)
+ {
+ perror("fail on setsockopt");
+ return 1;
+ }
+
+ struct sockaddr* sa;
+ socklen_t sa_len;
+ if (ipv6)
+ {
+ sa = (struct sockaddr*) &my_addr6;
+ sa_len = my_addr6_size;
+ }
+ else
+ {
+ sa = (struct sockaddr*) &my_addr;
+ sa_len = my_addr_size;
+ }
+
+ if (bind(listen_sock, sa, sa_len))
+ {
+ perror("fail on bind");
+ return 1;
+ }
+
+ if (listen(listen_sock, 0))
+ {
+ perror("fail on listen");
+ return 1;
+ }
+
+ do
+ {
+ struct in_addr ra = remote.sin_addr;
+ struct in6_addr ra6 = remote6.sin6_addr;
+ char host_address_str[256];
+ ssize_t read_rc;
+ struct sockaddr* r_sockaddr;
+ socklen_t* r_sockaddr_size;
+
+ if (ipv6)
+ {
+ bzero(&remote6, remote6_size);
+ r_sockaddr = (struct sockaddr*) &remote6;
+ r_sockaddr_size = &remote6_size;
+ }
+ else
+ {
+ bzero(&remote, remote_size);
+ r_sockaddr = (struct sockaddr*) &remote;
+ r_sockaddr_size = &remote_size;
+ }
+
+ /* handle single connection */
+ remote_sock = accept(listen_sock, r_sockaddr, r_sockaddr_size);
+ if (remote_sock == -1)
+ {
+ perror("failure on accept");
+ close(listen_sock);
+ return 1;
+ }
+
+ sem_wait(mutex);
+ *connection_count += 1;
+ sem_post(mutex);
+
+ if (ipv6)
+ inet_ntop(AF_INET6, &ra6, host_address_str, 255);
+ else
+ inet_ntop(AF_INET, &ra, host_address_str, 255);
+
+ snprintf(msg, MSG_MAX, "accepted connection from host %s port %i",
host_address_str, port);
+ debug(msg);
+
+ int sum = 0;
+ while (read_rc = read(remote_sock, &data, 256))
+ {
+ sum += read_rc;
+ }
+
+ snprintf(msg, MSG_MAX, "connection closed, read %d bytes (%i)", sum,
port);
+ debug(msg);
+ close(remote_sock);
+ } while (cont && (*term_flag) == 0);
+
+ close(listen_sock);
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int rc;
+ int p;
+ char port_str[256];
+ char str_port_start[128];
+ char str_port_end[128];
+ char host_str[16] = "\0";
+ int start_port;
+ int end_port;
+ int opt;
+ char *delimiter;
+ struct sigaction sa;
+ struct sigaction sa2;
+ int shm;
+ int ipv6 = 0;
+
+ term_flag = mmap(NULL, sizeof *term_flag, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ *term_flag = 0;
+
+ connection_count = mmap(NULL, sizeof *connection_count, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ *connection_count = 0;
+
+ /* counter synchronization stuff - semaphore and shared memory */
+ if ((shm = shm_open("myshm", O_RDWR | O_CREAT, S_IRWXU)) < 0) {
+ perror("shm_open");
+ exit(1);
+ }
+
+ if ( ftruncate(shm, sizeof(sem_t)) < 0 ) {
+ perror("ftruncate");
+ exit(1);
+ }
+
+ /* place shared mutex into shared memory */
+ if ((mutex = (sem_t*) mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED,
shm, 0)) == MAP_FAILED) {
+ perror("mmap");
+ exit(1);
+ }
+
+ if( sem_init(mutex,1,1) < 0)
+ {
+ perror("semaphore initilization");
+ exit(0);
+ }
+
+ /* signal handling */
+ memset(&sa, 0, sizeof(sa));
+ memset(&sa2, 0, sizeof(sa2));
+
+ sa.sa_handler = &terminate_connections;
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+
+ /* collect program args */
+ while ((opt = getopt(argc, argv, "p:a:dc6")) != -1) {
+ switch (opt) {
+ case 'p':
+ strncpy(port_str, optarg, 256);
+ port_str[256-1]='\0';
+ delimiter = strchr(port_str, '-');
+ if (delimiter == NULL)
+ {
+ usage();
+ return 1;
+ }
+ strncpy(str_port_start, port_str, delimiter - port_str);
+ str_port_start[delimiter - port_str] = '\0';
+ strncpy(str_port_end, delimiter+1, strlen(port_str) -
(delimiter+1-port_str));
+ start_port = atoi(str_port_start);
+ end_port = atoi(str_port_end);
+ break;
+ case 'a':
+ strncpy(host_str, optarg, 64);
+ host_str[16-1] = '\0';
+ break;
+ case 'd':
+ debug_on = 1;
+ break;
+ case 'c':
+ cont = 1;
+ break;
+ case '6':
+ ipv6 = 1;
+ break;
+ }
+ }
+
+ if (strlen(host_str) == 0)
+ {
+ usage();
+ return 1;
+ }
+
+ listener_count = 0;
+ /* spawn process to handle every port specified */
+ for (p = start_port; p < end_port; p++){
+ if ((rc = fork()) > 0)
+ {
+ /* parent, add pid to the list */
+ listeners[listener_count++] = rc;
+ }
+ else if (rc == 0)
+ {
+ /* child */
+ sa.sa_handler = SIG_DFL;
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+
+ /* run the main processing loop */
+ handle_connections(host_str, p, ipv6);
+ return 0;
+ }
+ }
+
+ /* gather children */
+ int child_status;
+ int i;
+ for (i=0; i < listener_count; i++)
+ {
+ while (wait(&child_status) == -1 && errno == EINTR)
+ {
+ ;
+ }
+ debug("worker finished");
+ }
+
+ debug("tcp_listener finished");
+
+ printf("handled %i connections\n", *connection_count);
+
+ return 0;
+}
diff --git a/regression-tests/tests/22/desc b/regression-tests/tests/22/desc
new file mode 100644
index 0000000..0882b9c
--- /dev/null
+++ b/regression-tests/tests/22/desc
@@ -0,0 +1,3 @@
+Two Slave Machine configs referencing the same machine
+
+https://github.com/jpirko/lnst/issues/32
diff --git a/regression-tests/tests/22/lnst-ctl.conf
b/regression-tests/tests/22/lnst-ctl.conf
new file mode 100644
index 0000000..81f1561
--- /dev/null
+++ b/regression-tests/tests/22/lnst-ctl.conf
@@ -0,0 +1,2 @@
+[environment]
+machine_pool_dirs += ./pool
diff --git a/regression-tests/tests/22/pool/slave1.xml
b/regression-tests/tests/22/pool/slave1.xml
new file mode 100644
index 0000000..f739d2b
--- /dev/null
+++ b/regression-tests/tests/22/pool/slave1.xml
@@ -0,0 +1,6 @@
+<slavemachine>
+ <params>
+ <param name="hostname" value="example.com"/>
+ <param name="libvirt_domain" value="example"/>
+ </params>
+</slavemachine>
diff --git a/regression-tests/tests/22/pool/slave2.xml
b/regression-tests/tests/22/pool/slave2.xml
new file mode 100644
index 0000000..f739d2b
--- /dev/null
+++ b/regression-tests/tests/22/pool/slave2.xml
@@ -0,0 +1,6 @@
+<slavemachine>
+ <params>
+ <param name="hostname" value="example.com"/>
+ <param name="libvirt_domain" value="example"/>
+ </params>
+</slavemachine>
diff --git a/regression-tests/tests/22/recipe.xml b/regression-tests/tests/22/recipe.xml
new file mode 100644
index 0000000..7565af0
--- /dev/null
+++ b/regression-tests/tests/22/recipe.xml
@@ -0,0 +1,26 @@
+<lnstrecipe>
+ <network>
+ <host id="tm1">
+ <interfaces>
+ <eth id="nic1" label="testnet">
+ <addresses>
+ <address value="192.168.131.201/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ <host id="tm2">
+ <interfaces>
+ <eth id="nic1" label="testnet">
+ <addresses>
+ <address value="192.168.131.202/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+
+ <task>
+ <run host="tm1" command="ip a"/>
+ </task>
+</lnstrecipe>
diff --git a/regression-tests/tests/22/run.sh b/regression-tests/tests/22/run.sh
new file mode 100755
index 0000000..14442b2
--- /dev/null
+++ b/regression-tests/tests/22/run.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+. ../lib.sh
+
+init_test
+
+lnst-ctl -c lnst-ctl.conf -d run recipe.xml | tee test.log
+rv=${PIPESTATUS[0]}
+
+log=`cat test.log`
+
+print_separator
+assert_status "error" "$rv"
+assert_log "error" "You have the same machine listed twice in your
pool" "$log"
+
+rm -f test.log
+
+end_test
diff --git a/regression-tests/tests/23/desc b/regression-tests/tests/23/desc
new file mode 100644
index 0000000..a75ee4d
--- /dev/null
+++ b/regression-tests/tests/23/desc
@@ -0,0 +1,3 @@
+synced resources not visible in network namespaces
+
+https://github.com/jpirko/lnst/issues/93
diff --git a/regression-tests/tests/23/lnst-ctl.conf
b/regression-tests/tests/23/lnst-ctl.conf
new file mode 100644
index 0000000..a4d654d
--- /dev/null
+++ b/regression-tests/tests/23/lnst-ctl.conf
@@ -0,0 +1,2 @@
+[environment]
+test_module_dirs = ./test_modules
diff --git a/regression-tests/tests/23/recipe.xml b/regression-tests/tests/23/recipe.xml
new file mode 100644
index 0000000..1866430
--- /dev/null
+++ b/regression-tests/tests/23/recipe.xml
@@ -0,0 +1,42 @@
+<lnstrecipe>
+ <network>
+ <host id="tm1">
+ <interfaces>
+ <eth id="nic1" label="testnet"/>
+ <veth_pair>
+ <veth id="veth1"/>
+ <veth id="veth2" netns="test_ns">
+ <addresses>
+ <address value="192.168.131.201/24"/>
+ </addresses>
+ </veth>
+ </veth_pair>
+ <bridge id="br">
+ <slaves>
+ <slave id="nic1"/>
+ <slave id="veth1"/>
+ </slaves>
+ </bridge>
+ </interfaces>
+ </host>
+ <host id="tm2">
+ <interfaces>
+ <eth id="nic1" label="testnet">
+ <addresses>
+ <address value="192.168.131.202/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+
+ <task>
+ <run host="tm1" module="IcmpPing"
netns="test_ns">
+ <options>
+ <option name="addr" value="{ip(tm2, nic1)}"/>
+ <option name="count" value="40"/>
+ <option name="interval" value="0"/>
+ </options>
+ </run>
+ </task>
+</lnstrecipe>
diff --git a/regression-tests/tests/23/run.sh b/regression-tests/tests/23/run.sh
new file mode 100755
index 0000000..a972660
--- /dev/null
+++ b/regression-tests/tests/23/run.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+. ../lib.sh
+
+init_test
+
+touch test_modules/*
+
+lnst-ctl -c lnst-ctl.conf -d run recipe.xml | tee test.log
+rv=${PIPESTATUS[0]}
+
+log=`cat test.log`
+
+print_separator
+assert_status "pass" "$rv"
+
+rm -f test.log
+
+end_test
diff --git a/regression-tests/tests/23/test_modules/IcmpPing.py
b/regression-tests/tests/23/test_modules/IcmpPing.py
new file mode 100644
index 0000000..5b9d888
--- /dev/null
+++ b/regression-tests/tests/23/test_modules/IcmpPing.py
@@ -0,0 +1,71 @@
+"""
+This module defines icmp ping test
+
+Copyright 2011 Red Hat, Inc.
+Licensed under the GNU General Public License, version 2 as
+published by the Free Software Foundation; see COPYING for details.
+"""
+
+__author__ = """
+jpirko(a)redhat.com (Jiri Pirko)
+"""
+
+import logging
+import re
+from lnst.Common.TestsCommon import TestGeneric
+from lnst.Common.ExecCmd import exec_cmd
+
+class IcmpPing(TestGeneric):
+ def _compose_cmd(self):
+ addr = self.get_mopt("addr", opt_type="addr")
+ cmd = "ping %s" % addr
+ count = self.get_opt("count")
+ if count:
+ cmd += " -c %s" % count
+ interval = self.get_opt("interval")
+ if interval:
+ cmd += " -i %s" % interval
+ iface = self.get_opt("iface")
+ if iface:
+ cmd += " -I %s" % iface
+ size = self.get_opt("size")
+ if size:
+ cmd += " -s %s" % size
+ return cmd
+
+ def run(self):
+ cmd = self._compose_cmd()
+ limit_rate = self.get_opt("limit_rate", default=80)
+
+ data_stdout = exec_cmd(cmd, die_on_err=False)[0]
+ stat_pttr1 = r'(\d+) packets transmitted, (\d+) received'
+ stat_pttr2 = r'rtt min/avg/max/mdev =
(\d+\.\d+)/(\d+\.\d+)/(\d+\.\d+)/(\d+\.\d+) ms'
+
+ match = re.search(stat_pttr1, data_stdout)
+ if not match:
+ res_data = {"msg": "expected pattern not found"}
+ return self.set_fail(res_data)
+
+ trans_pkts, recv_pkts = match.groups()
+ rate = int(round((float(recv_pkts) / float(trans_pkts)) * 100))
+ logging.debug("Transmitted \"%s\", received \"%s\",
"
+ "rate \"%d%%\", limit_rate \"%d%%\""
+ % (trans_pkts, recv_pkts, rate, limit_rate))
+
+ res_data = {"rate": rate,
+ "limit_rate": limit_rate}
+
+ match = re.search(stat_pttr2, data_stdout)
+ if match:
+ tmin, tavg, tmax, tmdev = [float(x) for x in match.groups()]
+ logging.debug("rtt min \"%.3f\", avg \"%.3f\", max
\"%.3f\", "
+ "mdev \"%.3f\"" % (tmin, tavg, tmax, tmdev))
+
+ res_data["rtt_min"] = tmin
+ res_data["rtt_max"] = tmax
+
+ if rate < limit_rate:
+ res_data["msg"] = "rate is lower than limit"
+ return self.set_fail(res_data)
+
+ return self.set_pass(res_data)
diff --git a/regression-tests/tests/24/desc b/regression-tests/tests/24/desc
new file mode 100644
index 0000000..5669380
--- /dev/null
+++ b/regression-tests/tests/24/desc
@@ -0,0 +1,6 @@
+timeout attribute is ignored
+
+This is tested by setting different timeouts to background commands and parsing
+logs to see if the test failed because of a timeout or finished succesfully.
+
+https://github.com/jpirko/lnst/issues/67
diff --git a/regression-tests/tests/24/recipe_fail.xml
b/regression-tests/tests/24/recipe_fail.xml
new file mode 100644
index 0000000..39bfe3d
--- /dev/null
+++ b/regression-tests/tests/24/recipe_fail.xml
@@ -0,0 +1,33 @@
+<lnstrecipe>
+ <network>
+ <host id="tm1">
+ <interfaces>
+ <eth id="nic1" label="testnet">
+ <addresses>
+ <address value="192.168.131.201/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ <host id="tm2">
+ <interfaces>
+ <eth id="nic1" label="testnet">
+ <addresses>
+ <address value="192.168.131.202/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+
+ <task>
+ <run host="tm1" module="IcmpPing" bg_id="test"
timeout="10">
+ <options>
+ <option name="addr" value="{ip(tm2, nic1)}"/>
+ <option name="count" value="70"/>
+ <option name="interval" value="1"/>
+ </options>
+ </run>
+ <wait host="tm1" bg_id="test"/>
+ </task>
+</lnstrecipe>
diff --git a/regression-tests/tests/24/recipe_pass.xml
b/regression-tests/tests/24/recipe_pass.xml
new file mode 100644
index 0000000..5896c33
--- /dev/null
+++ b/regression-tests/tests/24/recipe_pass.xml
@@ -0,0 +1,33 @@
+<lnstrecipe>
+ <network>
+ <host id="tm1">
+ <interfaces>
+ <eth id="nic1" label="testnet">
+ <addresses>
+ <address value="192.168.131.201/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ <host id="tm2">
+ <interfaces>
+ <eth id="nic1" label="testnet">
+ <addresses>
+ <address value="192.168.131.202/24"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+
+ <task>
+ <run host="tm1" module="IcmpPing" bg_id="test"
timeout="30">
+ <options>
+ <option name="addr" value="{ip(tm2, nic1)}"/>
+ <option name="count" value="10"/>
+ <option name="interval" value="1"/>
+ </options>
+ </run>
+ <wait host="tm1" bg_id="test"/>
+ </task>
+</lnstrecipe>
diff --git a/regression-tests/tests/24/run.sh b/regression-tests/tests/24/run.sh
new file mode 100755
index 0000000..1aff4a3
--- /dev/null
+++ b/regression-tests/tests/24/run.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+. ../lib.sh
+
+init_test
+
+lnst-ctl -d run recipe_fail.xml | tee test.log
+rv1=${PIPESTATUS[0]}
+log1=`cat test.log`
+
+lnst-ctl -d run recipe_pass.xml | tee test.log
+rv2=${PIPESTATUS[0]}
+log2=`cat test.log`
+
+print_separator
+assert_status "fail" "$rv1"
+assert_log "INFO" "RPC connection to machine \w* timed out"
"$log1"
+assert_status "pass" "$rv2"
+
+rm -f test.log
+
+end_test
--
2.1.0
_______________________________________________
LNST-developers mailing list
LNST-developers(a)lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/lnst-developers