转发:剖析嵌入式设计师易犯的错误点
by ������
����
�� �� �� ��
lnst-developers(a)lists.fedorahosted.org
ÐÏࡱá
5 years, 11 months
Can you help me?
by Ruth De Quincey
Hi,
Does alcohol cause or contribute to breast cancer?
My name is Ruth and I've just completed an infographic detailing the link between alcohol and breast cancer. Drinking only one glass of wine per day increases the risk of getting breast cancer. My infographic aims to highlight this risk.
You can view my infographic here: https://www.cassioburycourt.com/article/103/alcohol-and-breast-cancer-inf...
To raise awareness of this important issue, could I please ask that you link to my infographic from this page on your website: www.lists.fedorahosted.org/archives/list/users@lists.fedoraproject.org/th...
I choose this page because you already link to www.fundraise.cancerresearchuk.org/page/garys-march-march from this page.
Alternatively (or both), you could publish my infographic on your website as a 'guest post'. If this is ok, I can write a unique introduction to go with the infographic. This will save you time and also help to raise the important issues covered in the infographic.
I’m sure you are busy with the run up to Christmas, but promoting this information could help save lives.
I really appreciate your time.
Many thanks,
Ruth De Quincey
Cassiobury Court
5 years, 11 months
[PATCH v4] regression_tests: add ipsec_esp_aead test
by Kamil Jerabek
This patch adds new ipsec_esp_aead test to our phase3 regression_tests. It is
similar to ipsec_esp_ah_comp test. There is difference in configuration.
In the test is configured only esp aead with algorithm rfc4106(gcm(aes)),
key length 160bit and IV length 96bit.
Signed-off-by: Kamil Jerabek <kjerabek(a)redhat.com>
---
changes in:
*v2:
* add official_result handling for PerfRepo
*v3:
* add accidentally removed result parameters
* remove comment about compression check
*v4:
* removed unused imports
---
.../regression_tests/phase3/ipsec_esp_aead.README | 90 +++++
recipes/regression_tests/phase3/ipsec_esp_aead.py | 433 +++++++++++++++++++++
recipes/regression_tests/phase3/ipsec_esp_aead.xml | 51 +++
3 files changed, 574 insertions(+)
create mode 100644 recipes/regression_tests/phase3/ipsec_esp_aead.README
create mode 100644 recipes/regression_tests/phase3/ipsec_esp_aead.py
create mode 100644 recipes/regression_tests/phase3/ipsec_esp_aead.xml
diff --git a/recipes/regression_tests/phase3/ipsec_esp_aead.README b/recipes/regression_tests/phase3/ipsec_esp_aead.README
new file mode 100644
index 0000000..8738da6
--- /dev/null
+++ b/recipes/regression_tests/phase3/ipsec_esp_aead.README
@@ -0,0 +1,90 @@
+Topology:
+
+ switch
+ +------+
+ | |
+ | |
+ +-------------+ +-------------+
+ | | | |
+ | | | |
+ | +------+ |
+ | |
+ | |
+ +-+--+ +-+--+
++-------|eth1|------+ +-------|eth1|------+
+| +-+--+ | | +-+--+ |
+| | | |
+| | | |
+| | | |
+| | | |
+| | | |
+| host1 | | host2 |
+| | | |
+| | | |
+| | | |
++-------------------+ +-------------------+
+
+Number of hosts: 2
+Host #1 description:
+ One ethernet device configured with ip addresses:
+ 192.168.99.1/24
+ fc00:1::1/64
+
+Host #2 description:
+ One ethernet device configured with ip addresses:
+ 192.168.100.1/24
+ fc00:2::1/64
+
+Test name:
+ ipsec_esp_aead.py
+Test description:
+ Ping:
+ + count: 10
+ + interval: 0.1s
+ + between ipsec encrypted ethernet interfaces headers check expecting PASS
+ + between ipsec encrypted ethernet interfaces compression check expecting PASS
+ Ping6:
+ + count: 10
+ + interval: 0.1s
+ + between ipsec encrypted ethernet interfaces headers check expecting PASS
+ + between ipsec encrypted ethernet interfaces compression check expecting PASS
+ Netperf:
+ + duration: 60s
+ + TCP_STREAM and UDP_STREAM
+ + ipv4 and ipv6
+ + between ipsec encrypted ethernet interfaces
+ IPsec
+ + tested with esp AEAD
+ + tested with algorithm rfc4106(gcm(aes))
+ + key length - 160bit
+ + IV length - 96bit
+
+PerfRepo integration:
+ First, preparation in PerfRepo is required - you need to create Test objects
+ through the web interface that properly describe the individual Netperf
+ tests that this recipe runs. Don't forget to also add appropriate metrics.
+ For these Netperf tests it's always:
+ * throughput
+ * throughput_min
+ * throughput_max
+ * throughput_deviation
+
+ After that, to enable support for PerfRepo you need to create the file
+ vxlan_remote.mapping and define the following id mappings:
+ tcp_ipv4_id -> to store ipv4 TCP_STREAM Netperf test results, maps to TestUid of a PerfRepo Test object
+ tcp_ipv6_id -> to store ipv6 TCP_STREAM Netperf test results, maps to TestUid of a PerfRepo Test object
+ udp_ipv4_id -> to store ipv4 UDP_STREAM Netperf test results, maps to TestUid of a PerfRepo Test object
+ udp_ipv6_id -> to store ipv4 UDP_STREAM Netperf test results, maps to TestUid of a PerfRepo Test object
+
+ To enable result comparison agains baselines you need to create a Report in
+ PerfRepo that will store the baseline. Set up the Report to only contain results
+ with the same hash tag and then add a new mapping to the mapping file, with
+ this format:
+ <some_hash> = <report_id>
+
+ The hash value is automatically generated during test execution and added
+ to each result stored in PerfRepo. To get the Report id you need to open
+ that report in our browser and find if in the URL.
+
+ When running this recipe you should also define the 'product_name' alias
+ (e.g. RHEL7) in order to tag the result object in PerfRepo.
diff --git a/recipes/regression_tests/phase3/ipsec_esp_aead.py b/recipes/regression_tests/phase3/ipsec_esp_aead.py
new file mode 100644
index 0000000..a6cc67c
--- /dev/null
+++ b/recipes/regression_tests/phase3/ipsec_esp_aead.py
@@ -0,0 +1,433 @@
+from lnst.Common.Utils import bool_it
+from lnst.Controller.Task import ctl
+from lnst.Controller.PerfRepoUtils import perfrepo_baseline_to_dict
+from lnst.Controller.PerfRepoUtils import netperf_result_template
+
+from lnst.RecipeCommon.ModuleWrap import netperf
+from lnst.RecipeCommon.IRQ import pin_dev_irqs
+from lnst.RecipeCommon.PerfRepo import generate_perfrepo_comment
+
+# ---------------------------
+# ALGORITHM AND CIPHER CONFIG
+# ---------------------------
+
+#lenth param is in bits
+def generate_key(length):
+ key = "0x"
+ key = key + (length/8) * "0b"
+ return key
+
+algorithm = []
+
+algorithm.append(('rfc4106(gcm(aes))', 160, 96))
+
+# ------
+# SETUP
+# ------
+
+mapping_file = ctl.get_alias("mapping_file")
+perf_api = ctl.connect_PerfRepo(mapping_file)
+
+product_name = ctl.get_alias("product_name")
+
+m1 = ctl.get_host("machine1")
+m2 = ctl.get_host("machine2")
+
+m1.sync_resources(modules=["IcmpPing", "Icmp6Ping", "Netperf", "Custom"])
+m2.sync_resources(modules=["PacketAssert", "IcmpPing", "Icmp6Ping", "Netperf"])
+
+# ------
+# TESTS
+# ------
+
+ipv = ctl.get_alias("ipv")
+mtu = ctl.get_alias("mtu")
+netperf_duration = int(ctl.get_alias("netperf_duration"))
+nperf_reserve = int(ctl.get_alias("nperf_reserve"))
+nperf_confidence = ctl.get_alias("nperf_confidence")
+nperf_max_runs = int(ctl.get_alias("nperf_max_runs"))
+nperf_cpupin = ctl.get_alias("nperf_cpupin")
+nperf_cpu_util = ctl.get_alias("nperf_cpu_util")
+nperf_num_parallel = int(ctl.get_alias("nperf_num_parallel"))
+nperf_debug = ctl.get_alias("nperf_debug")
+nperf_max_dev = ctl.get_alias("nperf_max_dev")
+nperf_msg_size = ctl.get_alias("nperf_msg_size")
+pr_user_comment = ctl.get_alias("perfrepo_comment")
+ipsec_mode = ctl.get_alias("ipsec_mode")
+official_result = bool_it(ctl.get_alias("official_result"))
+
+pr_comment = generate_perfrepo_comment([m1, m2], pr_user_comment)
+
+m1_if = m1.get_interface("eth")
+m2_if = m2.get_interface("eth")
+
+m1_if.set_mtu(mtu)
+m2_if.set_mtu(mtu)
+
+m1_if_name = m1_if.get_devname()
+m2_if_name = m2_if.get_devname()
+
+m1_if_addr = m1_if.get_ip()
+m2_if_addr = m2_if.get_ip()
+
+m1_if_addr6 = m1_if.get_ip(1)
+m2_if_addr6 = m2_if.get_ip(1)
+
+
+# add routing rulez ipv4
+# so the host knows where to send traffic destined to remote site
+m1.run("ip route add %s dev %s" % (m2_if_addr, m1_if_name))
+
+# so the host knows where to send traffic destined to remote site
+m2.run("ip route add %s dev %s" % (m1_if_addr, m2_if_name))
+
+# add routing rulez ipv6
+# so the host knows where to send traffic destined to remote site
+m1.run("ip route add %s dev %s" % (m2_if_addr6, m1_if_name))
+
+# so the host knows where to send traffic destined to remote site
+m2.run("ip route add %s dev %s" % (m1_if_addr6, m2_if_name))
+
+if nperf_msg_size is None:
+ nperf_msg_size = 16000
+
+if ipsec_mode is None:
+ ipsec_mode = "transport"
+
+res = m1.run("rpm -qa iproute", save_output=True)
+if (res.get_result()["res_data"]["stdout"].find("iproute-2") != -1):
+ m1_key="0x"
+else:
+ m1_key=""
+
+res = m2.run("rpm -qa iproute", save_output=True)
+if (res.get_result()["res_data"]["stdout"].find("iproute-2") != -1):
+ m2_key="0x"
+else:
+ m2_key=""
+
+if nperf_cpupin:
+ m1.run("service irqbalance stop")
+ m2.run("service irqbalance stop")
+
+ dev_list = [(m1, m1_if), (m2, m2_if)]
+
+ # this will pin devices irqs to cpu #0
+ for m, d in dev_list:
+ pin_dev_irqs(m, d, 0)
+
+nperf_opts = ""
+if nperf_cpupin and nperf_num_parallel == 1:
+ nperf_opts = " -T%s,%s" % (nperf_cpupin, nperf_cpupin)
+
+ctl.wait(15)
+
+def configure_ipsec(algo, algo_key, icv_len, ip_version):
+ if ip_version == "ipv4":
+ m1_addr = m1_if_addr
+ m2_addr = m2_if_addr
+ else:
+ m1_addr = m1_if_addr6
+ m2_addr = m2_if_addr6
+
+ # configure policy and state
+ m1.run("ip xfrm policy flush")
+ m1.run("ip xfrm state flush")
+ m2.run("ip xfrm policy flush")
+ m2.run("ip xfrm state flush")
+
+ m1.run("ip xfrm state add src %s dst %s proto esp spi 0x1001 "\
+ "aead '%s' %s %s mode %s "\
+ "sel src %s dst %s"\
+ % (m2_addr, m1_addr,
+ algo, algo_key, icv_len, ipsec_mode,
+ m2_addr, m1_addr))
+
+ m1.run("ip xfrm policy add src %s dst %s dir in tmpl "\
+ "src %s dst %s proto esp mode %s action allow"\
+ % (m2_addr, m1_addr,
+ m2_addr, m1_addr, ipsec_mode))
+
+ m1.run("ip xfrm state add src %s dst %s proto esp spi 0x1000 "\
+ "aead '%s' %s %s mode %s "\
+ "sel src %s dst %s"\
+ % (m1_addr, m2_addr,
+ algo, algo_key, icv_len, ipsec_mode,
+ m1_addr, m2_addr))
+
+ m1.run("ip xfrm policy add src %s dst %s dir out tmpl "\
+ "src %s dst %s proto esp mode %s action allow"\
+ % (m1_addr, m2_addr,
+ m1_addr, m2_addr, ipsec_mode))
+
+
+
+
+ m2.run("ip xfrm state add src %s dst %s proto esp spi 0x1000 "\
+ "aead '%s' %s %s mode %s "\
+ "sel src %s dst %s"\
+ % (m1_addr, m2_addr,
+ algo, algo_key, icv_len, ipsec_mode,
+ m1_addr, m2_addr))
+
+ m2.run("ip xfrm policy add src %s dst %s dir in tmpl "\
+ "src %s dst %s proto esp mode %s action allow"\
+ % (m1_addr, m2_addr,
+ m1_addr, m2_addr, ipsec_mode))
+
+ m2.run("ip xfrm state add src %s dst %s proto esp spi 0x1001 "\
+ "aead '%s' %s %s mode %s sel "\
+ "src %s dst %s"\
+ % (m2_addr, m1_addr,
+ algo, algo_key, icv_len, ipsec_mode,
+ m2_addr, m1_addr))
+
+ m2.run("ip xfrm policy add src %s dst %s dir out tmpl "\
+ "src %s dst %s proto esp mode %s action allow"\
+ % (m2_addr, m1_addr,
+ m2_addr, m1_addr, ipsec_mode))
+
+
+
+for algo, key_len, icv_len in algorithm:
+ # test: TCP netperf, UDP netperf
+ if ipv in [ 'ipv4', 'both']:
+ configure_ipsec(algo,
+ generate_key(key_len),
+ icv_len,
+ "ipv4")
+
+ dump = m1.run("tcpdump -i %s -nn -vv" % m1_if_name, bg=True)
+
+ # ping + PacketAssert
+ assert_mod = ctl.get_module("PacketAssert",
+ options={
+ "interface": m2_if_name,
+ "filter": "esp",
+ "grep_for": [ "ESP\(spi=0x00001001" ],
+ "min": 10
+ })
+
+ assert_proc = m2.run(assert_mod, bg=True)
+
+ ping_mod = ctl.get_module("IcmpPing",
+ options={
+ "addr": m2_if_addr,
+ "count": 10,
+ "interval": 0.1})
+
+ ctl.wait(2)
+
+ m1.run(ping_mod)
+
+ ctl.wait(2)
+
+ assert_proc.intr()
+
+ dump.intr()
+
+ # prepare PerfRepo result for tcp
+ result_tcp = perf_api.new_result("tcp_ipv4_id",
+ "tcp_ipv4_result",
+ hash_ignore=[
+ r'kernel_release',
+ r'redhat_release'])
+ result_tcp.add_tag(product_name)
+
+ if nperf_num_parallel > 1:
+ result_tcp.add_tag("multithreaded")
+ result_tcp.set_parameter('num_parallel', nperf_num_parallel)
+
+ result_tcp.set_parameter('ipsec_algorithm', algo)
+ result_tcp.set_parameter('key_length', key_len)
+ result_tcp.set_parameter('iv_length', icv_len)
+ result_tcp.set_parameter('msg_size', nperf_msg_size)
+ result_tcp.set_parameter('ipsec_mode', ipsec_mode)
+
+ baseline = perf_api.get_baseline_of_result(result_tcp)
+ baseline = perfrepo_baseline_to_dict(baseline)
+
+
+ tcp_res_data = netperf((m1, m1_if, 0, {"scope": 0}),
+ (m2, m2_if, 0, {"scope": 0}),
+ client_opts={"duration" : netperf_duration,
+ "testname" : "TCP_STREAM",
+ "confidence" : nperf_confidence,
+ "num_parallel" : nperf_num_parallel,
+ "cpu_util" : nperf_cpu_util,
+ "runs": nperf_max_runs,
+ "debug": nperf_debug,
+ "max_deviation": nperf_max_dev,
+ "msg_size" : nperf_msg_size,
+ "netperf_opts": nperf_opts},
+ baseline = baseline,
+ timeout = (netperf_duration + nperf_reserve)*nperf_max_runs)
+
+ netperf_result_template(result_tcp, tcp_res_data)
+ result_tcp.set_comment(pr_comment)
+ perf_api.save_result(result_tcp, official_result)
+
+ # prepare PerfRepo result for udp
+ result_udp = perf_api.new_result("udp_ipv4_id",
+ "udp_ipv4_result",
+ hash_ignore=[
+ r'kernel_release',
+ r'redhat_release'])
+ result_udp.add_tag(product_name)
+
+ if nperf_num_parallel > 1:
+ result_udp.add_tag("multithreaded")
+ result_udp.set_parameter('num_parallel', nperf_num_parallel)
+
+ result_udp.set_parameter('ipsec_algorithm', algo)
+ result_udp.set_parameter('key_length', key_len)
+ result_udp.set_parameter('iv_length', icv_len)
+ result_udp.set_parameter('msg_size', nperf_msg_size)
+ result_udp.set_parameter('ipsec_mode', ipsec_mode)
+
+ baseline = perf_api.get_baseline_of_result(result_udp)
+ baseline = perfrepo_baseline_to_dict(baseline)
+
+ udp_res_data = netperf((m1, m1_if, 0, {"scope": 0}),
+ (m2, m2_if, 0, {"scope": 0}),
+ client_opts={"duration" : netperf_duration,
+ "testname" : "UDP_STREAM",
+ "confidence" : nperf_confidence,
+ "num_parallel" : nperf_num_parallel,
+ "cpu_util" : nperf_cpu_util,
+ "runs": nperf_max_runs,
+ "debug": nperf_debug,
+ "max_deviation": nperf_max_dev,
+ "msg_size" : nperf_msg_size,
+ "netperf_opts": nperf_opts},
+ baseline = baseline,
+ timeout = (netperf_duration + nperf_reserve)*nperf_max_runs)
+
+ netperf_result_template(result_udp, udp_res_data)
+ result_udp.set_comment(pr_comment)
+ perf_api.save_result(result_udp, official_result)
+
+ if ipv in [ 'ipv6', 'both']:
+ configure_ipsec(algo,
+ generate_key(key_len),
+ icv_len,
+ "ipv6")
+
+ dump = m1.run("tcpdump -i %s -nn -vv" % m1_if_name, bg=True)
+
+ # ping + PacketAssert
+ assert_mod = ctl.get_module("PacketAssert",
+ options={
+ "interface": m2_if_name,
+ "filter": "esp",
+ "grep_for": [ "ESP\(spi=0x00001001" ],
+ "min": 10
+ })
+
+ assert_proc = m2.run(assert_mod, bg=True)
+
+ ping_mod = ctl.get_module("Icmp6Ping",
+ options={
+ "addr": m2_if_addr6,
+ "count": 10,
+ "interval": 0.1})
+
+ ctl.wait(2)
+
+ m1.run(ping_mod)
+
+ ctl.wait(2)
+
+ assert_proc.intr()
+
+ dump.intr()
+
+ # prepare PerfRepo result for tcp
+ result_tcp = perf_api.new_result("tcp_ipv6_id",
+ "tcp_ipv6_result",
+ hash_ignore=[
+ r'kernel_release',
+ r'redhat_release'])
+ result_tcp.add_tag(product_name)
+
+ if nperf_num_parallel > 1:
+ result_tcp.add_tag("multithreaded")
+ result_tcp.set_parameter('num_parallel', nperf_num_parallel)
+
+ result_tcp.set_parameter('ipsec_algorithm', algo)
+ result_tcp.set_parameter('key_length', key_len)
+ result_tcp.set_parameter('iv_length', icv_len)
+ result_tcp.set_parameter('msg_size', nperf_msg_size)
+ result_tcp.set_parameter('ipsec_mode', ipsec_mode)
+
+ baseline = perf_api.get_baseline_of_result(result_tcp)
+ baseline = perfrepo_baseline_to_dict(baseline)
+
+
+ tcp_res_data = netperf((m1, m1_if, 1, {"scope": 0}),
+ (m2, m2_if, 1, {"scope": 0}),
+ client_opts={"duration" : netperf_duration,
+ "testname" : "TCP_STREAM",
+ "confidence" : nperf_confidence,
+ "num_parallel" : nperf_num_parallel,
+ "cpu_util" : nperf_cpu_util,
+ "runs": nperf_max_runs,
+ "debug": nperf_debug,
+ "max_deviation": nperf_max_dev,
+ "msg_size" : nperf_msg_size,
+ "netperf_opts" : nperf_opts + " -6"},
+ baseline = baseline,
+ timeout = (netperf_duration + nperf_reserve)*nperf_max_runs)
+
+ netperf_result_template(result_tcp, tcp_res_data)
+ result_tcp.set_comment(pr_comment)
+ perf_api.save_result(result_tcp, official_result)
+
+ # prepare PerfRepo result for udp
+ result_udp = perf_api.new_result("udp_ipv6_id",
+ "udp_ipv6_result",
+ hash_ignore=[
+ r'kernel_release',
+ r'redhat_release'])
+ result_udp.add_tag(product_name)
+
+ if nperf_num_parallel > 1:
+ result_udp.add_tag("multithreaded")
+ result_udp.set_parameter('num_parallel', nperf_num_parallel)
+
+ result_udp.set_parameter('ipsec_algorithm', algo)
+ result_udp.set_parameter('key_length', key_len)
+ result_udp.set_parameter('iv_length', icv_len)
+ result_udp.set_parameter('msg_size', nperf_msg_size)
+ result_udp.set_parameter('ipsec_mode', ipsec_mode)
+
+ baseline = perf_api.get_baseline_of_result(result_udp)
+ baseline = perfrepo_baseline_to_dict(baseline)
+
+ udp_res_data = netperf((m1, m1_if, 1, {"scope": 0}),
+ (m2, m2_if, 1, {"scope": 0}),
+ client_opts={"duration" : netperf_duration,
+ "testname" : "UDP_STREAM",
+ "confidence" : nperf_confidence,
+ "num_parallel" : nperf_num_parallel,
+ "cpu_util" : nperf_cpu_util,
+ "runs": nperf_max_runs,
+ "debug": nperf_debug,
+ "max_deviation": nperf_max_dev,
+ "msg_size" : nperf_msg_size,
+ "netperf_opts" : nperf_opts + " -6"},
+ baseline = baseline,
+ timeout = (netperf_duration + nperf_reserve)*nperf_max_runs)
+
+ netperf_result_template(result_udp, udp_res_data)
+ result_udp.set_comment(pr_comment)
+ perf_api.save_result(result_udp, official_result)
+
+m1.run("ip xfrm policy flush")
+m1.run("ip xfrm state flush")
+m2.run("ip xfrm policy flush")
+m2.run("ip xfrm state flush")
+
+if nperf_cpupin:
+ m1.run("service irqbalance start")
+ m2.run("service irqbalance start")
diff --git a/recipes/regression_tests/phase3/ipsec_esp_aead.xml b/recipes/regression_tests/phase3/ipsec_esp_aead.xml
new file mode 100644
index 0000000..c37010e
--- /dev/null
+++ b/recipes/regression_tests/phase3/ipsec_esp_aead.xml
@@ -0,0 +1,51 @@
+<lnstrecipe>
+ <define>
+ <alias name="ipv" value="both" />
+ <alias name="mtu" value="1500" />
+ <alias name="netperf_duration" value="60" />
+ <alias name="nperf_reserve" value="20" />
+ <alias name="nperf_confidence" value="99,5" />
+ <alias name="nperf_max_runs" value="5"/>
+ <alias name="nperf_num_parallel" value="1"/>
+ <alias name="nperf_debug" value="0"/>
+ <alias name="nperf_max_dev" value="20%"/>
+ <alias name="mapping_file" value="ipsec_esp_aead.mapping"/>
+ <alias name="net_1" value="192.168.99"/>
+ <alias name="net6_1" value="fc00:1::"/>
+ <alias name="net_2" value="192.168.100"/>
+ <alias name="net6_2" value="fc00:2::"/>
+ <alias name="driver" value=""/>
+ <alias name="official_result" value="no" />
+ </define>
+ <network>
+ <host id="machine1">
+ <interfaces>
+ <eth id="eth" label="localnet">
+ <params>
+ <param name="driver" value="{$driver}"/>
+ </params>
+ <addresses>
+ <address value="{$net_1}.1/24"/>
+ <address value="{$net6_1}1/64"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ <host id="machine2">
+ <interfaces>
+ <eth id="eth" label="localnet">
+ <params>
+ <param name="driver" value="{$driver}"/>
+ </params>
+ <addresses>
+ <address value="{$net_2}.1/24"/>
+ <address value="{$net6_2}1/64"/>
+ </addresses>
+ </eth>
+ </interfaces>
+ </host>
+ </network>
+
+ <task python="ipsec_esp_aead.py"/>
+
+</lnstrecipe>
--
2.5.5
5 years, 12 months
[PATCH] regression_tests: ovs-dpdk: add max deviation check
by olichtne@redhat.com
From: Ondrej Lichtner <olichtne(a)redhat.com>
Setting the max deviation value to 10%, meaning that if the measured
packet rate interval is larger than +-10% interval, we automatically
mark this as a failure.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
recipes/regression_tests/phase3/ovs-dpdk-pvp.py | 41 ++++++++++++++++++++----
recipes/regression_tests/phase3/ovs-dpdk-pvp.xml | 1 +
2 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/recipes/regression_tests/phase3/ovs-dpdk-pvp.py b/recipes/regression_tests/phase3/ovs-dpdk-pvp.py
index 027dae2..c476f7f 100644
--- a/recipes/regression_tests/phase3/ovs-dpdk-pvp.py
+++ b/recipes/regression_tests/phase3/ovs-dpdk-pvp.py
@@ -28,7 +28,7 @@ def run_ssh_command_on_bg_channel(command, channel, host, guest_name=""):
desc = "%s running in bg: %s" % (guest_name, command)
host.run(custom_mod, desc=desc)
-def compare_results(host, result, baseline):
+def compare_results(host, result, baseline, max_dev):
avg1 = result.get_value("rx_rate").get_result()
dev1 = result.get_value("rx_rate_deviation").get_result()
interval1 = (avg1 - dev1, avg1 + dev1)
@@ -38,16 +38,43 @@ def compare_results(host, result, baseline):
interval2 = (avg2 - dev2, avg2 + dev2)
if interval1[1] < interval2[0]:
- desc = "Measured rate %.2f +-%.2f pps is lower "\
- "than threshold %.2f +-%.2f pps"% (avg1, dev1, avg2, dev2)
+ desc = ("Measured rate {:.2f} +-{:.2f} pps is lower "
+ "than threshold {:.2f} +-{:.2f} pps".
+ format(avg1, dev1, avg2, dev2))
custom_mod = ctl.get_module("Custom", options = {"fail": True})
else:
- desc = "Measured rate %.2f +-%.2f pps is higher "\
- "than threshold %.2f +-%.2f pps"% (avg1, dev1, avg2, dev2)
+ desc = ("Measured rate {:.2f} +-{:.2f} pps is higher "
+ "than threshold {:.2f} +-{:.2f} pps".
+ format(avg1, dev1, avg2, dev2))
custom_mod = ctl.get_module("Custom")
host.run(custom_mod, desc=desc)
+def report_result(host, result, max_dev):
+ avg = result.get_value("rx_rate").get_result()
+ dev = result.get_value("rx_rate_deviation").get_result()
+
+ desc = "Measured rate is {:.2f} +-{:.2f} pps".format(avg, dev)
+ fail = False
+ if re.match("\d+%", max_dev):
+ if ((float(dev) / avg) * 100) > int(max_dev[:-1]):
+ desc = ("Measured rate {:.2f} +-{:.2f} pps has bigger "
+ "deviation than allowed (+-{})".
+ format(avg, dev, max_dev))
+ fail = True
+ elif re.match("\d+", max_dev):
+ if dev > int(max_dev):
+ desc = ("Measured rate {:.2f} +-{:.2f} pps has bigger "
+ "deviation than allowed (+-{} pps)".
+ format(avg, dev, max_dev))
+ fail = True
+ elif max_dev == None:
+ pass
+ else:
+ raise Exception("Unsupported format for max_dev argument.")
+
+ custom_mod = ctl.get_module("Custom", options={"fail": fail})
+ host.run(custom_mod, desc=desc)
# ------
# SETUP
@@ -93,6 +120,7 @@ trex_dir = ctl.get_alias("trex_dir")
pkt_size = int(ctl.get_alias("pkt_size"))
test_duration = int(ctl.get_alias("test_duration"))
test_runs = int(ctl.get_alias("test_runs"))
+max_dev = ctl.get_alias("max_dev")
pr_comment = generate_perfrepo_comment([h1, h2], pr_user_comment)
pr_comment += "\n<BR>DPDK version: {}".format(dpdk_version)
@@ -430,8 +458,9 @@ baseline = perf_api.get_baseline_of_result(pr_result)
pr_result.set_comment(pr_comment)
perf_api.save_result(pr_result, official_result)
+report_result(h1, pr_result.get_testExecution(), max_dev)
if not isinstance(baseline, Noop):
- compare_results(h1, pr_result.get_testExecution(), baseline.get_texec())
+ compare_results(h1, pr_result.get_testExecution(), baseline.get_texec(), max_dev)
#============================================
# Configuration cleanup
diff --git a/recipes/regression_tests/phase3/ovs-dpdk-pvp.xml b/recipes/regression_tests/phase3/ovs-dpdk-pvp.xml
index 35241ad..e9edf74 100644
--- a/recipes/regression_tests/phase3/ovs-dpdk-pvp.xml
+++ b/recipes/regression_tests/phase3/ovs-dpdk-pvp.xml
@@ -18,6 +18,7 @@
<alias name="pkt_size" value="64" />
<alias name="test_duration" value="60" />
<alias name="test_runs" value="5" />
+ <alias name="max_dev" value="10%"/>
</define>
<network>
<host id="host1">
--
2.15.1
5 years, 12 months
[PATCH-next] lnst.Common.Version: modify version detection and comparison
by olichtne@redhat.com
From: Ondrej Lichtner <olichtne(a)redhat.com>
LNSTVersion is now a class instantiated as a module object lnst_version.
This object is then used by both the Slave and Controller for
comparison.
This commit also adds a new module lnst.Common.GitVersion which will
only be present in the git repository (will not be installed by setup.py
and shouldn't be included in packages). This module defines a method
that detects a git instalation and returns the current revision hash
which is appended to the version number. If the module is present, LNST
runs as a development version - failed version comparison only warns
about the different versions. In case something goes wrong during the
git version detection (e.g. git isn't installed) LNST won't start and
return an exception.
If the module isn't present it's assumed that LNST is installed as a
stable version with the version number defined in
lnst.Common.Version.LNSTVersion._version and a failed version check will
report an error and the recipe execution won't continue.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Common/Config.py | 25 -------------------------
lnst/Common/GitVersion.py | 35 +++++++++++++++++++++++++++++++++++
lnst/Common/Version.py | 36 +++++++++++++++++++++++++++++++++++-
lnst/Controller/Machine.py | 19 ++++++++++---------
lnst/Slave/NetTestSlave.py | 3 ++-
5 files changed, 82 insertions(+), 36 deletions(-)
create mode 100644 lnst/Common/GitVersion.py
diff --git a/lnst/Common/Config.py b/lnst/Common/Config.py
index 3745094..2edf854 100644
--- a/lnst/Common/Config.py
+++ b/lnst/Common/Config.py
@@ -17,7 +17,6 @@ import subprocess
from lnst.Common.Utils import bool_it
from lnst.Common.NetUtils import verify_mac_address
from lnst.Common.Colours import get_preset_conf
-from lnst.Common.Version import LNSTMajorVersion
from lnst.Common.LnstError import LnstError
DefaultRPCPort = 9999
@@ -31,35 +30,11 @@ class Config():
def __init__(self):
self._options = dict()
- self.version = self._get_version()
self._init_options()
def _init_options(self):
raise NotImplementedError()
- def _get_version(self):
- # Check if I'm in git
- cwd = os.getcwd()
- abspath = os.path.abspath(__file__)
- dname = os.path.dirname(abspath)
- os.chdir(dname)
- with open(os.devnull, 'w') as null:
- cmd = ['git', 'rev-parse', 'HEAD']
- try:
- proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=null)
- data = proc.communicate()
- except:
- os.chdir(cwd)
- return LNSTMajorVersion
- # git command passed
- if data[0] != '':
- version = data[0].strip()
- # git command failed
- else:
- version = LNSTMajorVersion
- os.chdir(cwd)
- return version
-
def colours_scheme(self):
self._options['colours'] = dict()
self._options['colours']["disable_colours"] = {\
diff --git a/lnst/Common/GitVersion.py b/lnst/Common/GitVersion.py
new file mode 100644
index 0000000..b24962a
--- /dev/null
+++ b/lnst/Common/GitVersion.py
@@ -0,0 +1,35 @@
+"""
+Module that calculates the LNST version based on the currently checked-out git
+commit. Overrides the default LNST version that is reported when LNST is
+installed on the machine with setup.py which skips this module.
+
+Copyright 2017 Red Hat, Inc.
+Licensed under the GNU General Public License, version 2 as
+published by the Free Software Foundation; see COPYING for details.
+"""
+
+__autor__ = """
+olichtne(a)redhat.com (Ondrej Lichtner)
+"""
+
+import os
+import subprocess
+from lnst.Common.LnstError import LnstError
+from lnst.Common.Utils import is_installed
+
+def git_version():
+ if not is_installed("git"):
+ raise LnstError("git not installed, can't check for version")
+
+ with open(os.devnull, 'w') as null:
+ cwd = os.getcwd()
+ abspath = os.path.abspath(__file__)
+ dname = os.path.dirname(abspath)
+ os.chdir(dname)
+
+ cmd = ['git', 'rev-parse', 'HEAD']
+ try:
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=null)
+ return proc.communicate()[0].strip()
+ finally:
+ os.chdir(cwd)
diff --git a/lnst/Common/Version.py b/lnst/Common/Version.py
index bafbb83..b2da2d2 100644
--- a/lnst/Common/Version.py
+++ b/lnst/Common/Version.py
@@ -11,4 +11,38 @@ __autor__ = """
olichtne(a)redhat.com (Ondrej Lichtner)
"""
-LNSTMajorVersion = '11'
+try:
+ from lnst.Common.GitVersion import git_version
+except ImportError:
+ git_version = None
+
+class LNSTVersion(object):
+ def __init__(self):
+ self._version = "14"
+
+ if git_version:
+ self._version += "-" + git_version()
+
+ @property
+ def version(self):
+ return self._version
+
+ @property
+ def is_git_version(self):
+ return git_version is not None
+
+ def __str__(self):
+ return str(self.version)
+
+ def __eq__(self, other):
+ if isinstance(other, self.__class__):
+ return str(self) == str(other)
+ return NotImplemented
+
+ def __ne__(self, other):
+ res = self == other
+ if res is not NotImplemented:
+ return not res
+ return NotImplemented
+
+lnst_version = LNSTVersion()
diff --git a/lnst/Controller/Machine.py b/lnst/Controller/Machine.py
index 38a3646..7730d79 100644
--- a/lnst/Controller/Machine.py
+++ b/lnst/Controller/Machine.py
@@ -18,6 +18,7 @@ import signal
from lnst.Common.Utils import sha256sum
from lnst.Common.Utils import check_process_running
from lnst.Common.TestModule import BaseTestModule
+from lnst.Common.Version import lnst_version
from lnst.Controller.Common import ControllerError
from lnst.Controller.CtlSecSocket import CtlSecSocket
from lnst.Devices import device_classes
@@ -216,19 +217,19 @@ class Machine(object):
raise MachineError(msg)
slave_version = slave_desc["lnst_version"]
- slave_is_git = self.is_git_version(slave_version)
- ctl_version = self._ctl_config.version
- ctl_is_git = self.is_git_version(ctl_version)
- if slave_version != ctl_version:
- if ctl_is_git and slave_is_git:
- msg = "Controller and Slave '%s' git versions are different"\
- % hostname
+
+ if lnst_version != slave_version:
+ if lnst_version.is_git_version:
+ msg = ("Controller ({}) and Slave '{}' ({}) versions "
+ "are different".format(lnst_version, hostname,
+ slave_version))
logging.warning(len(msg)*"=")
logging.warning(msg)
logging.warning(len(msg)*"=")
else:
- msg = "Controller and Slave '%s' versions are not compatible!"\
- % hostname
+ msg = ("Controller ({}) and Slave '{}' ({}) versions "
+ "are not compatible!".format(lnst_version, hostname,
+ slave_version))
raise MachineError(msg)
self._slave_desc = slave_desc
diff --git a/lnst/Slave/NetTestSlave.py b/lnst/Slave/NetTestSlave.py
index 942a45c..9c5486c 100644
--- a/lnst/Slave/NetTestSlave.py
+++ b/lnst/Slave/NetTestSlave.py
@@ -44,6 +44,7 @@ from lnst.Common.DeviceError import DeviceConfigValueError
from lnst.Common.TestModule import BaseTestModule
from lnst.Common.Parameters import Parameters, DeviceParam
from lnst.Common.IpAddress import ipaddress
+from lnst.Common.Version import lnst_version
from lnst.Slave.Job import Job, JobContext
from lnst.Slave.InterfaceManager import InterfaceManager
from lnst.Slave.BridgeTool import BridgeTool
@@ -104,7 +105,7 @@ class SlaveMethods:
r_release, _ = exec_cmd("cat /etc/redhat-release", False, False, False)
slave_desc["kernel_release"] = k_release.strip()
slave_desc["redhat_release"] = r_release.strip()
- slave_desc["lnst_version"] = self._slave_config.version
+ slave_desc["lnst_version"] = lnst_version
return ("hello", slave_desc)
--
2.15.1
5 years, 12 months
[next update] master bugfixes ported
by Ondrej Lichtner
Hi all,
just a short notification about the next branch. I just pushed an update
containing all (AFAIK) relevant bugfixes that were added to the master
branch after the next branch split off.
The next items on my TODO list are:
* fix git version check
* wait/sleep looping on the controller (for now without conditions)
* Results reporting implementation
The first two should be fairly quick so I'll take care of those before
christmas, results reporting is a bit bigger so I can't promise the same
there.
-Ondrej
Info from the merge commit:
This branch contains bugfixes ported from the master branch that we were
still using and fixing while working on the LNST reimplementation. No
new features were ported in this branch.
I skipped all bugfixes related to features that aren't ported yet as
well.
I also had to skip several bugfixes to the Netperf module even though it
has been ported. The reason for this is that for some reason (human
error or confusion) it was ported from a version that is older than the
version from when the next branch split off from master. This means that
I would have to go even further into the history of the module and port
both bugfixes and feature reimplementations to achieve a synced state.
Instead I decided that it will be easier to sync the Netperf module
against the current master version manually, ignoring it's history.
This is also the approach that we'll probably take with all other
features when porting them from the legacy version (currently master)
directly into the next branch.
6 years
[patch lnst-next] Machine: reduce initial resource synchronization and load phase
by Jiri Pirko
From: Jiri Pirko <jiri(a)mellanox.com>
So far, each resource is checked and loaded one by one. That results
in many rpc calls. On my 20ms line, this makes ~4secs for one slave.
Bulk the checks and loads together which allows to be done in ~1sec.
Signed-off-by: Jiri Pirko <jiri(a)mellanox.com>
---
rfc->v1:
- avoid duplicates
- have rpc methods accept either list or a single entry
- store has_resource return value and sync accordingly
- compute res hash in get module info
---
lnst/Controller/Machine.py | 78 +++++++++++++++++++++++++++++-----------------
lnst/Slave/NetTestSlave.py | 33 +++++++++++++++-----
2 files changed, 75 insertions(+), 36 deletions(-)
diff --git a/lnst/Controller/Machine.py b/lnst/Controller/Machine.py
index 38a3646..e8e74d5 100644
--- a/lnst/Controller/Machine.py
+++ b/lnst/Controller/Machine.py
@@ -257,18 +257,17 @@ class Machine(object):
for cls_name, cls in device_classes:
classes.extend(reversed(self._get_base_classes(cls)))
+ minfos = []
for cls in classes:
if cls is object:
continue
- module_name = cls.__module__
- module = sys.modules[module_name]
- filename = module.__file__
-
- if filename[-3:] == "pyc":
- filename = filename[:-1]
+ name = cls.__module__
+ if any(minfo['name'] == name for minfo in minfos):
+ continue
+ minfos.append(self._get_module_info(name))
- res_hash = self.sync_resource(module_name, filename)
- self.rpc_call("load_cached_module", module_name, res_hash)
+ self.sync_resources(minfos)
+ self.rpc_call("load_cached_module", minfos)
for cls_name, cls in device_classes:
module_name = cls.__module__
@@ -348,15 +347,9 @@ class Machine(object):
for cls in reversed(classes):
if cls is object or cls is BaseTestModule:
continue
- m_name = cls.__module__
- m = sys.modules[m_name]
- filename = m.__file__
- if filename[-3:] == "pyc":
- filename = filename[:-1]
-
- res_hash = self.sync_resource(m_name, filename)
-
- self.rpc_call("load_cached_module", m_name, res_hash)
+ minfo = self._get_module_info(cls.__module__)
+ self.sync_resource(minfo)
+ self.rpc_call("load_cached_module", minfo)
logging.info("Host %s executing job %d: %s" %
(self._id, job.id, str(job)))
@@ -518,19 +511,48 @@ class Machine(object):
local_file.close()
self.rpc_call("finish_copy_from", remote_path)
- def sync_resource(self, res_name, file_path):
- digest = sha256sum(file_path)
+ def _get_module_info(self, name):
+ module = sys.modules[name]
+ filepath = module.__file__
+
+ if filepath[-3:] == "pyc":
+ filepath = filepath[:-1]
- if not self.rpc_call("has_resource", digest):
- msg = "Transfering %s to machine %s as '%s'" % (file_path,
- self.get_id(),
- res_name)
- logging.debug(msg)
+ res_hash = sha256sum(filepath)
- remote_path = self.copy_file_to_machine(file_path)
- self.rpc_call("add_resource_to_cache",
- "file", remote_path, res_name)
- return digest
+ return {"name": name, "filepath": filepath, "res_hash": res_hash}
+
+ def _sync_resource(self, minfo):
+ if minfo["has_resource"]:
+ return
+ msg = "Transfering %s to machine %s as '%s'" % (minfo["filepath"],
+ self.get_id(),
+ minfo["name"])
+ logging.debug(msg)
+ remote_path = self.copy_file_to_machine(minfo["filepath"])
+ self.rpc_call("add_resource_to_cache", "file",
+ remote_path, minfo["name"])
+
+ def sync_resource(self, minfo):
+ minfo["has_resource"] = self.rpc_call("has_resource",
+ minfo["res_hash"])
+ self._sync_resource(minfo)
+
+ def sync_resources(self, minfos):
+ res_hashes = list(map(lambda minfo: minfo["res_hash"], minfos))
+
+ # To avoid asking per-resource, ask for all resources in one call.
+ has_resources = self.rpc_call("has_resource", res_hashes)
+
+ from pprint import pprint
+ pprint(has_resources)
+ minfos = list(map(lambda minfo, has_resource:
+ dict(minfo.items() + {"has_resource": has_resource}.items()),
+ minfos, has_resources))
+ pprint(minfos)
+
+ for minfo in minfos:
+ self._sync_resource(minfo)
# def enable_nm(self):
# return self._rpc_call("enable_nm")
diff --git a/lnst/Slave/NetTestSlave.py b/lnst/Slave/NetTestSlave.py
index 908e85c..02a9d18 100644
--- a/lnst/Slave/NetTestSlave.py
+++ b/lnst/Slave/NetTestSlave.py
@@ -148,13 +148,21 @@ class SlaveMethods:
setattr(Devices, cls_name, cls)
- def load_cached_module(self, module_name, res_hash):
- self._cache.renew_entry(res_hash)
- if module_name in self._dynamic_modules:
+ def _load_cached_module(self, minfo):
+ self._cache.renew_entry(minfo["res_hash"])
+ if minfo["name"] in self._dynamic_modules:
return
- module_path = self._cache.get_path(res_hash)
- module = imp.load_source(module_name, module_path)
- self._dynamic_modules[module_name] = module
+ module_path = self._cache.get_path(minfo["res_hash"])
+ module = imp.load_source(minfo["name"], module_path)
+ self._dynamic_modules[minfo["name"]] = module
+
+ def load_cached_module(self, minfos):
+ if isinstance(minfos, list):
+ for minfo in minfos:
+ self._load_cached_module(minfo)
+ elif isinstance(minfos, dict):
+ minfo = minfos
+ self._load_cached_module(minfo)
def init_if_manager(self):
self._if_manager = InterfaceManager(self._server_handler)
@@ -401,12 +409,21 @@ class SlaveMethods:
self._remove_capture_files()
return True
- def has_resource(self, res_hash):
+ def _has_resource(self, res_hash):
if self._cache.query(res_hash):
return True
-
return False
+ def has_resource(self, res_hashes):
+ if isinstance(res_hashes, list):
+ retvals = []
+ for res_hash in res_hashes:
+ retvals.append(self._has_resource(res_hash))
+ return retvals
+ elif isinstance(res_hashes, str):
+ res_hash = res_hashes
+ return self._has_resource(res_hash)
+
def add_resource_to_cache(self, res_type, local_path, name):
if res_type == "file":
self._cache.add_file_entry(local_path, name)
--
2.9.5
6 years