CSIT-665: Re-write L1 robot keywords in python 03/8203/10
authorDasa Simkova <dspropagacie@gmail.com>
Thu, 24 Aug 2017 15:25:21 +0000 (17:25 +0200)
committerJan Gelety <jgelety@cisco.com>
Fri, 8 Sep 2017 06:30:07 +0000 (06:30 +0000)
Change-Id: Iddd823375ddd17b9abd5f02ee3aea3bfcb625149
Signed-off-by: Dasa Simkova <dspropagacie@gmail.com>
resources/libraries/python/DUTSetup.py
resources/libraries/python/VhostUser.py
resources/libraries/python/VppCounters.py
resources/libraries/robot/ip/ip6.robot
resources/libraries/robot/performance/performance_setup.robot
resources/libraries/robot/performance/performance_utils.robot
resources/libraries/robot/shared/counters.robot
resources/libraries/robot/shared/default.robot

index 7260292..bccf108 100644 (file)
@@ -15,8 +15,7 @@
 
 from robot.api import logger
 
-from resources.libraries.python.topology import NodeType
-from resources.libraries.python.topology import Topology
+from resources.libraries.python.topology import NodeType, Topology
 from resources.libraries.python.ssh import SSH
 from resources.libraries.python.constants import Constants
 from resources.libraries.python.VatExecutor import VatExecutor
@@ -49,6 +48,17 @@ class DUTSetup(object):
         vat = VatExecutor()
         vat.execute_script("show_version_verbose.vat", node, json_out=False)
 
+    @staticmethod
+    def show_vpp_version_on_all_duts(nodes):
+        """Show VPP version verbose on all DUTs.
+
+        :param nodes: VPP nodes
+        :type nodes: dict
+        """
+        for node in nodes.values():
+            if node['type'] == NodeType.DUT:
+                DUTSetup.vpp_show_version_verbose(node)
+
     @staticmethod
     def vpp_api_trace_save(node):
         """Run "api trace save" CLI command.
index 385d0f2..680d4ae 100644 (file)
@@ -14,6 +14,7 @@
 """Vhost-user interfaces library."""
 
 from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal
+from resources.libraries.python.topology import NodeType
 
 
 class VhostUser(object):
@@ -86,3 +87,14 @@ class VhostUser(object):
         """
         vat = VatExecutor()
         vat.execute_script("show_vhost.vat", node, json_out=False)
+
+    @staticmethod
+    def show_vpp_vhost_on_all_duts(nodes):
+        """Show Vhost User on all DUTs.
+
+        :param nodes: VPP nodes.
+        :type nodes: dict
+        """
+        for node in nodes.values():
+            if node['type'] == NodeType.DUT:
+                VhostUser.vpp_show_vhost(node)
index 6b2265d..8247a1e 100644 (file)
@@ -16,7 +16,6 @@
 import time
 
 from robot.api import logger
-
 from resources.libraries.python.topology import NodeType, Topology
 from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal
 
@@ -61,7 +60,7 @@ class VppCounters(object):
     def vpp_show_errors_on_all_duts(nodes, verbose=False):
         """Show errors on all DUTs.
 
-        :param nodes: VPP nodes
+        :param nodes: VPP nodes.
         :param verbose: If True show verbose output.
         :type nodes: dict
         :type verbose: bool
@@ -84,6 +83,17 @@ class VppCounters(object):
         vat = VatExecutor()
         vat.execute_script("show_runtime.vat", node, json_out=False)
 
+    @staticmethod
+    def show_runtime_counters_on_all_duts(nodes):
+        """Clear VPP runtime counters on all DUTs.
+
+        :param nodes: VPP nodes.
+        :type nodes: dict
+        """
+        for node in nodes.values():
+            if node['type'] == NodeType.DUT:
+                VppCounters.vpp_show_runtime(node)
+
     @staticmethod
     def vpp_show_runtime_verbose(node):
         """Run "show runtime verbose" CLI command.
@@ -114,6 +124,17 @@ class VppCounters(object):
         vat = VatExecutor()
         vat.execute_script("clear_runtime.vat", node, json_out=False)
 
