# test code for the lineinfile module # (c) 2014, James Cammarata # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . - name: deploy the test file for lineinfile copy: src: test.txt dest: "{{ output_dir }}/test.txt" register: result - name: assert that the test file was deployed assert: that: - result is changed - "result.checksum == '5feac65e442c91f557fc90069ce6efc4d346ab51'" - "result.state == 'file'" - name: insert a line at the beginning of the file, and back it up lineinfile: dest: "{{ output_dir }}/test.txt" state: present line: "New line at the beginning" insertbefore: "BOF" backup: yes register: result1 - name: insert a line at the beginning of the file again lineinfile: dest: "{{ output_dir }}/test.txt" state: present line: "New line at the beginning" insertbefore: "BOF" register: result2 - name: assert that the line was inserted at the head of the file assert: that: - result1 is changed - result2 is not changed - result1.msg == 'line added' - result1.backup != '' - name: stat the backup file stat: path: "{{ result1.backup }}" register: result - name: assert the backup file matches the previous hash assert: that: - "result.stat.checksum == '5feac65e442c91f557fc90069ce6efc4d346ab51'" - name: stat the test after the insert at the head stat: path: "{{ output_dir }}/test.txt" register: result - name: assert test hash is what we expect for the file with the insert at the head assert: that: - "result.stat.checksum == '7eade4042b23b800958fe807b5bfc29f8541ec09'" - name: insert a line at the end of the file lineinfile: dest: "{{ output_dir }}/test.txt" state: present line: "New line at the end" insertafter: "EOF" register: result - name: assert that the line was inserted at the end of the file assert: that: - result is changed - "result.msg == 'line added'" - name: stat the test after the insert at the end stat: path: "{{ output_dir }}/test.txt" register: result - name: assert test checksum matches after the insert at the end assert: that: - "result.stat.checksum == 'fb57af7dc10a1006061b000f1f04c38e4bef50a9'" - name: insert a line after the first line lineinfile: dest: "{{ output_dir }}/test.txt" state: present line: "New line after line 1" insertafter: "^This is line 1$" register: result - name: assert that the line was inserted after the first line assert: that: - result is changed - "result.msg == 'line added'" - name: stat the test after insert after the first line stat: path: "{{ output_dir }}/test.txt" register: result - name: assert test checksum matches after the insert after the first line assert: that: - "result.stat.checksum == '5348da605b1bc93dbadf3a16474cdf22ef975bec'" - name: insert a line before the last line lineinfile: dest: "{{ output_dir }}/test.txt" state: present line: "New line after line 5" insertbefore: "^This is line 5$" register: result - name: assert that the line was inserted before the last line assert: that: - result is changed - "result.msg == 'line added'" - name: stat the test after the insert before the last line stat: path: "{{ output_dir }}/test.txt" register: result - name: assert test checksum matches after the insert before the last line assert: that: - "result.stat.checksum == 'e1cae425403507feea4b55bb30a74decfdd4a23e'" - name: replace a line with backrefs lineinfile: dest: "{{ output_dir }}/test.txt" state: present line: "This is line 3" backrefs: yes regexp: "^(REF) .* \\1$" register: result - name: assert that the line with backrefs was changed assert: that: - result is changed - "result.msg == 'line replaced'" - name: stat the test after the backref line was replaced stat: path: "{{ output_dir }}/test.txt" register: result - name: assert test checksum matches after backref line was replaced assert: that: - "result.stat.checksum == '2ccdf45d20298f9eaece73b713648e5489a52444'" - name: remove the middle line lineinfile: dest: "{{ output_dir }}/test.txt" state: absent regexp: "^This is line 3$" register: result - name: assert that the line was removed assert: that: - result is changed - "result.msg == '1 line(s) removed'" - name: stat the test after the middle line was removed stat: path: "{{ output_dir }}/test.txt" register: result - name: assert test checksum matches after the middle line was removed assert: that: - "result.stat.checksum == 'a6ba6865547c19d4c203c38a35e728d6d1942c75'" - name: run a validation script that succeeds lineinfile: dest: "{{ output_dir }}/test.txt" state: absent regexp: "^This is line 5$" validate: "true %s" register: result - name: assert that the file validated after removing a line assert: that: - result is changed - "result.msg == '1 line(s) removed'" - name: stat the test after the validation succeeded stat: path: "{{ output_dir }}/test.txt" register: result - name: assert test checksum matches after the validation succeeded assert: that: - "result.stat.checksum == '76955a4516a00a38aad8427afc9ee3e361024ba5'" - name: run a validation script that fails lineinfile: dest: "{{ output_dir }}/test.txt" state: absent regexp: "^This is line 1$" validate: "/bin/false %s" register: result ignore_errors: yes - name: assert that the validate failed assert: that: - "result.failed == true" - name: stat the test after the validation failed stat: path: "{{ output_dir }}/test.txt" register: result - name: assert test checksum matches the previous after the validation failed assert: that: - "result.stat.checksum == '76955a4516a00a38aad8427afc9ee3e361024ba5'" - name: use create=yes lineinfile: dest: "{{ output_dir }}/new_test.txt" create: yes insertbefore: BOF state: present line: "This is a new file" register: result - name: assert that the new file was created assert: that: - result is changed - "result.msg == 'line added'" - name: validate that the newly created file exists stat: path: "{{ output_dir }}/new_test.txt" register: result ignore_errors: yes - name: assert the newly created test checksum matches assert: that: - "result.stat.checksum == '038f10f9e31202451b093163e81e06fbac0c6f3a'" # Test EOF in cases where file has no newline at EOF - name: testnoeof deploy the file for lineinfile copy: src: testnoeof.txt dest: "{{ output_dir }}/testnoeof.txt" register: result - name: testnoeof insert a line at the end of the file lineinfile: dest: "{{ output_dir }}/testnoeof.txt" state: present line: "New line at the end" insertafter: "EOF" register: result - name: testempty assert that the line was inserted at the end of the file assert: that: - result is changed - "result.msg == 'line added'" - name: insert a multiple lines at the end of the file lineinfile: dest: "{{ output_dir }}/test.txt" state: present line: "This is a line\nwith \\n character" insertafter: "EOF" register: result - name: assert that the multiple lines was inserted assert: that: - result is changed - "result.msg == 'line added'" - name: testnoeof stat the no newline EOF test after the insert at the end stat: path: "{{ output_dir }}/testnoeof.txt" register: result - name: testnoeof assert test checksum matches after the insert at the end assert: that: - "result.stat.checksum == 'f9af7008e3cb67575ce653d094c79cabebf6e523'" # Test EOF with empty file to make sure no unnecessary newline is added - name: testempty deploy the testempty file for lineinfile copy: src: testempty.txt dest: "{{ output_dir }}/testempty.txt" register: result - name: testempty insert a line at the end of the file lineinfile: dest: "{{ output_dir }}/testempty.txt" state: present line: "New line at the end" insertafter: "EOF" register: result - name: testempty assert that the line was inserted at the end of the file assert: that: - result is changed - "result.msg == 'line added'" - name: testempty stat the test after the insert at the end stat: path: "{{ output_dir }}/testempty.txt" register: result - name: testempty assert test checksum matches after the insert at the end assert: that: - "result.stat.checksum == 'f440dc65ea9cec3fd496c1479ddf937e1b949412'" - stat: path: "{{ output_dir }}/test.txt" register: result - name: assert test checksum matches after inserting multiple lines assert: that: - "result.stat.checksum == 'bf5b711f8f0509355aaeb9d0d61e3e82337c1365'" - name: replace a line with backrefs included in the line lineinfile: dest: "{{ output_dir }}/test.txt" state: present line: "New \\1 created with the backref" backrefs: yes regexp: "^This is (line 4)$" register: result - name: assert that the line with backrefs was changed assert: that: - result is changed - "result.msg == 'line replaced'" - name: stat the test after the backref line was replaced stat: path: "{{ output_dir }}/test.txt" register: result - name: assert test checksum matches after backref line was replaced assert: that: - "result.stat.checksum == '04b7a54d0fb233a4e26c9e625325bb4874841b3c'" ################################################################### # issue 8535 - name: create a new file for testing quoting issues file: dest: "{{ output_dir }}/test_quoting.txt" state: touch register: result - name: assert the new file was created assert: that: - result is changed - name: use with_items to add code-like strings to the quoting txt file lineinfile: dest: "{{ output_dir }}/test_quoting.txt" line: "{{ item }}" insertbefore: BOF with_items: - "'foo'" - "dotenv.load();" - "var dotenv = require('dotenv');" register: result - name: assert the quote test file was modified correctly assert: that: - result.results|length == 3 - result.results[0] is changed - result.results[0].item == "'foo'" - result.results[1] is changed - result.results[1].item == "dotenv.load();" - result.results[2] is changed - result.results[2].item == "var dotenv = require('dotenv');" - name: stat the quote test file stat: path: "{{ output_dir }}/test_quoting.txt" register: result - name: assert test checksum matches after backref line was replaced assert: that: - "result.stat.checksum == '7dc3cb033c3971e73af0eaed6623d4e71e5743f1'" - name: insert a line into the quoted file with a single quote lineinfile: dest: "{{ output_dir }}/test_quoting.txt" line: "import g'" register: result - name: assert that the quoted file was changed assert: that: - result is changed - name: stat the quote test file stat: path: "{{ output_dir }}/test_quoting.txt" register: result - name: assert test checksum matches after backref line was replaced assert: that: - "result.stat.checksum == '73b271c2cc1cef5663713bc0f00444b4bf9f4543'" - name: insert a line into the quoted file with many double quotation strings lineinfile: dest: "{{ output_dir }}/test_quoting.txt" line: "\"quote\" and \"unquote\"" register: result - name: assert that the quoted file was changed assert: that: - result is changed - name: stat the quote test file stat: path: "{{ output_dir }}/test_quoting.txt" register: result - name: assert test checksum matches after backref line was replaced assert: that: - "result.stat.checksum == 'b10ab2a3c3b6492680c8d0b1d6f35aa6b8f9e731'" ################################################################### # Issue 28721 - name: Deploy the testmultiple file copy: src: testmultiple.txt dest: "{{ output_dir }}/testmultiple.txt" register: result - name: Assert that the testmultiple file was deployed assert: that: - result is changed - result.checksum == '3e0090a34fb641f3c01e9011546ff586260ea0ea' - result.state == 'file' # Test insertafter - name: Write the same line to a file inserted after different lines lineinfile: path: "{{ output_dir }}/testmultiple.txt" insertafter: "{{ item.regex }}" line: "{{ item.replace }}" register: _multitest_1 with_items: "{{ test_regexp }}" - name: Do the same thing again to check for changes lineinfile: path: "{{ output_dir }}/testmultiple.txt" insertafter: "{{ item.regex }}" line: "{{ item.replace }}" register: _multitest_2 with_items: "{{ test_regexp }}" - name: Assert that the file was changed the first time but not the second time assert: that: - item.0 is changed - item.1 is not changed with_together: - "{{ _multitest_1.results }}" - "{{ _multitest_2.results }}" - name: Stat the insertafter file stat: path: "{{ output_dir }}/testmultiple.txt" register: result - name: Assert that the insertafter file matches expected checksum assert: that: - result.stat.checksum == '282fedf460b3ed7357667a9c8b457ec67b53b6ea' # Test insertbefore - name: Write the same line to a file inserted before different lines lineinfile: path: "{{ output_dir }}/testmultiple.txt" insertbefore: "{{ item.regex }}" line: "{{ item.replace }}" register: _multitest_3 with_items: "{{ test_regexp }}" - name: Do the same thing again to check for changes lineinfile: path: "{{ output_dir }}/testmultiple.txt" insertbefore: "{{ item.regex }}" line: "{{ item.replace }}" register: _multitest_4 with_items: "{{ test_regexp }}" - name: Assert that the file was changed the first time but not the second time assert: that: - item.0 is changed - item.1 is not changed with_together: - "{{ _multitest_3.results }}" - "{{ _multitest_4.results }}" - name: Stat the insertbefore file stat: path: "{{ output_dir }}/testmultiple.txt" register: result - name: Assert that the insertbefore file matches expected checksum assert: that: - result.stat.checksum == 'a8452bb3643be8d18ba3fc212632b1633bd9f885' ################################################################### # Issue 36156 # Test insertbefore and insertafter with regexp - name: Deploy the test.conf file copy: src: test.conf dest: "{{ output_dir }}/test.conf" register: result - name: Assert that the test.conf file was deployed assert: that: - result is changed - result.checksum == '6037f13e419b132eb3fd20a89e60c6c87a6add38' - result.state == 'file' # Test instertafter - name: Insert lines after with regexp lineinfile: path: "{{ output_dir }}/test.conf" regexp: "{{ item.regexp }}" line: "{{ item.line }}" insertafter: "{{ item.after }}" with_items: "{{ test_befaf_regexp }}" register: _multitest_5 - name: Do the same thing again and check for changes lineinfile: path: "{{ output_dir }}/test.conf" regexp: "{{ item.regexp }}" line: "{{ item.line }}" insertafter: "{{ item.after }}" with_items: "{{ test_befaf_regexp }}" register: _multitest_6 - name: Assert that the file was changed the first time but not the second time assert: that: - item.0 is changed - item.1 is not changed with_together: - "{{ _multitest_5.results }}" - "{{ _multitest_6.results }}" - name: Stat the file stat: path: "{{ output_dir }}/test.conf" register: result - name: Assert that the file contents match what is expected assert: that: - result.stat.checksum == '06e2c456e5028dd7bcd0b117b5927a1139458c82' - name: Do the same thing a third time without regexp and check for changes lineinfile: path: "{{ output_dir }}/test.conf" line: "{{ item.line }}" insertafter: "{{ item.after }}" with_items: "{{ test_befaf_regexp }}" register: _multitest_7 - name: Stat the file stat: path: "{{ output_dir }}/test.conf" register: result - name: Assert that the file was changed when no regexp was provided assert: that: - item is changed with_items: "{{ _multitest_7.results }}" - name: Stat the file stat: path: "{{ output_dir }}/test.conf" register: result - name: Assert that the file contents match what is expected assert: that: - result.stat.checksum == '5bf50f3d74afd20de4010ca5c04bc7037b062d30' # Test insertbefore - name: Deploy the test.conf file copy: src: test.conf dest: "{{ output_dir }}/test.conf" register: result - name: Assert that the test.conf file was deployed assert: that: - result is changed - result.checksum == '6037f13e419b132eb3fd20a89e60c6c87a6add38' - result.state == 'file' - name: Insert lines before with regexp lineinfile: path: "{{ output_dir }}/test.conf" regexp: "{{ item.regexp }}" line: "{{ item.line }}" insertbefore: "{{ item.before }}" with_items: "{{ test_befaf_regexp }}" register: _multitest_8 - name: Do the same thing again and check for changes lineinfile: path: "{{ output_dir }}/test.conf" regexp: "{{ item.regexp }}" line: "{{ item.line }}" insertbefore: "{{ item.before }}" with_items: "{{ test_befaf_regexp }}" register: _multitest_9 - name: Assert that the file was changed the first time but not the second time assert: that: - item.0 is changed - item.1 is not changed with_together: - "{{ _multitest_8.results }}" - "{{ _multitest_9.results }}" - name: Stat the file stat: path: "{{ output_dir }}/test.conf" register: result - name: Assert that the file contents match what is expected assert: that: - result.stat.checksum == 'c3be9438a07c44d4c256cebfcdbca15a15b1db91' - name: Do the same thing a third time without regexp and check for changes lineinfile: path: "{{ output_dir }}/test.conf" line: "{{ item.line }}" insertbefore: "{{ item.before }}" with_items: "{{ test_befaf_regexp }}" register: _multitest_10 - name: Stat the file stat: path: "{{ output_dir }}/test.conf" register: result - name: Assert that the file was changed when no regexp was provided assert: that: - item is changed with_items: "{{ _multitest_10.results }}" - name: Stat the file stat: path: "{{ output_dir }}/test.conf" register: result - name: Assert that the file contents match what is expected assert: that: - result.stat.checksum == 'eca8d8ea089d4ea57a3b87d4091599ca8b60dfd2' ################################################################### # Issue 29443 - name: Deploy the test file for lineinfile copy: src: test.txt dest: "{{ output_dir }}/test.txt" register: result - name: Assert that the test file was deployed assert: that: - result is changed - result.checksum == '5feac65e442c91f557fc90069ce6efc4d346ab51' - result.state == 'file' - name: Insert a line in the file using an empty string as a regular expression lineinfile: path: "{{ output_dir }}/test.txt" regexp: '' line: This is line 6 register: insert_empty_regexp - name: Stat the file stat: path: "{{ output_dir }}/test.txt" register: result - name: Assert that the file contents match what is expected assert: that: - insert_empty_regexp is changed - result.stat.checksum == '3baeade8eb2ecf4b01d70d541e9b8258b67c7f9f'