From ea4aaf7851220a2e89df327ae26753a52ea243c1 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 27 Jul 2025 16:17:25 +0000 Subject: [PATCH] feat: Add unit tests for keystroke simulation This commit adds unit tests to the project to simulate and verify keystrokes. It includes a new test script, input events for the test, and modifications to the CI and build files to incorporate the new tests. --- .github/workflows/ci.yml | 5 +++ depcomp | 1 + install-sh | 1 + missing | 1 + scripts/Makefile.am | 1 + scripts/input_events.txt | 19 ++++++++++ scripts/simple_test.sh | 81 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 109 insertions(+) create mode 120000 depcomp create mode 120000 install-sh create mode 120000 missing create mode 100644 scripts/input_events.txt create mode 100644 scripts/simple_test.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7cd4123..2cfead0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,3 +36,8 @@ jobs: run: | cd build src/logkeys --help + + - name: Run integration tests + run: | + sudo apt install python3-libevdev + scripts/simple_test.sh diff --git a/depcomp b/depcomp new file mode 120000 index 0000000..4ed246b --- /dev/null +++ b/depcomp @@ -0,0 +1 @@ +/usr/share/automake-1.16/depcomp \ No newline at end of file diff --git a/install-sh b/install-sh new file mode 120000 index 0000000..ae5e89b --- /dev/null +++ b/install-sh @@ -0,0 +1 @@ +/usr/share/automake-1.16/install-sh \ No newline at end of file diff --git a/missing b/missing new file mode 120000 index 0000000..6059988 --- /dev/null +++ b/missing @@ -0,0 +1 @@ +/usr/share/automake-1.16/missing \ No newline at end of file diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 89e8142..dad0d49 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -1,2 +1,3 @@ myconfdir=$(sysconfdir) myconf_SCRIPTS = logkeys-start.sh logkeys-kill.sh +dist_noinst_SCRIPTS = simple_test.sh diff --git a/scripts/input_events.txt b/scripts/input_events.txt new file mode 100644 index 0000000..ddcd685 --- /dev/null +++ b/scripts/input_events.txt @@ -0,0 +1,19 @@ +# This file contains a sequence of input events to be fed into +# the fake input device created by the simple_test.sh script. +# Each line represents a single input event, with the format: +# +# +# The events in this file correspond to the keystrokes "hello". + +EV_KEY KEY_H 1 +EV_KEY KEY_H 0 +EV_KEY KEY_E 1 +EV_KEY KEY_E 0 +EV_key KEY_L 1 +EV_key KEY_L 0 +EV_key KEY_L 1 +EV_key KEY_L 0 +EV_key KEY_O 1 +EV_key KEY_O 0 +EV_KEY KEY_ENTER 1 +EV_KEY KEY_ENTER 0 diff --git a/scripts/simple_test.sh b/scripts/simple_test.sh new file mode 100644 index 0000000..76fbfea --- /dev/null +++ b/scripts/simple_test.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +# A simple integration test for logkeys. +# +# This test creates a fake input device using libevdev, +# then runs logkeys to capture a few simulated keystrokes from this device. +# Finally, it checks that the keystrokes were logged correctly. + +set -euo pipefail + +INPUT_EVENTS_TXT="$(dirname "$0")/input_events.txt" +LOGKEYS_BIN="$(dirname "$0")/../build/src/logkeys" +FAKE_INPUT_DEV="/tmp/fake-input-dev" +LOG_FILE="/tmp/logkeys.log" + +if [ ! -x "$LOGKEYS_BIN" ]; then + echo "Error: logkeys binary not found at $LOGKEYS_BIN" + exit 1 +fi + +# Clean up from previous runs +rm -f "$FAKE_INPUT_DEV" "$LOG_FILE" + +# Create a fake input device and feed it some events. +# This needs to run in the background since libevdev-events-text +# will block waiting for a client to connect. +python3 -c ' +import libevdev +import sys +import time + +d = libevdev.Device() +d.name = "fake-input-device" +for line in sys.stdin: + line = line.strip() + if not line or line.startswith("#"): + continue + event_type, event_code, value = line.split() + event_type = getattr(libevdev.EV, event_type) + event_code = getattr(libevdev.EV, event_code) + value = int(value) + d.create_event(event_type, event_code, value) + d.create_event(libevdev.EV.EV_SYN, libevdev.EV.SYN_REPORT, 0) +with open("/tmp/fake-input-dev", "wb") as f: + f.write(d.fd.read()) +' < "$INPUT_EVENTS_TXT" & +evdev_pid=$! + +# Wait for the fake input device to be created +sleep 0.1 + +# Run logkeys in the background +"$LOGKEYS_BIN" --start --device "$FAKE_INPUT_DEV" --output "$LOG_FILE" +logkeys_pid=$(pgrep logkeys) + +# Wait for logkeys to start and log some keys +sleep 0.5 + +# Stop logkeys +kill "$logkeys_pid" + +# Stop the event generator +kill "$evdev_pid" + +# Wait for processes to exit +wait "$logkeys_pid" || true +wait "$evdev_pid" || true + +# Check that the log file contains the expected output +# The expected output is "hello" +EXPECTED_OUTPUT="hello" +ACTUAL_OUTPUT=$(cat "$LOG_FILE" | grep -v '^#' | tr -d '\n') +if [ "$ACTUAL_OUTPUT" = "$EXPECTED_OUTPUT" ]; then + echo "Test passed!" + exit 0 +else + echo "Test failed!" + echo "Expected output: $EXPECTED_OUTPUT" + echo "Actual output: $ACTUAL_OUTPUT" + exit 1 +fi