test-failing-maintainer-scripts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #!/bin/sh
  2. set -e
  3. TESTDIR=$(readlink -f $(dirname $0))
  4. . $TESTDIR/framework
  5. setupenvironment
  6. configarchitecture 'native'
  7. # create a bunch of failures
  8. createfailure() {
  9. setupsimplenativepackage "failure-$1" 'native' '1.0' 'unstable' 'Depends: dependee'
  10. BUILDDIR="incoming/failure-$1-1.0"
  11. echo '#!/bin/sh
  12. exit 29' > ${BUILDDIR}/debian/$1
  13. buildpackage "$BUILDDIR" 'unstable' 'main' 'native'
  14. rm -rf "$BUILDDIR"
  15. }
  16. buildsimplenativepackage 'dependee' 'native' '1.0' 'unstable'
  17. createfailure 'preinst'
  18. createfailure 'postinst'
  19. createfailure 'prerm'
  20. createfailure 'postrm'
  21. setupaptarchive
  22. # create a library to noop chroot() and rewrite maintainer script executions
  23. # via execvp() as used by dpkg as we don't want our rootdir to be a fullblown
  24. # chroot directory dpkg could chroot into to execute the maintainer scripts
  25. cat << EOF > noopchroot.c
  26. #define _GNU_SOURCE
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <dlfcn.h>
  31. static char * chrootdir = NULL;
  32. int chroot(const char *path) {
  33. printf("WARNING: CHROOTing to %s was ignored!\n", path);
  34. free(chrootdir);
  35. chrootdir = strdup(path);
  36. return 0;
  37. }
  38. int execvp(const char *file, char *const argv[]) {
  39. static int (*func_execvp) (const char *, char * const []) = NULL;
  40. if (func_execvp == NULL)
  41. func_execvp = (int (*) (const char *, char * const [])) dlsym(RTLD_NEXT, "execvp");
  42. if (chrootdir == NULL || strncmp(file, "/var/lib/dpkg/", strlen("/var/lib/dpkg/")) != 0)
  43. return func_execvp(file, argv);
  44. printf("REWRITE execvp call %s into %s\n", file, chrootdir);
  45. char newfile[strlen(chrootdir) + strlen(file)];
  46. strcpy(newfile, chrootdir);
  47. strcat(newfile, file);
  48. return func_execvp(newfile, argv);
  49. }
  50. EOF
  51. testsuccess gcc -fPIC -shared -o noopchroot.so noopchroot.c -ldl
  52. mkdir -p "${TMPWORKINGDIRECTORY}/rootdir/usr/bin/"
  53. DPKG="${TMPWORKINGDIRECTORY}/rootdir/usr/bin/dpkg"
  54. echo "#!/bin/sh
  55. if [ -n \"\$LD_PRELOAD\" ]; then
  56. export LD_PRELOAD=\"${TMPWORKINGDIRECTORY}/noopchroot.so \${LD_PRELOAD}\"
  57. else
  58. export LD_PRELOAD=\"${TMPWORKINGDIRECTORY}/noopchroot.so\"
  59. fi
  60. dpkg \"\$@\"" > $DPKG
  61. chmod +x $DPKG
  62. sed -ie "s|^DPKG::options:: \"dpkg\";\$|DPKG::options:: \"$DPKG\";|" aptconfig.conf
  63. # setup some pre- and post- invokes to check the output isn't garbled later
  64. APTHOOK="${TMPWORKINGDIRECTORY}/rootdir/usr/bin/apthook"
  65. echo '#!/bin/sh
  66. echo "$1: START"
  67. echo "$1: MaiN"
  68. echo "$1: ENd"' > $APTHOOK
  69. chmod +x $APTHOOK
  70. echo "DPKG::Pre-Invoke:: \"${APTHOOK} PRE\";
  71. DPKG::Post-Invoke:: \"${APTHOOK} POST\";" > rootdir/etc/apt/apt.conf.d/99apthooks
  72. testmyfailure() {
  73. local PROGRESS='rootdir/tmp/progress.log'
  74. exec 3> $PROGRESS
  75. testfailure "$@" -o APT::Status-Fd=3
  76. msgtest 'Test for failure message of maintainerscript in' 'console log'
  77. local TEST='rootdir/tmp/testfailure.output'
  78. if grep -q 'exit status 29$' "$TEST"; then
  79. msgpass
  80. else
  81. cat $TEST
  82. msgfail
  83. fi
  84. msgtest 'Test for proper execution of invoke scripts in' 'console log'
  85. if grep -q '^PRE: START$' $TEST &&
  86. grep -q '^PRE: MaiN$' $TEST &&
  87. grep -q '^PRE: ENd$' $TEST &&
  88. grep -q '^POST: START$' $TEST &&
  89. grep -q '^POST: MaiN$' $TEST &&
  90. grep -q '^POST: ENd$' $TEST; then
  91. msgpass
  92. else
  93. cat $TEST
  94. msgfail
  95. fi
  96. msgtest 'Test for failure message of maintainerscript in' 'progress log'
  97. if grep -q '^pmerror:.\+exit status 29$' "$PROGRESS"; then
  98. msgpass
  99. else
  100. cat $PROGRESS
  101. msgfail
  102. fi
  103. testmarkedauto 'dependee'
  104. }
  105. cp -a rootdir/var/lib/dpkg/status rootdir/var/lib/dpkg/status.backup
  106. testmyfailure aptget install failure-preinst -y
  107. cp -a rootdir/var/lib/dpkg/status.backup rootdir/var/lib/dpkg/status
  108. testmyfailure aptget install failure-postinst -y
  109. cp -a rootdir/var/lib/dpkg/status.backup rootdir/var/lib/dpkg/status
  110. testsuccess aptget install failure-prerm -y
  111. testdpkginstalled failure-prerm
  112. testmyfailure aptget purge failure-prerm -y
  113. cp -a rootdir/var/lib/dpkg/status.backup rootdir/var/lib/dpkg/status
  114. testsuccess aptget install failure-postrm -y
  115. testdpkginstalled failure-postrm
  116. testmyfailure aptget purge failure-postrm -y
  117. # FIXME: test with output going to a PTY as it usually does
  118. #cp -a rootdir/var/lib/dpkg/status.backup rootdir/var/lib/dpkg/status
  119. #aptget install failure-preinst -y