[libcamera-devel,2/2] tests: load-so: add tests to test LibLoader

Message ID 20190510232235.8724-2-paul.elder@ideasonboard.com
State Rejected
Headers show
Series
  • [libcamera-devel,1/2] libcamera: lib_loader: add shared library loader
Related show

Commit Message

Paul Elder May 10, 2019, 11:22 p.m. UTC
Add tests to test the the LibLoader class for loading struct
IPAModuleInfo of a given symbol from a .so library.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
---
This *should* Just Work (TM).

 test/load-so/libfoo.so.32 | Bin 0 -> 15344 bytes
 test/load-so/libfoo.so.64 | Bin 0 -> 16320 bytes
 test/load-so/load-so.cpp  |  79 ++++++++++++++++++++++++++++++++++++++
 test/load-so/meson.build  |  19 +++++++++
 test/meson.build          |   1 +
 5 files changed, 99 insertions(+)
 create mode 100755 test/load-so/libfoo.so.32
 create mode 100755 test/load-so/libfoo.so.64
 create mode 100644 test/load-so/load-so.cpp
 create mode 100644 test/load-so/meson.build

Comments

Laurent Pinchart May 11, 2019, 5:52 p.m. UTC | #1
Hi Paul,

Thank you for the patch.

On Fri, May 10, 2019 at 07:22:35PM -0400, Paul Elder wrote:
> Add tests to test the the LibLoader class for loading struct
> IPAModuleInfo of a given symbol from a .so library.
> 
> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
> ---
> This *should* Just Work (TM).
> 
>  test/load-so/libfoo.so.32 | Bin 0 -> 15344 bytes
>  test/load-so/libfoo.so.64 | Bin 0 -> 16320 bytes

You should not add binaries, but instead add the source code for these
modules, and rules to compile them.

Let's put these in test/ipa/

>  test/load-so/load-so.cpp  |  79 ++++++++++++++++++++++++++++++++++++++
>  test/load-so/meson.build  |  19 +++++++++
>  test/meson.build          |   1 +
>  5 files changed, 99 insertions(+)
>  create mode 100755 test/load-so/libfoo.so.32
>  create mode 100755 test/load-so/libfoo.so.64
>  create mode 100644 test/load-so/load-so.cpp
>  create mode 100644 test/load-so/meson.build
> 
> diff --git a/test/load-so/libfoo.so.32 b/test/load-so/libfoo.so.32
> new file mode 100755
> index 0000000000000000000000000000000000000000..8633f992f256d3f6fc50e8658caf39d3cf267e54
> GIT binary patch
> literal 15344
> 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
> 
> literal 0
> HcmV?d00001
> 
> diff --git a/test/load-so/libfoo.so.64 b/test/load-so/libfoo.so.64
> new file mode 100755
> index 0000000000000000000000000000000000000000..adaef585ec27dce37a505f93780134fb787c4e67
> GIT binary patch
> literal 16320
> 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
> H8nyo?p;1&7
> 
> literal 0
> HcmV?d00001
> 
> diff --git a/test/load-so/load-so.cpp b/test/load-so/load-so.cpp
> new file mode 100644
> index 0000000..e54ac4d
> --- /dev/null
> +++ b/test/load-so/load-so.cpp
> @@ -0,0 +1,79 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2019, Google Inc.
> + *
> + * load-so.cpp - loading .so tests
> + */
> +
> +#include <iostream>
> +
> +#include "lib_loader.h"
> +
> +#include "test.h"
> +
> +using namespace std;
> +using namespace libcamera;
> +
> +class LibLoaderTest : public Test
> +{
> +protected:
> +	int init()
> +	{
> +		cout << "!!! make sure to run this test from the build directory" << endl;

Does it run correctly with 'ninja test' ?

> +
> +		ll32 = new LibLoader("test/load-so/libfoo.so.32");
> +		ll64 = new LibLoader("test/load-so/libfoo.so.64");

With the rework of the API in patch 1/2 this will become a new
IPAModule(), and I think it should be moved to the run function that
will just test .isValid() and verify the contents of the IPAModuleInfo
(as the symbol load API will become private).

> +
> +		return 0;
> +	}
> +
> +	int run_test(LibLoader *ll, const std::string &symbol)
> +	{
> +		cout << "running lib loader test: " << symbol << endl;
> +		int ret = ll->loadIPAModuleInfo(symbol);
> +
> +		bool loaded = ll->isLoaded();
> +
> +		if (ret < 0 && !loaded) {
> +			cout << "failed to load" << endl;
> +			return TestFail;
> +		}
> +
> +		if ((ret < 0 && loaded) || (ret >= 0 && !loaded)) {
> +			cout << "CRITICAL: isLoaded() and return value disagree!" << endl;
> +			return TestFail;
> +		}
> +
> +		struct LibLoader::IPAModuleInfo info = ll->getIPAModuleInfo();
> +		cout << "loaded!" << endl;
> +		cout << "name = " << info.name << ", version = " << info.version << endl;
> +		return TestPass;
> +	}
> +
> +	int run()
> +	{
> +		cout << endl
> +		     << "testing 32-bit so: asdf from .rodata, hjkl from .data" << endl;
> +		run_test(ll32, "asdf");
> +		run_test(ll32, "hjkl");
> +
> +		cout << endl
> +		     << "testing 64-bit so: asdf from .rodata, hjkl from .data" << endl;
> +		run_test(ll64, "asdf");
> +		run_test(ll64, "hjkl");
> +
> +		return TestPass;
> +	}
> +
> +	void cleanup()
> +	{
> +		delete ll32;
> +		delete ll64;
> +	}
> +
> +private:
> +	LibLoader *ll32;
> +	LibLoader *ll64;
> +};
> +
> +TEST_REGISTER(LibLoaderTest)
> diff --git a/test/load-so/meson.build b/test/load-so/meson.build
> new file mode 100644
> index 0000000..376665b
> --- /dev/null
> +++ b/test/load-so/meson.build
> @@ -0,0 +1,19 @@
> +load_so_test = [
> +    ['load-so',	      'load-so.cpp'],
> +]
> +
> +foreach t : load_so_test
> +    exe = executable(t[0], t[1],
> +                     link_with : test_libraries,
> +                     include_directories : test_includes_internal)
> +
> +    test(t[0], exe, suite: 'load-so', is_parallel: false)
> +endforeach
> +
> +configure_file(input : 'libfoo.so.32',
> +    output : 'libfoo.so.32',
> +    command: ['cp', '@INPUT@', '@OUTPUT@'])
> +
> +configure_file(input : 'libfoo.so.64',
> +    output : 'libfoo.so.64',
> +    command: ['cp', '@INPUT@', '@OUTPUT@'])
> diff --git a/test/meson.build b/test/meson.build
> index d501f2b..a5937c2 100644
> --- a/test/meson.build
> +++ b/test/meson.build
> @@ -1,6 +1,7 @@
>  subdir('libtest')
>  
>  subdir('camera')
> +subdir('load-so')
>  subdir('media_device')
>  subdir('pipeline')
>  subdir('v4l2_device')