+    @staticmethod
+    def clear_runtime_counters_on_all_duts(nodes):
+        """Run "clear runtime" CLI command on all DUTs.
+
+        :param nodes: VPP nodes.
+        :type nodes: dict
+        """
+        for node in nodes.values():
+            if node['type'] == NodeType.DUT:
+                VppCounters.vpp_clear_runtime(node)
+
     @staticmethod
     def vpp_clear_interface_counters(node):
         """Clear interface counters on VPP node.
@@ -125,6 +146,17 @@ class VppCounters(object):
         vat.execute_script('clear_interface.vat', node)
         vat.script_should_have_passed()
 
+    @staticmethod
+    def clear_interface_counters_on_all_duts(nodes):
+        """Clear interface counters on all DUTs.
+
+        :param nodes: VPP nodes.
+        :type nodes: dict
+        """
+        for node in nodes.values():
+            if node['type'] == NodeType.DUT:
+                VppCounters.vpp_clear_interface_counters(node)
+
     @staticmethod
     def vpp_clear_hardware_counters(node):
         """Clear interface hardware counters on VPP node.
@@ -136,6 +168,17 @@ class VppCounters(object):
         vat.execute_script('clear_hardware.vat', node)
         vat.script_should_have_passed()
 
+    @staticmethod
+    def clear_hardware_counters_on_all_duts(nodes):
+        """Clear hardware counters on all DUTs.
+
+        :param nodes: VPP nodes.
+        :type nodes: dict
+        """
+        for node in nodes.values():
+            if node['type'] == NodeType.DUT:
+                VppCounters.vpp_clear_hardware_counters(node)
+
     @staticmethod
     def vpp_clear_errors_counters(node):
         """Clear errors counters on VPP node.
@@ -147,6 +190,17 @@ class VppCounters(object):
         vat.execute_script('clear_errors.vat', node)
         vat.script_should_have_passed()
 
+    @staticmethod
+    def clear_error_counters_on_all_duts(nodes):
+        """Clear VPP errors counters on all DUTs.
+
+        :param nodes: VPP nodes.
+        :type nodes: dict
+        """
+        for node in nodes.values():
+            if node['type'] == NodeType.DUT:
+                VppCounters.vpp_clear_errors_counters(node)
+
     def vpp_dump_stats_table(self, node):
         """Dump stats table on VPP node.
 
@@ -219,3 +273,29 @@ class VppCounters(object):
         logger.trace('{i} {v} counter not found.'.format(i=interface,
                                                          v=version))
         return 0
+
+    @staticmethod
+    def show_vpp_statistics(node):
+        """Show [error, hardware, interface] stats.
+
+        :param node: VPP node.
+        :type node: dict
+        """
+        VppCounters.vpp_show_errors(node)
+        VppCounters.vpp_show_hardware_detail(node)
+        VppCounters.vpp_show_runtime(node)
+
+    @staticmethod
+    def show_statistics_on_all_duts(nodes, sleeptime=5):
+        """Show VPP statistics on all DUTs.
+
+        :param nodes: VPP nodes.
+        :type nodes: dict
+        :param sleeptime: Time to wait for traffic to arrive back to TG.
+        :type sleeptime: int
+        """
+        logger.trace('Waiting for statistics to be collected')
+        time.sleep(sleeptime)
+        for node in nodes.values():
+            if node['type'] == NodeType.DUT:
+                VppCounters.show_vpp_statistics(node)
index 43b0b8c..f80d98f 100644 (file)
 | | ${dst_mac}= | Get Interface Mac | ${dst_node} | ${dst_port}
 | | ${src_port_name}= | Get interface name | ${src_node} | ${src_port}
 | | ${args}= | Traffic Script Gen Arg | ${src_port_name} | ${src_port_name} | ${src_mac}
-| |          | ...                    | ${dst_mac} | ${src_ip} | ${dst_ip}
+| | ... | ${dst_mac} | ${src_ip} | ${dst_ip}
 | | Run Traffic Script On Node | icmpv6_echo.py | ${tg_node} | ${args}
-| | Get interface statistics | ${dst_node}
-| | ${ipv6_counter}= | Get interface ipv6 counter | ${dst_node} | ${dst_port}
-| | Should Be Equal | ${ipv6_counter} | ${2} | #ICMPv6 neighbor advertisement + ICMPv6 echo request
+| | Vpp Dump Stats Table | ${dst_node}
+| | ${ipv6_counter}= | Vpp Get Ipv6 Interface Counter | ${dst_node}
+| | ... | ${dst_port}
+| | Should Be Equal | ${ipv6_counter} | ${2}
+| | ... | #ICMPv6 neighbor advertisement + ICMPv6 echo request
 
 | Execute IPv6 ICMP echo sweep
 | | [Documentation] | Type of the src_node must be TG and dst_node must be DUT
