Fix breakage in open_perf_buffer

The previous commit for splitting table.py into a separate file lost
some required imports. Add those back.

In addition, add a test for open_perf_buffer, and take out the
compile-time check in libbpf.c for this feature.

I couldn't think of a good way to fix the PERF_COUNT_SW_BPF_OUTPUT
literal, so for now left it as a comment. A #define wouldn't work since
the eventual value comes from an enum (no #ifndef/#define/#endif
pattern).

Fixes: #391 #363
Signed-off-by: Brenden Blanco <bblanco@plumgrid.com>
diff --git a/tests/cc/test_array.py b/tests/cc/test_array.py
index 9dcb731..3fe1dce 100755
--- a/tests/cc/test_array.py
+++ b/tests/cc/test_array.py
@@ -3,7 +3,7 @@
 # Licensed under the Apache License, Version 2.0 (the "License")
 
 from bcc import BPF
-from ctypes import c_int, c_ulonglong
+import ctypes as ct
 import random
 import time
 from unittest import main, TestCase
@@ -12,8 +12,8 @@
     def test_simple(self):
         b = BPF(text="""BPF_TABLE("array", int, u64, table1, 128);""")
         t1 = b["table1"]
-        t1[c_int(0)] = c_ulonglong(100)
-        t1[c_int(127)] = c_ulonglong(1000)
+        t1[ct.c_int(0)] = ct.c_ulonglong(100)
+        t1[ct.c_int(127)] = ct.c_ulonglong(1000)
         for i, v in t1.items():
             if i.value == 0:
                 self.assertEqual(v.value, 100)
@@ -24,9 +24,9 @@
     def test_native_type(self):
         b = BPF(text="""BPF_TABLE("array", int, u64, table1, 128);""")
         t1 = b["table1"]
-        t1[0] = c_ulonglong(100)
-        t1[-2] = c_ulonglong(37)
-        t1[127] = c_ulonglong(1000)
+        t1[0] = ct.c_ulonglong(100)
+        t1[-2] = ct.c_ulonglong(37)
+        t1[127] = ct.c_ulonglong(1000)
         for i, v in t1.items():
             if i.value == 0:
                 self.assertEqual(v.value, 100)
@@ -36,5 +36,32 @@
         self.assertEqual(t1[-2].value, 37)
         self.assertEqual(t1[-1].value, t1[127].value)
 
+    def test_perf_buffer(self):
+        self.counter = 0
+
+        class Data(ct.Structure):
+            _fields_ = [("ts", ct.c_ulonglong)]
+
+        def cb(cpu, data, size):
+            self.assertGreater(size, ct.sizeof(Data))
+            event = ct.cast(data, ct.POINTER(Data)).contents
+            self.counter += 1
+
+        text = """
+BPF_PERF_OUTPUT(events);
+int kprobe__sys_nanosleep(void *ctx) {
+    struct {
+        u64 ts;
+    } data = {bpf_ktime_get_ns()};
+    events.perf_submit(ctx, &data, sizeof(data));
+    return 0;
+}
+"""
+        b = BPF(text=text)
+        b["events"].open_perf_buffer(cb)
+        time.sleep(0.1)
+        b.kprobe_poll()
+        self.assertGreater(self.counter, 0)
+
 if __name__ == "__main__":
     main()