From patchwork Mon Mar 11 02:22: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: 711 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0A1CA610BF for ; Mon, 11 Mar 2019 03:23:06 +0100 (CET) X-Halon-ID: 99274ce3-43a4-11e9-985a-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 99274ce3-43a4-11e9-985a-005056917f90; Mon, 11 Mar 2019 03:23:03 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Mon, 11 Mar 2019 03:22:29 +0100 Message-Id: <20190311022232.4759-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190311022232.4759-1-niklas.soderlund@ragnatech.se> References: <20190311022232.4759-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: Mon, 11 Mar 2019 02:23:07 -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 | 68 ++++++++++++++++++++++++ test/camera/meson.build | 12 +++++ test/meson.build | 1 + 5 files changed, 190 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..4ba6813c40ece44b --- /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 numbers of streams matches that of configurations. */ + if (streams.size() != conf.size()) + return false; + + /* + * Test stream can be found in configuration and that the + * configuration is valid. + */ + for (Stream *stream : streams) { + std::map::const_iterator itr = + conf.find(stream); + + if (itr == conf.end()) + return false; + + const StreamConfiguration *sconf = &itr->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..b488b977c890a6da --- /dev/null +++ b/test/camera/configuration_default.cpp @@ -0,0 +1,68 @@ +/* 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 << "Retrieving 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 << "Retrieving 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 << "Retrieving 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 Mon Mar 11 02:22: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: 712 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 881B3610C5 for ; Mon, 11 Mar 2019 03:23:07 +0100 (CET) X-Halon-ID: 9a110e00-43a4-11e9-985a-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 9a110e00-43a4-11e9-985a-005056917f90; Mon, 11 Mar 2019 03:23:05 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Mon, 11 Mar 2019 03:22:30 +0100 Message-Id: <20190311022232.4759-3-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190311022232.4759-1-niklas.soderlund@ragnatech.se> References: <20190311022232.4759-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: Mon, 11 Mar 2019 02:23:07 -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 | 90 +++++++++++++++++++++++++++++++ test/camera/meson.build | 1 + 2 files changed, 91 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..cf0b96b7d1d6583c --- /dev/null +++ b/test/camera/configuration_set.cpp @@ -0,0 +1,90 @@ +/* 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 << "Reading default configuration" << endl; + return TestFail; + } + + if (camera_->acquire()) { + cout << "Acquiring the camera" << endl; + return TestFail; + } + + /* Test that setting the default configuration works. */ + if (camera_->configureStreams(conf)) { + cout << "Setting 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 << "Releasing the camera" << endl; + return TestFail; + } + + if (!camera_->configureStreams(conf)) { + cout << "Setting configuration on a camera not acquired" << endl; + return TestFail; + } + + if (camera_->acquire()) { + cout << "Acquiring 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 << "Setting modified configuration" << endl; + return TestFail; + } + + /* + * Test that setting an invalid configuration fails. + */ + sconf->width = 0; + sconf->height = 0; + if (!camera_->configureStreams(conf)) { + cout << "Setting invalid configuration" << 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 Mon Mar 11 02:22: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: 713 Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EE2CC610B6 for ; Mon, 11 Mar 2019 03:23:09 +0100 (CET) X-Halon-ID: 9ab61213-43a4-11e9-985a-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 9ab61213-43a4-11e9-985a-005056917f90; Mon, 11 Mar 2019 03:23:06 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Mon, 11 Mar 2019 03:22:31 +0100 Message-Id: <20190311022232.4759-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190311022232.4759-1-niklas.soderlund@ragnatech.se> References: <20190311022232.4759-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: Mon, 11 Mar 2019 02:23:10 -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 | 136 ++++++++++++++++++++++++++++++++++++++++ test/camera/meson.build | 1 + 2 files changed, 137 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..44adcf3639393d3f --- /dev/null +++ b/test/camera/capture.cpp @@ -0,0 +1,136 @@ +/* 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 << "Reading default configuration" << endl; + return TestFail; + } + + if (camera_->acquire()) { + cout << "Acquiring the camera" << endl; + return TestFail; + } + + if (camera_->configureStreams(conf)) { + cout << "Setting default configuration" << endl; + return TestFail; + } + + if (camera_->allocateBuffers()) { + cout << "Allocating buffers" << endl; + return TestFail; + } + + BufferPool &pool = stream->bufferPool(); + std::vector requests; + for (Buffer &buffer : pool.buffers()) { + Request *request = camera_->createRequest(); + if (!request) { + cout << "Creating requests" << endl; + return TestFail; + } + + std::map map = { { stream, &buffer } }; + if (request->setBuffers(map)) { + cout << "Associating buffers with requests" << 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 << "Starting camera" << endl; + return TestFail; + } + + for (Request *request : requests) { + if (camera_->queueRequest(request)) { + cout << "Queueing requests" << endl; + return TestFail; + } + } + + EventDispatcher *dispatcher = CameraManager::instance()->eventDispatcher(); + + Timer timer; + timer.start(100); + while (timer.isRunning()) + dispatcher->processEvents(); + + if (completeRequestsCount_ <= sconf->bufferCount * 2 || + completeRequestsCount_ != completeBuffersCount_) { + cout << "Capture failed" << endl; + return TestFail; + } + + if (camera_->stop()) { + cout << "Stopping camera" << endl; + return TestFail; + } + + if (camera_->freeBuffers()) { + cout << "Freeing 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 Mon Mar 11 02:22: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: 714 Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 572ED610B6 for ; Mon, 11 Mar 2019 03:23:10 +0100 (CET) X-Halon-ID: 9b54004b-43a4-11e9-985a-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 9b54004b-43a4-11e9-985a-005056917f90; Mon, 11 Mar 2019 03:23:07 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Mon, 11 Mar 2019 03:22:32 +0100 Message-Id: <20190311022232.4759-5-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190311022232.4759-1-niklas.soderlund@ragnatech.se> References: <20190311022232.4759-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 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: Mon, 11 Mar 2019 02:23:10 -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);