[libcamera-devel,v8,4/4] tests: Test IPA serializer generation
diff mbox series

Message ID 20210213042312.112572-5-paul.elder@ideasonboard.com
State Superseded
Headers show
Series
  • IPA isolation: Part 3: Tests and documentation
Related show

Commit Message

Paul Elder Feb. 13, 2021, 4:23 a.m. UTC
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@ideasonboard.com>

---
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 ++++++++++++++++++
 .../generated_serializer/meson.build          |  49 ++++++
 .../generated_serializer/vimc.mojom           |  33 ++++
 test/serialization/meson.build                |   2 +
 4 files changed, 240 insertions(+)
 create mode 100644 test/serialization/generated_serializer/generated_serializer_test.cpp
 create mode 100644 test/serialization/generated_serializer/meson.build
 create mode 100644 test/serialization/generated_serializer/vimc.mojom

Comments

Laurent Pinchart Feb. 23, 2021, 12:57 a.m. UTC | #1
Hi Paul,

Thank you for the patch.

On Sat, Feb 13, 2021 at 01:23:12PM +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@ideasonboard.com>
> 
> ---
> 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 ++++++++++++++++++
>  .../generated_serializer/meson.build          |  49 ++++++
>  .../generated_serializer/vimc.mojom           |  33 ++++
>  test/serialization/meson.build                |   2 +
>  4 files changed, 240 insertions(+)
>  create mode 100644 test/serialization/generated_serializer/generated_serializer_test.cpp
>  create mode 100644 test/serialization/generated_serializer/meson.build
>  create mode 100644 test/serialization/generated_serializer/vimc.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..471d0731
> --- /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 "vimc_test_ipa_interface.h"
> +#include "vimc_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;
> +
> +		vector<uint8_t> serialized;
> +
> +		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 */
> +		vector<ipa::test::TestStruct> v = { t, u };
> +		vector<ipa::test::TestStruct> w;
> +
> +		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/meson.build b/test/serialization/generated_serializer/meson.build
> new file mode 100644
> index 00000000..68bcf23d
> --- /dev/null
> +++ b/test/serialization/generated_serializer/meson.build
> @@ -0,0 +1,49 @@
> +# SPDX-License-Identifier: CC0-1.0
> +
> +# vimc.mojom-module
> +mojom = custom_target('vimc_test_mojom_module',
> +                      input : 'vimc.mojom',
> +                      output : 'vimc.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('vimc_test_ipa_interface_h',
> +                       input : mojom,
> +                       output : 'vimc_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('vimc_test_ipa_serializer_h',
> +                           input : mojom,
> +                           output : 'vimc_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)
> +
> +test('generated_serializer_test', exe,
> +     suite : 'generated_serializer', is_parallel : false)
> diff --git a/test/serialization/generated_serializer/vimc.mojom b/test/serialization/generated_serializer/vimc.mojom
> new file mode 100644
> index 00000000..2fd973e9
> --- /dev/null
> +++ b/test/serialization/generated_serializer/vimc.mojom

This has nothing to do with vimc, maybe test.mojom given that the module
is called ipa.test ? Same for the interface, it should be renamed.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> @@ -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);
> +};
> +
> +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'],

Patch
diff mbox series

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..471d0731
--- /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 "vimc_test_ipa_interface.h"
+#include "vimc_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;
+
+		vector<uint8_t> serialized;
+
+		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 */
+		vector<ipa::test::TestStruct> v = { t, u };
+		vector<ipa::test::TestStruct> w;
+
+		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/meson.build b/test/serialization/generated_serializer/meson.build
new file mode 100644
index 00000000..68bcf23d
--- /dev/null
+++ b/test/serialization/generated_serializer/meson.build
@@ -0,0 +1,49 @@ 
+# SPDX-License-Identifier: CC0-1.0
+
+# vimc.mojom-module
+mojom = custom_target('vimc_test_mojom_module',
+                      input : 'vimc.mojom',
+                      output : 'vimc.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('vimc_test_ipa_interface_h',
+                       input : mojom,
+                       output : 'vimc_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('vimc_test_ipa_serializer_h',
+                           input : mojom,
+                           output : 'vimc_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)
+
+test('generated_serializer_test', exe,
+     suite : 'generated_serializer', is_parallel : false)
diff --git a/test/serialization/generated_serializer/vimc.mojom b/test/serialization/generated_serializer/vimc.mojom
new file mode 100644
index 00000000..2fd973e9
--- /dev/null
+++ b/test/serialization/generated_serializer/vimc.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);
+};
+
+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'],