From patchwork Wed Mar 13 01:05:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 731 Return-Path: Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2DCC3610B6 for ; Wed, 13 Mar 2019 02:06:21 +0100 (CET) X-Halon-ID: 34d81ee4-452c-11e9-846a-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 34d81ee4-452c-11e9-846a-005056917a89; Wed, 13 Mar 2019 02:06:18 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 13 Mar 2019 02:05:29 +0100 Message-Id: <20190313010532.28960-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190313010532.28960-1-niklas.soderlund@ragnatech.se> References: <20190313010532.28960-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 1/4] test: camera: Add read default configuration test X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Mar 2019 01:06:21 -0000 Add a test to verify reading the default configuration from a camera works. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- test/camera/camera_test.cpp | 74 +++++++++++++++++++++++++++ test/camera/camera_test.h | 35 +++++++++++++ test/camera/configuration_default.cpp | 71 +++++++++++++++++++++++++ test/camera/meson.build | 12 +++++ test/meson.build | 1 + 5 files changed, 193 insertions(+) create mode 100644 test/camera/camera_test.cpp create mode 100644 test/camera/camera_test.h create mode 100644 test/camera/configuration_default.cpp create mode 100644 test/camera/meson.build diff --git a/test/camera/camera_test.cpp b/test/camera/camera_test.cpp new file mode 100644 index 0000000000000000..a92f2165bf3a53c1 --- /dev/null +++ b/test/camera/camera_test.cpp @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * libcamera Camera API tests + */ + +#include + +#include "camera_test.h" + +using namespace libcamera; +using namespace std; + +int CameraTest::init() +{ + cm_ = CameraManager::instance(); + + if (cm_->start()) { + cout << "Failed to start camera manager" << endl; + return TestFail; + } + + camera_ = cm_->get("VIMC Sensor B"); + if (!camera_) { + cout << "Can not find VIMC camera" << endl; + return TestSkip; + } + + /* Sanity check that the camera has streams. */ + if (camera_->streams().empty()) { + cout << "Camera has no stream" << endl; + return TestFail; + } + + return TestPass; +} + +void CameraTest::cleanup() +{ + if (camera_) { + camera_->release(); + camera_.reset(); + } + + cm_->stop(); +}; + +bool CameraTest::configurationValid(const std::set &streams, + const std::map &conf) const +{ + /* Test that the numbers of streams matches that of configuration. */ + if (streams.size() != conf.size()) + return false; + + /* + * Test that stream can be found in configuration and that the + * configuration is valid. + */ + for (Stream *stream : streams) { + std::map::const_iterator it = + conf.find(stream); + + if (it == conf.end()) + return false; + + const StreamConfiguration *sconf = &it->second; + if (sconf->width == 0 || sconf->height == 0 || + sconf->pixelFormat == 0 || sconf->bufferCount == 0) + return false; + } + + return true; +} diff --git a/test/camera/camera_test.h b/test/camera/camera_test.h new file mode 100644 index 0000000000000000..48fb47a23fe8f49c --- /dev/null +++ b/test/camera/camera_test.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * camera_test.h - libcamera camera test base class + */ +#ifndef __LIBCAMERA_CAMERA_TEST_H__ +#define __LIBCAMERA_CAMERA_TEST_H__ + +#include + +#include "test.h" + +using namespace libcamera; + +class CameraTest : public Test +{ +public: + CameraTest() + : cm_(nullptr) {} + +protected: + int init(); + void cleanup(); + + bool configurationValid(const std::set &streams, + const std::map &conf) const; + + std::shared_ptr camera_; + +private: + CameraManager *cm_; +}; + +#endif /* __LIBCAMERA_CAMERA_TEST_H__ */ diff --git a/test/camera/configuration_default.cpp b/test/camera/configuration_default.cpp new file mode 100644 index 0000000000000000..71e79844667591b2 --- /dev/null +++ b/test/camera/configuration_default.cpp @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * libcamera Camera API tests + */ + +#include + +#include "camera_test.h" + +using namespace std; + +namespace { + +class ConfigurationDefault : public CameraTest +{ +protected: + int run() + { + std::map conf; + + /* + * Test that asking for default configuration for a valid + * array of streams returns something valid. + */ + std::set streams = { *camera_->streams().begin() }; + conf = camera_->streamConfiguration(streams); + if (conf.empty()) { + cout << "Failed to retrieve configuration for valid streams" + << endl; + return TestFail; + } + + if (!configurationValid(streams, conf)) { + cout << "Default configuration invalid" << endl; + return TestFail; + } + + /* + * Test that asking for configuration for an empty array of + * streams returns an empty list of configurations. + */ + std::set streams_empty = {}; + conf = camera_->streamConfiguration(streams_empty); + if (!conf.empty()) { + cout << "Failed to retrieve configuration for empty streams" + << endl; + return TestFail; + } + + /* + * Test that asking for configuration for an array of bad streams + * returns an empty list of configurations. + */ + Stream *stream_bad = reinterpret_cast(0xdeadbeef); + std::set streams_bad = { stream_bad }; + conf = camera_->streamConfiguration(streams_bad); + if (!conf.empty()) { + cout << "Failed to retrieve configuration for bad streams" + << endl; + return TestFail; + } + + return TestPass; + } +}; + +} /* namespace */ + +TEST_REGISTER(ConfigurationDefault); diff --git a/test/camera/meson.build b/test/camera/meson.build new file mode 100644 index 0000000000000000..186ba211b9fde026 --- /dev/null +++ b/test/camera/meson.build @@ -0,0 +1,12 @@ +# Tests are listed in order of complexity. +# They are not alphabetically sorted. +camera_tests = [ + [ 'configuration_default', 'configuration_default.cpp' ], +] + +foreach t : camera_tests + exe = executable(t[0], [t[1], 'camera_test.cpp'], + link_with : test_libraries, + include_directories : test_includes_internal) + test(t[0], exe, suite: 'camera', is_parallel: false) +endforeach diff --git a/test/meson.build b/test/meson.build index 5fb16fa6afb62f8d..71a96921697c0e9e 100644 --- a/test/meson.build +++ b/test/meson.build @@ -1,5 +1,6 @@ subdir('libtest') +subdir('camera') subdir('media_device') subdir('pipeline') subdir('v4l2_device') From patchwork Wed Mar 13 01:05:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 732 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 16FCF600FD for ; Wed, 13 Mar 2019 02:06:22 +0100 (CET) X-Halon-ID: 360d9ffb-452c-11e9-846a-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 360d9ffb-452c-11e9-846a-005056917a89; Wed, 13 Mar 2019 02:06:20 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 13 Mar 2019 02:05:30 +0100 Message-Id: <20190313010532.28960-3-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190313010532.28960-1-niklas.soderlund@ragnatech.se> References: <20190313010532.28960-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 2/4] test: camera: Add setting of configuration test X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Mar 2019 01:06:22 -0000 Try to set the default configuration, a modified valid configuration and an invalid configuration. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- test/camera/configuration_set.cpp | 91 +++++++++++++++++++++++++++++++ test/camera/meson.build | 1 + 2 files changed, 92 insertions(+) create mode 100644 test/camera/configuration_set.cpp diff --git a/test/camera/configuration_set.cpp b/test/camera/configuration_set.cpp new file mode 100644 index 0000000000000000..dedb85009335aa46 --- /dev/null +++ b/test/camera/configuration_set.cpp @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * libcamera Camera API tests + */ + +#include + +#include "camera_test.h" + +using namespace std; + +namespace { + +class ConfigurationSet : public CameraTest +{ +protected: + int run() + { + std::set streams = { *camera_->streams().begin() }; + std::map conf = + camera_->streamConfiguration(streams); + StreamConfiguration *sconf = &conf.begin()->second; + + if (!configurationValid(streams, conf)) { + cout << "Failed to read default configuration" << endl; + return TestFail; + } + + if (camera_->acquire()) { + cout << "Failed to acquire the camera" << endl; + return TestFail; + } + + /* Test that setting the default configuration works. */ + if (camera_->configureStreams(conf)) { + cout << "Failed to set default configuration" << endl; + return TestFail; + } + + /* + * Test that configuring the camera fails if it is not + * acquired, this will also test release and reacquiring + * of the camera. + */ + if (camera_->release()) { + cout << "Failed to release the camera" << endl; + return TestFail; + } + + if (!camera_->configureStreams(conf)) { + cout << "Setting configuration on a camera not acquired succeeded when it should have failed" + << endl; + return TestFail; + } + + if (camera_->acquire()) { + cout << "Failed to acquire the camera" << endl; + return TestFail; + } + + /* + * Test that modifying the default configuration works. Doubling + * the default configuration of the VIMC camera is known to + * work. + */ + sconf->width *= 2; + sconf->height *= 2; + if (camera_->configureStreams(conf)) { + cout << "Failed to set modified configuration" << endl; + return TestFail; + } + + /* + * Test that setting an invalid configuration fails. + */ + sconf->width = 0; + sconf->height = 0; + if (!camera_->configureStreams(conf)) { + cout << "Invalid configuration incorrectly accepted" << endl; + return TestFail; + } + + return TestPass; + } +}; + +} /* namespace */ + +TEST_REGISTER(ConfigurationSet); diff --git a/test/camera/meson.build b/test/camera/meson.build index 186ba211b9fde026..ed4837190ff6c52c 100644 --- a/test/camera/meson.build +++ b/test/camera/meson.build @@ -2,6 +2,7 @@ # They are not alphabetically sorted. camera_tests = [ [ 'configuration_default', 'configuration_default.cpp' ], + [ 'configuration_set', 'configuration_set.cpp' ], ] foreach t : camera_tests From patchwork Wed Mar 13 01:05:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 733 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1EDE2610BF for ; Wed, 13 Mar 2019 02:06:23 +0100 (CET) X-Halon-ID: 3695721b-452c-11e9-846a-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 3695721b-452c-11e9-846a-005056917a89; Wed, 13 Mar 2019 02:06:21 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 13 Mar 2019 02:05:31 +0100 Message-Id: <20190313010532.28960-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190313010532.28960-1-niklas.soderlund@ragnatech.se> References: <20190313010532.28960-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 3/4] test: camera: Add capture test X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Mar 2019 01:06:23 -0000 Correctly configure the camera using the default configuration and run a capture session for 100 milliseconds, which is plenty of time, in tests over 600 requests completed using the vimc pipeline. The test passes if at least the number of buffers used in the capture times two number of requests completes to prove we cycle through all buffers. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- test/camera/capture.cpp | 142 ++++++++++++++++++++++++++++++++++++++++ test/camera/meson.build | 1 + 2 files changed, 143 insertions(+) create mode 100644 test/camera/capture.cpp diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp new file mode 100644 index 0000000000000000..28eb61405d90a4c7 --- /dev/null +++ b/test/camera/capture.cpp @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * libcamera Camera API tests + */ + +#include + +#include "camera_test.h" + +using namespace std; + +namespace { + +class Capture : public CameraTest +{ +protected: + unsigned int completeBuffersCount_; + unsigned int completeRequestsCount_; + + void bufferComplete(Request *request, Buffer *buffer) + { + if (buffer->status() != Buffer::BufferSuccess) + return; + + completeBuffersCount_++; + } + + void requestComplete(Request *request, const std::map &buffers) + { + if (request->status() != Request::RequestComplete) + return; + + completeRequestsCount_++; + + /* Reuse the buffers for a new request. */ + request = camera_->createRequest(); + request->setBuffers(buffers); + camera_->queueRequest(request); + } + + int run() + { + Stream *stream = *camera_->streams().begin(); + std::set streams = { stream }; + std::map conf = + camera_->streamConfiguration(streams); + StreamConfiguration *sconf = &conf.begin()->second; + + if (!configurationValid(streams, conf)) { + cout << "Failed to read default configuration" << endl; + return TestFail; + } + + if (camera_->acquire()) { + cout << "Failed to acquire the camera" << endl; + return TestFail; + } + + if (camera_->configureStreams(conf)) { + cout << "Failed to set default configuration" << endl; + return TestFail; + } + + if (camera_->allocateBuffers()) { + cout << "Failed to allocate buffers" << endl; + return TestFail; + } + + BufferPool &pool = stream->bufferPool(); + std::vector requests; + for (Buffer &buffer : pool.buffers()) { + Request *request = camera_->createRequest(); + if (!request) { + cout << "Failed to create request" << endl; + return TestFail; + } + + std::map map = { { stream, &buffer } }; + if (request->setBuffers(map)) { + cout << "Failed to associating buffer with request" << endl; + return TestFail; + } + + requests.push_back(request); + } + + completeRequestsCount_ = 0; + completeBuffersCount_ = 0; + + camera_->bufferCompleted.connect(this, &Capture::bufferComplete); + camera_->requestCompleted.connect(this, &Capture::requestComplete); + + if (camera_->start()) { + cout << "Failed to start camera" << endl; + return TestFail; + } + + for (Request *request : requests) { + if (camera_->queueRequest(request)) { + cout << "Failed to queue request" << endl; + return TestFail; + } + } + + EventDispatcher *dispatcher = CameraManager::instance()->eventDispatcher(); + + Timer timer; + timer.start(100); + while (timer.isRunning()) + dispatcher->processEvents(); + + if (completeRequestsCount_ <= sconf->bufferCount * 2) { + cout << "Failed to capture enough frames (got " + << completeRequestsCount_ << " expected at least " + << sconf->bufferCount * 2 << ")" << endl; + return TestFail; + } + + if (completeRequestsCount_ != completeBuffersCount_) { + cout << "Number of completed buffers and requests differ" << endl; + return TestFail; + } + + if (camera_->stop()) { + cout << "Failed to stop camera" << endl; + return TestFail; + } + + if (camera_->freeBuffers()) { + cout << "Failed to free buffers" << endl; + return TestFail; + } + + return TestPass; + } +}; + +} /* namespace */ + +TEST_REGISTER(Capture); diff --git a/test/camera/meson.build b/test/camera/meson.build index ed4837190ff6c52c..a1fd20326e97538b 100644 --- a/test/camera/meson.build +++ b/test/camera/meson.build @@ -3,6 +3,7 @@ camera_tests = [ [ 'configuration_default', 'configuration_default.cpp' ], [ 'configuration_set', 'configuration_set.cpp' ], + [ 'capture', 'capture.cpp' ], ] foreach t : camera_tests From patchwork Wed Mar 13 01:05:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 734 Return-Path: Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C7556610C5 for ; Wed, 13 Mar 2019 02:06:24 +0100 (CET) X-Halon-ID: 37439e65-452c-11e9-846a-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 37439e65-452c-11e9-846a-005056917a89; Wed, 13 Mar 2019 02:06:22 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 13 Mar 2019 02:05:32 +0100 Message-Id: <20190313010532.28960-5-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190313010532.28960-1-niklas.soderlund@ragnatech.se> References: <20190313010532.28960-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 4/4] test: camera: Add state machine test X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Mar 2019 01:06:25 -0000 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 Reviewed-by: Laurent Pinchart --- 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 a1fd20326e97538b..c4427945e4a25371 100644 --- a/test/camera/meson.build +++ b/test/camera/meson.build @@ -3,6 +3,7 @@ camera_tests = [ [ 'configuration_default', 'configuration_default.cpp' ], [ 'configuration_set', 'configuration_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 + +#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 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 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 defconf_; +}; + +} /* namespace */ + +TEST_REGISTER(Statemachine);