@@ -61,9 +63,9 @@
 | | ${dst_mac}= | Get Interface Mac | ${dst_node} | ${dst_port}
 | | ${src_port_name}= | Get interface name | ${src_node} | ${src_port}
 | | ${args}= | Traffic Script Gen Arg | ${src_port_name} | ${src_port_name}
-| |          | ... | ${src_mac} | ${dst_mac} | ${src_ip} | ${dst_ip}
+| | ... | ${src_mac} | ${dst_mac} | ${src_ip} | ${dst_ip}
 | | ${args}= | Set Variable
-| | ...      | ${args} --start_size ${start_size} --end_size ${end_size} --step ${step}
+| | ... | ${args} --start_size ${start_size} --end_size ${end_size} --step ${step}
 | | Run Traffic Script On Node | ipv6_sweep_ping.py | ${src_node} | ${args}
 | | ... | timeout=${180}
 
@@ -81,7 +83,7 @@
 | | ${dst_mac}= | Get Interface Mac | ${hop_node} | ${hop_port}
 | | ${src_port_name}= | Get interface name | ${src_node} | ${src_port}
 | | ${args}= | Traffic Script Gen Arg | ${src_port_name} | ${src_port_name} | ${src_mac}
-| |          | ...                    | ${dst_mac} | ${src_ip} | ${dst_ip}
+| | ... | ${dst_mac} | ${src_ip} | ${dst_ip}
 | | Run Traffic Script On Node | icmpv6_echo.py | ${tg_node} | ${args}
 
 
 | | ${dst_mac}= | Get Interface Mac | ${hop_node} | ${hop_port}
 | | ${src_port_name}= | Get interface name | ${src_node} | ${src_port}
 | | ${args}= | Traffic Script Gen Arg | ${src_port_name} | ${src_port_name} | ${src_mac}
-| |          | ...                    | ${dst_mac} | ${src_ip} | ${dst_ip}
+| | ... | ${dst_mac} | ${src_ip} | ${dst_ip}
 | | Run Traffic Script On Node | icmpv6_echo.py | ${tg_node} | ${args}
 
 | Send IPv6 ICMP echo request to DUT2 egress interface via DUT1 and verify answer
 | | ${dst_mac}= | Get Interface Mac | ${hop_node} | ${hop_port}
 | | ${src_port_name}= | Get interface name | ${src_node} | ${src_port}
 | | ${args}= | Traffic Script Gen Arg | ${src_port_name} | ${src_port_name} | ${src_mac}
-| |          | ...                    | ${dst_mac} | ${src_ip} | ${dst_ip}
+| | ... | ${dst_mac} | ${src_ip} | ${dst_ip}
 | | Run Traffic Script On Node | icmpv6_echo.py | ${tg_node} | ${args}
 
 | Ipv6 tg to tg routed
 | | ${src_port_name}= | Get interface name | ${src_node} | ${src_port}
 | | ${dst_port_name}= | Get interface name | ${dst_node} | ${dst_port}
 | | ${args}= | Traffic Script Gen Arg | ${src_port_name} | ${dst_port_name} | ${src_mac}
-| |          | ...                    | ${dst_mac} | ${src_ip} | ${dst_ip}
+| | ... | ${dst_mac} | ${src_ip} | ${dst_ip}
 | | ${args}= | Catenate | ${args} | --src_nh_mac ${src_nh_mac}
-| |          | ...      | --dst_nh_mac ${dst_nh_mac} | --h_num 2
+| | ... | --dst_nh_mac ${dst_nh_mac} | --h_num 2
 | | Run Traffic Script On Node | icmpv6_echo_req_resp.py | ${tg_node} | ${args}
 
 | Send IPv6 neighbor solicitation and verify answer
 | | ${dst_mac}= | Get Interface Mac | ${dst_node} | ${dst_port}
 | | ${src_port_name}= | Get interface name | ${src_node} | ${src_port}
 | | ${args}= | Traffic Script Gen Arg | ${src_port_name} | ${src_port_name} | ${src_mac}
