TT#24920 Introduce 'ngcpcfg patch --from-customtt' for initial import

The new function will simplify initial customtt->patchtt
migration for end users. Some code was merged to be generic.

Also more tests were add here.

Change-Id: I7719f45275018818b2db82f6deee5b7428670a29
changes/58/18258/4
Alexander Lutay 8 years ago
parent 3670689eb4
commit 051f27f03e

@ -397,10 +397,14 @@ Note: This feature is only available if the ngcp-ngcpcfg-carrier package is inst
Prints the log of local changes. Expand all changes if '-p' option is specified.
**patch** [--help] [<patchtt file(s)>]::
**patch** [--help | --from-customtt [<cusomtt file(s)>] | <patchtt file(s)>]::
Generate customtt files using default templates and patchtt files.
Using patchtt files automates template updating and simplifies customtt management.
You can perform initial migration from customtt to patchtt using option '--from-customtt',
ngcpcfg will process all/requested customtt files and generate patchtt files as a
difference between template and current customtt files. You should normally
execute '--from-customtt' only once during migration on patchtt.
**pull**::

@ -36,7 +36,7 @@ else
"${SCRIPTS}"/check --ignore-branch-check
fi
"${SCRIPTS}"/patch
"${SCRIPTS}"/patch "$@"
# Kill all previous started tt2-daemon Perl processes if they were not stopped properly
killall tt2-daemon 2>/dev/null || true

