OSDN Git Service

Update binder benchmark to use google-benchmark
[android-x86/system-extras.git] / tests / net_test / netlink.py
index 65dc4b6..2b8f744 100644 (file)
@@ -79,11 +79,12 @@ class NetlinkSocket(object):
   def _GetConstantName(self, module, value, prefix):
     thismodule = sys.modules[module]
     for name in dir(thismodule):
+      if name.startswith("INET_DIAG_BC"):
+        break
       if (name.startswith(prefix) and
           not name.startswith(prefix + "F_") and
-          name.isupper() and
-          getattr(thismodule, name) == value):
-        return name
+          name.isupper() and getattr(thismodule, name) == value):
+          return name
     return value
 
   def _Decode(self, command, msg, nla_type, nla_data):
@@ -121,9 +122,10 @@ class NetlinkSocket(object):
       # If it's an attribute we know about, try to decode it.
       nla_name, nla_data = self._Decode(command, msg, nla.nla_type, nla_data)
 
-      # We only support unique attributes for now.
-      if nla_name in attributes:
-        raise ValueError("Duplicate attribute %d" % nla_name)
+      # We only support unique attributes for now, except for INET_DIAG_NONE,
+      # which can appear more than once but doesn't seem to contain any data.
+      if nla_name in attributes and nla_name != "INET_DIAG_NONE":
+        raise ValueError("Duplicate attribute %s" % nla_name)
 
       attributes[nla_name] = nla_data
       self._Debug("      %s" % str((nla_name, nla_data)))
@@ -199,6 +201,12 @@ class NetlinkSocket(object):
     data = data[attrlen:]
     return (nlmsg, attributes), data
 
+  def _GetMsg(self, msgtype):
+    data = self._Recv()
+    if NLMsgHdr(data).type == NLMSG_ERROR:
+      self._ParseAck(data)
+    return self._ParseNLMsg(data, msgtype)[0]
+
   def _GetMsgList(self, msgtype, data, expect_done):
     out = []
     while data:
@@ -210,15 +218,26 @@ class NetlinkSocket(object):
       self._ExpectDone()
     return out
 
-  def _Dump(self, command, msg, msgtype):
-    """Sends a dump request and returns a list of decoded messages."""
+  def _Dump(self, command, msg, msgtype, attrs):
+    """Sends a dump request and returns a list of decoded messages.
+
+    Args:
+      command: An integer, the command to run (e.g., RTM_NEWADDR).
+      msg: A string, the raw bytes of the request (e.g., a packed RTMsg).
+      msgtype: A cstruct.Struct, the data type to parse the dump results as.
+      attrs: A string, the raw bytes of any request attributes to include.
+
+    Returns:
+      A list of (msg, attrs) tuples where msg is of type msgtype and attrs is
+      a dict of attributes.
+    """
     # Create a netlink dump request containing the msg.
     flags = NLM_F_DUMP | NLM_F_REQUEST
-    length = len(NLMsgHdr) + len(msg)
+    length = len(NLMsgHdr) + len(msg) + len(attrs)
     nlmsghdr = NLMsgHdr((length, command, flags, self.seq, self.pid))
 
     # Send the request.
-    self._Send(nlmsghdr.Pack() + msg.Pack())
+    self._Send(nlmsghdr.Pack() + msg.Pack() + attrs)
 
     # Keep reading netlink messages until we get a NLMSG_DONE.
     out = []
@@ -227,6 +246,10 @@ class NetlinkSocket(object):
       response_type = NLMsgHdr(data).type
       if response_type == NLMSG_DONE:
         break
+      elif response_type == NLMSG_ERROR:
+        # Likely means that the kernel didn't like our dump request.
+        # Parse the error and throw an exception.
+        self._ParseAck(data)
       out.extend(self._GetMsgList(msgtype, data, False))
 
     return out