From patchwork Wed Mar 6 02:47:51 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: 705 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 CA1A9611A8 for ; Wed, 6 Mar 2019 03:48:17 +0100 (CET) X-Halon-ID: 4979d1b6-3fba-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 4979d1b6-3fba-11e9-985a-005056917f90; Wed, 06 Mar 2019 03:48:16 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 6 Mar 2019 03:47:51 +0100 Message-Id: <20190306024755.28726-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190306024755.28726-1-niklas.soderlund@ragnatech.se> References: <20190306024755.28726-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/5] libcamera: camera: Fix access bug in configureStreams() 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, 06 Mar 2019 02:48:18 -0000 It is not permitted to configure streams before a camera is acquired. Fixes: 77100a7578d8a0cc ("libcamera: camera: add state machine to control access from applications") Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/camera.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index e3144c5b4ab093b2..8ee9cc0866167ae1 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -405,7 +405,7 @@ int Camera::configureStreams(std::map &config) if (disconnected_) return -ENODEV; - if (!stateBetween(CameraAvailable, CameraConfigured)) + if (!stateBetween(CameraAcquired, CameraConfigured)) return -EACCES; if (!config.size()) { From patchwork Wed Mar 6 02:47:52 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: 706 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 534DE611A8 for ; Wed, 6 Mar 2019 03:48:20 +0100 (CET) X-Halon-ID: 4b7644b0-3fba-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 4b7644b0-3fba-11e9-985a-005056917f90; Wed, 06 Mar 2019 03:48:18 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 6 Mar 2019 03:47:52 +0100 Message-Id: <20190306024755.28726-3-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190306024755.28726-1-niklas.soderlund@ragnatech.se> References: <20190306024755.28726-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/5] test: camera: Add read default format 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, 06 Mar 2019 02:48:20 -0000 Add a test to verify reading the default format from a camera works. Signed-off-by: Niklas Söderlund --- test/camera/camera_test.cpp | 47 ++++++++++++++++++++++ test/camera/camera_test.h | 32 +++++++++++++++ test/camera/format_default.cpp | 71 ++++++++++++++++++++++++++++++++++ test/camera/meson.build | 12 ++++++ test/meson.build | 1 + 5 files changed, 163 insertions(+) create mode 100644 test/camera/camera_test.cpp create mode 100644 test/camera/camera_test.h create mode 100644 test/camera/format_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..d39a0ed066665946 --- /dev/null +++ b/test/camera/camera_test.cpp @@ -0,0 +1,47 @@ +/* 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; +using namespace libcamera; + +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, skip." << endl; + return TestSkip; + } + + /* Sanity check that camera have streams. */ + if (camera_->streams().size() == 0) { + cout << "Camera have no streams, fail." << endl; + return TestFail; + } + + return TestPass; +} + +void CameraTest::cleanup() +{ + if (camera_) { + camera_->release(); + camera_.reset(); + } + + cm_->stop(); +}; diff --git a/test/camera/camera_test.h b/test/camera/camera_test.h new file mode 100644 index 0000000000000000..4aadd027675a5dbd --- /dev/null +++ b/test/camera/camera_test.h @@ -0,0 +1,32 @@ +/* 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(); + + std::shared_ptr camera_; + +private: + CameraManager *cm_; +}; + +#endif /* __LIBCAMERA_CAMERA_TEST_H_ */ diff --git a/test/camera/format_default.cpp b/test/camera/format_default.cpp new file mode 100644 index 0000000000000000..11b947f44c39b40a --- /dev/null +++ b/test/camera/format_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 FormatDefault : public CameraTest +{ +protected: + int run() + { + std::map conf; + std::set streams = { *camera_->streams().begin() }; + + /* + * Test that asking for default format for a valid array of + * streams returns formats and that the formats are somewhat + * sane. + */ + conf = camera_->streamConfiguration(streams); + if (!conf.size()) { + cout << "Default format for valid streams test failed" << endl; + return TestFail; + } + + StreamConfiguration *sconf = &conf.begin()->second; + if (sconf->width == 0 || sconf->height == 0 || + sconf->pixelFormat == 0 || sconf->bufferCount == 0) { + cout << "Default format is set test failed" << endl; + return TestFail; + } + + /* + * Test that asking for format for an empty array of streams + * returns an empty list of configurations. + */ + std::set streams_empty = {}; + conf = camera_->streamConfiguration(streams_empty); + if (conf.size()) { + cout << "Default format for empty streams test failed" << endl; + return TestFail; + } + + /* + * Test that asking for format for an array of streams bad streams + * returns an empty list of configurations. + */ + Stream *stream_bad = *streams.end(); + std::set streams_bad = { stream_bad }; + conf = camera_->streamConfiguration(streams_bad); + if (conf.size()) { + cout << "Default format for bad streams test failed" << endl; + return TestFail; + } + + return TestPass; + } +}; + +} /* namespace */ + +TEST_REGISTER(FormatDefault); diff --git a/test/camera/meson.build b/test/camera/meson.build new file mode 100644 index 0000000000000000..4f2ed244a9240512 --- /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 = [ + [ 'format_default', 'format_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 6 02:47:53 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: 707 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DE21D611A2 for ; Wed, 6 Mar 2019 03:48:21 +0100 (CET) X-Halon-ID: 4cdb3461-3fba-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 4cdb3461-3fba-11e9-985a-005056917f90; Wed, 06 Mar 2019 03:48:20 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 6 Mar 2019 03:47:53 +0100 Message-Id: <20190306024755.28726-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190306024755.28726-1-niklas.soderlund@ragnatech.se> References: <20190306024755.28726-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/5] test: camera: Add setting of format 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, 06 Mar 2019 02:48:22 -0000 Try to set the default format, a modified valid format and an invalid format. Signed-off-by: Niklas Söderlund --- test/camera/format_set.cpp | 88 ++++++++++++++++++++++++++++++++++++++ test/camera/meson.build | 1 + 2 files changed, 89 insertions(+) create mode 100644 test/camera/format_set.cpp diff --git a/test/camera/format_set.cpp b/test/camera/format_set.cpp new file mode 100644 index 0000000000000000..948428ca6b00d2d0 --- /dev/null +++ b/test/camera/format_set.cpp @@ -0,0 +1,88 @@ +/* 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 FormatSet : public CameraTest +{ +protected: + int run() + { + if (camera_->acquire()) { + cout << "Acquiring the camera failed" << endl; + return TestFail; + } + + std::set streams = { *camera_->streams().begin() }; + std::map conf = + camera_->streamConfiguration(streams); + StreamConfiguration *sconf = &conf.begin()->second; + if (conf.size() != 1) { + cout << "Reading default format failed" << endl; + return TestFail; + } + + /* + * Test setting the default format works. + */ + if (camera_->configureStreams(conf)) { + cout << "Setting valid format test failed" << endl; + return TestFail; + } + + /* + * Test setting the default format fails the camera is not + * acquired. + */ + if (camera_->release()) { + cout << "Releasing the camera failed" << endl; + return TestFail; + } + + if (!camera_->configureStreams(conf)) { + cout << "Setting valid format on a camera not acquired failed" << endl; + return TestFail; + } + + if (camera_->acquire()) { + cout << "Acquiring the camera failed" << endl; + return TestFail; + } + + /* + * Test doubling the resolution works. + */ + sconf->width *= 2; + sconf->height *= 2; + if (camera_->configureStreams(conf)) { + cout << "Setting modified valid format test failed" << endl; + return TestFail; + } + + /* + * Test Setting an invalid format fails. + */ + sconf->width = 0; + sconf->height = 0; + if (!camera_->configureStreams(conf)) { + cout << "Setting invalid format test failed" << endl; + return TestFail; + } + + return TestPass; + } +}; + +} /* namespace */ + +TEST_REGISTER(FormatSet); diff --git a/test/camera/meson.build b/test/camera/meson.build index 4f2ed244a9240512..f5f27c4229ac307f 100644 --- a/test/camera/meson.build +++ b/test/camera/meson.build @@ -2,6 +2,7 @@ # They are not alphabetically sorted. camera_tests = [ [ 'format_default', 'format_default.cpp' ], + [ 'format_set', 'format_set.cpp' ], ] foreach t : camera_tests From patchwork Wed Mar 6 02:47:54 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: 708 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 18231611A8 for ; Wed, 6 Mar 2019 03:48:22 +0100 (CET) X-Halon-ID: 4d650ea3-3fba-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 4d650ea3-3fba-11e9-985a-005056917f90; Wed, 06 Mar 2019 03:48:21 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 6 Mar 2019 03:47:54 +0100 Message-Id: <20190306024755.28726-5-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190306024755.28726-1-niklas.soderlund@ragnatech.se> References: <20190306024755.28726-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/5] 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, 06 Mar 2019 02:48:22 -0000 Add positive capture test. Correctly configure the camera using the default format 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 one requests completes. Signed-off-by: Niklas Söderlund --- test/camera/capture.cpp | 130 ++++++++++++++++++++++++++++++++++++++++ test/camera/meson.build | 1 + 2 files changed, 131 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..133b38318e471f3f --- /dev/null +++ b/test/camera/capture.cpp @@ -0,0 +1,130 @@ +/* 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 count_buffers_; + unsigned int count_requests_; + + void bufferComplete(Request *request, Buffer *buffer) + { + count_buffers_++; + } + + void requestComplete(Request *request, const std::map &buffers) + { + if (request->status() == Request::RequestCancelled) + return; + + count_requests_++; + + /* Reuse the buffers for a new request. */ + request = camera_->createRequest(); + request->setBuffers(buffers); + camera_->queueRequest(request); + } + + int run() + { + if (camera_->acquire()) { + cout << "Acquiring the camera failed" << endl; + return TestFail; + } + + Stream *stream = *camera_->streams().begin(); + std::set streams = { stream }; + std::map conf = + camera_->streamConfiguration(streams); + if (conf.size() != 1) { + cout << "Reading default format failed" << endl; + return TestFail; + } + + if (camera_->configureStreams(conf)) { + cout << "Setting valid format failed" << endl; + return TestFail; + } + + if (camera_->allocateBuffers()) { + cout << "Allocating buffers failed" << endl; + return TestFail; + } + + BufferPool &pool = stream->bufferPool(); + std::vector requests; + for (Buffer &buffer : pool.buffers()) { + Request *request = camera_->createRequest(); + if (!request) { + cout << "Creating request failed" << endl; + return TestFail; + } + + std::map map = { { stream, &buffer } }; + if (request->setBuffers(map)) { + cout << "Associating buffer with request failed" << endl; + return TestFail; + } + + requests.push_back(request); + } + + if (camera_->start()) { + cout << "Starting camera failed" << endl; + return TestFail; + } + + for (Request *request : requests) { + if (camera_->queueRequest(request)) { + cout << "Queueing request failed" << endl; + return TestFail; + } + } + + camera_->bufferCompleted.connect(this, &Capture::bufferComplete); + camera_->requestCompleted.connect(this, &Capture::requestComplete); + + count_requests_ = 0; + count_buffers_ = 0; + + EventDispatcher *dispatcher = CameraManager::instance()->eventDispatcher(); + + Timer timer; + timer.start(100); + while (timer.isRunning()) + dispatcher->processEvents(); + + if (!count_requests_ || !count_buffers_) { + cout << "Capture failed" << endl; + return TestFail; + } + + if (camera_->stop()) { + cout << "Stopping camera failed" << endl; + return TestFail; + } + + if (camera_->freeBuffers()) { + cout << "Freeing buffers failed" << endl; + return TestFail; + } + + return TestPass; + } +}; + +} /* namespace */ + +TEST_REGISTER(Capture); diff --git a/test/camera/meson.build b/test/camera/meson.build index f5f27c4229ac307f..6da297714f34a4e3 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' ], + [ 'capture', 'capture.cpp' ], ] foreach t : camera_tests From patchwork Wed Mar 6 02:47:55 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: 709 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8EA53611A8 for ; Wed, 6 Mar 2019 03:48:23 +0100 (CET) X-Halon-ID: 4e02980c-3fba-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 4e02980c-3fba-11e9-985a-005056917f90; Wed, 06 Mar 2019 03:48:22 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 6 Mar 2019 03:47:55 +0100 Message-Id: <20190306024755.28726-6-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190306024755.28726-1-niklas.soderlund@ragnatech.se> References: <20190306024755.28726-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 5/5] 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, 06 Mar 2019 02:48:23 -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 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 + +#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);