#!/bin/bash # Copyright 2016 The Bazel Authors. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Unit tests for docker_build global DIR := $[cd $[dirname $(BASH_SOURCE[0])] && pwd] source $(DIR)/testenv.sh || do { echo "testenv.sh not found!" > !2; exit 1setconst global FOO = "bar"; } readonly PLATFORM = $[uname -s | tr 'A-Z' 'a-z] if test $(PLATFORM) = "darwin" {setconst global FOO = "bar" readonly MAGIC_TIMESTAMP = $[date -r 0 "+%b %e %Y] } else {setconst global FOO = "bar" readonly MAGIC_TIMESTAMP = $[date --date=@0 "+%F %R] } proc EXPECT_CONTAINS { var complete = $(1) var substring = $(2) var message = $(3:-Expected '${substring}' not found in '${complete}') echo $(complete) | grep -Fsq -- $(substring) \ || fail $message } proc check_property { var property = $(1) var tarball = $(2) var image = $(3) var expected = $(4) var test_data = ""$(TEST_DATA_DIR)/$(tarball).tar"" var config = $[tar xOf $(test_data) "./$(image).json] # This would be much more accurate if we had 'jq' everywhere. EXPECT_CONTAINS $(config) "\"$(property)\": $(expected)" } proc check_no_property { var property = $(1) var tarball = $(2) var image = $(3) var test_data = ""$(TEST_DATA_DIR)/$(tarball).tar"" tar xOf $(test_data) "./$(image).json" >$TEST_log expect_not_log "\"$(property)\":" } proc check_entrypoint { global input := $1 shift check_property Entrypoint $(input) $(@) } proc check_cmd { global input := $1 shift check_property Cmd $(input) $(@) } proc check_ports { global input := $1 shift check_property ExposedPorts $(input) $(@) } proc check_volumes { global input := $1 shift check_property Volumes $(input) $(@) } proc check_env { global input := $1 shift check_property Env $(input) $(@) } proc check_label { global input := $1 shift check_property Label $(input) $(@) } proc check_workdir { global input := $1 shift check_property WorkingDir $(input) $(@) } proc check_user { global input := $1 shift check_property User $(input) $(@) } proc check_images { var input = $1 shift 1 var expected_images = '('${*}) var test_data = ""$(TEST_DATA_DIR)/$(input).tar"" var manifest = $[tar xOf $(test_data) "./manifest.json] var manifest_images = '( '$(echo "${manifest}" | grep -Eo '"Config":[[:space:]]*"[^"]+"' \ | sed -r -e 's#"Config":.*?"([0-9a-f]+)\.json"#\1#')) var manifest_parents = '( '$(echo "${manifest}" | grep -Eo '"Parent":[[:space:]]*"[^"]+"' \ | sed -r -e 's#"Parent":.*?"sha256:([0-9a-f]+)"#\1#')) # Verbose output for testing. echo Expected: $(expected_images[@]) echo Actual: $(manifest_images[@]) echo Parents: $(manifest_parents[@]) check_eq $(#expected_images[@]) $(#manifest_images[@]) var index = '0' while [ "${index}" -lt "${#expected_images[@]}" ] { # Check that the nth sorted layer matches check_eq $(expected_images[$index]) $(manifest_images[$index]) index := $(index + 1) } # Check that the image contains its predecessor as its parent in the manifest. check_eq $(#manifest_parents[@]) "$(${#manifest_images[@]} - 1)" var index = '0' while [ "${index}" -lt "${#manifest_parents[@]}" ] { # Check that the nth sorted layer matches check_eq $(manifest_parents[$index]) $(manifest_images[$index]) index := $(index + 1) } } # The bottom manifest entry must contain all layers in order proc check_image_manifest_layers { var input = $1 shift 1 var expected_layers = '('${*}) var test_data = ""$(TEST_DATA_DIR)/$(input).tar"" var manifest = $[tar xOf $(test_data) "./manifest.json] var manifest_layers = '( '$(echo "${manifest}" | grep -Eo '"Layers":[[:space:]]*\[[^]]+\]' \ | grep -Eo '\[.+\]' | tail -n 1 | tr ',' '\n' \ | sed -r -e 's#.*"([0-9a-f]+)/layer\.tar".*#\1#')) # Verbose output for testing. echo Expected: $(expected_layers[@]) echo Actual: $(manifest_layers[@]) check_eq $(#expected_layers[@]) $(#manifest_layers[@]) var index = '0' while [ "${index}" -lt "${#expected_layers[@]}" ] { # Check that the nth sorted layer matches check_eq $(expected_layers[$index]) $(manifest_layers[$index]) index := $(index + 1) } } proc check_layers_aux { var input = $1 shift 1 var expected_layers = '('${*}) var expected_layers_sorted = '( '$(for i in ${expected_layers[*]}; do echo $i; done | sort) ) var test_data = ""$(TEST_DATA_DIR)/$(input).tar"" # Verbose output for testing. tar tvf $(test_data) var actual_layers = '( '$(tar tvf ${test_data} | tr -s ' ' | cut -d' ' -f 4- | sort \ | cut -d'/' -f 2 | grep -E '^[0-9a-f]+$' | sort | uniq)) # Verbose output for testing. echo Expected: $(expected_layers_sorted[@]) echo Actual: $(actual_layers[@]) check_eq $(#expected_layers[@]) $(#actual_layers[@]) var index = '0' while [ "${index}" -lt "${#expected_layers[@]}" ] { # Check that the nth sorted layer matches check_eq $(expected_layers_sorted[$index]) $(actual_layers[$index]) # Grab the ordered layer and check it. var layer = $(expected_layers[$index]) # Verbose output for testing. echo Checking layer: $(layer) var listing = $[tar xOf $(test_data) "./$(layer)/layer.tar" | tar tv] # Check that all files in the layer, if any, have the magic timestamp check_eq $[echo $(listing) | grep -Fv $(MAGIC_TIMESTAMP) || true] "" index := $(index + 1) } } proc check_layers { var input = $1 shift check_layers_aux $input @Argv check_image_manifest_layers $input @Argv } proc test_gen_image { grep -Fsq "./gen.out" "$TEST_DATA_DIR/gen_image.tar" \ || fail "'./gen.out' not found in '$TEST_DATA_DIR/gen_image.tar'" } proc test_dummy_repository { var layer = '"0279f3ce8b08d10506abcf452393b3e48439f5eca41b836fae59a0d509fbafea'" var test_data = ""$(TEST_DATA_DIR)/dummy_repository.tar"" check_layers_aux "dummy_repository" $layer } proc test_files_base { check_layers "files_base" \ "82ca3945f7d07df82f274d7fafe83fd664c2154e5c64c988916ccd5b217bb710" } proc test_files_with_files_base { check_layers "files_with_files_base" \ "82ca3945f7d07df82f274d7fafe83fd664c2154e5c64c988916ccd5b217bb710" \ "84c0d09919ae8b06cb6b064d8cd5eab63341a46f11ccc7ecbe270ad3e1f52744" } proc test_tar_base { check_layers "tar_base" \ "8b9e4db9dd4b990ee6d8adc2843ad64702ad9063ae6c22e8ca5f94aa54e71277" # Check that this layer doesn't have any entrypoint data by looking # for *any* entrypoint. check_no_property "Entrypoint" "tar_base" \ "9fec194fd32c03350d6a6e60ee8ed7862471e8817aaa310306d9be6242b05d20" } proc test_tar_with_tar_base { check_layers "tar_with_tar_base" \ "8b9e4db9dd4b990ee6d8adc2843ad64702ad9063ae6c22e8ca5f94aa54e71277" \ "1cc81a2aaec2e3727d98d48bf9ba09d3ac96ef48adf5edae861d15dd0191dc40" } proc test_directory_with_tar_base { check_layers "directory_with_tar_base" \ "8b9e4db9dd4b990ee6d8adc2843ad64702ad9063ae6c22e8ca5f94aa54e71277" \ "e56ddeb8279698484f50d480f71cb5380223ad0f451766b7b9a9348129d02542" } proc test_files_with_tar_base { check_layers "files_with_tar_base" \ "8b9e4db9dd4b990ee6d8adc2843ad64702ad9063ae6c22e8ca5f94aa54e71277" \ "f099727fa58f9b688e77b511b3cc728b86ae0e84d197b9330bd51082ad5589f2" } proc test_workdir_with_tar_base { check_layers "workdir_with_tar_base" \ "8b9e4db9dd4b990ee6d8adc2843ad64702ad9063ae6c22e8ca5f94aa54e71277" \ "f24cbe53bd1b78909c6dba0bd47016354f3488b35b85aeee68ecc423062b927e" } proc test_tar_with_files_base { check_layers "tar_with_files_base" \ "82ca3945f7d07df82f274d7fafe83fd664c2154e5c64c988916ccd5b217bb710" \ "bee1a325e4b51a1dcfd7e447987b4e130590815865ab22e8744878053d525f20" } proc test_base_with_entrypoint { check_layers "base_with_entrypoint" \ "4acbeb0495918726c0107e372b421e1d2a6fd4825d58fc3f0b0b2a719fb3ce1b" check_entrypoint "base_with_entrypoint" \ "d59ab78d94f88b906227b8696d3065b91c71a1c6045d5103f3572c1e6fe9a1a9" \ '["/bar"]' # Check that the base layer has a port exposed. check_ports "base_with_entrypoint" \ "d59ab78d94f88b906227b8696d3065b91c71a1c6045d5103f3572c1e6fe9a1a9" \ '{"8080/tcp": {}}' } proc test_derivative_with_shadowed_cmd { check_layers "derivative_with_shadowed_cmd" \ "4acbeb0495918726c0107e372b421e1d2a6fd4825d58fc3f0b0b2a719fb3ce1b" \ "e35f57dc6c1e84ae67dcaaf3479a3a3c0f52ac4d194073bd6214e04c05beab42" } proc test_derivative_with_cmd { check_layers "derivative_with_cmd" \ "4acbeb0495918726c0107e372b421e1d2a6fd4825d58fc3f0b0b2a719fb3ce1b" \ "e35f57dc6c1e84ae67dcaaf3479a3a3c0f52ac4d194073bd6214e04c05beab42" \ "186289545131e34510006ac79498078dcf41736a5eb9a36920a6b30d3f45bc01" check_images "derivative_with_cmd" \ "d59ab78d94f88b906227b8696d3065b91c71a1c6045d5103f3572c1e6fe9a1a9" \ "a37fcc5dfa513987ecec8a19ebe5d17568a7d6e696771c596b110fcc30a2d8a6" \ "d3ea6e7cfc3e182a8ca43081db1e145f1bee8c5da5627639800c76abf61b5165" check_entrypoint "derivative_with_cmd" \ "d59ab78d94f88b906227b8696d3065b91c71a1c6045d5103f3572c1e6fe9a1a9" \ '["/bar"]' # Check that the middle image has our shadowed arg. check_cmd "derivative_with_cmd" \ "a37fcc5dfa513987ecec8a19ebe5d17568a7d6e696771c596b110fcc30a2d8a6" \ '["shadowed-arg"]' # Check that our topmost image excludes the shadowed arg. check_cmd "derivative_with_cmd" \ "d3ea6e7cfc3e182a8ca43081db1e145f1bee8c5da5627639800c76abf61b5165" \ '["arg1", "arg2"]' # Check that the topmost layer has the ports exposed by the bottom # layer, and itself. check_ports "derivative_with_cmd" \ "d3ea6e7cfc3e182a8ca43081db1e145f1bee8c5da5627639800c76abf61b5165" \ '{"80/tcp": {}, "8080/tcp": {}}' } proc test_derivative_with_volume { check_layers "derivative_with_volume" \ "125e7cfb9d4a6d803a57b88bcdb05d9a6a47ac0d6312a8b4cff52a2685c5c858" \ "08424283ad3a7e020e210bec22b166d7ebba57f7ba2d0713c2fd7bd1e2038f88" check_images "derivative_with_volume" \ "da0f0e314eb3187877754fd5ee1e487b93c13dbabdba18f35d130324f3c9b76d" \ "c872bf3f4c7eb5a01ae7ad6fae4c25e86ff2923bb1fe29be5edcdff1b31ed71a" # Check that the topmost layer has the ports exposed by the bottom # layer, and itself. check_volumes "derivative_with_volume" \ "da0f0e314eb3187877754fd5ee1e487b93c13dbabdba18f35d130324f3c9b76d" \ '{"/logs": {}}' check_volumes "derivative_with_volume" \ "c872bf3f4c7eb5a01ae7ad6fae4c25e86ff2923bb1fe29be5edcdff1b31ed71a" \ '{"/asdf": {}, "/blah": {}, "/logs": {}}' } proc test_generated_tarball { check_layers "generated_tarball" \ "54b8328604115255cc76c12a2a51939be65c40bf182ff5a898a5fb57c38f7772" } proc test_with_env { check_layers "with_env" \ "125e7cfb9d4a6d803a57b88bcdb05d9a6a47ac0d6312a8b4cff52a2685c5c858" \ "42a1bd0f449f61a23b8a7776875ffb6707b34ee99c87d6428a7394f5e55e8624" check_env "with_env" \ "87c0d91841f92847ec6c183810f720e5926dba0652eb5d52a807366825dd21c7" \ '["bar=blah blah blah", "foo=/asdf"]' } proc test_with_double_env { check_layers "with_double_env" \ "125e7cfb9d4a6d803a57b88bcdb05d9a6a47ac0d6312a8b4cff52a2685c5c858" \ "42a1bd0f449f61a23b8a7776875ffb6707b34ee99c87d6428a7394f5e55e8624" \ "576a9fd9c690be04dc7aacbb9dbd1f14816e32dbbcc510f4d42325bbff7163dd" # Check both the aggregation and the expansion of embedded variables. check_env "with_double_env" \ "273d2a6cfc25001baf9d3f7c68770ec79a1671b8249d153e7611a4f80165ecda" \ '["bar=blah blah blah", "baz=/asdf blah blah blah", "foo=/asdf"]' } proc test_with_label { check_layers "with_label" \ "125e7cfb9d4a6d803a57b88bcdb05d9a6a47ac0d6312a8b4cff52a2685c5c858" \ "eba6abda3d259ab6ed5f4d48b76df72a5193fad894d4ae78fbf0a363d8f9e8fd" check_label "with_label" \ "83c007425faff33ac421329af9f6444b7250abfc12c28f188b47e97fb715c006" \ '["com.example.bar={\"name\": \"blah\"}", "com.example.baz=qux", "com.example.foo={\"name\": \"blah\"}"]' } proc test_with_double_label { check_layers "with_double_label" \ "125e7cfb9d4a6d803a57b88bcdb05d9a6a47ac0d6312a8b4cff52a2685c5c858" \ "eba6abda3d259ab6ed5f4d48b76df72a5193fad894d4ae78fbf0a363d8f9e8fd" \ "bfe88fbb5e24fc5bff138f7a1923d53a2ee1bbc8e54b6f5d9c371d5f48b6b023" check_label "with_double_label" \ "8cfc89c83adf947cd2c18c11579559f1f48cf375a20364ec79eb14d6580dbf75" \ '["com.example.bar={\"name\": \"blah\"}", "com.example.baz=qux", "com.example.foo={\"name\": \"blah\"}", "com.example.qux={\"name\": \"blah-blah\"}"]' } proc test_with_user { check_user "with_user" \ "bd6666bdde7d4a837a0685d2861822507119f7f6e565acecbbbe93f1d0cc1974" \ "\"nobody\"" } proc get_layer_listing { var input = $1 var layer = $2 var test_data = ""$(TEST_DATA_DIR)/$(input).tar"" tar xOf $(test_data) \ "./$(layer)/layer.tar" | tar tv | sed -e 's/^.*:00 //' } proc test_data_path { var no_data_path_sha = '"451d182e5c71840f00ba9726dc0239db73a21b7e89e79c77f677e3f7c5c23d44'" var data_path_sha = '"9a41c9e1709558f7ef06f28f66e9056feafa7e0f83990801e1b27c987278d8e8'" var absolute_data_path_sha = '"f196c42ab4f3eb850d9655b950b824db2c99c01527703ac486a7b48bb2a34f44'" var root_data_path_sha = '"19d7fd26d67bfaeedd6232dcd441f14ee163bc81c56ed565cc20e73311c418b6'" check_layers_aux "no_data_path_image" $(no_data_path_sha) check_layers_aux "data_path_image" $(data_path_sha) check_layers_aux "absolute_data_path_image" $(absolute_data_path_sha) check_layers_aux "root_data_path_image" $(root_data_path_sha) # Without data_path = "." the file will be inserted as `./test` # (since it is the path in the package) and with data_path = "." # the file will be inserted relatively to the testdata package # (so `./test/test`). check_eq $[get_layer_listing "no_data_path_image" $(no_data_path_sha)] \ './ ./test' check_eq $[get_layer_listing "data_path_image" $(data_path_sha)] \ './ ./test/ ./test/test' # With an absolute path for data_path, we should strip that prefix # from the files' paths. Since the testdata images are in # //tools/build_defs/docker/testdata and data_path is set to # "/tools/build_defs", we should have `docker` as the top-level # directory. check_eq $[get_layer_listing "absolute_data_path_image" $(absolute_data_path_sha)] \ './ ./docker/ ./docker/testdata/ ./docker/testdata/test/ ./docker/testdata/test/test' # With data_path = "/", we expect the entire path from the repository # root. check_eq $[get_layer_listing "root_data_path_image" $(root_data_path_sha)] \ "./ ./tools/ ./tools/build_defs/ ./tools/build_defs/docker/ ./tools/build_defs/docker/testdata/ ./tools/build_defs/docker/testdata/test/ ./tools/build_defs/docker/testdata/test/test" } proc test_extras_with_deb { var test_data = ""$(TEST_DATA_DIR)/extras_with_deb.tar"" var sha = $[tar xOf $(test_data) ./top] # The content of the layer should have no duplicate var layer_listing = $[get_layer_listing "extras_with_deb" $(sha) | sort] check_eq $(layer_listing) \ "./ ./etc/ ./etc/nsswitch.conf ./tmp/ ./usr/ ./usr/bin/ ./usr/bin/java -> /path/to/bin/java ./usr/titi" } run_suite "build_test_oci" (CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:DIR) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (AndOr children: [ (C {(cd)} { (DQ (CommandSubPart command_list: (CommandList children: [ (C {(dirname)} { (DQ (BracedVarSub token: bracket_op: (ArrayIndex expr: (ArithWord w:{(Lit_Digits 0)}) ) spids: [57 62] ) ) } ) ] ) left_token: spids: [53 64] ) ) } ) (C {(pwd)}) ] op_id: Op_DAmp ) ] ) left_token: spids: [49 70] ) } spids: [48] ) ] spids: [48] ) (AndOr children: [ (C {(source)} {(${ VSub_Name DIR) (/testenv.sh)}) (BraceGroup children: [ (Sentence child: (SimpleCommand words: [{(echo)} {(DQ ("testenv.sh not found!"))}] redirects: [(Redir op_id:Redir_GreatAnd fd:-1 arg_word:{(2)} spids:[89])] ) terminator: ) (Sentence child:(C {(exit)} {(1)}) terminator:) ] spids: [81] ) ] op_id: Op_DPipe ) (Assignment keyword: Assign_Readonly pairs: [ (assign_pair lhs: (LhsName name:PLATFORM) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [(C {(uname)} {(-s)}) (C {(tr)} {(SQ )} {(SQ )})] negated: False ) ] ) left_token: spids: [105 121] ) ) } spids: [103] ) ] spids: [101] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(DQ (${ VSub_Name PLATFORM))} {(Lit_Other "=")} {(DQ (darwin))} {(Lit_Other "]")} ) terminator: ) ] action: [ (Assignment keyword: Assign_Readonly pairs: [ (assign_pair lhs: (LhsName name:MAGIC_TIMESTAMP) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [(C {(date)} {(-r)} {(0)} {(DQ ("+%b %e %Y"))})] ) left_token: spids: [150 160] ) ) } spids: [148] ) ] spids: [146] ) ] spids: [-1 143] ) ] else_action: [ (Assignment keyword: Assign_Readonly pairs: [ (assign_pair lhs: (LhsName name:MAGIC_TIMESTAMP) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (C {(date)} {(--date) (Lit_Other "=") (Lit_Other "@") (0)} {(DQ ("+%F %R"))}) ] ) left_token: spids: [170 181] ) ) } spids: [168] ) ] spids: [166] ) ] spids: [163 184] ) (FuncDef name: EXPECT_CONTAINS body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:complete) op: Equal rhs: {(DQ (${ VSub_Number 1))} spids: [198] ) ] spids: [196] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:substring) op: Equal rhs: {(DQ (${ VSub_Number 2))} spids: [208] ) ] spids: [206] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:message) op: Equal rhs: { (DQ (BracedVarSub token: suffix_op: (StringUnary op_id: VTest_ColonHyphen arg_word: {("Expected '") (${ VSub_Name substring) ("' not found in '") (${ VSub_Name complete) ("'") } ) spids: [220 232] ) ) } spids: [218] ) ] spids: [216] ) (AndOr children: [ (Pipeline children: [ (C {(echo)} {(DQ (${ VSub_Name complete))}) (C {(grep)} {(-Fsq)} {(--)} {(DQ (${ VSub_Name substring))}) ] negated: False ) (C {(fail)} {(DQ ($ VSub_Name "$message"))}) ] op_id: Op_DPipe ) ] spids: [193] ) spids: [187 192] ) (FuncDef name: check_property body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:property) op: Equal rhs: {(DQ (${ VSub_Number 1))} spids: [283] ) ] spids: [281] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:tarball) op: Equal rhs: {(DQ (${ VSub_Number 2))} spids: [293] ) ] spids: [291] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:image) op: Equal rhs: {(DQ (${ VSub_Number 3))} spids: [303] ) ] spids: [301] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:expected) op: Equal rhs: {(DQ (${ VSub_Number 4))} spids: [313] ) ] spids: [311] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:test_data) op: Equal rhs: {(DQ (${ VSub_Name TEST_DATA_DIR) (/) (${ VSub_Name tarball) (.tar))} spids: [323] ) ] spids: [321] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:config) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (C {(tar)} {(xOf)} {(DQ (${ VSub_Name test_data))} {(DQ (./) (${ VSub_Name image) (.json))} ) ] ) left_token: spids: [341 359] ) ) } spids: [339] ) ] spids: [337] ) (C {(EXPECT_CONTAINS)} {(DQ (${ VSub_Name config))} { (DQ (EscapedLiteralPart token:) (${ VSub_Name property) (EscapedLiteralPart token:) (": ") (${ VSub_Name expected) ) } ) ] spids: [278] ) spids: [272 277] ) (FuncDef name: check_no_property body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:property) op: Equal rhs: {(DQ (${ VSub_Number 1))} spids: [402] ) ] spids: [400] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:tarball) op: Equal rhs: {(DQ (${ VSub_Number 2))} spids: [412] ) ] spids: [410] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:image) op: Equal rhs: {(DQ (${ VSub_Number 3))} spids: [422] ) ] spids: [420] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:test_data) op: Equal rhs: {(DQ (${ VSub_Name TEST_DATA_DIR) (/) (${ VSub_Name tarball) (.tar))} spids: [432] ) ] spids: [430] ) (SimpleCommand words: [ {(tar)} {(xOf)} {(DQ (${ VSub_Name test_data))} {(DQ (./) (${ VSub_Name image) (.json))} ] redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {($ VSub_Name "$TEST_log")} spids: [464] ) ] ) (C {(expect_not_log)} { (DQ (EscapedLiteralPart token:) (${ VSub_Name property) (EscapedLiteralPart token:) (":") ) } ) ] spids: [397] ) spids: [391 396] ) (FuncDef name: check_entrypoint body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:input) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [491] ) ] spids: [491] ) (C {(shift)}) (C {(check_property)} {(Entrypoint)} {(DQ (${ VSub_Name input))} {(DQ (${ VSub_At "@"))}) ] spids: [488] ) spids: [482 487] ) (FuncDef name: check_cmd body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:input) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [528] ) ] spids: [528] ) (C {(shift)}) (C {(check_property)} {(Cmd)} {(DQ (${ VSub_Name input))} {(DQ (${ VSub_At "@"))}) ] spids: [525] ) spids: [519 524] ) (FuncDef name: check_ports body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:input) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [565] ) ] spids: [565] ) (C {(shift)}) (C {(check_property)} {(ExposedPorts)} {(DQ (${ VSub_Name input))} {(DQ (${ VSub_At "@"))}) ] spids: [562] ) spids: [556 561] ) (FuncDef name: check_volumes body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:input) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [602] ) ] spids: [602] ) (C {(shift)}) (C {(check_property)} {(Volumes)} {(DQ (${ VSub_Name input))} {(DQ (${ VSub_At "@"))}) ] spids: [599] ) spids: [593 598] ) (FuncDef name: check_env body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:input) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [639] ) ] spids: [639] ) (C {(shift)}) (C {(check_property)} {(Env)} {(DQ (${ VSub_Name input))} {(DQ (${ VSub_At "@"))}) ] spids: [636] ) spids: [630 635] ) (FuncDef name: check_label body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:input) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [676] ) ] spids: [676] ) (C {(shift)}) (C {(check_property)} {(Label)} {(DQ (${ VSub_Name input))} {(DQ (${ VSub_At "@"))}) ] spids: [673] ) spids: [667 672] ) (FuncDef name: check_workdir body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:input) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [713] ) ] spids: [713] ) (C {(shift)}) (C {(check_property)} {(WorkingDir)} {(DQ (${ VSub_Name input))} {(DQ (${ VSub_At "@"))}) ] spids: [710] ) spids: [704 709] ) (FuncDef name: check_user body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:input) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [750] ) ] spids: [750] ) (C {(shift)}) (C {(check_property)} {(User)} {(DQ (${ VSub_Name input))} {(DQ (${ VSub_At "@"))}) ] spids: [747] ) spids: [741 746] ) (FuncDef name: check_images body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:input) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [789] ) ] spids: [787] ) (C {(shift)} {(1)}) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:expected_images) op: Equal rhs: {(ArrayLiteralPart words:[{(${ VSub_Star "*")}])} spids: [802] ) ] spids: [800] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:test_data) op: Equal rhs: {(DQ (${ VSub_Name TEST_DATA_DIR) (/) (${ VSub_Name input) (.tar))} spids: [812] ) ] spids: [810] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:manifest) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (C {(tar)} {(xOf)} {(DQ (${ VSub_Name test_data))} {(DQ (./manifest.json))} ) ] ) left_token: spids: [830 844] ) ) } spids: [828] ) ] spids: [826] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:manifest_images) op: Equal rhs: { (ArrayLiteralPart words: [ { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {(DQ (${ VSub_Name manifest))}) (C {(grep)} {(-Eo)} {(SQ <"\"Config\":[[:space:]]*\"[^\"]+\"">)}) (C {(sed)} {(-r)} {(-e)} {(SQ <"s#\"Config\":.*?\"([0-9a-f]+)\\.json\"#\\1#">)} ) ] negated: False ) ] ) left_token: spids: [854 886] ) } ] ) } spids: [850] ) ] spids: [848] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:manifest_parents) op: Equal rhs: { (ArrayLiteralPart words: [ { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {(DQ (${ VSub_Name manifest))}) (C {(grep)} {(-Eo)} {(SQ <"\"Parent\":[[:space:]]*\"[^\"]+\"">)}) (C {(sed)} {(-r)} {(-e)} {(SQ <"s#\"Parent\":.*?\"sha256:([0-9a-f]+)\"#\\1#">)} ) ] negated: False ) ] ) left_token: spids: [897 929] ) } ] ) } spids: [893] ) ] spids: [891] ) (C {(echo)} {(Expected) (Lit_Other ":")} { (DQ (BracedVarSub token: bracket_op: (WholeArray op_id:Lit_At) spids: [944 949] ) ) } ) (C {(echo)} {(Actual) (Lit_Other ":")} { (DQ (BracedVarSub token: bracket_op: (WholeArray op_id:Lit_At) spids: [959 964] ) ) } ) (C {(echo)} {(Parents) (Lit_Other ":")} { (DQ (BracedVarSub token: bracket_op: (WholeArray op_id:Lit_At) spids: [974 979] ) ) } ) (C {(check_eq)} { (DQ (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Lit_At) spids: [987 993] ) ) } { (DQ (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Lit_At) spids: [997 1003] ) ) } ) (Assignment keyword: Assign_Local pairs: [(assign_pair lhs:(LhsName name:index) op:Equal rhs:{(0)} spids:[1010])] spids: [1008] ) (While cond: [ (C {(Lit_Other "[")} {(DQ (${ VSub_Name index))} {(-lt)} { (DQ (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Lit_At) spids: [1027 1033] ) ) } {(Lit_Other "]")} ) ] body: (DoGroup children: [ (C {(check_eq)} { (DQ (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{($ VSub_Name "$index")})) spids: [1049 1054] ) ) } { (DQ (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{($ VSub_Name "$index")})) spids: [1058 1063] ) ) } ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:index) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithVarRef name:index) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [1069 1076] ) } spids: [1068] ) ] spids: [1068] ) ] spids: [1039 1079] ) ) (C {(check_eq)} { (DQ (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Lit_At) spids: [1090 1096] ) ) } { (DQ (ArithSubPart anode: (ArithBinary op_id: Arith_Minus left: (ArithWord w: { (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Lit_At) spids: [1101 1107] ) } ) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [1100 1113] ) ) } ) (Assignment keyword: Assign_Local pairs: [(assign_pair lhs:(LhsName name:index) op:Equal rhs:{(0)} spids:[1120])] spids: [1118] ) (While cond: [ (C {(Lit_Other "[")} {(DQ (${ VSub_Name index))} {(-lt)} { (DQ (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Lit_At) spids: [1137 1143] ) ) } {(Lit_Other "]")} ) ] body: (DoGroup children: [ (C {(check_eq)} { (DQ (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{($ VSub_Name "$index")})) spids: [1159 1164] ) ) } { (DQ (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{($ VSub_Name "$index")})) spids: [1168 1173] ) ) } ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:index) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithVarRef name:index) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [1179 1186] ) } spids: [1178] ) ] spids: [1178] ) ] spids: [1149 1189] ) ) ] spids: [784] ) spids: [778 783] ) (FuncDef name: check_image_manifest_layers body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:input) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [1208] ) ] spids: [1206] ) (C {(shift)} {(1)}) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:expected_layers) op: Equal rhs: {(ArrayLiteralPart words:[{(${ VSub_Star "*")}])} spids: [1221] ) ] spids: [1219] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:test_data) op: Equal rhs: {(DQ (${ VSub_Name TEST_DATA_DIR) (/) (${ VSub_Name input) (.tar))} spids: [1231] ) ] spids: [1229] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:manifest) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (C {(tar)} {(xOf)} {(DQ (${ VSub_Name test_data))} {(DQ (./manifest.json))} ) ] ) left_token: spids: [1249 1263] ) ) } spids: [1247] ) ] spids: [1245] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:manifest_layers) op: Equal rhs: { (ArrayLiteralPart words: [ { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {(DQ (${ VSub_Name manifest))}) (C {(grep)} {(-Eo)} {(SQ <"\"Layers\":[[:space:]]*\\[[^]]+\\]">)}) (C {(grep)} {(-Eo)} {(SQ <"\\[.+\\]">)}) (C {(tail)} {(-n)} {(1)}) (C {(tr)} {(SQ <",">)} {(SQ <"\\n">)}) (C {(sed)} {(-r)} {(-e)} {(SQ <"s#.*\"([0-9a-f]+)/layer\\.tar\".*#\\1#">)} ) ] negated: False ) ] ) left_token: spids: [1273 1337] ) } ] ) } spids: [1269] ) ] spids: [1267] ) (C {(echo)} {(Expected) (Lit_Other ":")} { (DQ (BracedVarSub token: bracket_op: (WholeArray op_id:Lit_At) spids: [1352 1357] ) ) } ) (C {(echo)} {(Actual) (Lit_Other ":")} { (DQ (BracedVarSub token: bracket_op: (WholeArray op_id:Lit_At) spids: [1367 1372] ) ) } ) (C {(check_eq)} { (DQ (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Lit_At) spids: [1380 1386] ) ) } { (DQ (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Lit_At) spids: [1390 1396] ) ) } ) (Assignment keyword: Assign_Local pairs: [(assign_pair lhs:(LhsName name:index) op:Equal rhs:{(0)} spids:[1403])] spids: [1401] ) (While cond: [ (C {(Lit_Other "[")} {(DQ (${ VSub_Name index))} {(-lt)} { (DQ (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Lit_At) spids: [1420 1426] ) ) } {(Lit_Other "]")} ) ] body: (DoGroup children: [ (C {(check_eq)} { (DQ (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{($ VSub_Name "$index")})) spids: [1442 1447] ) ) } { (DQ (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{($ VSub_Name "$index")})) spids: [1451 1456] ) ) } ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:index) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithVarRef name:index) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [1462 1469] ) } spids: [1461] ) ] spids: [1461] ) ] spids: [1432 1472] ) ) ] spids: [1203] ) spids: [1197 1202] ) (FuncDef name: check_layers_aux body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:input) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [1488] ) ] spids: [1486] ) (C {(shift)} {(1)}) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:expected_layers) op: Equal rhs: {(ArrayLiteralPart words:[{(${ VSub_Star "*")}])} spids: [1501] ) ] spids: [1499] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:expected_layers_sorted) op: Equal rhs: { (ArrayLiteralPart words: [ { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (ForEach iter_name: i iter_words: [ { (BracedVarSub token: bracket_op: (WholeArray op_id:Arith_Star) spids: [1523 1528] ) } ] do_arg_iter: False body: (DoGroup children: [ (Sentence child: (C {(echo)} {($ VSub_Name "$i")}) terminator: ) ] spids: [1531 1538] ) spids: [1522 1529] ) (C {(sort)}) ] negated: False ) ] ) left_token: spids: [1516 1543] ) } ] ) } spids: [1512] ) ] spids: [1510] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:test_data) op: Equal rhs: {(DQ (${ VSub_Name TEST_DATA_DIR) (/) (${ VSub_Name input) (.tar))} spids: [1551] ) ] spids: [1549] ) (C {(tar)} {(tvf)} {(DQ (${ VSub_Name test_data))}) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:actual_layers) op: Equal rhs: { (ArrayLiteralPart words: [ { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(tar)} {(tvf)} {(${ VSub_Name test_data)}) (C {(tr)} {(-s)} {(SQ <" ">)}) (C {(cut)} {(-d) (SQ <" ">)} {(-f)} {(4-)}) (C {(sort)}) (C {(cut)} {(-d) (SQ )} {(-f)} {(2)}) (C {(grep)} {(-E)} {(SQ <"^[0-9a-f]+$">)}) (C {(sort)}) (C {(uniq)}) ] negated: False ) ] ) left_token: spids: [1587 1655] ) } ] ) } spids: [1583] ) ] spids: [1581] ) (C {(echo)} {(Expected) (Lit_Other ":")} { (DQ (BracedVarSub token: bracket_op: (WholeArray op_id:Lit_At) spids: [1670 1675] ) ) } ) (C {(echo)} {(Actual) (Lit_Other ":")} { (DQ (BracedVarSub token: bracket_op: (WholeArray op_id:Lit_At) spids: [1685 1690] ) ) } ) (C {(check_eq)} { (DQ (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Lit_At) spids: [1698 1704] ) ) } { (DQ (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Lit_At) spids: [1708 1714] ) ) } ) (Assignment keyword: Assign_Local pairs: [(assign_pair lhs:(LhsName name:index) op:Equal rhs:{(0)} spids:[1721])] spids: [1719] ) (While cond: [ (C {(Lit_Other "[")} {(DQ (${ VSub_Name index))} {(-lt)} { (DQ (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Lit_At) spids: [1738 1744] ) ) } {(Lit_Other "]")} ) ] body: (DoGroup children: [ (C {(check_eq)} { (DQ (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{($ VSub_Name "$index")})) spids: [1760 1765] ) ) } { (DQ (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{($ VSub_Name "$index")})) spids: [1769 1774] ) ) } ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:layer) op: Equal rhs: { (DQ (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{($ VSub_Name "$index")})) spids: [1787 1792] ) ) } spids: [1785] ) ] spids: [1783] ) (C {(echo)} {(Checking)} {(layer) (Lit_Other ":")} {(DQ (${ VSub_Name layer))}) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:listing) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(tar)} {(xOf)} {(DQ (${ VSub_Name test_data))} {(DQ (./) (${ VSub_Name layer) (/layer.tar))} ) (C {(tar)} {(tv)}) ] negated: False ) ] ) left_token: spids: [1820 1844] ) ) } spids: [1818] ) ] spids: [1816] ) (C {(check_eq)} { (DQ (CommandSubPart command_list: (CommandList children: [ (AndOr children: [ (Pipeline children: [ (C {(echo)} {(DQ (${ VSub_Name listing))}) (C {(grep)} {(-Fv)} {(DQ (${ VSub_Name MAGIC_TIMESTAMP))}) ] negated: False ) (C {(true)}) ] op_id: Op_DPipe ) ] ) left_token: spids: [1856 1880] ) ) } {(DQ )} ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:index) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithVarRef name:index) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [1889 1896] ) } spids: [1888] ) ] spids: [1888] ) ] spids: [1750 1899] ) ) ] spids: [1483] ) spids: [1477 1482] ) (FuncDef name: check_layers body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:input) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [1915] ) ] spids: [1913] ) (C {(shift)}) (C {(check_layers_aux)} {(DQ ($ VSub_Name "$input"))} {(DQ ($ VSub_At "$@"))}) (C {(check_image_manifest_layers)} {(DQ ($ VSub_Name "$input"))} {(DQ ($ VSub_At "$@"))}) ] spids: [1910] ) spids: [1904 1909] ) (FuncDef name: test_gen_image body: (BraceGroup children: [ (AndOr children: [ (C {(grep)} {(-Fsq)} {(DQ (./gen.out))} {(DQ ($ VSub_Name "$TEST_DATA_DIR") (/gen_image.tar))} ) (C {(fail)} { (DQ ("'./gen.out' not found in '") ($ VSub_Name "$TEST_DATA_DIR") ("/gen_image.tar'") ) } ) ] op_id: Op_DPipe ) ] spids: [1954] ) spids: [1948 1953] ) (FuncDef name: test_dummy_repository body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:layer) op: Equal rhs: {(DQ (0279f3ce8b08d10506abcf452393b3e48439f5eca41b836fae59a0d509fbafea))} spids: [1996] ) ] spids: [1994] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:test_data) op: Equal rhs: {(DQ (${ VSub_Name TEST_DATA_DIR) (/dummy_repository.tar))} spids: [2004] ) ] spids: [2002] ) (C {(check_layers_aux)} {(DQ (dummy_repository))} {(DQ ($ VSub_Name "$layer"))}) ] spids: [1991] ) spids: [1985 1990] ) (FuncDef name: test_files_base body: (BraceGroup children: [ (C {(check_layers)} {(DQ (files_base))} {(DQ (82ca3945f7d07df82f274d7fafe83fd664c2154e5c64c988916ccd5b217bb710))} ) ] spids: [2032] ) spids: [2026 2031] ) (FuncDef name: test_files_with_files_base body: (BraceGroup children: [ (C {(check_layers)} {(DQ (files_with_files_base))} {(DQ (82ca3945f7d07df82f274d7fafe83fd664c2154e5c64c988916ccd5b217bb710))} {(DQ (84c0d09919ae8b06cb6b064d8cd5eab63341a46f11ccc7ecbe270ad3e1f52744))} ) ] spids: [2056] ) spids: [2050 2055] ) (FuncDef name: test_tar_base body: (BraceGroup children: [ (C {(check_layers)} {(DQ (tar_base))} {(DQ (8b9e4db9dd4b990ee6d8adc2843ad64702ad9063ae6c22e8ca5f94aa54e71277))} ) (C {(check_no_property)} {(DQ (Entrypoint))} {(DQ (tar_base))} {(DQ (9fec194fd32c03350d6a6e60ee8ed7862471e8817aaa310306d9be6242b05d20))} ) ] spids: [2086] ) spids: [2080 2085] ) (FuncDef name: test_tar_with_tar_base body: (BraceGroup children: [ (C {(check_layers)} {(DQ (tar_with_tar_base))} {(DQ (8b9e4db9dd4b990ee6d8adc2843ad64702ad9063ae6c22e8ca5f94aa54e71277))} {(DQ (1cc81a2aaec2e3727d98d48bf9ba09d3ac96ef48adf5edae861d15dd0191dc40))} ) ] spids: [2136] ) spids: [2130 2135] ) (FuncDef name: test_directory_with_tar_base body: (BraceGroup children: [ (C {(check_layers)} {(DQ (directory_with_tar_base))} {(DQ (8b9e4db9dd4b990ee6d8adc2843ad64702ad9063ae6c22e8ca5f94aa54e71277))} {(DQ (e56ddeb8279698484f50d480f71cb5380223ad0f451766b7b9a9348129d02542))} ) ] spids: [2166] ) spids: [2160 2165] ) (FuncDef name: test_files_with_tar_base body: (BraceGroup children: [ (C {(check_layers)} {(DQ (files_with_tar_base))} {(DQ (8b9e4db9dd4b990ee6d8adc2843ad64702ad9063ae6c22e8ca5f94aa54e71277))} {(DQ (f099727fa58f9b688e77b511b3cc728b86ae0e84d197b9330bd51082ad5589f2))} ) ] spids: [2196] ) spids: [2190 2195] ) (FuncDef name: test_workdir_with_tar_base body: (BraceGroup children: [ (C {(check_layers)} {(DQ (workdir_with_tar_base))} {(DQ (8b9e4db9dd4b990ee6d8adc2843ad64702ad9063ae6c22e8ca5f94aa54e71277))} {(DQ (f24cbe53bd1b78909c6dba0bd47016354f3488b35b85aeee68ecc423062b927e))} ) ] spids: [2226] ) spids: [2220 2225] ) (FuncDef name: test_tar_with_files_base body: (BraceGroup children: [ (C {(check_layers)} {(DQ (tar_with_files_base))} {(DQ (82ca3945f7d07df82f274d7fafe83fd664c2154e5c64c988916ccd5b217bb710))} {(DQ (bee1a325e4b51a1dcfd7e447987b4e130590815865ab22e8744878053d525f20))} ) ] spids: [2256] ) spids: [2250 2255] ) (FuncDef name: test_base_with_entrypoint body: (BraceGroup children: [ (C {(check_layers)} {(DQ (base_with_entrypoint))} {(DQ (4acbeb0495918726c0107e372b421e1d2a6fd4825d58fc3f0b0b2a719fb3ce1b))} ) (C {(check_entrypoint)} {(DQ (base_with_entrypoint))} {(DQ (d59ab78d94f88b906227b8696d3065b91c71a1c6045d5103f3572c1e6fe9a1a9))} {(SQ <"[\"/bar\"]">)} ) (C {(check_ports)} {(DQ (base_with_entrypoint))} {(DQ (d59ab78d94f88b906227b8696d3065b91c71a1c6045d5103f3572c1e6fe9a1a9))} {(SQ <"{\"8080/tcp\": {}}">)} ) ] spids: [2286] ) spids: [2280 2285] ) (FuncDef name: test_derivative_with_shadowed_cmd body: (BraceGroup children: [ (C {(check_layers)} {(DQ (derivative_with_shadowed_cmd))} {(DQ (4acbeb0495918726c0107e372b421e1d2a6fd4825d58fc3f0b0b2a719fb3ce1b))} {(DQ (e35f57dc6c1e84ae67dcaaf3479a3a3c0f52ac4d194073bd6214e04c05beab42))} ) ] spids: [2354] ) spids: [2348 2353] ) (FuncDef name: test_derivative_with_cmd body: (BraceGroup children: [ (C {(check_layers)} {(DQ (derivative_with_cmd))} {(DQ (4acbeb0495918726c0107e372b421e1d2a6fd4825d58fc3f0b0b2a719fb3ce1b))} {(DQ (e35f57dc6c1e84ae67dcaaf3479a3a3c0f52ac4d194073bd6214e04c05beab42))} {(DQ (186289545131e34510006ac79498078dcf41736a5eb9a36920a6b30d3f45bc01))} ) (C {(check_images)} {(DQ (derivative_with_cmd))} {(DQ (d59ab78d94f88b906227b8696d3065b91c71a1c6045d5103f3572c1e6fe9a1a9))} {(DQ (a37fcc5dfa513987ecec8a19ebe5d17568a7d6e696771c596b110fcc30a2d8a6))} {(DQ (d3ea6e7cfc3e182a8ca43081db1e145f1bee8c5da5627639800c76abf61b5165))} ) (C {(check_entrypoint)} {(DQ (derivative_with_cmd))} {(DQ (d59ab78d94f88b906227b8696d3065b91c71a1c6045d5103f3572c1e6fe9a1a9))} {(SQ <"[\"/bar\"]">)} ) (C {(check_cmd)} {(DQ (derivative_with_cmd))} {(DQ (a37fcc5dfa513987ecec8a19ebe5d17568a7d6e696771c596b110fcc30a2d8a6))} {(SQ <"[\"shadowed-arg\"]">)} ) (C {(check_cmd)} {(DQ (derivative_with_cmd))} {(DQ (d3ea6e7cfc3e182a8ca43081db1e145f1bee8c5da5627639800c76abf61b5165))} {(SQ <"[\"arg1\", \"arg2\"]">)} ) (C {(check_ports)} {(DQ (derivative_with_cmd))} {(DQ (d3ea6e7cfc3e182a8ca43081db1e145f1bee8c5da5627639800c76abf61b5165))} {(SQ <"{\"80/tcp\": {}, \"8080/tcp\": {}}">)} ) ] spids: [2384] ) spids: [2378 2383] ) (FuncDef name: test_derivative_with_volume body: (BraceGroup children: [ (C {(check_layers)} {(DQ (derivative_with_volume))} {(DQ (125e7cfb9d4a6d803a57b88bcdb05d9a6a47ac0d6312a8b4cff52a2685c5c858))} {(DQ (08424283ad3a7e020e210bec22b166d7ebba57f7ba2d0713c2fd7bd1e2038f88))} ) (C {(check_images)} {(DQ (derivative_with_volume))} {(DQ (da0f0e314eb3187877754fd5ee1e487b93c13dbabdba18f35d130324f3c9b76d))} {(DQ (c872bf3f4c7eb5a01ae7ad6fae4c25e86ff2923bb1fe29be5edcdff1b31ed71a))} ) (C {(check_volumes)} {(DQ (derivative_with_volume))} {(DQ (da0f0e314eb3187877754fd5ee1e487b93c13dbabdba18f35d130324f3c9b76d))} {(SQ <"{\"/logs\": {}}">)} ) (C {(check_volumes)} {(DQ (derivative_with_volume))} {(DQ (c872bf3f4c7eb5a01ae7ad6fae4c25e86ff2923bb1fe29be5edcdff1b31ed71a))} {(SQ <"{\"/asdf\": {}, \"/blah\": {}, \"/logs\": {}}">)} ) ] spids: [2542] ) spids: [2536 2541] ) (FuncDef name: test_generated_tarball body: (BraceGroup children: [ (C {(check_layers)} {(DQ (generated_tarball))} {(DQ (54b8328604115255cc76c12a2a51939be65c40bf182ff5a898a5fb57c38f7772))} ) ] spids: [2640] ) spids: [2634 2639] ) (FuncDef name: test_with_env body: (BraceGroup children: [ (C {(check_layers)} {(DQ (with_env))} {(DQ (125e7cfb9d4a6d803a57b88bcdb05d9a6a47ac0d6312a8b4cff52a2685c5c858))} {(DQ (42a1bd0f449f61a23b8a7776875ffb6707b34ee99c87d6428a7394f5e55e8624))} ) (C {(check_env)} {(DQ (with_env))} {(DQ (87c0d91841f92847ec6c183810f720e5926dba0652eb5d52a807366825dd21c7))} {(SQ <"[\"bar=blah blah blah\", \"foo=/asdf\"]">)} ) ] spids: [2664] ) spids: [2658 2663] ) (FuncDef name: test_with_double_env body: (BraceGroup children: [ (C {(check_layers)} {(DQ (with_double_env))} {(DQ (125e7cfb9d4a6d803a57b88bcdb05d9a6a47ac0d6312a8b4cff52a2685c5c858))} {(DQ (42a1bd0f449f61a23b8a7776875ffb6707b34ee99c87d6428a7394f5e55e8624))} {(DQ (576a9fd9c690be04dc7aacbb9dbd1f14816e32dbbcc510f4d42325bbff7163dd))} ) (C {(check_env)} {(DQ (with_double_env))} {(DQ (273d2a6cfc25001baf9d3f7c68770ec79a1671b8249d153e7611a4f80165ecda))} {(SQ <"[\"bar=blah blah blah\", \"baz=/asdf blah blah blah\", \"foo=/asdf\"]">)} ) ] spids: [2714] ) spids: [2708 2713] ) (FuncDef name: test_with_label body: (BraceGroup children: [ (C {(check_layers)} {(DQ (with_label))} {(DQ (125e7cfb9d4a6d803a57b88bcdb05d9a6a47ac0d6312a8b4cff52a2685c5c858))} {(DQ (eba6abda3d259ab6ed5f4d48b76df72a5193fad894d4ae78fbf0a363d8f9e8fd))} ) (C {(check_label)} {(DQ (with_label))} {(DQ (83c007425faff33ac421329af9f6444b7250abfc12c28f188b47e97fb715c006))} { (SQ < "[\"com.example.bar={\\\"name\\\": \\\"blah\\\"}\", \"com.example.baz=qux\", \"com.example.foo={\\\"name\\\": \\\"blah\\\"}\"]" > ) } ) ] spids: [2774] ) spids: [2768 2773] ) (FuncDef name: test_with_double_label body: (BraceGroup children: [ (C {(check_layers)} {(DQ (with_double_label))} {(DQ (125e7cfb9d4a6d803a57b88bcdb05d9a6a47ac0d6312a8b4cff52a2685c5c858))} {(DQ (eba6abda3d259ab6ed5f4d48b76df72a5193fad894d4ae78fbf0a363d8f9e8fd))} {(DQ (bfe88fbb5e24fc5bff138f7a1923d53a2ee1bbc8e54b6f5d9c371d5f48b6b023))} ) (C {(check_label)} {(DQ (with_double_label))} {(DQ (8cfc89c83adf947cd2c18c11579559f1f48cf375a20364ec79eb14d6580dbf75))} { (SQ < "[\"com.example.bar={\\\"name\\\": \\\"blah\\\"}\", \"com.example.baz=qux\", \"com.example.foo={\\\"name\\\": \\\"blah\\\"}\", \"com.example.qux={\\\"name\\\": \\\"blah-blah\\\"}\"]" > ) } ) ] spids: [2824] ) spids: [2818 2823] ) (FuncDef name: test_with_user body: (BraceGroup children: [ (C {(check_user)} {(DQ (with_user))} {(DQ (bd6666bdde7d4a837a0685d2861822507119f7f6e565acecbbbe93f1d0cc1974))} { (DQ (EscapedLiteralPart token:) (nobody) (EscapedLiteralPart token:) ) } ) ] spids: [2880] ) spids: [2874 2879] ) (FuncDef name: get_layer_listing body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:input) op: Equal rhs: {($ VSub_Number "$1")} spids: [2917] ) ] spids: [2915] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:layer) op: Equal rhs: {($ VSub_Number "$2")} spids: [2923] ) ] spids: [2921] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:test_data) op: Equal rhs: {(DQ (${ VSub_Name TEST_DATA_DIR) (/) (${ VSub_Name input) (.tar))} spids: [2929] ) ] spids: [2927] ) (Pipeline children: [ (C {(tar)} {(xOf)} {(DQ (${ VSub_Name test_data))} {(DQ (./) (${ VSub_Name layer) (/layer.tar))} ) (C {(tar)} {(tv)}) (C {(sed)} {(-e)} {(SQ <"s/^.*:00 //">)}) ] negated: False ) ] spids: [2912] ) spids: [2906 2911] ) (FuncDef name: test_data_path body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:no_data_path_sha) op: Equal rhs: {(DQ (451d182e5c71840f00ba9726dc0239db73a21b7e89e79c77f677e3f7c5c23d44))} spids: [2992] ) ] spids: [2990] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:data_path_sha) op: Equal rhs: {(DQ (9a41c9e1709558f7ef06f28f66e9056feafa7e0f83990801e1b27c987278d8e8))} spids: [3000] ) ] spids: [2998] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:absolute_data_path_sha) op: Equal rhs: {(DQ (f196c42ab4f3eb850d9655b950b824db2c99c01527703ac486a7b48bb2a34f44))} spids: [3008] ) ] spids: [3006] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:root_data_path_sha) op: Equal rhs: {(DQ (19d7fd26d67bfaeedd6232dcd441f14ee163bc81c56ed565cc20e73311c418b6))} spids: [3016] ) ] spids: [3014] ) (C {(check_layers_aux)} {(DQ (no_data_path_image))} {(DQ (${ VSub_Name no_data_path_sha))}) (C {(check_layers_aux)} {(DQ (data_path_image))} {(DQ (${ VSub_Name data_path_sha))}) (C {(check_layers_aux)} {(DQ (absolute_data_path_image))} {(DQ (${ VSub_Name absolute_data_path_sha))} ) (C {(check_layers_aux)} {(DQ (root_data_path_image))} {(DQ (${ VSub_Name root_data_path_sha))} ) (C {(check_eq)} { (DQ (CommandSubPart command_list: (CommandList children: [ (C {(get_layer_listing)} {(DQ (no_data_path_image))} {(DQ (${ VSub_Name no_data_path_sha))} ) ] ) left_token: spids: [3095 3107] ) ) } {(SQ <"./\n"> <./test>)} ) (C {(check_eq)} { (DQ (CommandSubPart command_list: (CommandList children: [ (C {(get_layer_listing)} {(DQ (data_path_image))} {(DQ (${ VSub_Name data_path_sha))} ) ] ) left_token: spids: [3121 3133] ) ) } {(SQ <"./\n"> <"./test/\n"> <./test/test>)} ) (C {(check_eq)} { (DQ (CommandSubPart command_list: (CommandList children: [ (C {(get_layer_listing)} {(DQ (absolute_data_path_image))} {(DQ (${ VSub_Name absolute_data_path_sha))} ) ] ) left_token: spids: [3169 3181] ) ) } { (SQ <"./\n"> <"./docker/\n"> <"./docker/testdata/\n"> <"./docker/testdata/test/\n"> <./docker/testdata/test/test> ) } ) (C {(check_eq)} { (DQ (CommandSubPart command_list: (CommandList children: [ (C {(get_layer_listing)} {(DQ (root_data_path_image))} {(DQ (${ VSub_Name root_data_path_sha))} ) ] ) left_token: spids: [3207 3219] ) ) } { (DQ ("./\n") ("./tools/\n") ("./tools/build_defs/\n") ("./tools/build_defs/docker/\n") ("./tools/build_defs/docker/testdata/\n") ("./tools/build_defs/docker/testdata/test/\n") (./tools/build_defs/docker/testdata/test/test) ) } ) ] spids: [2987] ) spids: [2981 2986] ) (FuncDef name: test_extras_with_deb body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:test_data) op: Equal rhs: {(DQ (${ VSub_Name TEST_DATA_DIR) (/extras_with_deb.tar))} spids: [3248] ) ] spids: [3246] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:sha) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [(C {(tar)} {(xOf)} {(${ VSub_Name test_data)} {(./top)})] ) left_token: spids: [3260 3270] ) } spids: [3259] ) ] spids: [3257] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:layer_listing) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(get_layer_listing)} {(DQ (extras_with_deb))} {(DQ (${ VSub_Name sha))} ) (C {(sort)}) ] negated: False ) ] ) left_token: spids: [3282 3298] ) ) } spids: [3280] ) ] spids: [3278] ) (C {(check_eq)} {(DQ (${ VSub_Name layer_listing))} { (DQ ("./\n") ("./etc/\n") ("./etc/nsswitch.conf\n") ("./tmp/\n") ("./usr/\n") ("./usr/bin/\n") ("./usr/bin/java -> /path/to/bin/java\n") (./usr/titi) ) } ) ] spids: [3243] ) spids: [3237 3242] ) (C {(run_suite)} {(DQ (build_test_oci))}) ] )