You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

466 lines
13 KiB

пре 1 година
пре 3 година
пре 3 година
пре 1 година
пре 3 година
пре 1 година
пре 3 година
пре 3 година
пре 3 година
пре 1 година
пре 1 година
пре 1 година
пре 3 година
пре 1 година
пре 3 година
пре 3 година
пре 3 година
  1. #!/usr/bin/env bats
  2. load test_helper
  3. export PYTHON_BUILD_CACHE_PATH="$TMP/cache"
  4. export MAKE=make
  5. export MAKE_OPTS="-j 2"
  6. export CC=cc
  7. export PYTHON_BUILD_HTTP_CLIENT="curl"
  8. export TMP_FIXTURES="$TMP/fixtures"
  9. setup() {
  10. mkdir -p "$INSTALL_ROOT"
  11. stub md5 false
  12. stub curl false
  13. }
  14. executable() {
  15. local file="$1"
  16. mkdir -p "${file%/*}"
  17. cat > "$file"
  18. chmod +x "$file"
  19. }
  20. cached_tarball() {
  21. mkdir -p "$PYTHON_BUILD_CACHE_PATH"
  22. pushd "$PYTHON_BUILD_CACHE_PATH" >/dev/null
  23. tarball "$@"
  24. popd >/dev/null
  25. }
  26. tarball() {
  27. local name="$1"
  28. local path="$PWD/$name"
  29. local configure="$path/configure"
  30. shift 1
  31. executable "$configure" <<OUT
  32. #!$BASH
  33. echo "$name: CPPFLAGS=\\"\$CPPFLAGS\\" LDFLAGS=\\"\$LDFLAGS\\"" >> build.log
  34. echo "$name: \$@" \${PYTHONOPT:+PYTHONOPT=\$PYTHONOPT} >> build.log
  35. OUT
  36. for file; do
  37. mkdir -p "$(dirname "${path}/${file}")"
  38. touch "${path}/${file}"
  39. done
  40. tar czf "${path}.tar.gz" -C "${path%/*}" "$name"
  41. }
  42. stub_make_install() {
  43. stub "$MAKE" \
  44. " : echo \"$MAKE \$@\" >> build.log" \
  45. "install : echo \"$MAKE \$@\" >> build.log && cat build.log >> '$INSTALL_ROOT/build.log'"
  46. }
  47. assert_build_log() {
  48. run cat "$INSTALL_ROOT/build.log"
  49. assert_output
  50. }
  51. install_patch() {
  52. local name="$1"
  53. local patch="$2"
  54. [ -n "$patch" ] || patch="python.patch"
  55. mkdir -p "${TMP_FIXTURES}/${name%/*}/patches/${name##*/}/${patch%/*}"
  56. cat > "${TMP_FIXTURES}/${name%/*}/patches/${name##*/}/${patch}"
  57. }
  58. install_tmp_fixture() {
  59. local args
  60. while [ "${1#-}" != "$1" ]; do
  61. args="$args $1"
  62. shift 1
  63. done
  64. local name="$1"
  65. local destination="$2"
  66. [ -n "$destination" ] || destination="$INSTALL_ROOT"
  67. # Copy fixture to temporary path
  68. mkdir -p "${TMP_FIXTURES}/${name%/*}"
  69. cp "${FIXTURE_ROOT}/${name}" "${TMP_FIXTURES}/${name}"
  70. run python-build $args "$TMP_FIXTURES/$name" "$destination"
  71. }
  72. resolve_link() {
  73. $(type -P greadlink readlink | head -n1) "$1"
  74. }
  75. run_inline_definition_with_name() {
  76. local definition_name="build-definition"
  77. case "$1" in
  78. "--name="* )
  79. local definition_name="${1#--name=}"
  80. shift 1
  81. ;;
  82. esac
  83. local definition="${TMP}/${definition_name}"
  84. cat > "$definition"
  85. run python-build "$definition" "${1:-$INSTALL_ROOT}"
  86. }
  87. @test "apply built-in python patch before building" {
  88. cached_tarball "Python-3.6.2"
  89. stub brew false
  90. stub_make_install
  91. stub patch ' : echo patch "$@" | sed -E "s/\.[[:alnum:]]+$/.XXX/" >> build.log'
  92. echo | install_patch definitions/vanilla-python "Python-3.6.2/empty.patch"
  93. # yyuu/pyenv#257
  94. stub uname '-s : echo Linux'
  95. stub uname '-s : echo Linux'
  96. TMPDIR="$TMP" install_tmp_fixture definitions/vanilla-python < /dev/null
  97. assert_success
  98. assert_build_log <<OUT
  99. patch -p0 --force -i $TMP/python-patch.XXX
  100. Python-3.6.2: CPPFLAGS="-I${TMP}/install/include" LDFLAGS="-L${TMP}/install/lib -Wl,-rpath,${TMP}/install/lib"
  101. Python-3.6.2: --prefix=$INSTALL_ROOT --enable-shared --libdir=$INSTALL_ROOT/lib
  102. make -j 2
  103. make install
  104. OUT
  105. unstub make
  106. unstub patch
  107. }
  108. @test "apply built-in python patches should be sorted by its name" {
  109. cached_tarball "Python-3.6.2"
  110. for i in {1..2}; do stub brew '* : false'; done
  111. stub_make_install
  112. stub patch ' : for arg; do [[ "$arg" == "-"* ]] || sed -e "s/^/patch: /" "$arg"; done >> build.log'
  113. echo "foo" | install_patch definitions/vanilla-python "Python-3.6.2/foo.patch"
  114. echo "bar" | install_patch definitions/vanilla-python "Python-3.6.2/bar.patch"
  115. echo "baz" | install_patch definitions/vanilla-python "Python-3.6.2/baz.patch"
  116. for i in {1..2}; do stub uname '-s : echo Linux'; done
  117. TMPDIR="$TMP" install_tmp_fixture definitions/vanilla-python < /dev/null
  118. assert_success
  119. assert_build_log <<OUT
  120. patch: bar
  121. patch: baz
  122. patch: foo
  123. Python-3.6.2: CPPFLAGS="-I${TMP}/install/include" LDFLAGS="-L${TMP}/install/lib -Wl,-rpath,${TMP}/install/lib"
  124. Python-3.6.2: --prefix=$INSTALL_ROOT --enable-shared --libdir=$INSTALL_ROOT/lib
  125. make -j 2
  126. make install
  127. OUT
  128. unstub make
  129. unstub patch
  130. }
  131. @test "allow custom make install target" {
  132. cached_tarball "Python-3.6.2"
  133. stub brew false
  134. stub "$MAKE" \
  135. " : echo \"$MAKE \$@\" >> build.log" \
  136. " : echo \"$MAKE \$@\" >> build.log && cat build.log >> '$INSTALL_ROOT/build.log'"
  137. for i in {1..4}; do stub uname '-s : echo Darwin'; done
  138. PYTHON_MAKE_INSTALL_TARGET="altinstall" TMPDIR="$TMP" install_tmp_fixture definitions/vanilla-python < /dev/null
  139. assert_success
  140. assert_build_log <<OUT
  141. Python-3.6.2: CPPFLAGS="-I${TMP}/install/include" LDFLAGS="-L${TMP}/install/lib -Wl,-rpath,${TMP}/install/lib"
  142. Python-3.6.2: --prefix=$INSTALL_ROOT --enable-shared --libdir=$INSTALL_ROOT/lib
  143. make -j 2
  144. make altinstall
  145. OUT
  146. unstub make
  147. }
  148. @test "ensurepip without altinstall" {
  149. mkdir -p "${INSTALL_ROOT}/bin"
  150. cat <<OUT > "${INSTALL_ROOT}/bin/python"
  151. #!$BASH
  152. echo "python \$@" >> "${INSTALL_ROOT}/build.log"
  153. OUT
  154. chmod +x "${INSTALL_ROOT}/bin/python"
  155. PYTHON_MAKE_INSTALL_TARGET="" TMPDIR="$TMP" run_inline_definition <<OUT
  156. build_package_ensurepip
  157. OUT
  158. assert_success
  159. assert_build_log <<OUT
  160. python -I -m ensurepip
  161. OUT
  162. }
  163. @test "ensurepip with altinstall" {
  164. mkdir -p "${INSTALL_ROOT}/bin"
  165. cat <<OUT > "${INSTALL_ROOT}/bin/python"
  166. #!$BASH
  167. echo "python \$@" >> "${INSTALL_ROOT}/build.log"
  168. OUT
  169. chmod +x "${INSTALL_ROOT}/bin/python"
  170. PYTHON_MAKE_INSTALL_TARGET="altinstall" TMPDIR="$TMP" run_inline_definition <<OUT
  171. build_package_ensurepip
  172. OUT
  173. assert_success
  174. assert_build_log <<OUT
  175. python -I -m ensurepip --altinstall
  176. OUT
  177. }
  178. @test "python3-config" {
  179. mkdir -p "${INSTALL_ROOT}/bin"
  180. touch "${INSTALL_ROOT}/bin/python3"
  181. chmod +x "${INSTALL_ROOT}/bin/python3"
  182. touch "${INSTALL_ROOT}/bin/python3.4"
  183. chmod +x "${INSTALL_ROOT}/bin/python3.4"
  184. touch "${INSTALL_ROOT}/bin/python3-config"
  185. chmod +x "${INSTALL_ROOT}/bin/python3-config"
  186. touch "${INSTALL_ROOT}/bin/python3.4-config"
  187. chmod +x "${INSTALL_ROOT}/bin/python3.4-config"
  188. TMPDIR="$TMP" run_inline_definition <<OUT
  189. verify_python python3.4
  190. OUT
  191. assert_success
  192. [ -L "${INSTALL_ROOT}/bin/python" ]
  193. [ -L "${INSTALL_ROOT}/bin/python-config" ]
  194. [[ "$(resolve_link "${INSTALL_ROOT}/bin/python")" == "python3.4" ]]
  195. [[ "$(resolve_link "${INSTALL_ROOT}/bin/python-config")" == "python3.4-config" ]]
  196. }
  197. @test "enable framework" {
  198. framework_path="${INSTALL_ROOT}/Library/Frameworks/Python.framework/Versions/Current/bin"
  199. mkdir -p "$framework_path"
  200. for executable in python3{,.4}{,-config}; do
  201. touch "$framework_path/$executable"
  202. chmod +x "$framework_path/$executable"
  203. done
  204. unset framework_path executable
  205. for i in {1..3}; do stub uname '-s : echo Darwin'; done
  206. PYTHON_CONFIGURE_OPTS="--enable-framework" TMPDIR="$TMP" run_inline_definition <<OUT
  207. echo "PYTHON_CONFIGURE_OPTS_ARRAY=(\${PYTHON_CONFIGURE_OPTS_ARRAY[@]})"
  208. echo "PYTHON_CONFIGURE_OPTS=(\${PYTHON_CONFIGURE_OPTS})"
  209. echo "CONFIGURE_OPTS=(\${CONFIGURE_OPTS})"
  210. verify_python python3.4
  211. OUT
  212. assert_success
  213. assert_output <<EOS
  214. PYTHON_CONFIGURE_OPTS_ARRAY=(--libdir=${TMP}/install/lib --enable-framework=${TMP}/install/Library/Frameworks)
  215. PYTHON_CONFIGURE_OPTS=()
  216. CONFIGURE_OPTS=()
  217. EOS
  218. [ -L "${INSTALL_ROOT}/Library/Frameworks/Python.framework/Versions/Current/bin/python" ]
  219. [ -L "${INSTALL_ROOT}/Library/Frameworks/Python.framework/Versions/Current/bin/python-config" ]
  220. }
  221. @test "enable universalsdk" {
  222. for i in {1..3}; do stub uname '-s : echo Darwin'; done
  223. stub arch "echo x86_64"
  224. PYTHON_CONFIGURE_OPTS="--enable-universalsdk" TMPDIR="$TMP" run_inline_definition <<OUT
  225. echo "PYTHON_CONFIGURE_OPTS_ARRAY=(\${PYTHON_CONFIGURE_OPTS_ARRAY[@]})"
  226. echo "PYTHON_CONFIGURE_OPTS=(\${PYTHON_CONFIGURE_OPTS})"
  227. echo "CONFIGURE_OPTS=(\${CONFIGURE_OPTS})"
  228. OUT
  229. assert_success
  230. assert_output <<EOS
  231. PYTHON_CONFIGURE_OPTS_ARRAY=(--enable-shared --libdir=${TMP}/install/lib --enable-universalsdk=/)
  232. PYTHON_CONFIGURE_OPTS=()
  233. CONFIGURE_OPTS=()
  234. EOS
  235. }
  236. @test "enable universalsdk on Apple Silicon" {
  237. for i in {1..3}; do stub uname '-s : echo Darwin'; done
  238. stub arch "echo arm64"
  239. PYTHON_CONFIGURE_OPTS="--enable-universalsdk" TMPDIR="$TMP" run_inline_definition <<OUT
  240. echo "PYTHON_CONFIGURE_OPTS_ARRAY=(\${PYTHON_CONFIGURE_OPTS_ARRAY[@]})"
  241. echo "PYTHON_CONFIGURE_OPTS=(\${PYTHON_CONFIGURE_OPTS})"
  242. echo "CONFIGURE_OPTS=(\${CONFIGURE_OPTS})"
  243. OUT
  244. assert_success
  245. assert_output <<EOS
  246. PYTHON_CONFIGURE_OPTS_ARRAY=(--enable-shared --libdir=${TMP}/install/lib --enable-universalsdk=/ --with-universal-archs=universal2)
  247. PYTHON_CONFIGURE_OPTS=()
  248. CONFIGURE_OPTS=()
  249. EOS
  250. }
  251. @test "enable universalsdk with explicit archs argument" {
  252. for i in {1..3}; do stub uname '-s : echo Darwin'; done
  253. PYTHON_CONFIGURE_OPTS="--enable-universalsdk --with-universal-archs=foo" TMPDIR="$TMP" run_inline_definition <<OUT
  254. echo "PYTHON_CONFIGURE_OPTS_ARRAY=(\${PYTHON_CONFIGURE_OPTS_ARRAY[@]})"
  255. OUT
  256. assert_success
  257. assert_output <<EOS
  258. PYTHON_CONFIGURE_OPTS_ARRAY=(--enable-shared --libdir=${TMP}/install/lib --enable-universalsdk=/)
  259. EOS
  260. }
  261. @test "enable custom unicode configuration" {
  262. cached_tarball "Python-3.6.2"
  263. for i in {1..4}; do stub brew false; done
  264. for i in {1..8}; do stub uname '-s : echo Linux'; done
  265. stub "$MAKE" \
  266. " : echo \"$MAKE \$@\" >> build.log" \
  267. " : echo \"$MAKE \$@\" >> build.log && cat build.log >> '$INSTALL_ROOT/build.log'"
  268. PYTHON_CONFIGURE_OPTS="--enable-unicode=ucs2" TMPDIR="$TMP" install_tmp_fixture definitions/vanilla-python < /dev/null
  269. assert_success
  270. assert_build_log <<OUT
  271. Python-3.6.2: CPPFLAGS="-I${TMP}/install/include" LDFLAGS="-L${TMP}/install/lib -Wl,-rpath,${TMP}/install/lib"
  272. Python-3.6.2: --prefix=$INSTALL_ROOT --enable-shared --libdir=$INSTALL_ROOT/lib --enable-unicode=ucs2
  273. make -j 2
  274. make install
  275. OUT
  276. unstub make
  277. unstub uname
  278. }
  279. @test "default MACOSX_DEPLOYMENT_TARGET" {
  280. # yyuu/pyenv#257
  281. for i in {1..3}; do stub uname '-s : echo Darwin'; done
  282. for i in {1..2}; do stub sw_vers '-productVersion : echo 10.10'; done
  283. TMPDIR="$TMP" run_inline_definition <<OUT
  284. echo "\${MACOSX_DEPLOYMENT_TARGET}"
  285. OUT
  286. assert_success
  287. assert_output "10.10"
  288. }
  289. @test "use custom MACOSX_DEPLOYMENT_TARGET if defined" {
  290. # yyuu/pyenv#257
  291. stub uname '-s : echo Darwin'
  292. stub uname '-s : echo Darwin'
  293. MACOSX_DEPLOYMENT_TARGET="10.4" TMPDIR="$TMP" run_inline_definition <<OUT
  294. echo "\${MACOSX_DEPLOYMENT_TARGET}"
  295. OUT
  296. assert_success
  297. assert_output "10.4"
  298. }
  299. @test "use the default EZ_SETUP_URL by default" {
  300. run_inline_definition <<OUT
  301. echo "\${EZ_SETUP_URL}"
  302. OUT
  303. assert_output "https://bootstrap.pypa.io/ez_setup.py"
  304. assert_success
  305. }
  306. @test "use the default GET_PIP_URL by default" {
  307. run_inline_definition <<OUT
  308. echo "\${GET_PIP_URL}"
  309. OUT
  310. assert_output "https://bootstrap.pypa.io/get-pip.py"
  311. assert_success
  312. }
  313. @test "use the custom GET_PIP_URL for 2.6 versions" {
  314. run_inline_definition_with_name --name=2.6 <<OUT
  315. echo "\${GET_PIP_URL}"
  316. OUT
  317. assert_output "https://bootstrap.pypa.io/pip/2.6/get-pip.py"
  318. assert_success
  319. }
  320. @test "use the custom GET_PIP_URL for 2.7 versions" {
  321. run_inline_definition_with_name --name=2.7 <<OUT
  322. echo "\${GET_PIP_URL}"
  323. OUT
  324. assert_output "https://bootstrap.pypa.io/pip/2.7/get-pip.py"
  325. assert_success
  326. }
  327. @test "use the custom GET_PIP_URL for 3.2 versions" {
  328. run_inline_definition_with_name --name=3.2 <<OUT
  329. echo "\${GET_PIP_URL}"
  330. OUT
  331. assert_output "https://bootstrap.pypa.io/pip/3.2/get-pip.py"
  332. assert_success
  333. }
  334. @test "use the custom GET_PIP_URL for 3.3 versions" {
  335. run_inline_definition_with_name --name=3.3 <<OUT
  336. echo "\${GET_PIP_URL}"
  337. OUT
  338. assert_output "https://bootstrap.pypa.io/pip/3.3/get-pip.py"
  339. assert_success
  340. }
  341. @test "use the custom GET_PIP_URL for 3.4 versions" {
  342. run_inline_definition_with_name --name=3.4 <<OUT
  343. echo "\${GET_PIP_URL}"
  344. OUT
  345. assert_output "https://bootstrap.pypa.io/pip/3.4/get-pip.py"
  346. assert_success
  347. }
  348. @test "use the custom GET_PIP_URL for 3.5 versions" {
  349. run_inline_definition_with_name --name=3.5 <<OUT
  350. echo "\${GET_PIP_URL}"
  351. OUT
  352. assert_output "https://bootstrap.pypa.io/pip/3.5/get-pip.py"
  353. assert_success
  354. }
  355. @test "use the custom GET_PIP_URL for 3.6 versions" {
  356. run_inline_definition_with_name --name=3.6 <<OUT
  357. echo "\${GET_PIP_URL}"
  358. OUT
  359. assert_output "https://bootstrap.pypa.io/pip/3.6/get-pip.py"
  360. assert_success
  361. }
  362. @test "use the custom GET_PIP_URL for pypy2.7 versions" {
  363. run_inline_definition_with_name --name=pypy2.7-7.3.12 <<OUT
  364. echo "\${GET_PIP_URL}"
  365. OUT
  366. assert_output "https://bootstrap.pypa.io/pip/2.7/get-pip.py"
  367. assert_success
  368. }
  369. @test "use the custom GET_PIP_URL for pypy3.5 versions" {
  370. run_inline_definition_with_name --name=pypy3.5-7.0.0 <<OUT
  371. echo "\${GET_PIP_URL}"
  372. OUT
  373. assert_output "https://bootstrap.pypa.io/pip/3.5/get-pip.py"
  374. assert_success
  375. }
  376. @test "use the custom GET_PIP_URL for pypy3.6 versions" {
  377. run_inline_definition_with_name --name=pypy3.6-7.3.3 <<OUT
  378. echo "\${GET_PIP_URL}"
  379. OUT
  380. assert_output "https://bootstrap.pypa.io/pip/3.6/get-pip.py"
  381. assert_success
  382. }