@ -23,38 +23,43 @@ cd "${NGCPCTL_MAIN}"
patch_help() {
export TIME_FORMAT=''
log_info "'ngcpcfg patch' walks through all templates searching for '*.patchtt.tt2' files"
log_info "and generates '*.customtt.tt2' files based on the original template"
log_info "and generates '*.customtt.tt2' files based on the original template."
log_info "The option '--from-customtt' simplifies migration from customtt to patchtt."
log_info ""
log_info "Sample:"
log_info " ngcpcfg patch [--help] [<patchtt file(s)>]"
log_info " ngcpcfg patch [--help | --from-customtt [<cusomtt file(s)>] | <patchtt file(s)>]"
log_info ""
log_info "Run 'man ngcpcfg' for more information."
}
patch_search() {
log_debug "Searching for patchtt files"
local name="$1"
shift # remove the first 'patchtt/customtt'
local files=("$@")
local patchlist
patchlist=$(mktemp)
log_debug "Searching for ${name} files (requested '${files[*]}')"
local fileslist
fileslist=$(mktemp)
local a="\.sp[12]?"
local b="\.(web|db|prx|lb|slb)[0-9]+[ab]?"
local awk_regexp=".*patchtt\.tt2(${a}|${b})?$"
local awk_regexp=".*${name}\.tt2(${a}|${b})?$"
for dir in ${CONFIG_POOL} ; do
[ -n "${dir}" ] || log_error "${dir} doesn't exist"
# iterate over all files
while read -r patch ; do
# *NO* arguments provided via cmdline
if [ -z "${1:-}" ] ; then
log_debug "Found patch '${patch}'"
echo "${patch}" >> "${patchlist}"
log_debug "Iterate over all files in ${TEMPLATE_POOL_BASE%/}/${dir#/}"
while read -r file ; do
if [ "${#files[@]}" = "0" ] ; then
log_debug "NO arguments provided via cmdline"
log_debug "Found ${name} '${file}'"
echo "${file}" >> "${fileslist}"
else
# arguments (file list/pattern) provided via cmdline
for arg in "$@"; do
if echo "${patch}" | grep -q -- "${arg}" ; then
log_debug "Processing patch '${patch}' as requested"
echo "${patch}" >> "${patchlist}"
for arg in "${files[@]}"; do
if echo "${file}" | grep -q -- "${arg}" ; then
log_debug "Processing ${name} '${file}' as requested"
echo "${file}" >> "${fileslist}"
fi
done
fi
@ -62,24 +67,24 @@ patch_search() {
done
# output patch list, make sure we provide the file names just once
sort -u "${patchlist}"
sort -u "${fileslist}"
if [ -n "${DEBUG:-}" ] ; then
# send to stderr since stdout is used from outside
log_debug "Not removing temporary patchlist files since we are in debug mode:" >&2
log_debug " patchlist = ${patchlist}" >&2
log_debug "Not removing temporary fileslist files since we are in debug mode:" >&2
log_debug " fileslist = ${fileslist}" >&2
else
rm -f "${patchlist}"
rm -f "${fileslist}"
fi
}
patch_validate() {
patch_validate_patch() {
local patch="$1"
log_debug "Validating patch: '${patch}'"
if [ ! -f "${patch}" ] ; then
log_error "Missing patch file '${patch}'"
bad_patches+=("${patch}")
bad_files+=("${patch}")
return 1
fi
@ -89,7 +94,7 @@ patch_validate() {
log_debug "Found template for the patch: '${template}'"
else
log_error "Missing template for patch '${patch}'"
bad_patches+=("${patch}")
bad_files+=("${patch}")
return 1
fi
@ -129,56 +134,165 @@ patch_apply() {
else
log_debug "Patch '${patch}' can be applied"
fi
good_patches+=("${patch}")
good_files+=("${patch}")
else
log_error "The patch '${patch}' cannot be applied:"
cat "${patch_output}" >&2
bad_patches+=("${patch}")
bad_files+=("${patch}")
fi
rm -f "${patch_output}"
}
patch_main() {
for patch in $(patch_search "$@") ; do
patch_validate_customtt() {
local file="$1"
log_debug "Validating customtt: '${file}'"
if [ ! -f "${file}" ] ; then
log_error "Missing customtt file '${file}'"
bad_files+=("${file}")
return 1
fi
local template="${file%%.customtt*}.tt2"
if [ -f "${template}" ] ; then
log_debug "Found template for the customtt: '${template}'"
else
log_error "Missing template for customtt '${customtt}'"
bad_files+=("${customtt}")
return 1
fi
local patchtt="${file//.customtt/.patchtt}"
if [ -f "${patchtt}" ] ; then
log_debug "Overwriting patchtt '${patchtt}'"
else
log_debug "Not found patchtt for the customtt: '${patchtt}'"
fi
}
patch_import_customtt() {
local customtt_file="$1"
local apply="${2:-false}"
local template="${customtt_file%%.customtt*}.tt2"
local patchtt="${customtt_file//.customtt/.patchtt}"
local tmp_patchtt
tmp_patchtt=$(mktemp)
local diff_output
diff_output=$(mktemp)
# diff exit status is 0 if inputs are the same, 1 if different, 2 if trouble.
log_debug "Generating temporary patchtt '${tmp_patchtt}' from template '${template}' and customtt '${customtt_file}'"
case "$(diff -u "${template}" "${customtt_file}" > "${tmp_patchtt}" 2>"${diff_output}" && echo $? || echo $?)" in
0)
log_error "No difference between customtt '${customtt_file}' and template '${template}' (patchtt is not necessary here, remove or change customtt file)"
bad_files+=("${customtt_file}")
;;
1)
log_debug "Successfully processed diff for customtt '${customtt_file}'"
good_files+=("${customtt_file}")
;;
2)
log_error "Diff failed between template '${template}' and customtt file '${customtt_file}':"
cat "${diff_output}" >&2
bad_files+=("${customtt_file}")
;;
*)
log_error "We should not be here. Aborting (better safe then sorry)."
exit 1
;;
esac
if "${apply}" ; then
log_info "Creating patchtt file '${patchtt}'"
log_debug "Removing first 2 lines (filename + date) from 'diff -u' output (due to time changes on '--from-customtt')"
tail -n +3 "${tmp_patchtt}" > "${patchtt}"
fi
rm -f "${diff_output}"
}
patch_import() {
declare -a files=($(patch_search "customtt" "$@"))
log_debug "Validating customtt files"
for customtt in "${files[@]}" ; do
log_info "Validating customtt '${customtt}'"
if patch_validate_customtt "${customtt}" ; then
patch_import_customtt "${customtt}" "false"
fi
done
if [ "${#bad_files[@]}" != "0" ] ; then
log_debug "Aborted here due to failed patch validation above"
return
fi
log_debug "Validating patchtt files from customtt"
for customtt in "${files[@]}" ; do
patch_import_customtt "${customtt}" "true"
done
}
patch_patch() {
declare -a files=($(patch_search "patchtt" "$@"))
for patch in "${files[@]}" ; do
log_info "Validating patch '${patch}'"
patch_validate "${patch}" && patch_apply "${patch}" "false"
if patch_validate_patch "${patch}" ; then
patch_apply "${patch}" "false"
fi
done
if [ "${#bad_patches[@]}" != "0" ] ; then
if [ "${#bad_files[@]}" != "0" ] ; then
log_debug "Aborted here due to failed patch validation above"
return
fi
for patch in $(patch_search "$@") ; do
for patch in "${files[@]}" ; do
log_info "Applying patch '${patch}'"
patch_apply "${patch}" "true"
done
}
## }}}
if [ "${1:-}" = "--help" ]; then
patch_help
exit 0
fi
declare -a bad_patches=()
declare -a good_patches=()
patch_main "$@"
patch_footer() {
local label="$1"
if [ "${#bad_patches[@]}" = "0" ] ; then
if [ "${#good_patches[@]}" = "0" ] ; then
log_info "No patchtt files found, nothing to patch."
if [ "${#bad_files[@]}" = "0" ] ; then
if [ "${#good_files[@]}" = "0" ] ; then
log_info "No ${label} files found, nothing to patch."
else
log_info "Requested ${label} operation has finished successfully."
fi
else
log_info "Patch operation has finished successfully."
log_error "Some operations above finished with an error for the file(s):"
bad_files_unique=($(echo "${bad_files[@]}" | tr ' ' '\n' | sort -u))
printf '\t%s\n' "${bad_files_unique[@]}"
RC=1
fi
else
log_error "Some operations above finished with an error for the patch(es):"
bad_patches_unique=($(echo "${bad_patches[@]}" | tr ' ' '\n' | sort -u))
printf '\t%s\n' "${bad_patches_unique[@]}"
RC=1
fi
}
## }}}
declare -a bad_files=()
declare -a good_files=()
case "${1:-}" in
"--help")
patch_help
;;
"--from-customtt")
shift # removing '--from-customtt'
patch_import "$@"
patch_footer "customtt"
;;
*)
patch_patch "$@"
patch_footer "patchtt"
;;
esac
exit "${RC:-0}"

