[libcamera-devel,v2,10/11] test: Add timer test

Message ID 20190107231151.23291-11-laurent.pinchart@ideasonboard.com
State Accepted
Headers show
Series
  • libcamera: Add event notification and timers
Related show

Commit Message

Laurent Pinchart Jan. 7, 2019, 11:11 p.m. UTC
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
---
 test/meson.build |   1 +
 test/timer.cpp   | 149 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 150 insertions(+)
 create mode 100644 test/timer.cpp

Patch

diff --git a/test/meson.build b/test/meson.build
index 4000bd51808a..f26c8701d827 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -5,6 +5,7 @@  subdir('media_device')
 public_tests = [
     ['list-cameras',    'list-cameras.cpp'],
     ['signal',          'signal.cpp'],
+    ['timer',           'timer.cpp'],
 ]
 
 internal_tests = [
diff --git a/test/timer.cpp b/test/timer.cpp
new file mode 100644
index 000000000000..6a3cda70bef4
--- /dev/null
+++ b/test/timer.cpp
@@ -0,0 +1,149 @@ 
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * timer.cpp - Timer test
+ */
+
+#include <iostream>
+
+#include <libcamera/camera_manager.h>
+#include <libcamera/event_dispatcher.h>
+#include <libcamera/timer.h>
+
+#include "test.h"
+
+using namespace std;
+using namespace libcamera;
+
+class ManagedTimer : public Timer
+{
+public:
+	ManagedTimer() : Timer()
+	{
+		timeout.connect(this, &ManagedTimer::timeoutHandler);
+	}
+
+	void start(int msec)
+	{
+		interval_ = msec;
+		clock_gettime(CLOCK_MONOTONIC, &start_);
+		expiration_ = { 0, 0 };
+
+		Timer::start(msec);
+	}
+
+	int jitter()
+	{
+		int duration = (expiration_.tv_sec - start_.tv_sec) * 1000;
+		duration += (expiration_.tv_nsec - start_.tv_nsec) / 1000000;
+		return abs(duration - interval_);
+	}
+
+private:
+	void timeoutHandler(Timer *timer)
+	{
+		clock_gettime(CLOCK_MONOTONIC, &expiration_);
+	}
+
+	int interval_;
+	struct timespec start_;
+	struct timespec expiration_;
+};
+
+class TimerTest : public Test
+{
+protected:
+	int init()
+	{
+		return 0;
+	}
+
+	int run()
+	{
+		EventDispatcher *dispatcher = CameraManager::instance()->eventDispatcher();
+		ManagedTimer timer;
+		ManagedTimer timer2;
+
+		/* Timer expiration. */
+		timer.start(1000);
+
+		if (!timer.isRunning()) {
+			cout << "Timer expiration test failed" << endl;
+			return TestFail;
+		}
+
+		dispatcher->processEvents();
+
+		if (timer.isRunning() || timer.jitter() > 50) {
+			cout << "Timer expiration test failed" << endl;
+			return TestFail;
+		}
+
+		/* Timer restart. */
+		timer.start(500);
+
+		if (!timer.isRunning()) {
+			cout << "Timer restart test failed" << endl;
+			return TestFail;
+		}
+
+		dispatcher->processEvents();
+
+		if (timer.isRunning() || timer.jitter() > 50) {
+			cout << "Timer restart test failed" << endl;
+			return TestFail;
+		}
+
+		/* Two timers. */
+		timer.start(1000);
+		timer2.start(300);
+
+		dispatcher->processEvents();
+
+		if (!timer.isRunning()) {
+			cout << "Two timers test failed" << endl;
+			return TestFail;
+		}
+
+		if (timer2.jitter() > 50) {
+			cout << "Two timers test failed" << endl;
+			return TestFail;
+		}
+
+		dispatcher->processEvents();
+
+		if (timer.jitter() > 50) {
+			cout << "Two timers test failed" << endl;
+			return TestFail;
+		}
+
+		/* Restart timer before expiration. */
+		timer.start(1000);
+		timer2.start(300);
+
+		dispatcher->processEvents();
+
+		if (timer2.jitter() > 50) {
+			cout << "Two timers test failed" << endl;
+			return TestFail;
+		}
+
+		timer.start(1000);
+
+		dispatcher->processEvents();
+
+		if (timer.jitter() > 50) {
+			cout << "Two timers test failed" << endl;
+			return TestFail;
+		}
+
+		return TestPass;
+	}
+
+	void cleanup()
+	{
+	}
+};
+
+TEST_REGISTER(TimerTest)