{"id":39245,"date":"2015-04-09T20:26:30","date_gmt":"2015-04-09T17:26:30","guid":{"rendered":"https:\/\/www.altoros.com\/blog\/?p=39245"},"modified":"2020-04-21T02:56:02","modified_gmt":"2020-04-20T23:56:02","slug":"how-to-implement-integration-tests-for-juju-charms","status":"publish","type":"post","link":"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/","title":{"rendered":"How to Implement Integration Tests for Juju Charms"},"content":{"rendered":"<p>If you think that implementing integration tests for <a href=\"https:\/\/charmhub.io\/solutions?type=charm\" target=\"_blank\" rel=\"noopener noreferrer\">Juju Charms<\/a>\u2014Canonical\u2019s orchestration solution\u2014is a trivial task, you\u2019ll be surprised it\u2019s not. Last month, I was involved in testing a collection of 30 mature charms and summarized my experience in recommendations on how to solve the challenges that arise.<\/p>\n<p>&nbsp;<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_79_2 counter-hierarchy ez-toc-counter ez-toc-transparent ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#The_testing_workflow\" >The testing workflow<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#Tip_1_Using_the_DEB_transparent_proxy\" >Tip #1: Using the DEB transparent proxy<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#Tip_2_Run_tests_faster_with_the_LXC_test_environment\" >Tip #2: Run tests faster with the LXC test environment<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#Tip_3_Accelerate_with_BTRFS_subvolumes_and_snapshots\" >Tip #3: Accelerate with BTRFS subvolumes and snapshots<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#Tip_4_Save_time_with_the_AWS_machine_startup_%E2%80%98button\" >Tip #4: Save time with the AWS machine startup &#8216;button&#8217;<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#Tip_5_Track_disk_space_shortage_on_LXC\" >Tip #5: Track disk space shortage on LXC!<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#Tip_6_Install_Python_3_dependencies\" >Tip #6: Install Python 3 dependencies<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#Tip_7_Improve_your_test_implementation_workflow\" >Tip #7: Improve your test implementation workflow<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#Tools_used\" >Tools used<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#Conclusions\" >Conclusions<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#Further_reading\" >Further reading:<\/a><\/li><\/ul><\/nav><\/div>\n<h3><span class=\"ez-toc-section\" id=\"The_testing_workflow\"><\/span>The testing workflow<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Juju Charms are recipes for deploying software and maintaining its life cycle. If anyone needs to implement a test, s\/he will also need to understand how the software works as part of the implementation. The procedure of implementing an integration test for a charm comes down to these steps:<\/p>\n<p><img decoding=\"async\" class=\"alignright size-full wp-image-39246\" style=\"margin: 15px\" alt=\"Integration Tests for Juju Charms\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/11\/how-to-implement-integration-tests-for-juju-charms.png\" width=\"190\" \/><\/p>\n<ol>\n<li>Download the charm&#8217;s code<\/li>\n<li>Understand what the tool does<\/li>\n<li>Proofread the charm&#8217;s code<\/li>\n<li>Code the test inside the test directory<\/li>\n<li>Run the code and ensure that it runs as expected<\/li>\n<li>Report any bug detected while running a test<\/li>\n<li>Push the code and request it to merge into the main branch<\/li>\n<\/ol>\n<p>To successfully complete this task, you need to be familiar with the internals of the <a href=\"https:\/\/charmhub.io\/\" target=\"_blank\" rel=\"noopener noreferrer\">Juju platform<\/a>, understand how charms work, and have basic Python programming skills under your belt. Below, I share the tips\u2014that worked out in my case\u2014on how to implement integration tests for Juju Charms with no bumpy ride.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Tip_1_Using_the_DEB_transparent_proxy\"><\/span>Tip #1: Using the DEB transparent proxy<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>To start working with the DEB transparent proxy, install <code style=\"color: black; background-color: #e6e6e6;\">apt-cacher-ng<\/code>:<\/p>\n<pre>apt-get install apt-cacher-ng<\/pre>\n<p>Add config to <code style=\"color: black; background-color: #e6e6e6;\">environments.yaml<\/code>, it should look like this:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nenvironments:\r\n\tlocal:\r\n\t\tapt-http-proxy: http:\/\/10.0.3.1:3142\r\n<\/pre>\n<p>If you test this in the LXC environment in the <em>c3.xlarge AWS<\/em> machine, as I did, you would be amazed at the results. Without the <em>DEB transparent proxy<\/em>, the installation of packages (23.2 MB) to deploy the <em>nagios charm<\/em> took 11 seconds (2,048 KB\/s). With the <em>apt-cacher-ng DEB proxy<\/em>, it took almost 0 seconds (48.7 MB\/s).<\/p>\n<p>Saving 11 seconds seems like a trifle\u2014still, if you are testing OpenStack\u2026it means 2 minutes\/run!<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Tip_2_Run_tests_faster_with_the_LXC_test_environment\"><\/span>Tip #2: Run tests faster with the LXC test environment<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The LXC provider outperforms AWS in machine supplying and speed (depending on your hardware). My computer has seen better days, so I decided to use the LXC provider inside the <em>c3.xlarge AWS<\/em> machine.<\/p>\n<p>The difference in performance of running test is pretty significant. We tested two scenarios. The first scenario was the environment bootstrapping (running <code style=\"color: black; background-color: #e6e6e6;\">juju bootstrap<\/code>). Using the Amazon cloud provider, it took 5 minutes 2 seconds to bootstrap the environment. By comparison, it only took 22 seconds with the LXC provider inside the <em>c3.xlarge AWS<\/em>.<\/p>\n<p>The second scenario was to run <em>Bundletester<\/em> against the <em>Meteor charm<\/em>. In this scenario, using the Amazon cloud provider, it took 12 minutes to run all tests, while with LXC it took 3 minutes 18 seconds.<\/p>\n<p>Here&#8217;s the results overview.<\/p>\n<p><center><\/p>\n<table>\n<tr bgcolor=\"#F0F0F0\">\n<th width=\"30%\"><center><small>Method<\/small><\/center><\/th>\n<th width=\"30%\"><center><small>Amazon + LXC<\/small><\/center><\/th>\n<th width=\"30%\"><center><small>Amazon<\/small><\/center><\/th>\n<\/tr>\n<tr>\n<td><code style=\"color: black; background-color: #e6e6e6;\">juju bootstrap<\/code><\/td>\n<td><center><small>22s<\/small><\/center><\/td>\n<td><center><small>5m 2.398s<\/small><\/center><\/td>\n<\/tr>\n<tr>\n<td><small>Bundletester trusty meteor<\/small><\/td>\n<td><center><small>3m 18.190s<\/small><\/center><\/td>\n<td><center><small>12m 4.494s<\/small><\/center><\/td>\n<\/tr>\n<\/table>\n<p><\/center><\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Tip_3_Accelerate_with_BTRFS_subvolumes_and_snapshots\"><\/span>Tip #3: Accelerate with BTRFS subvolumes and snapshots<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>If the provisioned machines are stored in the BTRFS partition, LXC will provision those machines much faster thanks to the cloning capabilities of BTRFS. The BTRFS file system features the subvolume technology, which allows for creating directories with the ability to make snapshots. A snapshot is a special type of a subvolume that contains a copy of the current state of some other subvolume. If you need more info about this, take a look at this <a href=\"https:\/\/lwn.net\/Articles\/579009\/\" target=\"_blank\" rel=\"noopener noreferrer\">article<\/a>.<\/p>\n<p>You can make use of this feature by adding a volume via AWS. After doing so, run these commands as root:<\/p>\n<pre>\r\nmkfs.btrfs -m single \/dev\/xvdf  # or the name of your device\r\nmv \/var\/lib\/lxc \/var\/lib\/lxc-old\r\nmkdir \/var\/lib\/lxc\r\nmount \/dev\/xcdf \/var\/lib\/lxc\r\nservice lxc stop\r\nmv \/var\/lib\/lxc-old\/* \/var\/lib\/lxc\/  # Ignore moving errors\r\n<\/pre>\n<p>Now, you can see how fast it is by testing it on LXC directly:<\/p>\n<pre>\r\nroot@ip-172-31-14-23:\/home\/ubuntu# time lxc-clone -s -o ubuntu-local-machine-1 -n ubuntu-local-machine-2\r\nCreated container ubuntu-local-machine-2 as snapshot of ubuntu-local-machine-1\r\n\r\nreal    0m0.056s\r\nuser    0m0.000s\r\nsys     0m0.019s\r\nroot@ip-172-31-14-23:\/home\/ubuntu# time lxc-clone -o ubuntu-local-machine-1 -n ubuntu-local-machine-3\r\nCreated container ubuntu-local-machine-3 as copy of ubuntu-local-machine-1\r\n\r\nreal    0m18.332s\r\nuser    0m3.921s\r\nsys     0m2.996s\r\nroot@ip-172-31-14-23:\/home\/ubuntu#\r\n<\/pre>\n<p>The <code style=\"color: black; background-color: #e6e6e6;\">-s<\/code> flag ensures that it uses snapshotting instead of copying. That means it is an extremely big improvement! It also reduces disk usage.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Tip_4_Save_time_with_the_AWS_machine_startup_%E2%80%98button\"><\/span>Tip #4: Save time with the AWS machine startup &#8216;button&#8217;<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>As I was using my large AWS machine to run the tests and there was no point in having this machine online all the time, I modified a script that starts and stops it. With this script, I no longer have to waste time entering the AWS Dashboard to start and stop my machine.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\n#\r\n# Based on work done by Andrew McDonald andrew@mcdee.com.au http:\/\/mcdee.com.au\r\n#\r\n\r\nimport boto.ec2\r\nimport sys\r\nimport time\r\n\r\n# AWS_ACCESS_KEY_ID\r\nAKID = 'Your Access Key ID'\r\n# AWS_SECRET_ACCESS_KEY\r\nASAK = 'Your AWS Secret Access Key'\r\n# Region string\r\nREGION = 'us-west-2'  # your region\r\n\r\ndef print_usage(args):\r\n    print 'Usage:', args&#x5B;0], 'stop|start &amp;lt;instance name&amp;gt;'\r\n    sys.exit(1)\r\n\r\ndef usage(args):\r\n    arg1 = &#x5B;'stop', 'start']\r\n    if not len(args) == 3:\r\n        print_usage(args)\r\n    else:\r\n        if not args&#x5B;1] in arg1:\r\n            print_usage(args)\r\n        else:\r\n            return args&#x5B;2]\r\n\r\nmyinstance = usage(sys.argv)\r\nconn = boto.ec2.connect_to_region(REGION,\r\n                                aws_access_key_id=AKID,\r\n                                aws_secret_access_key=ASAK)\r\nif sys.argv&#x5B;1] == 'start':\r\n    try:\r\n        inst = conn.get_all_instances(\r\n            filters={'tag:Name': myinstance})&#x5B;0].instances&#x5B;0]\r\n    except IndexError:\r\n        print 'Error:', myinstance, 'not found!'\r\n        sys.exit(1)\r\n    if not inst.state == 'running':\r\n        print 'Starting', myinstance\r\n        inst.start()\r\n        while inst.state != 'running':\r\n            print '...instance is %s' % inst.state\r\n            time.sleep(10)\r\n            inst.update()\r\n        print 'Instance started'\r\n        print 'Instance IP: %s' % inst.ip_address\r\n        print 'ssh -A -D 9999 ubuntu@%s' % inst.ip_address\r\n    else:\r\n        print 'Error:', myinstance, 'already running or starting up!'\r\n        print 'Instance IP: %s' % inst.ip_address\r\n        print 'ssh -D 9999 ubuntu@%s' % inst.ip_address\r\n        sys.exit(1)\r\n\r\nif sys.argv&#x5B;1] == 'stop':\r\n    try:\r\n        inst = conn.get_all_instances(\r\n            filters={'tag:Name': myinstance})&#x5B;0].instances&#x5B;0]\r\n    except IndexError:\r\n        print 'Error:', myinstance, 'not found!'\r\n        sys.exit(1)\r\n    if inst.state == 'running':\r\n        print 'Stopping', myinstance\r\n        inst.stop()\r\n    else:\r\n        print 'Error:', myinstance, 'already stopped or stopping'\r\n        sys.exit(1)\r\n<\/pre>\n<p>You can improve it by adding a cron job that shuts down the machine, if no Bundletester process is seen in a certain time gap.<\/p>\n<p>You can start the machine just to run tests, too. So, the script can start the machine, copy the test to the machine, run it, extract the test output, and stop the machine automatically.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Tip_5_Track_disk_space_shortage_on_LXC\"><\/span>Tip #5: Track disk space shortage on LXC!<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>To never, ever run out of disk space should be among your priorities. Making the environment usable again is a real pain, once you reach this point. Ensure you have at least 20 GB in the partition, where <code style=\"color: black; background-color: #e6e6e6;\">~\/.juju<\/code> is.<\/p>\n<p>If you run out of disk space, this is what you should do:<\/p>\n<ol>\n<li>Force-destroy the environment<\/li>\n<li><code style=\"color: black; background-color: #e6e6e6;\">juju destroy-environment local -y --force<\/code><\/li>\n<li>Then, if there is a hanged LXC environment, destroy it using <code style=\"color: black; background-color: #e6e6e6;\">lxc-destroy<\/code><\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Tip_6_Install_Python_3_dependencies\"><\/span>Tip #6: Install Python 3 dependencies<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Remember to install the Python v3 dependencies. All the dependencies are usually installed using the <em>tests\/00-setup<\/em> script. You need to invoke the Python 3 version of <em>easy_install<\/em>, which belongs to the <em>python3-setuptools<\/em> package.<\/p>\n<p>This is what you need to add:<\/p>\n<pre>apt-get install python3-setuptools\r\neasy_install3<\/pre>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Tip_7_Improve_your_test_implementation_workflow\"><\/span>Tip #7: Improve your test implementation workflow<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>As the days went by, I realized that the proposed workflow had many problems.<\/p>\n<ol>\n<li>It stuck me while I was waiting for a test run to finish. Since the integration tests take much more time than unit tests (minutes instead of seconds), it is hard to stay focused on the task. So, it was a big waste to wait minutes each time a test runs.<\/li>\n<p><\/p>\n<li>Limited test planning: We were missing the opportunity to gather information from the community on the most wanted tests.<\/li>\n<\/ol>\n<p>Therefore, we modified the workflow in order to address these two issues.<\/p>\n<ol>\n<li>We started implementing all charms tests together, so we could run them in a batch. This way, I could have some other tests implemented, while I was waiting for the test run to finish.<\/li>\n<p><\/p>\n<li>We started publishing the test plan as a bug on the Launchpad platform a few days before implementing them, so we were able:<\/li>\n<p><\/p>\n<ul>\n<li>give the community the opportunity to improve and correct the list<\/li>\n<li>engage the community in the practice of implementing tests, as they are crucial for a solid platform<\/li>\n<\/ul>\n<\/ol>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Tools_used\"><\/span>Tools used<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This section features an overview of the tools used for the implementation.<\/p>\n<p>&nbsp;<br \/>\n<strong>Amulet<\/strong><\/p>\n<p><a href=\"https:\/\/github.com\/juju\/amulet\" target=\"_blank\" rel=\"noopener noreferrer\">Amulet<\/a> is a Python 3 library designed to test Juju Charms. It wraps the Juju command line tool with a pythonic interface and a proposed workflow for testing.<\/p>\n<p>&nbsp;<br \/>\n<strong>Charm tools<\/strong><\/p>\n<p>Charms are designed to simplify deployment, configuration, and exposure of services in the cloud. The Juju platform offers some tools to debug charms and understand how they behave. The entry point of this package is the <code style=\"color: black; background-color: #e6e6e6;\">juju<\/code> command. The main options I\u2019ve used:<\/p>\n<ul>\n<li><code style=\"color: black; background-color: #e6e6e6;\">juju deploy &lt;charm&gt;<\/code>: It allowed me to test the charm as it comes without much research.<\/li>\n<p><\/p>\n<li><code style=\"color: black; background-color: #e6e6e6;\">juju debug-log<\/code>: While running tests and deployments, this command gives you access to the logs of all the machines in one chronological log.<\/li>\n<p><\/p>\n<li><code style=\"color: black; background-color: #e6e6e6;\">juju debug-hooks &lt;charm&gt; &lt;hook&gt;<\/code>: To understand how hooks work, I used this to break a specific run and inspect what data the charms were exchanging.<\/li>\n<\/ul>\n<p>For more info, check out the <a href=\"https:\/\/charmhub.io\/docs\/charms\" target=\"_blank\" rel=\"noopener noreferrer\">charms documentation<\/a>.<\/p>\n<p>&nbsp;<br \/>\n<strong>Charm helpers<\/strong><\/p>\n<p>The <em>charmhelpers<\/em> Python library is a collection of functions that simplifies the development of charms. It also enables Charm Test Authors to easily interact with the deployment.<\/p>\n<p>The main use cases where I applied this library were as follows:<\/p>\n<ul>\n<li>running commands in a specific unit<\/li>\n<li>reading config files<\/li>\n<li>checking if a process is running<\/li>\n<li>checking open ports<\/li>\n<\/ul>\n<p>For more info, check out this <a href=\"https:\/\/pythonhosted.org\/charmhelpers\/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">website<\/a>.<\/p>\n<p>&nbsp;<br \/>\n<strong>Canonical\/Juju online tools<\/strong><\/p>\n<p>Canonical provides certain tools that simplify coordination between developers.<\/p>\n<p>a) The <a href=\"http:\/\/review.juju.solutions\/\" target=\"_blank\" rel=\"noopener noreferrer\">review.juju.solutions<\/a> queue is used to coordinate the charmers launchpad group. The main task of this tool is to review merge proposals in the charm repository. The review queue also allows reviewers to run the tests batteries against the new branches, verifying that merge proposals don&#8217;t break anything before the merge.<\/p>\n<p>b) <a href=\"https:\/\/launchpad.net\/\" target=\"_blank\" rel=\"noopener noreferrer\">Launchpad<\/a> is an all-in-one project management tool that helps Canonical and free software advocates to coordinate their work. It features bazaar code repositories per project, issue tracking, and other functionality. If you plan to implement a test for a charm, you will have to check the charm&#8217;s project page, clone the project&#8217;s bazaar repository, push your branch into bazaar, and ask for a merge proposal. Don&#8217;t forget to create a user in Launchpad before taking these steps and completing your registration. There is a particular point that is not pretty clear\u2014the signage of the Ubuntu Code of Conduct. To do it, you need to follow the steps specified in <a href=\"https:\/\/help.launchpad.net\/Signing%20the%20Ubuntu%20Code%20of%20Conduct\" target=\"_blank\" rel=\"noopener noreferrer\">this guide<\/a>.<\/p>\n<p>c) <a href=\"http:\/\/webchat.freenode.net\/?channels=%23juju&amp;uio=d4\" target=\"_blank\" rel=\"noopener noreferrer\">IRC<\/a> is the preferred way of communication between the team members of the Juju project. The channel is <code style=\"color: black; background-color: #e6e6e6;\">irc:\/\/irc.freenode.net:6667\/#juju<\/code>. You can use a Freenode Webchat Client, if you are not used to IRC.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Conclusions\"><\/span>Conclusions<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>As you see, the implementation of integration tests for the Juju platform was successful, but not without its bumps and jumps. Still, if you follow these recommendations, you will have a pleasant experience with Juju Charms, an incredible tool for deploying and maintaining services online.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Further_reading\"><\/span>Further reading:<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/juju-charms-for-cloud-foundry-how-to-deploy-customize-and-upgrade\/\">How to Deploy, Customize, and Upgrade Juju Charms for Cloud Foundry<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/deploying-cloud-foundry-in-a-single-click-with-juju-charms\/\">Deploying Cloud Foundry in a Single Click with Juju Charms<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/cloud-foundry-deployment-tools-bosh-vs-juju-charms\/\">Cloud Foundry Deployment Tools: BOSH vs. Juju Charms<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3>About the author<\/p>\n<h3>\n<p><em><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/04\/nicolas-pace-altoros.jpg\"><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/04\/nicolas-pace-altoros.jpg\" width=\"150\" class=\"alignright size-full wp-image-53965\" \/><\/a><a href=\"https:\/\/github.com\/nicopace\" rel=\"noopener noreferrer\" target=\"_blank\">Nicol\u00e1s Pace<\/a> is Senior Python Developer at Altoros. With 10 years of engineering experience, he drives project planning, architecture design, app deployment, and team management. Nicol\u00e1s has successfully led a variety of cross-functional projects, reaching organizational objectives and mentoring other developers. He is proficient in resolving complex technical issues, possessing deep knowledge of open-source tools that enable developers to quickly prototype and test business systems.<\/em><\/p>\n<p>&nbsp;<\/p>\n<hr\/>\n<p><center><small>The post is written by Nicol\u00e1s Pace; edited and published by Sophia Turol and <a href=\"https:\/\/www.altoros.com\/blog\/author\/alex\/\">Alex Khizhniak<\/a>.<\/small><\/center><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you think that implementing integration tests for Juju Charms\u2014Canonical\u2019s orchestration solution\u2014is a trivial task, you\u2019ll be surprised it\u2019s not. Last month, I was involved in testing a collection of 30 mature charms and summarized my experience in recommendations on how to solve the challenges that arise.<\/p>\n<p>&nbsp;<\/p>\n<p>The testing workflow<\/p>\n<p>Juju Charms [&#8230;]<\/p>\n","protected":false},"author":5,"featured_media":39280,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":"","_links_to":"","_links_to_target":""},"categories":[214],"tags":[873],"class_list":["post-39245","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-cloud-native"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>How to Implement Integration Tests for Juju Charms | Altoros<\/title>\n<meta name=\"description\" content=\"From this tutorial, learn about the testing workflow and the tools used, as well as explore seven tips to accelerate integration tests for Juju Charms.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Implement Integration Tests for Juju Charms | Altoros\" \/>\n<meta property=\"og:description\" content=\"If you think that implementing integration tests for Juju Charms\u2014Canonical\u2019s orchestration solution\u2014is a trivial task, you\u2019ll be surprised it\u2019s not. Last month, I was involved in testing a collection of 30 mature charms and summarized my experience in recommendations on how to solve the challenges that arise. &nbsp; The testing workflow Juju Charms [...]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/\" \/>\n<meta property=\"og:site_name\" content=\"Altoros\" \/>\n<meta property=\"article:published_time\" content=\"2015-04-09T17:26:30+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-04-20T23:56:02+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/04\/cloud-foundry-deployment-tools-bosh-vs-juju-charms-26-1024.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"576\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Alex Khizhniak\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alex Khizhniak\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/\",\"name\":\"How to Implement Integration Tests for Juju Charms | Altoros\",\"isPartOf\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/04\/cloud-foundry-deployment-tools-bosh-vs-juju-charms-26-1024.jpg\",\"datePublished\":\"2015-04-09T17:26:30+00:00\",\"dateModified\":\"2020-04-20T23:56:02+00:00\",\"author\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/3d914db6ad1b2908c32c0dc5dcabc420\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#primaryimage\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/04\/cloud-foundry-deployment-tools-bosh-vs-juju-charms-26-1024.jpg\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/04\/cloud-foundry-deployment-tools-bosh-vs-juju-charms-26-1024.jpg\",\"width\":1024,\"height\":576},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.altoros.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Implement Integration Tests for Juju Charms\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\",\"url\":\"https:\/\/www.altoros.com\/blog\/\",\"name\":\"Altoros\",\"description\":\"Insight\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.altoros.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/3d914db6ad1b2908c32c0dc5dcabc420\",\"name\":\"Alex Khizhniak\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2017\/06\/druzya-edit1-150x150.jpg\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2017\/06\/druzya-edit1-150x150.jpg\",\"caption\":\"Alex Khizhniak\"},\"description\":\"Alex Khizhniak is Director of Technical Content Strategy at Altoros and a cofounder of a local Java User Group. Managing distributed teams since 2004, he has gained experience as a journalist, an editor-in-chief, a technical writer, a technology evangelist, a project manager, and a product owner. Alex is obsessed with AI\/ML, data science, data integration, ETL\/DWH, data quality, databases (SQL\/NoSQL), big data, IoT, and BI. The articles and industry reports he created or helped to publish reached out to 3,000,000+ tech-savvy readers. Some of the pieces were covered on TechRepublic, ebizQ, NetworkWorld, CIO.com, etc. Find him on Twitter at @alxkh.\",\"sameAs\":[\"https:\/\/x.com\/https:\/\/twitter.com\/alxkh\"],\"url\":\"https:\/\/www.altoros.com\/blog\/author\/alex\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Implement Integration Tests for Juju Charms | Altoros","description":"From this tutorial, learn about the testing workflow and the tools used, as well as explore seven tips to accelerate integration tests for Juju Charms.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/","og_locale":"en_US","og_type":"article","og_title":"How to Implement Integration Tests for Juju Charms | Altoros","og_description":"If you think that implementing integration tests for Juju Charms\u2014Canonical\u2019s orchestration solution\u2014is a trivial task, you\u2019ll be surprised it\u2019s not. Last month, I was involved in testing a collection of 30 mature charms and summarized my experience in recommendations on how to solve the challenges that arise. &nbsp; The testing workflow Juju Charms [...]","og_url":"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/","og_site_name":"Altoros","article_published_time":"2015-04-09T17:26:30+00:00","article_modified_time":"2020-04-20T23:56:02+00:00","og_image":[{"width":1024,"height":576,"url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/04\/cloud-foundry-deployment-tools-bosh-vs-juju-charms-26-1024.jpg","type":"image\/jpeg"}],"author":"Alex Khizhniak","twitter_misc":{"Written by":"Alex Khizhniak","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/","url":"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/","name":"How to Implement Integration Tests for Juju Charms | Altoros","isPartOf":{"@id":"https:\/\/www.altoros.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#primaryimage"},"image":{"@id":"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#primaryimage"},"thumbnailUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/04\/cloud-foundry-deployment-tools-bosh-vs-juju-charms-26-1024.jpg","datePublished":"2015-04-09T17:26:30+00:00","dateModified":"2020-04-20T23:56:02+00:00","author":{"@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/3d914db6ad1b2908c32c0dc5dcabc420"},"breadcrumb":{"@id":"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#primaryimage","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/04\/cloud-foundry-deployment-tools-bosh-vs-juju-charms-26-1024.jpg","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/04\/cloud-foundry-deployment-tools-bosh-vs-juju-charms-26-1024.jpg","width":1024,"height":576},{"@type":"BreadcrumbList","@id":"https:\/\/www.altoros.com\/blog\/how-to-implement-integration-tests-for-juju-charms\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.altoros.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How to Implement Integration Tests for Juju Charms"}]},{"@type":"WebSite","@id":"https:\/\/www.altoros.com\/blog\/#website","url":"https:\/\/www.altoros.com\/blog\/","name":"Altoros","description":"Insight","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.altoros.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/3d914db6ad1b2908c32c0dc5dcabc420","name":"Alex Khizhniak","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2017\/06\/druzya-edit1-150x150.jpg","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2017\/06\/druzya-edit1-150x150.jpg","caption":"Alex Khizhniak"},"description":"Alex Khizhniak is Director of Technical Content Strategy at Altoros and a cofounder of a local Java User Group. Managing distributed teams since 2004, he has gained experience as a journalist, an editor-in-chief, a technical writer, a technology evangelist, a project manager, and a product owner. Alex is obsessed with AI\/ML, data science, data integration, ETL\/DWH, data quality, databases (SQL\/NoSQL), big data, IoT, and BI. The articles and industry reports he created or helped to publish reached out to 3,000,000+ tech-savvy readers. Some of the pieces were covered on TechRepublic, ebizQ, NetworkWorld, CIO.com, etc. Find him on Twitter at @alxkh.","sameAs":["https:\/\/x.com\/https:\/\/twitter.com\/alxkh"],"url":"https:\/\/www.altoros.com\/blog\/author\/alex\/"}]}},"_links":{"self":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/39245","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/comments?post=39245"}],"version-history":[{"count":33,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/39245\/revisions"}],"predecessor-version":[{"id":53976,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/39245\/revisions\/53976"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media\/39280"}],"wp:attachment":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media?parent=39245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/categories?post=39245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/tags?post=39245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}