[libcamera-devel] [PATCH v9 3/3] tests: Test IPA serializer generation
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Tue Mar 2 02:18:45 CET 2021
Hi Paul,
On Tue, Mar 02, 2021 at 10:13:16AM +0900, paul.elder at ideasonboard.com wrote:
> On Tue, Mar 02, 2021 at 03:01:36AM +0200, Laurent Pinchart wrote:
> > 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>.
Ah good point.
> 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?
If it's easy, sure. Otherwise, the empty header is fine, with a comment
in the file to explain what it's for.
> > > 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.
>
> > > +
> > > +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'],
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list