1b2752497SKyle Evans# 2b2752497SKyle Evans# SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3b2752497SKyle Evans# 4b2752497SKyle Evans# Copyright (c) 2019 Kyle Evans <kevans@FreeBSD.org> 5b2752497SKyle Evans# 6b2752497SKyle Evans# Redistribution and use in source and binary forms, with or without 7b2752497SKyle Evans# modification, are permitted provided that the following conditions 8b2752497SKyle Evans# are met: 9b2752497SKyle Evans# 1. Redistributions of source code must retain the above copyright 10b2752497SKyle Evans# notice, this list of conditions and the following disclaimer. 11b2752497SKyle Evans# 2. Redistributions in binary form must reproduce the above copyright 12b2752497SKyle Evans# notice, this list of conditions and the following disclaimer in the 13b2752497SKyle Evans# documentation and/or other materials provided with the distribution. 14b2752497SKyle Evans# 15b2752497SKyle Evans# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16b2752497SKyle Evans# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17b2752497SKyle Evans# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18b2752497SKyle Evans# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19b2752497SKyle Evans# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20b2752497SKyle Evans# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21b2752497SKyle Evans# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22b2752497SKyle Evans# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23b2752497SKyle Evans# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24b2752497SKyle Evans# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25b2752497SKyle Evans# SUCH DAMAGE. 26b2752497SKyle Evans# 27b2752497SKyle Evans# $FreeBSD$ 28b2752497SKyle Evans 29b2752497SKyle Evansatf_test_case basic 30b2752497SKyle Evansbasic_body() 31b2752497SKyle Evans{ 32b2752497SKyle Evans printf "a\nb\nc\nd\ne\nf\ng\nh\ni\n" > foo_full 33b2752497SKyle Evans printf "a\nb\nc\n" > foo_start 34b2752497SKyle Evans printf "g\nh\ni\n" > foo_end 35b2752497SKyle Evans printf "d\ne\nf\n" > foo_middle 36b2752497SKyle Evans 37b2752497SKyle Evans diff -u foo_start foo_full > foo_start2full.diff 38b2752497SKyle Evans diff -u foo_end foo_full > foo_end2full.diff 39b2752497SKyle Evans diff -u foo_middle foo_full > foo_mid2full.diff 40b2752497SKyle Evans 41b2752497SKyle Evans # Check lengths... each should have all 9 lines + 3 line header 42b2752497SKyle Evans atf_check -o inline:"12" -x \ 43b2752497SKyle Evans "cat foo_start2full.diff | wc -l | tr -d '[:space:]'" 44b2752497SKyle Evans atf_check -o inline:"12" -x \ 45b2752497SKyle Evans "cat foo_end2full.diff | wc -l | tr -d '[:space:]'" 46b2752497SKyle Evans atf_check -o inline:"12" -x \ 47b2752497SKyle Evans "cat foo_mid2full.diff | wc -l | tr -d '[:space:]'" 48b2752497SKyle Evans 49b2752497SKyle Evans # Apply the patch! Should succeed 50b2752497SKyle Evans atf_check -o ignore patch foo_start foo_start2full.diff \ 51b2752497SKyle Evans -o foo_start2full 52b2752497SKyle Evans atf_check -o ignore patch foo_end foo_end2full.diff \ 53b2752497SKyle Evans -o foo_end2full 54b2752497SKyle Evans atf_check -o ignore patch foo_middle foo_mid2full.diff \ 55b2752497SKyle Evans -o foo_mid2full 56b2752497SKyle Evans 57b2752497SKyle Evans # And these should all produce equivalent to the original full 58b2752497SKyle Evans atf_check -o ignore diff foo_start2full foo_full 59b2752497SKyle Evans atf_check -o ignore diff foo_end2full foo_full 60b2752497SKyle Evans atf_check -o ignore diff foo_mid2full foo_full 61b2752497SKyle Evans} 62b2752497SKyle Evans 63b2752497SKyle Evansatf_test_case limited_ctx 64b2752497SKyle Evanslimited_ctx_head() 65b2752497SKyle Evans{ 66b2752497SKyle Evans atf_set "descr" "Verify correct behavior with limited context (PR 74127)" 67b2752497SKyle Evans} 68b2752497SKyle Evanslimited_ctx_body() 69b2752497SKyle Evans{ 70b2752497SKyle Evans 71b2752497SKyle Evans # First; PR74127-repro.diff should not have applied, but it instead 72b2752497SKyle Evans # assumed a match and added the modified line at the offset specified... 73b2752497SKyle Evans atf_check -s not-exit:0 -o ignore -e ignore patch -o _.out \ 74b2752497SKyle Evans "$(atf_get_srcdir)/PR74127.in" \ 75b2752497SKyle Evans "$(atf_get_srcdir)/PR74127-repro.diff" 76b2752497SKyle Evans 77b2752497SKyle Evans # Let's extend that and make sure a similarly ill-contexted diff does 78b2752497SKyle Evans # not apply even with the correct line number 79b2752497SKyle Evans atf_check -s not-exit:0 -o ignore -e ignore patch -o _.out \ 80b2752497SKyle Evans "$(atf_get_srcdir)/PR74127.in" \ 81b2752497SKyle Evans "$(atf_get_srcdir)/PR74127-line.diff" 82b2752497SKyle Evans 83b2752497SKyle Evans # Correct line number and correct old line should always work 84b2752497SKyle Evans atf_check -o ignore -e ignore patch -o _.out \ 85b2752497SKyle Evans "$(atf_get_srcdir)/PR74127.in" \ 86b2752497SKyle Evans "$(atf_get_srcdir)/PR74127-good.diff" 87b2752497SKyle Evans} 88b2752497SKyle Evans 89b2752497SKyle Evansatf_test_case file_creation 90b2752497SKyle Evansfile_creation_body() 91b2752497SKyle Evans{ 92b2752497SKyle Evans 93b2752497SKyle Evans echo "x" > foo 94b2752497SKyle Evans diff -u /dev/null foo > foo.diff 95b2752497SKyle Evans rm foo 96b2752497SKyle Evans 97b2752497SKyle Evans atf_check -x "patch -s < foo.diff" 98b2752497SKyle Evans atf_check -o ignore stat foo 99b2752497SKyle Evans} 100b2752497SKyle Evans 101b2752497SKyle Evans# This test is motivated by long-standing bugs that occasionally slip by in 102b2752497SKyle Evans# commits. If a file is created by a diff, patch(1) will happily duplicate the 103b2752497SKyle Evans# contents as many times as you apply the diff. It should instead detect that 104b2752497SKyle Evans# a source of /dev/null creates the file, so it shouldn't exist. Furthermore, 10589b5571eSKyle Evans# the reverse of creation is deletion -- hence the next test, which ensures that 106*50dacbf6SKyle Evans# the file is removed if it's empty once the patch is reversed. The size checks 107*50dacbf6SKyle Evans# are scattered throughout to make sure that we didn't get some kind of false 108*50dacbf6SKyle Evans# error, and the first size check is merely a sanity check that should be 109*50dacbf6SKyle Evans# trivially true as this is executed in a sandbox. 110b2752497SKyle Evansatf_test_case file_nodupe 111b2752497SKyle Evansfile_nodupe_body() 112b2752497SKyle Evans{ 113b2752497SKyle Evans 114b2752497SKyle Evans echo "x" > foo 115b2752497SKyle Evans diff -u /dev/null foo > foo.diff 116b2752497SKyle Evans 117*50dacbf6SKyle Evans atf_check -o inline:"2\n" stat -f "%z" foo 118*50dacbf6SKyle Evans atf_check -s not-exit:0 -o ignore -x "patch -Ns < foo.diff" 119*50dacbf6SKyle Evans atf_check -o inline:"2\n" stat -f "%z" foo 120*50dacbf6SKyle Evans atf_check -s not-exit:0 -o ignore -x "patch -fs < foo.diff" 121*50dacbf6SKyle Evans atf_check -o inline:"2\n" stat -f "%z" foo 122b2752497SKyle Evans} 123b2752497SKyle Evans 124b2752497SKyle Evansatf_test_case file_removal 125b2752497SKyle Evansfile_removal_body() 126b2752497SKyle Evans{ 127b2752497SKyle Evans 128b2752497SKyle Evans echo "x" > foo 129b2752497SKyle Evans diff -u /dev/null foo > foo.diff 130b2752497SKyle Evans 13189b5571eSKyle Evans # Check that the file is removed completely if it was sourced from 13289b5571eSKyle Evans # /dev/null 133b2752497SKyle Evans atf_check -x "patch -Rs < foo.diff" 13489b5571eSKyle Evans atf_check -s not-exit:0 -e ignore stat foo 13589b5571eSKyle Evans 13689b5571eSKyle Evans # But if it had been modified, we'll only remove the portion that the 13789b5571eSKyle Evans # patch would have created. This makes us compatible with GNU patch's 13889b5571eSKyle Evans # behavior, at least. Whether that is the sane action or not is a 13989b5571eSKyle Evans # question for further study, and then this comment may be removed. 14089b5571eSKyle Evans printf "x\ny\n" > foo 14189b5571eSKyle Evans atf_check -x "patch -Rs < foo.diff" 14289b5571eSKyle Evans atf_check -o inline:"y\n" cat foo 143b2752497SKyle Evans} 144b2752497SKyle Evans 145b2752497SKyle Evansatf_init_test_cases() 146b2752497SKyle Evans{ 147b2752497SKyle Evans atf_add_test_case basic 148b2752497SKyle Evans atf_add_test_case limited_ctx 149b2752497SKyle Evans atf_add_test_case file_creation 150b2752497SKyle Evans atf_add_test_case file_nodupe 151b2752497SKyle Evans atf_add_test_case file_removal 152b2752497SKyle Evans} 153