From 53f57c1a8c86dbc16414fe86b55f2ef48988f3d0 Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Sat, 1 Jun 2024 21:46:56 +0100 Subject: [PATCH] devout: support sysfs attributes for (grand*)parent device --- pkgs/devout/devout.fnl | 21 ++++++++++++++++++--- pkgs/devout/test.fnl | 23 +++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/pkgs/devout/devout.fnl b/pkgs/devout/devout.fnl index d45c4d3..1d4f888 100644 --- a/pkgs/devout/devout.fnl +++ b/pkgs/devout/devout.fnl @@ -31,13 +31,18 @@ name value (pairs expected)] (and match? (= value (event:attr name))))) +(fn ancestor-attrs-match? [event expected] + (accumulate [match? true + name value (pairs expected)] + (and match? (= value (event:ancestor-attr name))))) + (fn event-matches? [e terms] (accumulate [match? true name value (pairs terms)] (and match? (case name :attr (attrs-match? e value) - :attrs true + :attrs (ancestor-attrs-match? e value) other (= value (. e.properties name)))))) (fn read-if-exists [pathname] @@ -48,6 +53,16 @@ s1) nil nil)) +(fn event-ancestor-attr [event name] + (fn walk-up [sys-path path name] + (when path + (or (read-if-exists (.. sys-path "/" path "/" name)) + (walk-up sys-path (dirname path) name)))) + (walk-up event.sys-path event.path name)) + +(fn event-attr [event name] + (read-if-exists (.. event.sys-path "/" event.path "/" name))) + (fn parse-event [s] (let [at (string.find s "@" 1 true) (nl nxt) (string.find s "\0" 1 true) @@ -61,8 +76,8 @@ :action (string.sub s 1 (- at 1)) :format format-event :matches? event-matches? - :attr (fn [self name] - (read-if-exists (.. self.sys-path "/" self.path "/" name))) + :attr event-attr + :ancestor-attr event-ancestor-attr })) (fn find-in-database [db terms] diff --git a/pkgs/devout/test.fnl b/pkgs/devout/test.fnl index f934739..122e65f 100644 --- a/pkgs/devout/test.fnl +++ b/pkgs/devout/test.fnl @@ -133,6 +133,29 @@ MINOR=17") (expect (not m))) )) +(example + "I can find a device matching ancestor sysfs attributes" + (let [db (database {:sys-path "./fixtures/sys"}) + path "/devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.1" + e (.. "add@" path "\0ACTION=add\n" + (with-open [f (io.open (.. "fixtures/sys" path "/uevent"))] + (f:read "*a")))] + (db:add e) + (let [[m & more] (db:find {:devtype "usb_interface" + :driver "uvcvideo" + :attrs {:idVendor "13d3" + :manufacturer "Azurewave" + }})] + (expect= m.properties.driver "uvcvideo") + (expect= m.properties.interface "14/2/0") + (expect= more [])) + + (let [[m & more] (db:find {:devtype "usb_interface" + :driver "uvcvideo" + :attrs {:idVendor "23d3" + :manufacturer "Azurewave" + }})] + (expect (not m))))) ;;; tests for indices