-| |          | ...                    | ${dst_mac} | ${src_ip} | ${dst_ip}
+| | ... | ${dst_mac} | ${src_ip} | ${dst_ip}
 | | Run Traffic Script On Node | ipv6_ns.py | ${src_node} | ${args}
 
 | Configure IPv6 on all DUTs in topology
index 5838590..9f6d5ae 100644 (file)
@@ -12,6 +12,8 @@
 # limitations under the License.
 
 *** Settings ***
+| Library | resources.libraries.python.DUTSetup
+| Library | resources.libraries.python.VhostUser
 | Resource | resources/libraries/robot/performance/performance_configuration.robot
 | Resource | resources/libraries/robot/performance/performance_utils.robot
 | Documentation | Performance suite keywords - Suite and test setups and
 | | ...
 | | [Arguments] | ${topology_type} | ${nic_model}
 | | ...
-| | Show vpp version on all DUTs
+| | Show vpp version on all DUTs | ${nodes}
 | | Set variables in 2-node circular topology with DUT interface model
 | | ... | ${nic_model}
 | | Initialize traffic generator | ${tg} | ${tg_if1} | ${tg_if2}
 | | [Arguments] | ${topology_type} | ${nic_model} | ${tg_if1_dest_mac}
 | | ... | ${tg_if2_dest_mac}
 | | ...
-| | Show vpp version on all DUTs
+| | Show vpp version on all DUTs | ${nodes}
 | | Set variables in 2-node circular topology with DUT interface model
 | | ... | ${nic_model}
 | | Initialize traffic generator | ${tg} | ${tg_if1} | ${tg_if2}
 | | ...
 | | [Arguments] | ${topology_type} | ${nic_model}
 | | ...
-| | Show vpp version on all DUTs
+| | Show vpp version on all DUTs | ${nodes}
 | | Set variables in 3-node circular topology with DUT interface model
 | | ... | ${nic_model}
 | | Initialize traffic generator | ${tg} | ${tg_if1} | ${tg_if2}
 | | [Arguments] | ${rate} | ${framesize} | ${topology_type}
 | | ...
 | | Show VAT History On All DUTs | ${nodes}
-| | Show statistics on all DUTs
+| | Show statistics on all DUTs | ${nodes}
 | | Run Keyword If Test Failed
 | | ... | Traffic should pass with no loss | ${perf_trial_duration} | ${rate}
 | | ... | ${framesize} | ${topology_type} | fail_on_loss=${False}
 | | [Documentation] | Common test teardown for ndrchk performance tests.
 | | ...
 | | Show VAT History On All DUTs | ${nodes}
-| | Show statistics on all DUTs
+| | Show statistics on all DUTs | ${nodes}
 
 | Tear down performance pdrchk test
 | | [Documentation] | Common test teardown for pdrchk performance tests.
 | | ...
 | | Show VAT History On All DUTs | ${nodes}
-| | Show statistics on all DUTs
+| | Show statistics on all DUTs | ${nodes}
 
 | Tear down performance test with vhost and VM with dpdk-testpmd
 | | [Documentation] | Common test teardown for performance tests which use
 | | ... | ${dut2_node}=${None} | ${dut2_vm_refs}=${None}
 | | ...
 | | Show VAT History On All DUTs | ${nodes}
-| | Show VPP vhost on all DUTs
-| | Show statistics on all DUTs
+| | Show VPP vhost on all DUTs | ${nodes}
+| | Show statistics on all DUTs | ${nodes}
 | | Run Keyword If Test Failed
 | | ... | Traffic should pass with no loss | ${perf_trial_duration} | ${rate}
 | | ... | ${framesize} | ${topology_type} | fail_on_loss=${False}
 | | ... | ${dut2_node}=${None} | ${dut2_vm_refs}=${None}
 | | ...
 | | Show VAT History On All DUTs | ${nodes}
-| | Show VPP vhost on all DUTs
-| | Show statistics on all DUTs
+| | Show VPP vhost on all DUTs | ${nodes}
+| | Show statistics on all DUTs | ${nodes}
 | | Run keyword unless | ${dut1_node}==${None}
 | | ... | Tear down guest VM with dpdk-testpmd | ${dut1} | ${dut1_vm_refs}
 | | Run keyword unless | ${dut2_node}==${None}
