{"id":714,"url":"https://patchwork.libcamera.org/api/1.1/patches/714/?format=json","web_url":"https://patchwork.libcamera.org/patch/714/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20190311022232.4759-5-niklas.soderlund@ragnatech.se>","date":"2019-03-11T02:22:32","name":"[libcamera-devel,v2,4/4] test: camera: Add state machine test","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"5d14d4f776d7b5467a9c2dbfaba456bb4860e855","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/1.1/people/5/?format=json","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/714/mbox/","series":[{"id":204,"url":"https://patchwork.libcamera.org/api/1.1/series/204/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=204","date":"2019-03-11T02:22:28","name":"test: camera: Add basic tests for the camera","version":2,"mbox":"https://patchwork.libcamera.org/series/204/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/714/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/714/checks/","tags":{},"headers":{"Return-Path":"<niklas.soderlund@ragnatech.se>","Received":["from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net\n\t[195.74.38.228])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 572ED610B6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 11 Mar 2019 03:23:10 +0100 (CET)","from bismarck.berto.se (unknown [89.233.230.99])\n\tby bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA\n\tid 9b54004b-43a4-11e9-985a-005056917f90;\n\tMon, 11 Mar 2019 03:23:07 +0100 (CET)"],"X-Halon-ID":"9b54004b-43a4-11e9-985a-005056917f90","Authorized-sender":"niklas@soderlund.pp.se","From":"=?utf-8?q?Niklas_S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","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","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH v2 4/4] test: camera: Add state machine\n\ttest","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Mon, 11 Mar 2019 02:23:10 -0000"},"content":"Add a test of the different access level enforced by the state machine\ninside the camera. The state machine aims to limit operations on the\ncamera to the cameras state.\n\nThe test exercises all states of the camera and verifies that only the\nintended operations are possible at each stage.\n\nSigned-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n test/camera/meson.build      |   1 +\n test/camera/statemachine.cpp | 275 +++++++++++++++++++++++++++++++++++\n 2 files changed, 276 insertions(+)\n create mode 100644 test/camera/statemachine.cpp","diff":"diff --git a/test/camera/meson.build b/test/camera/meson.build\nindex a1fd20326e97538b..c4427945e4a25371 100644\n--- a/test/camera/meson.build\n+++ b/test/camera/meson.build\n@@ -3,6 +3,7 @@\n camera_tests = [\n   [ 'configuration_default',  'configuration_default.cpp' ],\n   [ 'configuration_set',      'configuration_set.cpp' ],\n+  [ 'statemachine',           'statemachine.cpp' ],\n   [ 'capture',                'capture.cpp' ],\n ]\n \ndiff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp\nnew file mode 100644\nindex 0000000000000000..f4395f2b1bfed698\n--- /dev/null\n+++ b/test/camera/statemachine.cpp\n@@ -0,0 +1,275 @@\n+/* SPDX-License-Identifier: GPL-2.0-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * libcamera Camera API tests\n+ */\n+\n+#include <iostream>\n+\n+#include \"camera_test.h\"\n+\n+using namespace std;\n+\n+namespace {\n+\n+class Statemachine : public CameraTest\n+{\n+protected:\n+\tint testAvailable()\n+\t{\n+\t\t/* Test operations which should fail. */\n+\t\tif (camera_->configureStreams(defconf_) != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->allocateBuffers() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->freeBuffers() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->createRequest())\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->start() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tRequest request(camera_.get());\n+\t\tif (camera_->queueRequest(&request) != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->stop() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\t/* Test operations which should pass. */\n+\t\tif (camera_->release())\n+\t\t\treturn TestFail;\n+\n+\t\t/* Test valid state transitions, end in Acquired state. */\n+\t\tif (camera_->acquire())\n+\t\t\treturn TestFail;\n+\n+\t\treturn TestPass;\n+\t}\n+\n+\tint testAcquired()\n+\t{\n+\t\t/* Test operations which should fail. */\n+\t\tif (camera_->acquire() != -EBUSY)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->allocateBuffers() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->freeBuffers() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->createRequest())\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->start() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tRequest request(camera_.get());\n+\t\tif (camera_->queueRequest(&request) != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->stop() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\t/* Test valid state transitions, end in Configured state. */\n+\t\tif (camera_->release())\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->acquire())\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->configureStreams(defconf_))\n+\t\t\treturn TestFail;\n+\n+\t\treturn TestPass;\n+\t}\n+\n+\tint testConfigured()\n+\t{\n+\t\t/* Test operations which should fail. */\n+\t\tif (camera_->acquire() != -EBUSY)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->freeBuffers() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->createRequest())\n+\t\t\treturn TestFail;\n+\n+\t\tRequest request(camera_.get());\n+\t\tif (camera_->queueRequest(&request) != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->start() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->stop() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\t/* Test operations which should pass. */\n+\t\tif (camera_->configureStreams(defconf_))\n+\t\t\treturn TestFail;\n+\n+\t\t/* Test valid state transitions, end in Prepared state. */\n+\t\tif (camera_->release())\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->acquire())\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->configureStreams(defconf_))\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->allocateBuffers())\n+\t\t\treturn TestFail;\n+\n+\t\treturn TestPass;\n+\t}\n+\n+\tint testPrepared()\n+\t{\n+\t\t/* Test operations which should fail. */\n+\t\tif (camera_->acquire() != -EBUSY)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->release() != -EBUSY)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->configureStreams(defconf_) != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->allocateBuffers() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tRequest request1(camera_.get());\n+\t\tif (camera_->queueRequest(&request1) != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->stop() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\t/* Test operations which should pass. */\n+\t\tRequest *request2 = camera_->createRequest();\n+\t\tif (!request2)\n+\t\t\treturn TestFail;\n+\n+\t\t/* Never handed to hardware so need to manually delete it. */\n+\t\tdelete request2;\n+\n+\t\t/* Test valid state transitions, end in Running state. */\n+\t\tif (camera_->freeBuffers())\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->release())\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->acquire())\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->configureStreams(defconf_))\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->allocateBuffers())\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->start())\n+\t\t\treturn TestFail;\n+\n+\t\treturn TestPass;\n+\t}\n+\n+\tint testRuning()\n+\t{\n+\t\t/* Test operations which should fail. */\n+\t\tif (camera_->acquire() != -EBUSY)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->release() != -EBUSY)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->configureStreams(defconf_) != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->allocateBuffers() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->freeBuffers() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->start() != -EACCES)\n+\t\t\treturn TestFail;\n+\n+\t\t/* Test operations which should pass. */\n+\t\tRequest *request = camera_->createRequest();\n+\t\tif (!request)\n+\t\t\treturn TestFail;\n+\n+\t\tStream *stream = *camera_->streams().begin();\n+\t\tBufferPool &pool = stream->bufferPool();\n+\t\tBuffer &buffer = pool.buffers().front();\n+\t\tstd::map<Stream *, Buffer *> map = { { stream, &buffer } };\n+\t\tif (request->setBuffers(map))\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->queueRequest(request))\n+\t\t\treturn TestFail;\n+\n+\t\t/* Test valid state transitions, end in Available state. */\n+\t\tif (camera_->stop())\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->freeBuffers())\n+\t\t\treturn TestFail;\n+\n+\t\tif (camera_->release())\n+\t\t\treturn TestFail;\n+\n+\t\treturn TestPass;\n+\t}\n+\n+\tint run()\n+\t{\n+\t\tStream *stream = *camera_->streams().begin();\n+\t\tstd::set<Stream *> streams = { stream };\n+\t\tdefconf_ = camera_->streamConfiguration(streams);\n+\n+\t\tif (testAvailable() != TestPass) {\n+\t\t\tcout << \"State machine in Available state failed\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (testAcquired() != TestPass) {\n+\t\t\tcout << \"State machine in Acquired state failed\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (testConfigured() != TestPass) {\n+\t\t\tcout << \"State machine in Configured state failed\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (testPrepared() != TestPass) {\n+\t\t\tcout << \"State machine in Prepared state failed\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (testRuning() != TestPass) {\n+\t\t\tcout << \"State machine in Running state failed\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\treturn TestPass;\n+\t}\n+\n+\tstd::map<Stream *, StreamConfiguration> defconf_;\n+};\n+\n+} /* namespace */\n+\n+TEST_REGISTER(Statemachine);\n","prefixes":["libcamera-devel","v2","4/4"]}