@ -5,6 +5,9 @@ import pytest
import re
import tempfile
###############################################################################
# tests for "ngcpcfg patch" (no options provides)
###############################################################################
@pytest.mark.tt_24920
def test_patch_action_no_args(ngcpcfgcli, tmpdir):
@ -19,7 +22,7 @@ def test_patch_action_no_args(ngcpcfgcli, tmpdir):
@pytest.mark.tt_24920
def test_patch_action_help(ngcpcfgcli, tmpdir):
# ensure 'ngcpcfg patch' assert on corrupted patchtt file
# ensure 'ngcpcfg patch --help' works as expected
template_path = tmpdir.join('/etc')
apt_path = template_path.join('/apt/apt.conf.d')
@ -50,7 +53,7 @@ APT::Install-Recommends "0";
assert "'ngcpcfg patch' walks through all templates" in out.stdout
assert "Validating patch" not in out.stdout
assert 'Patch operation has finished successfully.' not in out.stdout
assert 'Requested patchtt operation has finished successfully.' not in out.stdout
assert out.stderr == "b''"
@ -87,7 +90,7 @@ APT::Install-Recommends "0";
assert "Validating patch '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2'" in out.stdout
assert 'Patch operation has finished successfully.' in out.stdout
assert 'Requested patchtt operation has finished successfully.' in out.stdout
assert out.stderr == "b''"
generated_customtt = str(tmpdir) + \
@ -134,8 +137,8 @@ APT::Install-Recommends "0";
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2'" in out.stdout
assert "Error: The patch '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2' cannot be applied" in out.stderr
assert "Error: Some operations above finished with an error for the patch(es)" in out.stderr
assert 'Patch operation has finished successfully.' not in out.stdout
assert "Error: Some operations above finished with an error for the file(s)" in out.stderr
assert 'Requested patchtt operation has finished successfully.' not in out.stdout
# TODO: ensure no customtt.tt2 were generated
@ -154,7 +157,7 @@ def test_patch_action_template_missing_for_patchtt(ngcpcfgcli, tmpdir):
@@ -1,2 +1 @@
-
-the changes here
+doesn't matter as not tt2 file available
+doesn't matter as no tt2 file available
''')
out = ngcpcfgcli("patch",
@ -171,8 +174,8 @@ def test_patch_action_template_missing_for_patchtt(ngcpcfgcli, tmpdir):
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2'" in out.stdout
assert "Error: Missing template for patch '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2'" in out.stderr
assert "Error: Some operations above finished with an error for the patch(es)" in out.stderr
assert 'Patch operation has finished successfully.' not in out.stdout
assert "Error: Some operations above finished with an error for the file(s)" in out.stderr
assert 'Requested patchtt operation has finished successfully.' not in out.stdout
@pytest.mark.tt_24920
@ -226,7 +229,72 @@ APT::Install-Recommends "0";
assert "Successfully created '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.customtt.tt2'" in out.stdout
assert '72_another_file.customtt.tt2' not in out.stdout
assert 'Patch operation has finished successfully.' in out.stdout
assert 'Requested patchtt operation has finished successfully.' in out.stdout
assert out.stderr == "b''"
generated_customtt = str(tmpdir) + \
'/etc/apt/apt.conf.d/71_no_recommended.customtt.tt2'
assert os.path.isfile(generated_customtt)
with open(generated_customtt) as customtt:
customtt_output = customtt.read()
assert customtt_output == '''APT::Install-Recommends "1";\n'''
# TODO ensure file '/etc/apt/apt.conf.d/72_another_file.tt2' was not created
@pytest.mark.tt_24920
def test_patch_action_generate_requested_customtt_only_shortname(ngcpcfgcli, tmpdir):
# ensure 'ngcpcfg patch .../some.patchtt.tt2' will build one
# requested patchtt only using the short filename
template_path = tmpdir.join('/etc')
apt_path = template_path.join('/apt/apt.conf.d')
os.makedirs(str(apt_path), exist_ok=True)
apt_path.join('71_no_recommended.tt2').write('''
APT::Install-Recommends "0";
''')
apt_path.join("71_no_recommended.patchtt.tt2").write('''
--- 71_no_recommended.tt2.orig 2017-12-08 13:31:49.763402557 +0100
+++ 71_no_recommended.tt2 2017-12-08 13:32:00.559382702 +0100
@@ -1,2 +1 @@
-
-APT::Install-Recommends "0";
+APT::Install-Recommends "1";
''')
apt_path.join('72_another_file.tt2').write('''
# This is a dummy message you should not see
''')
apt_path.join("72_another_file.patchtt.tt2").write('''
--- 71_no_recommended.tt2.orig 2017-12-08 13:31:49.763402557 +0100
+++ 71_no_recommended.tt2 2017-12-08 13:32:00.559382702 +0100
@@ -1,2 +1 @@
-
-# This is a dummy message you should not see
+# This is a dummy message you should not see on 'ngcpcfg build'
''')
out = ngcpcfgcli("patch",
"71_no_recommended.patchtt.tt2",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'OUTPUT_DIRECTORY': str(tmpdir),
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
})
assert "Validating patch '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2'" in out.stdout
assert "Applying patch '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2'" in out.stdout
assert "Successfully created '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.customtt.tt2'" in out.stdout
assert '72_another_file.customtt.tt2' not in out.stdout
assert 'Requested patchtt operation has finished successfully.' in out.stdout
assert out.stderr == "b''"
generated_customtt = str(tmpdir) + \
@ -269,15 +337,18 @@ APT::Install-Recommends "0";
def test_patch_action_build_generate_and_overwrite_customtt_file(ngcpcfgcli, tmpdir):
# Ensure here "ngcpcfg build" will:
# * find available patchtt file
# * validate available patchtt file
# * validate available patchtt file (necessary only)
# * use available patchtt file
# * generate proper customtt file using tt2 + patchtt
# * overwrite old/available customtt file
# * build proper config using new customtt file
# * care about patchtt.tt2.sp1 file
# * generate proper customtt files using tt2 + patchtt
# * overwrite old/available customtt files
# * build proper config using new customtt files
template_path = tmpdir.join('/etc')
apt_path = template_path.join('/apt/apt.conf.d')
dummy_path = template_path.join('/dummy')
os.makedirs(str(apt_path), exist_ok=True)
os.makedirs(str(dummy_path), exist_ok=True)
apt_path.join('71_no_recommended.tt2').write('''
APT::Install-Recommends "0";
@ -288,6 +359,10 @@ APT::Install-Recommends "0";
APT::Install-Recommends "2";
''')
expected_output = '''
APT::Install-Recommends "1";
'''
apt_path.join("71_no_recommended.patchtt.tt2").write('''
--- 71_no_recommended.tt2.orig 2018-01-10 15:24:06.951855880 +0100
+++ 71_no_recommended.tt2 2018-01-10 15:27:14.891237633 +0100
@ -297,9 +372,36 @@ APT::Install-Recommends "2";
''')
expected_output = '''
apt_path.join('71_no_recommended.customtt.tt2.sp1').write('''
# generated via customtt.sp1 without patch file
APT::Install-Recommends "3";
''')
apt_path.join("71_no_recommended.patchtt.tt2.sp1").write('''
@@ -1 +1 @@
-APT::Install-Recommends "0";
+APT::Install-Recommends "3";
''')
expected_output_sp1 = '''
APT::Install-Recommends "1";
'''
dummy_path.join('dummy.tt2').write('''
dome dummy template message
''')
dummy_path.join('dummy.customtt.tt2').write('''
dome dummy customtt message
''')
dummy_path.join("dummy.patchtt.tt2").write('''
@@ -1 +1 @@
-dome dummy template message
+dome dummy customtt message
''')
out = ngcpcfgcli("build", "--ignore-branch-check",
"/etc/apt/apt.conf.d/",
env={
@ -311,13 +413,20 @@ APT::Install-Recommends "1";
})
assert 'No patchtt files found, nothing to patch.' not in out.stdout
assert 'dummy' not in out.stdout
assert "Validating patch '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2'" in out.stdout
assert "Validating patch '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2.sp1'" in out.stdout
assert "Applying patch '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2'" in out.stdout
assert "Successfully created '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.customtt.tt2'" in out.stdout
assert 'Patch operation has finished successfully.' in out.stdout
assert "Applying patch '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2.sp1'" in out.stdout
assert "Successfully created '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.customtt.tt2.sp1'" in out.stdout
assert 'Requested patchtt operation has finished successfully.' in out.stdout
assert "Generating " + str(tmpdir) + "/output/" + str(tmpdir) + \
"//etc/apt/apt.conf.d/71_no_recommended: OK" in out.stdout
# disabled for the moment, see https://gerrit.mgm.sipwise.com/#/c/17739/4/t/test_ngcpcfg_patch.py@99
@ -331,6 +440,136 @@ APT::Install-Recommends "1";
output = output_file.read()
assert output == expected_output
generated_customtt_sp1 = str(template_path) + \
'/apt/apt.conf.d/71_no_recommended.customtt.tt2.sp1'
assert os.path.isfile(generated_customtt)
with open(generated_customtt) as output_file:
output = output_file.read()
assert output == expected_output_sp1
generated_config = str(tmpdir) + "/output" + str(tmpdir) + \
'/etc/apt/apt.conf.d/71_no_recommended'
assert os.path.isfile(generated_config)
with open(generated_config) as output_file:
output = output_file.read()
assert output == expected_output
@pytest.mark.tt_24920
def test_patch_action_build_generate_all_file(ngcpcfgcli, tmpdir):
# the same as test 'test_patch_action_build_generate_and_overwrite_customtt_file'
# while build all available files
template_path = tmpdir.join('/etc')
apt_path = template_path.join('/apt/apt.conf.d')
dummy_path = template_path.join('/dummy')
os.makedirs(str(apt_path), exist_ok=True)
os.makedirs(str(dummy_path), exist_ok=True)
apt_path.join('71_no_recommended.tt2').write('''
APT::Install-Recommends "0";
''')
apt_path.join('71_no_recommended.customtt.tt2').write('''
# generated via customtt without patch file
APT::Install-Recommends "2";
''')
expected_output = '''
APT::Install-Recommends "1";
'''
apt_path.join("71_no_recommended.patchtt.tt2").write('''
--- 71_no_recommended.tt2.orig 2018-01-10 15:24:06.951855880 +0100
+++ 71_no_recommended.tt2 2018-01-10 15:27:14.891237633 +0100
@@ -1 +1 @@
-APT::Install-Recommends "0";
+APT::Install-Recommends "1";
''')
apt_path.join('71_no_recommended.customtt.tt2.sp1').write('''
# generated via customtt.sp1 without patch file
APT::Install-Recommends "3";
''')
apt_path.join("71_no_recommended.patchtt.tt2.sp1").write('''
@@ -1 +1 @@
-APT::Install-Recommends "0";
+APT::Install-Recommends "3";
''')
expected_output_sp1 = '''
APT::Install-Recommends "1";
'''
dummy_path.join('dummy.tt2').write('''
dome dummy template message
''')
dummy_path.join('dummy.customtt.tt2').write('''
dome dummy customtt message
''')
dummy_path.join("dummy.patchtt.tt2").write('''
@@ -1 +1 @@
-dome dummy template message
+dome dummy customtt message
''')
out = ngcpcfgcli("build", "--ignore-branch-check",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'OUTPUT_DIRECTORY': str(tmpdir) + "/output",
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
})
assert 'No patchtt files found, nothing to patch.' not in out.stdout
assert "Validating patch '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2'" in out.stdout
assert "Validating patch '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2.sp1'" in out.stdout
assert "Validating patch '" + str(template_path) + \
"/dummy/dummy.patchtt.tt2'" in out.stdout
assert "Applying patch '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2'" in out.stdout
assert "Successfully created '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.customtt.tt2'" in out.stdout
assert "Applying patch '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2.sp1'" in out.stdout
assert "Successfully created '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.customtt.tt2.sp1'" in out.stdout
assert "Applying patch '" + str(template_path) + \
"/dummy/dummy.patchtt.tt2'" in out.stdout
assert "Successfully created '" + str(template_path) + \
"/dummy/dummy.customtt.tt2'" in out.stdout
assert 'Requested patchtt operation has finished successfully.' in out.stdout
assert "Generating " + str(tmpdir) + "/output/" + str(tmpdir) + \
"//etc/apt/apt.conf.d/71_no_recommended: OK" in out.stdout
# disabled for the moment, see https://gerrit.mgm.sipwise.com/#/c/17739/4/t/test_ngcpcfg_patch.py@99
#assert out.stderr == "b''"
generated_customtt = str(template_path) + \
'/apt/apt.conf.d/71_no_recommended.customtt.tt2'
assert os.path.isfile(generated_customtt)
with open(generated_customtt) as output_file:
output = output_file.read()
assert output == expected_output
generated_customtt_sp1 = str(template_path) + \
'/apt/apt.conf.d/71_no_recommended.customtt.tt2.sp1'
assert os.path.isfile(generated_customtt)
with open(generated_customtt) as output_file:
output = output_file.read()
assert output == expected_output_sp1
generated_config = str(tmpdir) + "/output" + str(tmpdir) + \
'/etc/apt/apt.conf.d/71_no_recommended'
@ -372,7 +611,7 @@ APT::Install-Recommends "1";
})
assert 'No patchtt files found, nothing to patch.' in out.stdout
assert 'Patch operation has finished successfully.' not in out.stdout
assert 'Requested patchtt operation has finished successfully.' not in out.stdout
assert 'Generating ' in out.stdout
assert '/etc/apt/apt.conf.d/71_no_recommended: OK' in out.stdout
assert 'Validating patch' not in out.stdout
@ -424,7 +663,183 @@ APT::Install-Recommends "0";
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2'" in out.stdout
assert "Error: The patch '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2' cannot be applied" in out.stderr
assert "Error: Some operations above finished with an error for the patch(es)" in out.stderr
assert 'Patch operation has finished successfully.' not in out.stdout
assert "Error: Some operations above finished with an error for the file(s)" in out.stderr
assert 'Requested patchtt operation has finished successfully.' not in out.stdout
assert 'Generating ' not in out.stdout
assert '/etc/apt/apt.conf.d/71_no_recommended: OK' not in out.stdout
###############################################################################
# tests for "ngcpcfg patch --from-customtt"
###############################################################################
@pytest.mark.tt_24920
def test_patch_action_from_customtt_files(ngcpcfgcli, tmpdir):
# Ensure here "ngcpcfg patch --from-customtt" will:
# * find all available customtt file
# * create all necessary patchtt files
template_path = tmpdir.join('/etc')
apt_path = template_path.join('/apt/apt.conf.d')
os.makedirs(str(apt_path), exist_ok=True)
apt_path.join('71_no_recommended.tt2').write('''
# some comment
APT::Install-Recommends "0";
''')
apt_path.join('71_no_recommended.customtt.tt2').write('''
# some comment
APT::Install-Recommends "2";
''')
template_path.join('expected_patch.diff').write('''@@ -1,3 +1,3 @@
# some comment
-APT::Install-Recommends "0";
+APT::Install-Recommends "2";
''')
out = ngcpcfgcli("patch", "--from-customtt",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'OUTPUT_DIRECTORY': str(tmpdir) + "/output",
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
})
assert 'No patchtt files found, nothing to patch.' not in out.stdout
assert "Validating customtt '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.customtt.tt2'" in out.stdout
assert "Creating patchtt file '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2'" in out.stdout
assert 'Requested customtt operation has finished successfully.' in out.stdout
# disabled for the moment, see https://gerrit.mgm.sipwise.com/#/c/17739/4/t/test_ngcpcfg_patch.py@99
#assert out.stderr == "b''"
generated_patchtt = str(template_path) + \
'/apt/apt.conf.d/71_no_recommended.patchtt.tt2'
expected_patchtt = str(template_path) + \
'/expected_patch.diff'
assert os.path.isfile(generated_patchtt)
assert os.path.isfile(expected_patchtt)
with open(generated_patchtt) as output_file:
output = output_file.read()
with open(expected_patchtt) as expected_file:
expected = expected_file.read()
assert output == expected
@pytest.mark.tt_24920
def test_patch_action_from_customtt_missing_file_argument(ngcpcfgcli, tmpdir):
# ensure "ngcpcfg patch --from-customtt missing.customtt.tt2" will be handled properly if
# no some.customtt.tt2 file are available
out = ngcpcfgcli("patch",
"--from-customtt",
"missing.customtt.tt2",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'OUTPUT_DIRECTORY': str(tmpdir),
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
})
assert 'No customtt files found, nothing to patch.' in out.stdout
assert "Creating patchtt file '" not in out.stdout
# disabled for the moment, see https://gerrit.mgm.sipwise.com/#/c/17739/4/t/test_ngcpcfg_patch.py@99
#assert out.stderr == "b''"
@pytest.mark.tt_24920
def test_patch_action_from_customtt_filename_only(ngcpcfgcli, tmpdir):
# ensure "ngcpcfg patch --from-customtt valid.customtt.tt2" will be handled properly if
# no filename only valid.customtt.tt2 has been passed instead of full path
template_path = tmpdir.join('/etc')
apt_path = template_path.join('/apt/apt.conf.d')
os.makedirs(str(apt_path), exist_ok=True)
apt_path.join('71_no_recommended.tt2').write('''
# some comment
APT::Install-Recommends "0";
''')
apt_path.join('71_no_recommended.customtt.tt2').write('''
# some comment
APT::Install-Recommends "2";
''')
template_path.join('expected_patch.diff').write('''@@ -1,3 +1,3 @@
# some comment
-APT::Install-Recommends "0";
+APT::Install-Recommends "2";
''')
out = ngcpcfgcli("patch",
"--from-customtt",
"71_no_recommended.customtt.tt2",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'OUTPUT_DIRECTORY': str(tmpdir),
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
})
assert 'No patchtt files found, nothing to patch.' not in out.stdout
assert "Validating customtt '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.customtt.tt2'" in out.stdout
assert "Creating patchtt file '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.patchtt.tt2'" in out.stdout
assert 'Requested customtt operation has finished successfully.' in out.stdout
# disabled for the moment, see https://gerrit.mgm.sipwise.com/#/c/17739/4/t/test_ngcpcfg_patch.py@99
#assert out.stderr == "b''"
generated_patchtt = str(template_path) + \
'/apt/apt.conf.d/71_no_recommended.patchtt.tt2'
expected_patchtt = str(template_path) + \
'/expected_patch.diff'
assert os.path.isfile(generated_patchtt)
assert os.path.isfile(expected_patchtt)
with open(generated_patchtt) as output_file:
output = output_file.read()
with open(expected_patchtt) as expected_file:
expected = expected_file.read()
assert output == expected
@pytest.mark.tt_24920
def test_patch_action_from_customtt_missing_templates(ngcpcfgcli, tmpdir):
# ensure "ngcpcfg patch --from-customtt" will be aborted if template is missing for customtt
template_path = tmpdir.join('/etc')
apt_path = template_path.join('/apt/apt.conf.d')
os.makedirs(str(apt_path), exist_ok=True)
apt_path.join("71_no_recommended.customtt.tt2").write('''
the content here doesn't matter as no tt2 file available
''')
out = ngcpcfgcli("patch",
"--from-customtt",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'OUTPUT_DIRECTORY': str(tmpdir),
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
})
assert "Validating customtt '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.customtt.tt2'" in out.stdout
assert "Error: Missing template for customtt '" + str(template_path) + \
"/apt/apt.conf.d/71_no_recommended.customtt.tt2'" in out.stderr
assert "Error: Some operations above finished with an error for the file(s)" in out.stderr
assert 'Requested patchtt operation has finished successfully.' not in out.stdout

Loading…
Cancel
Save