{"id":2249,"date":"2019-05-20T10:00:39","date_gmt":"2019-05-20T08:00:39","guid":{"rendered":"https:\/\/craftcoders.app\/?p=1043"},"modified":"2024-08-14T14:27:52","modified_gmt":"2024-08-14T12:27:52","slug":"sophisticated-google-container-structure-tests","status":"publish","type":"post","link":"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/","title":{"rendered":"Sophisticated Google container structure tests"},"content":{"rendered":"\r\n

Last week we did an innovation week at our company, crowding up together and trying to figure out what can be done to improve our systems. Our group chose to setup a private docker registry and to automate the creation of docker<\/strong> images for our test-system. After some research we came up with Google’s framework named container structure tests<\/strong>, to verify that the automatically created containers are actually working.<\/p>\r\n\r\n\r\n\r\n

\r\n

The Container Structure Tests provide a powerful framework to validate the structure of a container image. These tests can be used to check the output of commands in an image, as well as verify metadata and contents of the filesystem.<\/p>\r\nGoogleContainerTools @ Github<\/a><\/cite><\/blockquote>\r\n\r\n\r\n\r\n

The way it is always, you can create very simple test scenarios very fast, but there is few documentation when it comes to more complicated stuff. With this post I want to sum up the pitfalls you might encounter and offer solutions<\/strong>, so you can get the most out of the framework. If you need to know the basic stuff first jump over to the read-me<\/a> and come back later \ud83d\ude09<\/p>\r\n\r\n\r\n\r\n

Pitfalls and solutions<\/h2>\r\n\r\n\r\n\r\n

Image entry-points are removed by default<\/h3>\r\n\r\n\r\n\r\n

Every docker container comes with an entry-point defining what it should do on startup. These can influence the structure of the container or consume a lot of time, so they are removed by default. In our case we needed the entry-point, since we wanted to test whether our PostgreSQL container is working properly. What you should do (according to the docs) is using the setup<\/code> section of the test like so:<\/p>\r\n\r\n\r\n\r\n

commandTests:\r\n  - name: \"postgres starts without errors\"\r\n    setup:\r\n      - [\".\/docker-entrypoint.sh\", \"postgres\"]\r\n    command: \"psql\"\r\n    args: [\"-d\", \"db-name\", \"-U\", \"db-user\", \"-c\", \"\\q\"]<\/code><\/pre>\r\n\r\n\r\n\r\n

This small test should start a new container, run the entrypoint script for postgres and finally check that we can connect to a database without any error. The exit code is expected to be zero by default. Sadly, this is not how it actually works as you will see in the next section.<\/p>\r\n\r\n\r\n\r\n

Every command runs in a separate container instance<\/h3>\r\n\r\n\r\n\r\n

The setup<\/code> section and the teardown<\/code> section as well, are a list of commands, whereas the command section is just a single command. All of these commands run in their own separate container and then commit a modified image to be the new base image<\/strong> for the next command in the list. Since in our postgres<\/em> example the entrypoint is starting a database in a setup command, this database will be running in this command’s container only. This leads to the need of multiple commands in the same container, which we can’t accomplish using the setup<\/code> section.<\/p>\r\n\r\n\r\n\r\n

Multi-line commands<\/h3>\r\n\r\n\r\n\r\n

We can trick the framework to run multiple commands in the same container using bash -c <list of commands><\/code>. Since this can get convoluted pretty fast, we can make use of YAML’s <\/em>“literal style” option (the | <\/code> sign) to preserve newlines.<\/p>\r\n\r\n\r\n\r\n

  - name: \"postgres starts without errors\"\r\n    command: \"bash\"\r\n    args:\r\n      - -c\r\n      - |\r\n          bash -c '.\/docker-entrypoint.sh postgres &' &&\r\n          sleep 10 &&\r\n          psql -d \"db-name\" -U \"db-user\" -c '\\q'<\/code><\/pre>\r\n\r\n\r\n\r\n

This is the final (and actually working) version of the same test. As you can see, we are now running the docker-entrypoint<\/code> script in the same container like the psql<\/code> command. But since the script is starting a database instance we had to wrap it up in a second bash -c<\/code> command so we could detach it from the console output with the ampersand (&) at the end. Furthermore we had to add some sleep time to give the database a chance to come up before we check if it is working.<\/p>\r\n\r\n\r\n\r\n

Switching user profiles<\/h3>\r\n\r\n\r\n\r\n

Sometimes it might be necessary to run a command as a different user than root. As user postgres for example \ud83d\ude00 Fortunately, this can be accomplished similar to bash -c<\/code> using su -c<\/code> like that:<\/p>\r\n\r\n\r\n\r\n

  - name: \"run a command as a different user\"\r\n    command: \"su\"\r\n    args:\r\n      - postgres\r\n      - -c\r\n      - whoami\r\n    expectedOutput: [\"postgres\"]<\/code><\/pre>\r\n\r\n\r\n
\r\n\r\n\r\n

Alrighty, that’s all I wanted to share for now. I hope the post will spare some time of yours. Please keep in mind that Google’s framework container structure tests<\/strong> has been made to verify the structure and general setup of your container. It is not meant to be used for something like integration tests. Thank’s for reading and have a nice day \ud83d\ude42<\/p>\r\n\r\n\r\n\r\n

\r\n
\"\"<\/figure>\r\n<\/div>\r\n\r\n\r\n\r\n

Greets, Domi<\/strong><\/p>\r\n","protected":false},"excerpt":{"rendered":"

Last week we did an innovation week at our company, crowding up together and trying to figure out what can be done to improve our systems. Our group chose to setup a private docker registry and to automate the creation of docker images for our test-system. After some research we came up with Google’s framework named container structure tests, to … Read More<\/a><\/p>\n","protected":false},"author":3,"featured_media":2316,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[185,109,186],"tags":[],"acf":[],"yoast_head":"\nSophisticated Google container structure tests - CraftCoders.app<\/title>\n<meta name=\"description\" content=\"This post provides a sum-up of pitfalls and solutions using Google's framework container structure tests for docker to create more sophisticated test cases.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Sophisticated Google container structure tests - CraftCoders.app\" \/>\n<meta property=\"og:description\" content=\"This post provides a sum-up of pitfalls and solutions using Google's framework container structure tests for docker to create more sophisticated test cases.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/\" \/>\n<meta property=\"og:site_name\" content=\"CraftCoders.app\" \/>\n<meta property=\"article:published_time\" content=\"2019-05-20T08:00:39+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-08-14T12:27:52+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/craftcoders.app\/wp-content\/uploads\/2019\/05\/soph-go-co-str-te-850x706-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"850\" \/>\n\t<meta property=\"og:image:height\" content=\"706\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Dominik J\u00fclg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Dominik J\u00fclg\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/\",\"url\":\"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/\",\"name\":\"Sophisticated Google container structure tests - CraftCoders.app\",\"isPartOf\":{\"@id\":\"https:\/\/craftcoders.app\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/craftcoders.app\/wp-content\/uploads\/2019\/05\/soph-go-co-str-te-850x706-1.png\",\"datePublished\":\"2019-05-20T08:00:39+00:00\",\"dateModified\":\"2024-08-14T12:27:52+00:00\",\"author\":{\"@id\":\"https:\/\/craftcoders.app\/#\/schema\/person\/950725b140a7ce1147b1308a746a8cce\"},\"description\":\"This post provides a sum-up of pitfalls and solutions using Google's framework container structure tests for docker to create more sophisticated test cases.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/#primaryimage\",\"url\":\"https:\/\/craftcoders.app\/wp-content\/uploads\/2019\/05\/soph-go-co-str-te-850x706-1.png\",\"contentUrl\":\"https:\/\/craftcoders.app\/wp-content\/uploads\/2019\/05\/soph-go-co-str-te-850x706-1.png\",\"width\":850,\"height\":706},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/craftcoders.app\/#website\",\"url\":\"https:\/\/craftcoders.app\/\",\"name\":\"CraftCoders.app\",\"description\":\"Jira and Confluence apps\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/craftcoders.app\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/craftcoders.app\/#\/schema\/person\/950725b140a7ce1147b1308a746a8cce\",\"name\":\"Dominik J\u00fclg\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/craftcoders.app\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bd18a95cdfc659ad254c8a3bd7f70cc5?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bd18a95cdfc659ad254c8a3bd7f70cc5?s=96&d=mm&r=g\",\"caption\":\"Dominik J\u00fclg\"},\"url\":\"https:\/\/craftcoders.app\/author\/domi\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Sophisticated Google container structure tests - CraftCoders.app","description":"This post provides a sum-up of pitfalls and solutions using Google's framework container structure tests for docker to create more sophisticated test cases.","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:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/","og_locale":"en_US","og_type":"article","og_title":"Sophisticated Google container structure tests - CraftCoders.app","og_description":"This post provides a sum-up of pitfalls and solutions using Google's framework container structure tests for docker to create more sophisticated test cases.","og_url":"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/","og_site_name":"CraftCoders.app","article_published_time":"2019-05-20T08:00:39+00:00","article_modified_time":"2024-08-14T12:27:52+00:00","og_image":[{"width":850,"height":706,"url":"https:\/\/craftcoders.app\/wp-content\/uploads\/2019\/05\/soph-go-co-str-te-850x706-1.png","type":"image\/png"}],"author":"Dominik J\u00fclg","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Dominik J\u00fclg","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/","url":"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/","name":"Sophisticated Google container structure tests - CraftCoders.app","isPartOf":{"@id":"https:\/\/craftcoders.app\/#website"},"primaryImageOfPage":{"@id":"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/#primaryimage"},"image":{"@id":"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/#primaryimage"},"thumbnailUrl":"https:\/\/craftcoders.app\/wp-content\/uploads\/2019\/05\/soph-go-co-str-te-850x706-1.png","datePublished":"2019-05-20T08:00:39+00:00","dateModified":"2024-08-14T12:27:52+00:00","author":{"@id":"https:\/\/craftcoders.app\/#\/schema\/person\/950725b140a7ce1147b1308a746a8cce"},"description":"This post provides a sum-up of pitfalls and solutions using Google's framework container structure tests for docker to create more sophisticated test cases.","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/craftcoders.app\/sophisticated-google-container-structure-tests\/#primaryimage","url":"https:\/\/craftcoders.app\/wp-content\/uploads\/2019\/05\/soph-go-co-str-te-850x706-1.png","contentUrl":"https:\/\/craftcoders.app\/wp-content\/uploads\/2019\/05\/soph-go-co-str-te-850x706-1.png","width":850,"height":706},{"@type":"WebSite","@id":"https:\/\/craftcoders.app\/#website","url":"https:\/\/craftcoders.app\/","name":"CraftCoders.app","description":"Jira and Confluence apps","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/craftcoders.app\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/craftcoders.app\/#\/schema\/person\/950725b140a7ce1147b1308a746a8cce","name":"Dominik J\u00fclg","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/craftcoders.app\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/bd18a95cdfc659ad254c8a3bd7f70cc5?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bd18a95cdfc659ad254c8a3bd7f70cc5?s=96&d=mm&r=g","caption":"Dominik J\u00fclg"},"url":"https:\/\/craftcoders.app\/author\/domi\/"}]}},"_links":{"self":[{"href":"https:\/\/craftcoders.app\/wp-json\/wp\/v2\/posts\/2249"}],"collection":[{"href":"https:\/\/craftcoders.app\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/craftcoders.app\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/craftcoders.app\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/craftcoders.app\/wp-json\/wp\/v2\/comments?post=2249"}],"version-history":[{"count":1,"href":"https:\/\/craftcoders.app\/wp-json\/wp\/v2\/posts\/2249\/revisions"}],"predecessor-version":[{"id":2317,"href":"https:\/\/craftcoders.app\/wp-json\/wp\/v2\/posts\/2249\/revisions\/2317"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/craftcoders.app\/wp-json\/wp\/v2\/media\/2316"}],"wp:attachment":[{"href":"https:\/\/craftcoders.app\/wp-json\/wp\/v2\/media?parent=2249"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/craftcoders.app\/wp-json\/wp\/v2\/categories?post=2249"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/craftcoders.app\/wp-json\/wp\/v2\/tags?post=2249"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}