{"id":251,"date":"2010-07-10T18:54:00","date_gmt":"2010-07-10T16:54:00","guid":{"rendered":""},"modified":"2023-03-20T12:49:56","modified_gmt":"2023-03-20T11:49:56","slug":"integration-tests-for-smx4-with-python","status":"publish","type":"post","link":"https:\/\/touk.pl\/blog\/2010\/07\/10\/integration-tests-for-smx4-with-python\/","title":{"rendered":"Integration Tests for SMX4 with Python"},"content":{"rendered":"<p>Integration tests and unit tests are important for project quality. Unit tests usually are well suited for developer to verify his changes in runtime. On the other hand, integration tests, are for target user to verify that project&#8217;s features in the way he interacts with project, work properly. In this article, I will show how to automate integration tests for ServiceMix 4 using SoapUI testrunner and a simple python script.<br \/>\nThe idea is to spawn ServiceMix 4 Karaf console and interact with it using python expect library. During this interaction, SoapUI testrunner script is invoked in order to run SoapUI tests.<br \/>\nFirst, we need to grab SMX4_DIR and SOAPUI_DIR environment variables in our script, like this:<\/p>\n<pre class=\"hl\">SMX4_DIR<span class=\"hl sym\">=<\/span>os<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">getenv<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"SMX4_DIR\"<\/span><span class=\"hl sym\">)<\/span>\r\nSOAPUI_DIR<span class=\"hl sym\">=<\/span>os<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">getenv<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"SOAPUI_DIR\"<\/span><span class=\"hl sym\">)<\/span><\/pre>\n<p>&nbsp;<br \/>\nThis way, we can invoke later our script using following shell command:<\/p>\n<pre class=\"hl\">SMX4_DIR<span class=\"hl sym\">=\/<\/span>some<span class=\"hl sym\">\/<\/span>path SOAPUI_DIR<span class=\"hl sym\">=\/<\/span>some<span class=\"hl sym\">\/<\/span>other<span class=\"hl sym\">\/<\/span>path .<span class=\"hl sym\">\/<\/span>our<span class=\"hl sym\">-<\/span>python<span class=\"hl sym\">-<\/span><span class=\"hl kwc\">script<\/span><\/pre>\n<p>&nbsp;<br \/>\nThen, we need to spawn ServiceMix 4 console by using python expect library:<\/p>\n<pre class=\"hl\"><span class=\"hl kwa\">import<\/span> pexpect\r\n<span class=\"hl kwa\">import<\/span> time\r\n<span class=\"hl kwa\">import<\/span> sys\r\nchild <span class=\"hl sym\">=<\/span> pexpect<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">spawn<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"bin\/servicemix\"<\/span><span class=\"hl sym\">)<\/span>\r\nchild<span class=\"hl sym\">.<\/span>logfile <span class=\"hl sym\">=<\/span> sys<span class=\"hl sym\">.<\/span>stdout\r\nchild<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">expect<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"karaf.*&gt;\"<\/span><span class=\"hl sym\">)<\/span>\r\ntime<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">sleep<\/span><span class=\"hl sym\">(<\/span><span class=\"hl num\">3<\/span><span class=\"hl sym\">)<\/span><\/pre>\n<p>&nbsp;<br \/>\nHere, we set logfile to stdout in order to see our automated interaction with ServiceMix console. Then we need to wait for ServiceMix console command prompt, which would mean console is ready. Additionally, we need to wait a few seconds to avoid problems with running commands too early (which is a kind of small bug in ServiceMix). Then, we can install our features, which we want to test. This example starts Apache HISE test bundle, which loads also Apache HISE engine from dependencies.<\/p>\n<pre class=\"hl\">child<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">sendline<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"features:addUrl mvn:org.apache.hise\/hise-karaf\/0.3.0-SNAPSHOT\/xml\/features\"<\/span><span class=\"hl sym\">);<\/span>\r\nchild<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">expect<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"karaf.*&gt;\"<\/span><span class=\"hl sym\">)<\/span>\r\nchild<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">sendline<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"features:install hise-h2-test-example-osgi\"<\/span><span class=\"hl sym\">)<\/span>\r\nchild<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">expect<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"karaf.*&gt;\"<\/span><span class=\"hl sym\">)<\/span><\/pre>\n<p>&nbsp;<br \/>\nNext, we need to wait until the feature is properly started. ServiceMix 4 OSGi container initializes bundles in background, so it&#8217;s not enough to wait for command prompt to have it started (there doesn&#8217;t seem to exist a &#8220;wait-until-started&#8221; console command).So we grep in a loop over installed bundles and see if status is started. In this example, we do 30 retries every second and fail our integration test script after this period, by raising exception.<\/p>\n<pre class=\"hl\">child<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">sendline<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"features:addUrl mvn:org.apache.hise\/hise-karaf\/0.3.0-SNAPSHOT\/xml\/features\"<\/span><span class=\"hl sym\">);<\/span>\r\nrep<span class=\"hl sym\">=<\/span><span class=\"hl num\">0<\/span>\r\n<span class=\"hl kwa\">while True<\/span><span class=\"hl sym\">:<\/span>\r\n    child<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">sendline<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"osgi:list|grep -i hise-test-example-osgi\"<\/span><span class=\"hl sym\">)<\/span>\r\n    l<span class=\"hl sym\">=<\/span>child<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">readline<\/span><span class=\"hl sym\">()<\/span>\r\n    l<span class=\"hl sym\">=<\/span>child<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">readline<\/span><span class=\"hl sym\">()<\/span>\r\n    <span class=\"hl kwa\">if<\/span> re<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">match<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\".*Started\"<\/span><span class=\"hl sym\">,<\/span> l<span class=\"hl sym\">) !=<\/span> <span class=\"hl kwa\">None<\/span><span class=\"hl sym\">:<\/span>\r\n        <span class=\"hl kwa\">break<\/span>\r\n    time<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">sleep<\/span><span class=\"hl sym\">(<\/span><span class=\"hl num\">1<\/span><span class=\"hl sym\">)<\/span>\r\n    child<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">expect<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"karaf.*&gt;\"<\/span><span class=\"hl sym\">)<\/span>\r\n    rep<span class=\"hl sym\">=<\/span>rep<span class=\"hl sym\">+<\/span><span class=\"hl num\">1<\/span>\r\n    <span class=\"hl kwa\">if<\/span> rep<span class=\"hl sym\">&gt;<\/span><span class=\"hl num\">30<\/span><span class=\"hl sym\">:<\/span>\r\n        <span class=\"hl kwa\">raise<\/span> <span class=\"hl kwc\">Exception<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"Bundle not installed\"<\/span><span class=\"hl sym\">)<\/span><\/pre>\n<p>&nbsp;<br \/>\nNext, we need to run SoapUI testrunner in order to execute test cases. We need to implement syscall method in order to fail integration tests if SoapUI testrunner completes with fault (non-zero exit code).<\/p>\n<pre class=\"hl\"><span class=\"hl kwa\">import<\/span> os\r\n<span class=\"hl kwa\">def<\/span> <span class=\"hl kwd\">syscall<\/span><span class=\"hl sym\">(<\/span>c<span class=\"hl sym\">):<\/span>\r\n    <span class=\"hl kwa\">if<\/span> os<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">system<\/span><span class=\"hl sym\">(<\/span>c<span class=\"hl sym\">) !=<\/span> <span class=\"hl num\">0<\/span><span class=\"hl sym\">:<\/span>\r\n        <span class=\"hl kwa\">raise<\/span> <span class=\"hl kwc\">Exception<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"Sys call failed: \"<\/span> <span class=\"hl sym\">+<\/span> c<span class=\"hl sym\">)<\/span><\/pre>\n<p><span class=\"hl kwd\">syscall<\/span><span class=\"hl sym\">(<\/span>SOAPUI_DIR <span class=\"hl sym\">+<\/span> <span class=\"hl str\">&#8220;\/bin\/testrunner.sh -f results hise-soapui-project.xml&#8221;<\/span><span class=\"hl sym\">)<\/span><br \/>\nAt the end, we can exit gracefully from ServiceMix console by using shutdown command, like this:<\/p>\n<pre class=\"hl\">child<span class=\"hl sym\">.<\/span><span class=\"hl kwd\">sendline<\/span><span class=\"hl sym\">(<\/span><span class=\"hl str\">\"shutdown\"<\/span><span class=\"hl sym\">)<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>And that&#8217;s it. Full code of integration test script is available in Apache HISE sources, from Apache repository <a href=\"http:\/\/svn.apache.org\/repos\/asf\/incubator\/hise\/trunk\/itest\/itest\">http:\/\/svn.apache.org\/repos\/asf\/incubator\/hise\/trunk\/itest\/itest<\/a>.<\/p>\n<div class=\"blogger-post-footer\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogger.googleusercontent.com\/tracker\/6983141563768732668-859346365298205761?l=rrusin.blogspot.com\" alt=\"\" width=\"1\" height=\"1\" \/><\/div>\n","protected":false},"excerpt":{"rendered":"Integration tests and unit tests are important for project quality. Unit tests usually are well suited for developer&hellip;\n","protected":false},"author":35,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":{"0":"post-251","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-development-design"},"_links":{"self":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/251","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/users\/35"}],"replies":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/comments?post=251"}],"version-history":[{"count":30,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/251\/revisions"}],"predecessor-version":[{"id":15352,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/251\/revisions\/15352"}],"wp:attachment":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/media?parent=251"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/categories?post=251"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/tags?post=251"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}