index 6c9f3a5..e045075 100644 (file)
 | | Run Keyword If | ${ret}==${FALSE} | Clear all counters on all DUTs
 | | Send traffic on tg | ${duration} | ${rate}pps | ${framesize}
 | | ... | ${topology_type} | warmup_time=0
-| | Run Keyword If | ${ret}==${FALSE} | Show statistics on all DUTs
+| | Run Keyword If | ${ret}==${FALSE} | Show statistics on all DUTs | ${nodes}
 | | Run keyword and return | Get latency
 
 | Traffic should pass with no loss
 | | Run Keyword If | ${ret}==${FALSE} | Clear all counters on all DUTs
 | | Send traffic on tg | ${duration} | ${rate} | ${framesize}
 | | ... | ${topology_type} | warmup_time=0
-| | Run Keyword If | ${ret}==${FALSE} | Show statistics on all DUTs
+| | Run Keyword If | ${ret}==${FALSE} | Show statistics on all DUTs | ${nodes}
 | | Run Keyword If | ${fail_on_loss} | No traffic loss occurred
 
 | Traffic should pass with partial loss
 | | Run Keyword If | ${ret}==${FALSE} | Clear all counters on all DUTs
 | | Send traffic on tg | ${duration} | ${rate} | ${framesize}
 | | ... | ${topology_type} | warmup_time=0
-| | Run Keyword If | ${ret}==${FALSE} | Show statistics on all DUTs
+| | Run Keyword If | ${ret}==${FALSE} | Show statistics on all DUTs | ${nodes}
 | | Run Keyword If | ${fail_on_loss} | Partial traffic loss accepted
 | | ... | ${loss_acceptance} | ${loss_acceptance_type}
 
 | | Send traffic on tg | -1 | ${rate} | ${framesize} | ${topology_type}
 | | ... | warmup_time=0 | async_call=${True} | latency=${False}
 | | ${ret}= | Is DPDK performance test
-| | Run Keyword If | ${ret}==${FALSE} | Clear runtime counters on all DUTs
+| | Run Keyword If | ${ret}==${FALSE}
+| | ... | Clear runtime counters on all DUTs | ${nodes}
 | | Sleep | ${duration}
-| | Run Keyword If | ${ret}==${FALSE} | Show runtime counters on all DUTs
+| | Run Keyword If | ${ret}==${FALSE}
+| | ... | Show runtime counters on all DUTs | ${nodes}
 | | Stop traffic on tg
index 3591dd5..8a3e611 100644 (file)
@@ -13,7 +13,7 @@
 
 *** Settings ***
 | Documentation | VPP counters keywords
-| Library | resources/libraries/python/VppCounters.py
+| Library | resources.libraries.python.VppCounters
 
 *** Keywords ***
 | Clear interface counters on all vpp nodes in topology
 | | [Arguments] | ${nodes}
 | | Vpp Nodes Clear Interface Counters | ${nodes}
 
-| Get interface statistics
-| | [Documentation] | Dump stats table on VPP node
-| | [Arguments] | ${node}
-| | Vpp Dump Stats Table | ${node}
-
-| Get interface ipv6 counter
-| | [Documentation] | Return IPv6 statistics for node interface
-| | [Arguments] | ${node} | ${interface}
-| | ${ipv6_counter}= | Vpp Get Ipv6 Interface Counter | ${node} | ${interface}
-| | [Return] | ${ipv6_counter}
-
 | Check ipv4 interface counter
 | | [Documentation] | Check that ipv4 interface counter has right value
 | | [Arguments] | ${node} | ${interface} | ${value}
-| | ${ipv4_counter}= | Vpp get ipv4 interface counter | ${node} | ${interface}
+| | ${ipv4_counter}= | Vpp get ipv4 interface counter | ${node}
+| | ... | ${interface}
 | | Should Be Equal | ${ipv4_counter} | ${value}
 
