[libcamera-devel] [PATCH 5/5] test: camera: Add state machine test
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Sun Mar 10 14:41:35 CET 2019
Hi Niklas,
Thank you for the patch.
On Wed, Mar 06, 2019 at 03:47:55AM +0100, Niklas Söderlund wrote:
> Add a test of the different access level enforced by the state machine
> inside the camera. The state machine aims to limit operations on the
> camera to the cameras state.
>
> The test exercises all states of the camera and verifies that only the
> intended operations are possible at each stage.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Nice work !
> ---
> test/camera/meson.build | 1 +
> test/camera/statemachine.cpp | 275 +++++++++++++++++++++++++++++++++++
> 2 files changed, 276 insertions(+)
> create mode 100644 test/camera/statemachine.cpp
>
> diff --git a/test/camera/meson.build b/test/camera/meson.build
> index 6da297714f34a4e3..8f1cfe5a7a5c2884 100644
> --- a/test/camera/meson.build
> +++ b/test/camera/meson.build
> @@ -3,6 +3,7 @@
> camera_tests = [
> [ 'format_default', 'format_default.cpp' ],
> [ 'format_set', 'format_set.cpp' ],
> + [ 'statemachine', 'statemachine.cpp' ],
> [ 'capture', 'capture.cpp' ],
> ]
>
> diff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp
> new file mode 100644
> index 0000000000000000..f4395f2b1bfed698
> --- /dev/null
> +++ b/test/camera/statemachine.cpp
> @@ -0,0 +1,275 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2019, Google Inc.
> + *
> + * libcamera Camera API tests
> + */
> +
> +#include <iostream>
> +
> +#include "camera_test.h"
> +
> +using namespace std;
> +
> +namespace {
> +
> +class Statemachine : public CameraTest
> +{
> +protected:
> + int testAvailable()
> + {
> + /* Test operations which should fail. */
> + if (camera_->configureStreams(defconf_) != -EACCES)
> + return TestFail;
> +
> + if (camera_->allocateBuffers() != -EACCES)
> + return TestFail;
> +
> + if (camera_->freeBuffers() != -EACCES)
> + return TestFail;
> +
> + if (camera_->createRequest())
> + return TestFail;
> +
> + if (camera_->start() != -EACCES)
> + return TestFail;
> +
> + Request request(camera_.get());
> + if (camera_->queueRequest(&request) != -EACCES)
> + return TestFail;
> +
> + if (camera_->stop() != -EACCES)
> + return TestFail;
> +
> + /* Test operations which should pass. */
> + if (camera_->release())
> + return TestFail;
> +
> + /* Test valid state transitions, end in Acquired state. */
> + if (camera_->acquire())
> + return TestFail;
> +
> + return TestPass;
> + }
> +
> + int testAcquired()
> + {
> + /* Test operations which should fail. */
> + if (camera_->acquire() != -EBUSY)
> + return TestFail;
> +
> + if (camera_->allocateBuffers() != -EACCES)
> + return TestFail;
> +
> + if (camera_->freeBuffers() != -EACCES)
> + return TestFail;
> +
> + if (camera_->createRequest())
> + return TestFail;
> +
> + if (camera_->start() != -EACCES)
> + return TestFail;
> +
> + Request request(camera_.get());
> + if (camera_->queueRequest(&request) != -EACCES)
> + return TestFail;
> +
> + if (camera_->stop() != -EACCES)
> + return TestFail;
> +
> + /* Test valid state transitions, end in Configured state. */
> + if (camera_->release())
> + return TestFail;
> +
> + if (camera_->acquire())
> + return TestFail;
> +
> + if (camera_->configureStreams(defconf_))
> + return TestFail;
> +
> + return TestPass;
> + }
> +
> + int testConfigured()
> + {
> + /* Test operations which should fail. */
> + if (camera_->acquire() != -EBUSY)
> + return TestFail;
> +
> + if (camera_->freeBuffers() != -EACCES)
> + return TestFail;
> +
> + if (camera_->createRequest())
> + return TestFail;
> +
> + Request request(camera_.get());
> + if (camera_->queueRequest(&request) != -EACCES)
> + return TestFail;
> +
> + if (camera_->start() != -EACCES)
> + return TestFail;
> +
> + if (camera_->stop() != -EACCES)
> + return TestFail;
> +
> + /* Test operations which should pass. */
> + if (camera_->configureStreams(defconf_))
> + return TestFail;
> +
> + /* Test valid state transitions, end in Prepared state. */
> + if (camera_->release())
> + return TestFail;
> +
> + if (camera_->acquire())
> + return TestFail;
> +
> + if (camera_->configureStreams(defconf_))
> + return TestFail;
> +
> + if (camera_->allocateBuffers())
> + return TestFail;
> +
> + return TestPass;
> + }
> +
> + int testPrepared()
> + {
> + /* Test operations which should fail. */
> + if (camera_->acquire() != -EBUSY)
> + return TestFail;
> +
> + if (camera_->release() != -EBUSY)
> + return TestFail;
> +
> + if (camera_->configureStreams(defconf_) != -EACCES)
> + return TestFail;
> +
> + if (camera_->allocateBuffers() != -EACCES)
> + return TestFail;
> +
> + Request request1(camera_.get());
> + if (camera_->queueRequest(&request1) != -EACCES)
> + return TestFail;
> +
> + if (camera_->stop() != -EACCES)
> + return TestFail;
> +
> + /* Test operations which should pass. */
> + Request *request2 = camera_->createRequest();
> + if (!request2)
> + return TestFail;
> +
> + /* Never handed to hardware so need to manually delete it. */
> + delete request2;
> +
> + /* Test valid state transitions, end in Running state. */
> + if (camera_->freeBuffers())
> + return TestFail;
> +
> + if (camera_->release())
> + return TestFail;
> +
> + if (camera_->acquire())
> + return TestFail;
> +
> + if (camera_->configureStreams(defconf_))
> + return TestFail;
> +
> + if (camera_->allocateBuffers())
> + return TestFail;
> +
> + if (camera_->start())
> + return TestFail;
> +
> + return TestPass;
> + }
> +
> + int testRuning()
> + {
> + /* Test operations which should fail. */
> + if (camera_->acquire() != -EBUSY)
> + return TestFail;
> +
> + if (camera_->release() != -EBUSY)
> + return TestFail;
> +
> + if (camera_->configureStreams(defconf_) != -EACCES)
> + return TestFail;
> +
> + if (camera_->allocateBuffers() != -EACCES)
> + return TestFail;
> +
> + if (camera_->freeBuffers() != -EACCES)
> + return TestFail;
> +
> + if (camera_->start() != -EACCES)
> + return TestFail;
> +
> + /* Test operations which should pass. */
> + Request *request = camera_->createRequest();
> + if (!request)
> + return TestFail;
> +
> + Stream *stream = *camera_->streams().begin();
> + BufferPool &pool = stream->bufferPool();
> + Buffer &buffer = pool.buffers().front();
> + std::map<Stream *, Buffer *> map = { { stream, &buffer } };
> + if (request->setBuffers(map))
> + return TestFail;
> +
> + if (camera_->queueRequest(request))
> + return TestFail;
> +
> + /* Test valid state transitions, end in Available state. */
> + if (camera_->stop())
> + return TestFail;
> +
> + if (camera_->freeBuffers())
> + return TestFail;
> +
> + if (camera_->release())
> + return TestFail;
> +
> + return TestPass;
> + }
> +
> + int run()
> + {
> + Stream *stream = *camera_->streams().begin();
> + std::set<Stream *> streams = { stream };
> + defconf_ = camera_->streamConfiguration(streams);
> +
> + if (testAvailable() != TestPass) {
> + cout << "State machine in Available state failed" << endl;
> + return TestFail;
> + }
> +
> + if (testAcquired() != TestPass) {
> + cout << "State machine in Acquired state failed" << endl;
> + return TestFail;
> + }
> +
> + if (testConfigured() != TestPass) {
> + cout << "State machine in Configured state failed" << endl;
> + return TestFail;
> + }
> +
> + if (testPrepared() != TestPass) {
> + cout << "State machine in Prepared state failed" << endl;
> + return TestFail;
> + }
> +
> + if (testRuning() != TestPass) {
> + cout << "State machine in Running state failed" << endl;
> + return TestFail;
> + }
> +
> + return TestPass;
> + }
> +
> + std::map<Stream *, StreamConfiguration> defconf_;
> +};
> +
> +} /* namespace */
> +
> +TEST_REGISTER(Statemachine);
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list