{"id":1184,"url":"https://patchwork.libcamera.org/api/patches/1184/?format=json","web_url":"https://patchwork.libcamera.org/patch/1184/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/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":"<20190510232235.8724-2-paul.elder@ideasonboard.com>","date":"2019-05-10T23:22:35","name":"[libcamera-devel,2/2] tests: load-so: add tests to test LibLoader","commit_ref":null,"pull_url":null,"state":"rejected","archived":false,"hash":"bd89aa8fb76ba171c38ce0f10822f825fc053d05","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/?format=json","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/1184/mbox/","series":[{"id":302,"url":"https://patchwork.libcamera.org/api/series/302/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=302","date":"2019-05-10T23:22:34","name":"[libcamera-devel,1/2] libcamera: lib_loader: add shared library loader","version":1,"mbox":"https://patchwork.libcamera.org/series/302/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/1184/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/1184/checks/","tags":{},"headers":{"Return-Path":"<paul.elder@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3ECBE60E6A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 11 May 2019 01:22:50 +0200 (CEST)","from localhost.localdomain (unknown [96.44.9.117])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 84FED305;\n\tSat, 11 May 2019 01:22:49 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1557530570;\n\tbh=urKqOi2Hu1I8rDaOwYxbIzNAXxJmpIWTOTgNim/YdS8=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=XWUMCdN1JYiJVeRSyBj2+/2236nkkCUPoYnmqADJdIx/x//5lKN6iMV9qRqmlDV38\n\tUAAPoo1HBO/90mZG5yVKkIKTEO5PiVOdrU0zelRbwxkt5aL86XlddgcQyyHz0zw6fD\n\t+4FydHk9A4A+L26imE1I2bcTZD8VN/kz9IZRkdfI=","From":"Paul Elder <paul.elder@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Date":"Fri, 10 May 2019 19:22:35 -0400","Message-Id":"<20190510232235.8724-2-paul.elder@ideasonboard.com>","X-Mailer":"git-send-email 2.20.1","In-Reply-To":"<20190510232235.8724-1-paul.elder@ideasonboard.com>","References":"<20190510232235.8724-1-paul.elder@ideasonboard.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH 2/2] tests: load-so: add tests to test\n\tLibLoader","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":"Fri, 10 May 2019 23:22:50 -0000"},"content":"Add tests to test the the LibLoader class for loading struct\nIPAModuleInfo of a given symbol from a .so library.\n\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\n---\nThis *should* Just Work (TM).\n\n test/load-so/libfoo.so.32 | Bin 0 -> 15344 bytes\n test/load-so/libfoo.so.64 | Bin 0 -> 16320 bytes\n test/load-so/load-so.cpp  |  79 ++++++++++++++++++++++++++++++++++++++\n test/load-so/meson.build  |  19 +++++++++\n test/meson.build          |   1 +\n 5 files changed, 99 insertions(+)\n create mode 100755 test/load-so/libfoo.so.32\n create mode 100755 test/load-so/libfoo.so.64\n create mode 100644 test/load-so/load-so.cpp\n create mode 100644 test/load-so/meson.build","diff":"diff --git a/test/load-so/libfoo.so.32 b/test/load-so/libfoo.so.32\nnew file mode 100755\nindex 0000000000000000000000000000000000000000..8633f992f256d3f6fc50e8658caf39d3cf267e54\nGIT binary patch\nliteral 15344\n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\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/test/load-so/libfoo.so.64 b/test/load-so/libfoo.so.64\nnew file mode 100755\nindex 0000000000000000000000000000000000000000..adaef585ec27dce37a505f93780134fb787c4e67\nGIT binary patch\nliteral 16320\nzcmeHOU2Ggz6~4P`H=Edroi;5dsg!BtKvSg~lMvS-O|$;Z202LywgiZ1GWLwUo9<7v\nzGj8n?z#;-_RY8$J0*UvkNIcO#RDHoAC`Cd-sRSYqfGk2K2LVkUK<SH@bLO6Jc4s`U\nzA_S;{xz^5i&v(x`_s-cnckg=d`TFSiSUQzbC>iyfV(IyA&E%zFc|a-zc{QLm)Aez+\nz%hzpdHm$4OmqwrxzuZSVYl|GkBQhi)+L`uU8f;9(@UH>>SnPnUb`OziHmCKo&xP^X\nzjF$6)uuBuoc0FR(BX+=L=?|FIZu~LwI0x844EAbT0sVU-?)mpTo9mrVXoV<39|*h8\nzksXioK?}luR{Gm0F8AgBfFk<$w}U$4aGf|ksownSt=+|r-}N22mdP)@<Gyj{!f$Wz\nzSh$_X#deI@A(cg)M74=tOYSQj+g87S>3aY7E-@EZc)UhT!!&UZ$MD>T5yS7_fFC1%\nzPmI1v+{3C<wQtvr`$XqUgxl3)DxcRx8+S-$l3v@@wxDzH$~0#ywW{fQR^2mAWuBZk\nzW!g^NnJu}VQ=d3BT&`7}32UnC=(hM4b9&w~XG&G8Tzc72mTS+b;)NH=YNl3G7we^}\nzH>1j>sp*_s%k`@h<0prP&4amvxx@b0^i)jKd%=IYaP0zBF(2l3mNqMuR-Uv6&xy!%\nzbAIW@^CSGSI56^>z;gik)^W{aE{K_0Y2oqcaocJO4`0mRZQ(KZnZMt{`|ApmRC@A0\nz`14HPzm}705`iQFNd%GzBoRm=kVGJfKoWuf#|RWI|0P>^wf#2-lq!64*-JNW7B2rh\nzdp!t6<M1D;sj>G@bnV)mry9#eZojkAptAQTB+p!hLE*}=dwt~VO8cJ~j@<ViCHGa*\nzVfULGD_y%6S@*gi>0k5p55LW@Z>?}`EmK&!Te!A*ypXz4cz4a)K@LX6LAJ3n)3tk~\nzX}@^vt7NC<4ons<ANvGpslw8GUT5LeV?!jYo}&@27U^=MeUkK2=g=?k&R3{$l5F03\nzifosDMt!|YU-b)1H)v$HyOes1Xtml-T363eSp0Z}BE;=UNg|L$Ac;T{fg}P+1d<3O\nz5lAACL?DSk5`iQFAMFUZR{2H8;2#^S)<=7!|C!P8xBk8Eeq*n_MWuFSjv6HM?~ps*\nzZ#14I{4}9W_yHmRIL*I#b4k5?R;A{<Q@c7hWv|kYslCKKPOqDPYcvc(wXJ(>ThC{^\nzI$p{ys^dG4K6R*f57TT<|GrSaAidV#HQDyd^qQl7{NI=dw{?FjJ-qcHn>rvqDM<v9\nz2qY0mB9KHNi9iy8BmzkUk_aRb__sws&UNA(C(eiR*-$Q>8iIqOTSe{@yN`>E^P;;T\nz3+@!exl#VU!v)`M{=U|zv3y<*Y2plLQ4WRjxlt}xrG1MQ)uLdBV2_}f@nLnph?zn=\nzzQ^(TV=f=lpjO&+1-v0L#<?tdbV$}O@VC~`<M$6nQw#lG?B5UKcvs|A8Q2FR2jdif\nz|82lI_GrKT-I_7-(U!10S1p$+CC{;qsj_7|#!I#O3vO8De_DFw5jy`qJp38s$q{F&\nzWL1rU+@W0G)BXE&<wNg1Luap%AJD3pq4U>x4#IpUnEzqEP2o8S^X&@rEzHx?B=b7V\nzZ&H}=VLlr?7h#^B0+}aaev2|<`3{wj<vW9Xldzwy3hPUlZ=SCY^IbvSM40bZeNVJ9\nzx}KrK>{zc_TQhXxAL~?@e?-MSFB$r;4$ilS^&bt^pD_QJihHgyv<i(3wrc8nCRnwa\nzZM?3use6qkqieiQr)jlD{tntHVm`kZi9d&h^_L_3GsLG_#>4$_;XH{{OnfTDvmfLK\nzur8McdZl9G`~%|S#=p^hz2^JrR<HAbBPGtyo1~Lg>*vqg#HT24BO3pAe184=d(-c0\nz{k*y@ehP!WLU4KC=hwgQ?Q~;l%9>J<ICl_l1lG;UCy9^CYdK1MT;55313zbc{pRz6\nze3S{_|N6X^FKpnaPW+zc@S3&hy61XxGc&nq)l6qGy^1-_2`w(=z1TH#wp^RC%BJnr\nz>aJ<c&8z8J<zm^PkB!_jhYlW&SK>UEl4;fJ)`IC&z50ThsaqAtwC5_71u|)oOw#m1\nzs&3J$JGSXLu16y?&9SqCr$)`u(<7XF!;ZO6w`LZts?8}kBVRl{c<SUZv6RhZjuynA\nzFmjeC%Fco5iSaW-gX89zv9ZsOPM8yeL*t|5kh}lTlpdX%lh3!N<oJm@k+dK`qlc4u\nz{QRH?$N>twR5^E{;#pIKUR`4mwQ9|Ca<kRB+|*pDY(HJHl`j=7x2SUVLX|8vdUf6M\nzqEmNEwQ5K(sjcpmEjEza#j>YzegJY*&CS+G^qhIR`eDx1YqsTCD(4jC9V^=81d=w@\nzZ=JS4oqDh;rD^KE=CNlQobPAKbybe$Ple`0a~l4uHQuN4UN0>U@OcdEjW~{eY|>dl\nz^$*(1!T!8dfPG?*eIE9aa63R1-n+sc`&-~GQRIH<5e)Xr*mvfMW8bjHJ^;8#ZLNiU\nzw3Y%1yjO)i_6tC)K^Q;ufSm8fdtb=GzCr?JNN3UU3$1Lba2xCm*a<F+BKk-CaQ{`Y\nz9}>M4u>(Sn?P*nB7r%MpI41ah5v<R$PUCw4srW_QLsY!iZM8SVF2F!jSFrp8zZS92\nzO9K%13pbE~-;UVhb07Ez7z(0a&{rb%*lz*xJqP;H`~R-k<NZ^HXbN^lCLEeYOZ|{4\nztOEOu@?D`H?f*v+d+hUomtZJ}xPg9yD!exe<`?oB`N5_V)rSoHDe2HD;lLjI#_k8S\nz|0UV-+(ZA^Un1XlS>lKLM!$F;zd^RF0(<O3Zyg|#%99#`E9`;4rj}NFl^4}MjfRK-\nz*a3e}4XyS@UTYd+-z(#Xy@870Z9?{i@niox@+qx=`xbS-FVq=V>BU`0cTD*O_V_;o\nzcnqf%G54UucwYL)I>P_I*iSFqH`Wz?J}`Ew1|{FGtKUIK(h?E<?Q)#`uXqDa<(`J%\nH8nyo?p;1&7\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/test/load-so/load-so.cpp b/test/load-so/load-so.cpp\nnew file mode 100644\nindex 0000000..e54ac4d\n--- /dev/null\n+++ b/test/load-so/load-so.cpp\n@@ -0,0 +1,79 @@\n+/* SPDX-License-Identifier: GPL-2.0-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * load-so.cpp - loading .so tests\n+ */\n+\n+#include <iostream>\n+\n+#include \"lib_loader.h\"\n+\n+#include \"test.h\"\n+\n+using namespace std;\n+using namespace libcamera;\n+\n+class LibLoaderTest : public Test\n+{\n+protected:\n+\tint init()\n+\t{\n+\t\tcout << \"!!! make sure to run this test from the build directory\" << endl;\n+\n+\t\tll32 = new LibLoader(\"test/load-so/libfoo.so.32\");\n+\t\tll64 = new LibLoader(\"test/load-so/libfoo.so.64\");\n+\n+\t\treturn 0;\n+\t}\n+\n+\tint run_test(LibLoader *ll, const std::string &symbol)\n+\t{\n+\t\tcout << \"running lib loader test: \" << symbol << endl;\n+\t\tint ret = ll->loadIPAModuleInfo(symbol);\n+\n+\t\tbool loaded = ll->isLoaded();\n+\n+\t\tif (ret < 0 && !loaded) {\n+\t\t\tcout << \"failed to load\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif ((ret < 0 && loaded) || (ret >= 0 && !loaded)) {\n+\t\t\tcout << \"CRITICAL: isLoaded() and return value disagree!\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tstruct LibLoader::IPAModuleInfo info = ll->getIPAModuleInfo();\n+\t\tcout << \"loaded!\" << endl;\n+\t\tcout << \"name = \" << info.name << \", version = \" << info.version << endl;\n+\t\treturn TestPass;\n+\t}\n+\n+\tint run()\n+\t{\n+\t\tcout << endl\n+\t\t     << \"testing 32-bit so: asdf from .rodata, hjkl from .data\" << endl;\n+\t\trun_test(ll32, \"asdf\");\n+\t\trun_test(ll32, \"hjkl\");\n+\n+\t\tcout << endl\n+\t\t     << \"testing 64-bit so: asdf from .rodata, hjkl from .data\" << endl;\n+\t\trun_test(ll64, \"asdf\");\n+\t\trun_test(ll64, \"hjkl\");\n+\n+\t\treturn TestPass;\n+\t}\n+\n+\tvoid cleanup()\n+\t{\n+\t\tdelete ll32;\n+\t\tdelete ll64;\n+\t}\n+\n+private:\n+\tLibLoader *ll32;\n+\tLibLoader *ll64;\n+};\n+\n+TEST_REGISTER(LibLoaderTest)\ndiff --git a/test/load-so/meson.build b/test/load-so/meson.build\nnew file mode 100644\nindex 0000000..376665b\n--- /dev/null\n+++ b/test/load-so/meson.build\n@@ -0,0 +1,19 @@\n+load_so_test = [\n+    ['load-so',\t      'load-so.cpp'],\n+]\n+\n+foreach t : load_so_test\n+    exe = executable(t[0], t[1],\n+                     link_with : test_libraries,\n+                     include_directories : test_includes_internal)\n+\n+    test(t[0], exe, suite: 'load-so', is_parallel: false)\n+endforeach\n+\n+configure_file(input : 'libfoo.so.32',\n+    output : 'libfoo.so.32',\n+    command: ['cp', '@INPUT@', '@OUTPUT@'])\n+\n+configure_file(input : 'libfoo.so.64',\n+    output : 'libfoo.so.64',\n+    command: ['cp', '@INPUT@', '@OUTPUT@'])\ndiff --git a/test/meson.build b/test/meson.build\nindex d501f2b..a5937c2 100644\n--- a/test/meson.build\n+++ b/test/meson.build\n@@ -1,6 +1,7 @@\n subdir('libtest')\n \n subdir('camera')\n+subdir('load-so')\n subdir('media_device')\n subdir('pipeline')\n subdir('v4l2_device')\n","prefixes":["libcamera-devel","2/2"]}