-| Show statistics on all DUTs
-| | [Documentation] | Show VPP statistics on all DUTs
-| | Sleep | 10 | Waiting for statistics to be collected
-| | ${duts}= | Get Matches | ${nodes} | DUT*
-| | :FOR | ${dut} | IN | @{duts}
-| | | Show vpp statistics | ${nodes['${dut}']}
-
-| Show vpp statistics
-| | [Documentation] | Show [error, hardware, interface] stats
-| | [Arguments] | ${node}
-| | Vpp Show Errors | ${node}
-| | Vpp Show Hardware Detail | ${node}
-| | Vpp Show Runtime | ${node}
-
 | Clear all counters on all DUTs
 | | [Documentation] | Clear runtime, interface, hardware and error counters
 | | ... | on all DUTs with VPP instance
-| | Clear runtime counters on all DUTs
-| | Clear interface counters on all DUTs
-| | Clear hardware counters on all DUTs
-| | Clear error counters on all DUTs
-
-| Clear runtime counters on all DUTs
-| | [Documentation] | Clear VPP runtime counters on all DUTs
-| | ${duts}= | Get Matches | ${nodes} | DUT*
-| | :FOR | ${dut} | IN | @{duts}
-| | | Vpp clear runtime | ${nodes['${dut}']}
-
-| Clear interface counters on all DUTs
-| | [Documentation] | Clear VPP interface counters on all DUTs
-| | ${duts}= | Get Matches | ${nodes} | DUT*
-| | :FOR | ${dut} | IN | @{duts}
-| | | Vpp clear interface counters | ${nodes['${dut}']}
-
-| Clear hardware counters on all DUTs
-| | [Documentation] | Clear VPP hardware counters on all DUTs
-| | ${duts}= | Get Matches | ${nodes} | DUT*
-| | :FOR | ${dut} | IN | @{duts}
-| | | Vpp clear hardware counters | ${nodes['${dut}']}
-
-| Clear error counters on all DUTs
-| | [Documentation] | Clear VPP errors counters on all DUTs
-| | ${duts}= | Get Matches | ${nodes} | DUT*
-| | :FOR | ${dut} | IN | @{duts}
-| | | Vpp clear errors counters | ${nodes['${dut}']}
-
-| Show runtime counters on all DUTs
-| | [Documentation] | Show VPP runtime counters on all DUTs
-| | ${duts}= | Get Matches | ${nodes} | DUT*
-| | :FOR | ${dut} | IN | @{duts}
-| | | Vpp show runtime | ${nodes['${dut}']}
+| | Clear runtime counters on all DUTs | ${nodes}
+| | Clear interface counters on all DUTs | ${nodes}
+| | Clear hardware counters on all DUTs | ${nodes}
+| | Clear error counters on all DUTs | ${nodes}
index 48b61e5..ddf2040 100644 (file)
@@ -23,8 +23,8 @@
 | Library | resources.libraries.python.TGSetup
 | Library | resources.libraries.python.L2Util
 | Library | resources.libraries.python.Tap
-| Library | resources/libraries/python/VppConfigGenerator.py
-| Library | resources/libraries/python/VppCounters.py
+| Library | resources.libraries.python.VppConfigGenerator
+| Library | resources.libraries.python.VppCounters
 | Library | Collections
 
 *** Keywords ***
 | | ...
 | | All TGs Set Interface Default Driver | ${nodes}
 
-| Show VPP version on all DUTs
-| | [Documentation] | Show VPP version verbose on all DUTs.
-| | ...
-| | ${duts}= | Get Matches | ${nodes} | DUT*
-| | :FOR | ${dut} | IN | @{duts}
-| | | Vpp show version verbose | ${nodes['${dut}']}
-
 | Show Vpp Errors On All DUTs
 | | [Documentation] | Show VPP errors verbose on all DUTs.
 | | ...
 | | | Vpp api trace save | ${nodes['${dut}']}
 | | | Vpp api trace dump | ${nodes['${dut}']}
 
-| Show VPP vhost on all DUTs
-| | [Documentation] | Show Vhost User on all DUTs.
-| | ...
-| | ${duts}= | Get Matches | ${nodes} | DUT*
-| | :FOR | ${dut} | IN | @{duts}
-| | | Vpp Show Vhost | ${nodes['${dut}']}
-
 | Show Bridge Domain Data On All DUTs
 | | [Documentation] | Show Bridge Domain data on all DUTs.
 | | ...

©2016 FD.io a Linux Foundation Collaborative Project. All Rights Reserved.
Linux Foundation is a registered trademark of The Linux Foundation. Linux is a registered trademark of Linus Torvalds.
Please see our privacy policy and terms of use.