docker_container_copy_into: add mode_parse option (#1074)

* Add mode_parse option.

* Make yamllint config strict.

* Lint.
This commit is contained in:
Felix Fontein
2025-04-28 20:46:11 +02:00
committed by GitHub
parent 424b39fe36
commit ad989c1942
9 changed files with 431 additions and 100 deletions
@@ -56,7 +56,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: false
register: result_1
@@ -67,7 +68,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: true
register: result_1_diff
@@ -78,7 +80,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
register: result_2
- name: Copy content (idempotent, check mode)
@@ -87,7 +90,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: false
register: result_3
@@ -98,7 +102,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: true
register: result_3_diff
@@ -109,7 +114,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
register: result_4
- name: Copy content (idempotent, check mode, base 64)
@@ -118,7 +124,8 @@
content: "{{ 'Content 1\n' | b64encode }}"
content_is_b64: true
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: false
register: result_3b64
@@ -129,7 +136,8 @@
content: "{{ 'Content 1\n' | b64encode }}"
content_is_b64: true
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: true
register: result_3b64_diff
@@ -140,7 +148,8 @@
content: "{{ 'Content 1\n' | b64encode }}"
content_is_b64: true
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
register: result_4b64
- name: Dump file
@@ -161,7 +170,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
force: true
check_mode: true
diff: false
@@ -173,7 +183,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
force: true
check_mode: true
diff: true
@@ -185,7 +196,8 @@
content: |
Content 1
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
force: true
register: result_7
@@ -207,7 +219,8 @@
content: |
Some other content
container_path: '/file'
mode: 0777
mode: "0777"
mode_parse: modern
owner_id: 123
group_id: 321
force: false
@@ -221,7 +234,8 @@
content: |
Some other content
container_path: '/file'
mode: 0777
mode: "0777"
mode_parse: modern
owner_id: 123
group_id: 321
force: false
@@ -235,7 +249,8 @@
content: |
Some other content
container_path: '/file'
mode: 0777
mode: "0777"
mode_parse: modern
owner_id: 123
group_id: 321
force: false
@@ -253,6 +268,117 @@
chdir: /root
register: result_11
- name: Copy content (octal mode, mode_parse=modern)
docker_container_copy_into:
container: '{{ cname }}'
content: |
Content 1
container_path: '/file'
# yamllint disable
mode: 0770
# yamllint enable
mode_parse: modern
owner_id: 0
group_id: 0
register: result_12
- name: Dump file
docker_container_exec:
container: '{{ cname }}'
argv:
- /bin/sh
- "-c"
- >-
cat /file | base64;
stat -c '%s %a %F %u %g %N' /file > /dev/stderr
chdir: /root
register: result_13
- name: Copy content (octal mode, mode_parse=legacy)
docker_container_copy_into:
container: '{{ cname }}'
content: |
Content 1
container_path: '/file'
# yamllint disable
mode: 0707
# yamllint enable
mode_parse: legacy
owner_id: 0
group_id: 0
register: result_14
- name: Dump file
docker_container_exec:
container: '{{ cname }}'
argv:
- /bin/sh
- "-c"
- >-
cat /file | base64;
stat -c '%s %a %F %u %g %N' /file > /dev/stderr
chdir: /root
register: result_15
- name: Copy content (string mode, mode_parse=legacy)
docker_container_copy_into:
container: '{{ cname }}'
content: |
Content 1
container_path: '/file'
mode: "420"
mode_parse: legacy
owner_id: 0
group_id: 0
register: result_16
- name: Dump file
docker_container_exec:
container: '{{ cname }}'
argv:
- /bin/sh
- "-c"
- >-
cat /file | base64;
stat -c '%s %a %F %u %g %N' /file > /dev/stderr
chdir: /root
register: result_17
- name: Copy content (string mode, mode_parse=octal_string_only)
docker_container_copy_into:
container: '{{ cname }}'
content: |
Content 1
container_path: '/file'
mode: "0600"
mode_parse: octal_string_only
owner_id: 0
group_id: 0
register: result_18
- name: Dump file
docker_container_exec:
container: '{{ cname }}'
argv:
- /bin/sh
- "-c"
- >-
cat /file | base64;
stat -c '%s %a %F %u %g %N' /file > /dev/stderr
chdir: /root
register: result_19
- name: Restore state for next tasks
docker_container_copy_into:
container: '{{ cname }}'
content: |
Content 1
container_path: '/file'
mode: "0644"
mode_parse: octal_string_only
owner_id: 0
group_id: 0
- name: Check results
assert:
that:
@@ -302,6 +428,18 @@
- result_10 is not changed
- result_11.stdout | b64decode == 'Content 1\n'
- result_11.stderr == '10 644 regular file 0 0 /file'
- result_12 is changed
- result_13.stdout | b64decode == 'Content 1\n'
- result_13.stderr == '10 770 regular file 0 0 /file'
- result_14 is changed
- result_15.stdout | b64decode == 'Content 1\n'
- result_15.stderr == '10 707 regular file 0 0 /file'
- result_16 is changed
- result_17.stdout | b64decode == 'Content 1\n'
- result_17.stderr == '10 644 regular file 0 0 /file'
- result_18 is changed
- result_19.stdout | b64decode == 'Content 1\n'
- result_19.stderr == '10 600 regular file 0 0 /file'
######################### Follow link - idempotence
@@ -323,7 +461,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: true
check_mode: true
diff: false
@@ -335,7 +474,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: true
check_mode: true
diff: true
@@ -347,7 +487,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: true
register: result_2
@@ -370,7 +511,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: true
force: true
check_mode: true
@@ -383,7 +525,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: true
force: true
check_mode: true
@@ -396,7 +539,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: true
force: true
register: result_5
@@ -454,7 +598,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: false
check_mode: true
diff: false
@@ -466,7 +611,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: false
check_mode: true
diff: true
@@ -478,7 +624,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
follow: false
register: result_2
@@ -488,7 +635,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: false
register: result_3
@@ -499,7 +647,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: true
register: result_3_diff
@@ -510,7 +659,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
register: result_4
- name: Dump file
@@ -531,7 +681,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
force: true
check_mode: true
diff: false
@@ -543,7 +694,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
force: true
check_mode: true
diff: true
@@ -555,7 +707,8 @@
content: |
Content 1
container_path: '/lnk'
mode: 0644
mode: "0644"
mode_parse: modern
force: true
register: result_7
@@ -615,7 +768,8 @@
content: |
Content 1
container_path: '/dir'
mode: 0644
mode: "0644"
mode_parse: modern
follow: false
check_mode: true
diff: false
@@ -627,7 +781,8 @@
content: |
Content 1
container_path: '/dir'
mode: 0644
mode: "0644"
mode_parse: modern
follow: false
check_mode: true
diff: true
@@ -639,7 +794,8 @@
content: |
Content 1
container_path: '/dir'
mode: 0644
mode: "0644"
mode_parse: modern
follow: false
register: result_2
@@ -649,7 +805,8 @@
content: |
Content 1
container_path: '/dir'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: false
register: result_3
@@ -660,7 +817,8 @@
content: |
Content 1
container_path: '/dir'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: true
register: result_3_diff
@@ -671,7 +829,8 @@
content: |
Content 1
container_path: '/dir'
mode: 0644
mode: "0644"
mode_parse: modern
register: result_4
- name: Dump file
@@ -719,7 +878,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: false
register: result_1
@@ -731,7 +891,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
check_mode: true
diff: true
register: result_1_diff
@@ -743,7 +904,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0644
mode: "0644"
mode_parse: modern
register: result_2
- name: Dump file
@@ -781,7 +943,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: false
register: result_1
@@ -793,7 +956,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: true
register: result_1_diff
@@ -805,7 +969,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
register: result_2
- name: Copy content (idempotent, check mode)
@@ -815,7 +980,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: false
register: result_3
@@ -827,7 +993,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: true
register: result_3_diff
@@ -839,7 +1006,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
register: result_4
- name: Dump file
@@ -885,7 +1053,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -899,7 +1068,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -913,7 +1083,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_2
@@ -925,7 +1096,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -939,7 +1111,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -953,7 +1126,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_4
@@ -977,7 +1151,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 13
group_id: 13
check_mode: true
@@ -991,7 +1166,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 13
group_id: 13
check_mode: true
@@ -1005,7 +1181,8 @@
Content 2
Extra line
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 13
group_id: 13
register: result_7
@@ -1068,7 +1245,8 @@
content: |
Content 1
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -1081,7 +1259,8 @@
content: |
Content 1
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -1094,7 +1273,8 @@
content: |
Content 1
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_2
@@ -1105,7 +1285,8 @@
content: |
Content 1
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -1118,7 +1299,8 @@
content: |
Content 1
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -1131,7 +1313,8 @@
content: |
Content 1
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_4
@@ -1142,7 +1325,8 @@
content: |
Content 1
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
register: result_5
ignore_errors: true
@@ -34,7 +34,7 @@
dest: '{{ remote_tmp_dir }}/file_1'
content: |
Content 1
mode: 0644
mode: "0644"
- name: Create file 2
copy:
@@ -42,7 +42,7 @@
content: |-
Content 2
Extra line
mode: 0644
mode: "0644"
- name: Create link 1
file:
@@ -50,7 +50,7 @@
state: link
src: file_1
follow: false
mode: 0644
mode: "0644"
- name: Create link 2
file:
@@ -59,7 +59,7 @@
src: dead
force: true
follow: false
mode: 0644
mode: "0644"
################################################################################################
# Do tests
@@ -173,7 +173,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0777
mode: "0777"
mode_parse: modern
owner_id: 123
group_id: 321
force: false
@@ -186,7 +187,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0777
mode: "0777"
mode_parse: modern
owner_id: 123
group_id: 321
force: false
@@ -199,7 +201,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0777
mode: "0777"
mode_parse: modern
owner_id: 123
group_id: 321
force: false
@@ -684,7 +687,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: false
register: result_1
@@ -694,7 +698,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: true
register: result_1_diff
@@ -704,7 +709,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
register: result_2
- name: Copy file (idempotent, check mode)
@@ -712,7 +718,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: false
register: result_3
@@ -722,7 +729,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
check_mode: true
diff: true
register: result_3_diff
@@ -732,7 +740,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
register: result_4
- name: Dump file
@@ -776,7 +785,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -788,7 +798,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -800,7 +811,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_2
@@ -810,7 +822,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -822,7 +835,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -834,7 +848,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_4
@@ -856,7 +871,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 13
group_id: 13
check_mode: true
@@ -868,7 +884,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 13
group_id: 13
check_mode: true
@@ -880,7 +897,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_2'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 13
group_id: 13
register: result_7
@@ -942,7 +960,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_1'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -954,7 +973,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_1'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -966,7 +986,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_1'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_2
@@ -976,7 +997,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_1'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -988,7 +1010,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_1'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
check_mode: true
@@ -1000,7 +1023,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_1'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
owner_id: 12
group_id: 910
register: result_4
@@ -1010,7 +1034,8 @@
container: '{{ cname }}'
path: '{{ remote_tmp_dir }}/file_1'
container_path: '/file'
mode: 0707
mode: "0707"
mode_parse: modern
register: result_5
ignore_errors: true
+1
View File
@@ -2,5 +2,6 @@
plugins/inventory/docker_containers.py yamllint:unparsable-with-libyaml
plugins/inventory/docker_machine.py yamllint:unparsable-with-libyaml
plugins/inventory/docker_swarm.py yamllint:unparsable-with-libyaml
plugins/modules/docker_container_copy_into.py validate-modules:invalid-documentation
plugins/modules/docker_container_copy_into.py validate-modules:undocumented-parameter # _max_file_size_for_diff is used by the action plugin
plugins/modules/docker_image_build.py validate-modules:invalid-documentation
+1
View File
@@ -1,5 +1,6 @@
plugins/inventory/docker_containers.py yamllint:unparsable-with-libyaml
plugins/inventory/docker_machine.py yamllint:unparsable-with-libyaml
plugins/inventory/docker_swarm.py yamllint:unparsable-with-libyaml
plugins/modules/docker_container_copy_into.py validate-modules:invalid-documentation
plugins/modules/docker_container_copy_into.py validate-modules:undocumented-parameter # _max_file_size_for_diff is used by the action plugin
plugins/modules/docker_image_build.py validate-modules:invalid-documentation
@@ -0,0 +1,68 @@
# Copyright 2025 Felix Fontein <felix@fontein.de>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import pytest
from ansible_collections.community.docker.plugins.modules.docker_container_copy_into import parse_modern, parse_octal_string_only
@pytest.mark.parametrize("input, expected", [
('0777', 0o777),
('777', 0o777),
('0o777', 0o777),
('0755', 0o755),
('755', 0o755),
('0o755', 0o755),
('0644', 0o644),
('644', 0o644),
('0o644', 0o644),
(' 0644 ', 0o644),
(' 644 ', 0o644),
(' 0o644 ', 0o644),
('-1', -1),
])
def test_parse_string(input, expected):
assert parse_modern(input) == expected
assert parse_octal_string_only(input) == expected
@pytest.mark.parametrize("input", [
0o777,
0o755,
0o644,
12345,
123456789012345678901234567890123456789012345678901234567890,
])
def test_parse_int(input):
assert parse_modern(input) == input
with pytest.raises(TypeError, match="^must be an octal string, got {value}L?$".format(value=input)):
parse_octal_string_only(input)
@pytest.mark.parametrize("input", [
1.0,
755.5,
[],
{},
])
def test_parse_bad_type(input):
with pytest.raises(TypeError, match="^must be an octal string or an integer, got "):
parse_modern(input)
with pytest.raises(TypeError, match="^must be an octal string, got "):
parse_octal_string_only(input)
@pytest.mark.parametrize("input", [
"foo",
"8",
"9",
])
def test_parse_bad_value(input):
with pytest.raises(ValueError):
parse_modern(input)
with pytest.raises(ValueError):
parse_octal_string_only(input)