[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