Patch

diff --git a/test/load-so/libfoo.so.32 b/test/load-so/libfoo.so.32
new file mode 100755
index 0000000000000000000000000000000000000000..8633f992f256d3f6fc50e8658caf39d3cf267e54
GIT binary patch
literal 15344
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

literal 0
HcmV?d00001

diff --git a/test/load-so/libfoo.so.64 b/test/load-so/libfoo.so.64
new file mode 100755
index 0000000000000000000000000000000000000000..adaef585ec27dce37a505f93780134fb787c4e67
GIT binary patch
literal 16320
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
H8nyo?p;1&7

literal 0
HcmV?d00001

diff --git a/test/load-so/load-so.cpp b/test/load-so/load-so.cpp
new file mode 100644
index 0000000..e54ac4d
--- /dev/null
+++ b/test/load-so/load-so.cpp
@@ -0,0 +1,79 @@ 
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * load-so.cpp - loading .so tests
+ */
+
+#include <iostream>
+
+#include "lib_loader.h"
+
+#include "test.h"
+
+using namespace std;
+using namespace libcamera;
+
+class LibLoaderTest : public Test
+{
+protected:
+	int init()
+	{
+		cout << "!!! make sure to run this test from the build directory" << endl;
+
+		ll32 = new LibLoader("test/load-so/libfoo.so.32");
+		ll64 = new LibLoader("test/load-so/libfoo.so.64");
+
+		return 0;
+	}
+
+	int run_test(LibLoader *ll, const std::string &symbol)
+	{
+		cout << "running lib loader test: " << symbol << endl;
+		int ret = ll->loadIPAModuleInfo(symbol);
+
+		bool loaded = ll->isLoaded();
+
+		if (ret < 0 && !loaded) {
+			cout << "failed to load" << endl;
+			return TestFail;
+		}
+
+		if ((ret < 0 && loaded) || (ret >= 0 && !loaded)) {
+			cout << "CRITICAL: isLoaded() and return value disagree!" << endl;
+			return TestFail;
+		}
+
+		struct LibLoader::IPAModuleInfo info = ll->getIPAModuleInfo();
+		cout << "loaded!" << endl;
+		cout << "name = " << info.name << ", version = " << info.version << endl;
+		return TestPass;
+	}
+
+	int run()
+	{
+		cout << endl
+		     << "testing 32-bit so: asdf from .rodata, hjkl from .data" << endl;
+		run_test(ll32, "asdf");
+		run_test(ll32, "hjkl");
+
+		cout << endl
+		     << "testing 64-bit so: asdf from .rodata, hjkl from .data" << endl;
+		run_test(ll64, "asdf");
+		run_test(ll64, "hjkl");
+
+		return TestPass;
+	}
+
+	void cleanup()
+	{
+		delete ll32;
+		delete ll64;
+	}
+
+private:
+	LibLoader *ll32;
+	LibLoader *ll64;
+};
+
+TEST_REGISTER(LibLoaderTest)
diff --git a/test/load-so/meson.build b/test/load-so/meson.build
new file mode 100644
index 0000000..376665b
--- /dev/null
+++ b/test/load-so/meson.build
@@ -0,0 +1,19 @@ 
+load_so_test = [
+    ['load-so',	      'load-so.cpp'],
+]
+
+foreach t : load_so_test
+    exe = executable(t[0], t[1],
+                     link_with : test_libraries,
+                     include_directories : test_includes_internal)
+
+    test(t[0], exe, suite: 'load-so', is_parallel: false)
+endforeach
+
+configure_file(input : 'libfoo.so.32',
+    output : 'libfoo.so.32',
+    command: ['cp', '@INPUT@', '@OUTPUT@'])
+
+configure_file(input : 'libfoo.so.64',
+    output : 'libfoo.so.64',
+    command: ['cp', '@INPUT@', '@OUTPUT@'])
diff --git a/test/meson.build b/test/meson.build
index d501f2b..a5937c2 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -1,6 +1,7 @@ 
 subdir('libtest')
 
 subdir('camera')
+subdir('load-so')
 subdir('media_device')
 subdir('pipeline')
 subdir('v4l2_device')