[libcamera-devel,1/4] tests: Test event dispatcher interruption by signal

Message ID 20190123085923.12524-2-laurent.pinchart@ideasonboard.com
State Accepted
Commit 83c73c39c5c6b115fc80e6133433b70753499bab
Headers show
Series
  • Event dispatcher enhancements
Related show

Commit Message

Laurent Pinchart Jan. 23, 2019, 8:59 a.m. UTC
Add a test to verify that the event dispatcher correctly restarts event
processing when interrupted by a signal. The test currently fails as
this feature isn't implemented.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 test/event-dispatcher.cpp | 73 +++++++++++++++++++++++++++++++++++++++
 test/meson.build          |  9 ++---
 2 files changed, 78 insertions(+), 4 deletions(-)
 create mode 100644 test/event-dispatcher.cpp

Comments

Kieran Bingham Jan. 23, 2019, 11:13 a.m. UTC | #1
Hi Laurent,

On 23/01/2019 08:59, Laurent Pinchart wrote:
> Add a test to verify that the event dispatcher correctly restarts event
> processing when interrupted by a signal. The test currently fails as
> this feature isn't implemented.

A test which fails! Yay :)

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  test/event-dispatcher.cpp | 73 +++++++++++++++++++++++++++++++++++++++
>  test/meson.build          |  9 ++---
>  2 files changed, 78 insertions(+), 4 deletions(-)
>  create mode 100644 test/event-dispatcher.cpp
> 
> diff --git a/test/event-dispatcher.cpp b/test/event-dispatcher.cpp
> new file mode 100644
> index 000000000000..06c2657f09d6
> --- /dev/null
> +++ b/test/event-dispatcher.cpp
> @@ -0,0 +1,73 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2019, Google Inc.
> + *
> + * event-dispatcher.cpp - Event dispatcher test
> + */
> +
> +#include <iostream>
> +#include <signal.h>
> +#include <sys/time.h>
> +
> +#include <libcamera/camera_manager.h>
> +#include <libcamera/event_dispatcher.h>
> +#include <libcamera/timer.h>
> +
> +#include "test.h"
> +
> +using namespace std;
> +using namespace libcamera;
> +
> +class EventDispatcherTest : public Test
> +{
> +protected:
> +	static void sigAlarmHandler(int)
> +	{
> +		cout << "SIGALARM received" << endl;
> +	}
> +
> +	int init()
> +	{
> +		struct sigaction sa = {};
> +		sa.sa_handler = &sigAlarmHandler;
> +		sigaction(SIGALRM, &sa, nullptr);
> +
> +		return 0;
> +	}
> +
> +	int run()
> +	{
> +		EventDispatcher *dispatcher = CameraManager::instance()->eventDispatcher();
> +		Timer timer;
> +
> +		/* Event processing interruption by signal. */
> +		struct timespec start;
> +		clock_gettime(CLOCK_MONOTONIC, &start);
> +
> +		timer.start(1000);
> +
> +		struct itimerval itimer = {};
> +		itimer.it_value.tv_usec = 500000;

I would have suggested reducing these timers but I don't think it matters.

The meson test suite executes these tests in parallel, and the longest
test is the timer test already.

time ninja test:
...
6/9 libcamera / event-dispatcher            OK       1.52 s
...
9/9 libcamera / timer                       OK       8.12 s
...
real    0m8.488s

The full duration of running the tests is not much longer than the
longest test, so we're good.


> +		setitimer(ITIMER_REAL, &itimer, nullptr);
> +
> +		dispatcher->processEvents();
> +
> +		struct timespec stop;
> +		clock_gettime(CLOCK_MONOTONIC, &stop);
> +		int duration = (stop.tv_sec - start.tv_sec) * 1000;
> +		duration += (stop.tv_nsec - start.tv_nsec) / 1000000;
> +
> +		if (abs(duration - 1000) > 50) {
> +			cout << "Event processing restart test failed" << endl;
> +			return TestFail;
> +		}
> +
> +		return TestPass;
> +	}
> +
> +	void cleanup()
> +	{
> +	}
> +};
> +
> +TEST_REGISTER(EventDispatcherTest)
> diff --git a/test/meson.build b/test/meson.build
> index 8cdcae2c9e87..d515a716207e 100644
> --- a/test/meson.build
> +++ b/test/meson.build
> @@ -5,10 +5,11 @@ subdir('pipeline')
>  subdir('v4l2_device')
>  
>  public_tests = [
> -    ['event',           'event.cpp'],
> -    ['list-cameras',    'list-cameras.cpp'],
> -    ['signal',          'signal.cpp'],
> -    ['timer',           'timer.cpp'],
> +    ['event',                           'event.cpp'],
> +    ['event-dispatcher',                'event-dispatcher.cpp'],
> +    ['list-cameras',                    'list-cameras.cpp'],
> +    ['signal',                          'signal.cpp'],
> +    ['timer',                           'timer.cpp'],

Ahh - my pre-allocation of tables was not enough ...

This should last a bit longer...


>  ]
>  
>  internal_tests = [
>

Patch

diff --git a/test/event-dispatcher.cpp b/test/event-dispatcher.cpp
new file mode 100644
index 000000000000..06c2657f09d6
--- /dev/null
+++ b/test/event-dispatcher.cpp
@@ -0,0 +1,73 @@ 
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * event-dispatcher.cpp - Event dispatcher test
+ */
+
+#include <iostream>
+#include <signal.h>
+#include <sys/time.h>
+
+#include <libcamera/camera_manager.h>
+#include <libcamera/event_dispatcher.h>
+#include <libcamera/timer.h>
+
+#include "test.h"
+
+using namespace std;
+using namespace libcamera;
+
+class EventDispatcherTest : public Test
+{
+protected:
+	static void sigAlarmHandler(int)
+	{
+		cout << "SIGALARM received" << endl;
+	}
+
+	int init()
+	{
+		struct sigaction sa = {};
+		sa.sa_handler = &sigAlarmHandler;
+		sigaction(SIGALRM, &sa, nullptr);
+
+		return 0;
+	}
+
+	int run()
+	{
+		EventDispatcher *dispatcher = CameraManager::instance()->eventDispatcher();
+		Timer timer;
+
+		/* Event processing interruption by signal. */
+		struct timespec start;
+		clock_gettime(CLOCK_MONOTONIC, &start);
+
+		timer.start(1000);
+
+		struct itimerval itimer = {};
+		itimer.it_value.tv_usec = 500000;
+		setitimer(ITIMER_REAL, &itimer, nullptr);
+
+		dispatcher->processEvents();
+
+		struct timespec stop;
+		clock_gettime(CLOCK_MONOTONIC, &stop);
+		int duration = (stop.tv_sec - start.tv_sec) * 1000;
+		duration += (stop.tv_nsec - start.tv_nsec) / 1000000;
+
+		if (abs(duration - 1000) > 50) {
+			cout << "Event processing restart test failed" << endl;
+			return TestFail;
+		}
+
+		return TestPass;
+	}
+
+	void cleanup()
+	{
+	}
+};
+
+TEST_REGISTER(EventDispatcherTest)
diff --git a/test/meson.build b/test/meson.build
index 8cdcae2c9e87..d515a716207e 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -5,10 +5,11 @@  subdir('pipeline')
 subdir('v4l2_device')
 
 public_tests = [
-    ['event',           'event.cpp'],
-    ['list-cameras',    'list-cameras.cpp'],
-    ['signal',          'signal.cpp'],
-    ['timer',           'timer.cpp'],
+    ['event',                           'event.cpp'],
+    ['event-dispatcher',                'event-dispatcher.cpp'],
+    ['list-cameras',                    'list-cameras.cpp'],
+    ['signal',                          'signal.cpp'],
+    ['timer',                           'timer.cpp'],
 ]
 
 internal_tests = [