[libcamera-devel] [PATCH v9 3/3] tests: Test IPA serializer generation
paul.elder at ideasonboard.com
paul.elder at ideasonboard.com
Tue Mar 2 02:13:16 CET 2021
Hi Laurent,
On Tue, Mar 02, 2021 at 03:01:36AM +0200, Laurent Pinchart wrote:
> Hi Paul,
>
> Thank you for the patch.
>
> On Mon, Mar 01, 2021 at 03:52:26PM +0900, Paul Elder wrote:
> > Add a test to confirm that serializer and header generation works
> > properly for mojom definition files, and that the serializer works
> > properly.
> >
> > Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> > Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> >
> > ---
> > Changes in v9:
> > - rename everything vimc to test
> > - add std:: to vectors and ties
> >
> > No change in v8
> >
> > Changes in v7:
> > - add test to test serdes of a vector of *generated* structs
> >
> > Changes in v6:
> > - use namespacing in the mojom file, and in the test
> > - add the enum to the test mojom file, as vimc.h no longer exists
> >
> > Changes in v5:
> > - add dummy event to event interface
> >
> > New in v4
> > ---
> > .../generated_serializer_test.cpp | 156 ++++++++++++++++++
> > .../libcamera/ipa/test_ipa_interface.h | 0
> > .../generated_serializer/meson.build | 52 ++++++
> > .../generated_serializer/test.mojom | 33 ++++
> > test/serialization/meson.build | 2 +
> > 5 files changed, 243 insertions(+)
> > create mode 100644 test/serialization/generated_serializer/generated_serializer_test.cpp
> > create mode 100644 test/serialization/generated_serializer/include/libcamera/ipa/test_ipa_interface.h
> > create mode 100644 test/serialization/generated_serializer/meson.build
> > create mode 100644 test/serialization/generated_serializer/test.mojom
> >
> > diff --git a/test/serialization/generated_serializer/generated_serializer_test.cpp b/test/serialization/generated_serializer/generated_serializer_test.cpp
> > new file mode 100644
> > index 00000000..698c81d6
> > --- /dev/null
> > +++ b/test/serialization/generated_serializer/generated_serializer_test.cpp
> > @@ -0,0 +1,156 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * Copyright (C) 2020, Google Inc.
> > + *
> > + * generated_serializer_test.cpp - Test generated serializer
> > + */
> > +
> > +#include <algorithm>
> > +#include <tuple>
> > +#include <vector>
> > +
> > +#include "test.h"
> > +
> > +#include "test_ipa_interface.h"
> > +#include "test_ipa_serializer.h"
> > +
> > +using namespace std;
> > +using namespace libcamera;
> > +
> > +class IPAGeneratedSerializerTest : public Test
> > +{
> > +protected:
> > + int init() override
> > + {
> > + return TestPass;
> > + }
> > +
> > + int run() override
> > + {
> > +
> > +#define TEST_FIELD_EQUALITY(struct1, struct2, field) \
> > +if (struct1.field != struct2.field) { \
> > + cerr << #field << " field incorrect: expected \"" \
> > + << t.field << "\", got \"" << u.field << "\"" << endl;\
> > + return TestFail; \
> > +}
> > +
> > + ipa::test::TestStruct t, u;
> > +
> > + t.m = {
> > + { "a", "z" },
> > + { "b", "z" },
> > + { "c", "z" },
> > + { "d", "z" },
> > + { "e", "z" },
> > + };
> > +
> > + t.a = { "a", "b", "c", "d", "e" };
> > +
> > + t.s1 = "hello world";
> > + t.s2 = "goodbye";
> > + t.s3 = "lorem ipsum";
> > + t.i = 58527;
> > +
> > + std::vector<uint8_t> serialized;
> > +
> > + std::tie(serialized, ignore) =
> > + IPADataSerializer<ipa::test::TestStruct>::serialize(t);
> > +
> > + u = IPADataSerializer<ipa::test::TestStruct>::deserialize(serialized);
> > +
> > + if (!equals(t.m, u.m))
> > + return TestFail;
> > +
> > + if (!equals(t.a, u.a))
> > + return TestFail;
> > +
> > + TEST_FIELD_EQUALITY(t, u, s1);
> > + TEST_FIELD_EQUALITY(t, u, s2);
> > + TEST_FIELD_EQUALITY(t, u, s3);
> > + TEST_FIELD_EQUALITY(t, u, i);
> > +
> > +
> > + /* Test vector of generated structs */
> > + std::vector<ipa::test::TestStruct> v = { t, u };
> > + std::vector<ipa::test::TestStruct> w;
> > +
> > + std::tie(serialized, ignore) =
> > + IPADataSerializer<vector<ipa::test::TestStruct>>::serialize(v);
> > +
> > + w = IPADataSerializer<vector<ipa::test::TestStruct>>::deserialize(serialized);
> > +
> > + if (!equals(v[0].m, w[0].m) ||
> > + !equals(v[1].m, w[1].m))
> > + return TestFail;
> > +
> > + if (!equals(v[0].a, w[0].a) ||
> > + !equals(v[1].a, w[1].a))
> > + return TestFail;
> > +
> > + TEST_FIELD_EQUALITY(v[0], w[0], s1);
> > + TEST_FIELD_EQUALITY(v[0], w[0], s2);
> > + TEST_FIELD_EQUALITY(v[0], w[0], s3);
> > + TEST_FIELD_EQUALITY(v[0], w[0], i);
> > +
> > + TEST_FIELD_EQUALITY(v[1], w[1], s1);
> > + TEST_FIELD_EQUALITY(v[1], w[1], s2);
> > + TEST_FIELD_EQUALITY(v[1], w[1], s3);
> > + TEST_FIELD_EQUALITY(v[1], w[1], i);
> > +
> > + return TestPass;
> > + }
> > +
> > +private:
> > + bool equals(const map<string, string> &lhs, const map<string, string> &rhs)
> > + {
> > + bool eq = lhs.size() == rhs.size() &&
> > + equal(lhs.begin(), lhs.end(), rhs.begin(),
> > + [](auto &a, auto &b) { return a.first == b.first &&
> > + a.second == b.second; });
> > +
> > + if (eq)
> > + return true;
> > +
> > + cerr << "lhs:" << endl;
> > + for (const auto &pair : lhs)
> > + cerr << "- " << pair.first << ": "
> > + << pair.second << endl;
> > +
> > + cerr << "rhs:" << endl;
> > + for (const auto &pair : rhs)
> > + cerr << "- " << pair.first << ": "
> > + << pair.second << endl;
> > +
> > + return false;
> > + }
> > +
> > + bool equals(const vector<string> &lhs, const vector<string> &rhs)
> > + {
> > + bool eq = lhs.size() == rhs.size();
> > +
> > + if (!eq) {
> > + cerr << "sizes not equal" << endl;
> > + return false;
> > + }
> > +
> > + for (unsigned int i = 0; i < lhs.size(); i++)
> > + if (lhs[i] != rhs[i])
> > + eq = false;
> > +
> > + if (eq)
> > + return true;
> > +
> > + cerr << "lhs:" << endl;
> > + for (const auto &str : lhs)
> > + cerr << "- " << str << endl;
> > +
> > + cerr << "rhs:" << endl;
> > + for (const auto &str : rhs)
> > + cerr << "- " << str << endl;
> > +
> > + return false;
> > + }
> > +};
> > +
> > +TEST_REGISTER(IPAGeneratedSerializerTest)
> > diff --git a/test/serialization/generated_serializer/include/libcamera/ipa/test_ipa_interface.h b/test/serialization/generated_serializer/include/libcamera/ipa/test_ipa_interface.h
> > new file mode 100644
> > index 00000000..e69de29b
>
> Did you mean to add an empty test_ipa_interface.h ?
Yes, I did.
We tell the generator to generate a test_ipa_serializer.h based on
test.mojom, but this generates #include
<libcamera/test_ipa_interface.h>.
Although, below I generate test_ipa_interface.h from test.mojom.
Maybe it's better to mkdir -p
test/serialization/generated_serializer/include/libcamera/ipa and then
put the mojom file and the meson generator there?
> > diff --git a/test/serialization/generated_serializer/meson.build b/test/serialization/generated_serializer/meson.build
> > new file mode 100644
> > index 00000000..aad6c4a1
> > --- /dev/null
> > +++ b/test/serialization/generated_serializer/meson.build
> > @@ -0,0 +1,52 @@
> > +# SPDX-License-Identifier: CC0-1.0
> > +
> > +# vimc.mojom-module
Oh I need to s/vimc/test here and below.
> > +mojom = custom_target('test_mojom_module',
> > + input : 'test.mojom',
> > + output : 'test.mojom-module',
> > + command : [
> > + mojom_parser,
> > + '--output-root', meson.build_root(),
> > + '--input-root', meson.source_root(),
> > + '--mojoms', '@INPUT@'
> > + ])
> > +
> > +# vimc_test_ipa_interface.h
> > +header = custom_target('test_ipa_interface_h',
> > + input : mojom,
> > + output : 'test_ipa_interface.h',
> > + depends : mojom_templates,
> > + command : [
> > + mojom_generator, 'generate',
> > + '-g', 'libcamera',
> > + '--bytecode_path', mojom_templates_dir,
> > + '--libcamera_generate_header',
> > + '--libcamera_output_path=@OUTPUT@',
> > + './' +'@INPUT@'
> > + ])
> > +
> > +# vimc_test_ipa_serializer.h
> > +serializer = custom_target('test_ipa_serializer_h',
> > + input : mojom,
> > + output : 'test_ipa_serializer.h',
> > + depends : mojom_templates,
> > + command : [
> > + mojom_generator, 'generate',
> > + '-g', 'libcamera',
> > + '--bytecode_path', mojom_templates_dir,
> > + '--libcamera_generate_serializer',
> > + '--libcamera_output_path=@OUTPUT@',
> > + './' +'@INPUT@'
> > + ])
> > +
> > +exe = executable('generated_serializer_test',
> > + ['generated_serializer_test.cpp', header, serializer],
> > + dependencies : libcamera_dep,
> > + link_with : test_libraries,
> > + include_directories : [
> > + test_includes_internal,
> > + './include',
> > + ])
> > +
> > +test('generated_serializer_test', exe,
> > + suite : 'generated_serializer', is_parallel : false)
> > diff --git a/test/serialization/generated_serializer/test.mojom b/test/serialization/generated_serializer/test.mojom
> > new file mode 100644
> > index 00000000..2fd973e9
> > --- /dev/null
> > +++ b/test/serialization/generated_serializer/test.mojom
> > @@ -0,0 +1,33 @@
> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> > +
> > +module ipa.test;
> > +
> > +enum IPAOperationCode {
> > + IPAOperationNone,
> > + IPAOperationInit,
> > + IPAOperationStart,
> > + IPAOperationStop,
> > +};
> > +
> > +struct IPASettings {};
> > +
> > +struct TestStruct {
> > + map<string, string> m;
> > + array<string> a;
> > + string s1;
> > + string s2;
> > + int32 i;
> > + string s3;
> > +};
> > +
> > +interface IPAVimcInterface {
> > + init(IPASettings settings) => (int32 ret);
> > + start() => (int32 ret);
> > + stop();
> > +
> > + test(TestStruct s);
> > +};
Oh I forgot to s/Vimc/Test here and below too.
Paul
> > +
> > +interface IPAVimcEventInterface {
> > + dummyEvent(uint32 val);
> > +};
> > diff --git a/test/serialization/meson.build b/test/serialization/meson.build
> > index a4636337..60ebf325 100644
> > --- a/test/serialization/meson.build
> > +++ b/test/serialization/meson.build
> > @@ -1,5 +1,7 @@
> > # SPDX-License-Identifier: CC0-1.0
> >
> > +subdir('generated_serializer')
> > +
> > serialization_tests = [
> > ['control_serialization', 'control_serialization.cpp'],
> > ['ipa_data_serializer_test', 'ipa_data_serializer_test.cpp'],
More information about the libcamera-devel
mailing list