/ tests / frontend / add.sh
add.sh
  1  #! /usr/bin/env atf-sh
  2  
  3  . $(atf_get_srcdir)/test_environment.sh
  4  tests_init	\
  5  		add \
  6  		add_automatic \
  7  		add_noscript \
  8  		add_noscript \
  9  		add_force \
 10  		add_accept_missing \
 11  		add_quiet \
 12  		add_stdin \
 13  		add_stdin_missing \
 14  		add_no_version \
 15  		add_no_version_multi \
 16  		add_deps_multi \
 17  		add_wrong_version \
 18  		add_shlib_provider \
 19  		add_shlib_priority \
 20  		add_shlib_missing \
 21  		add_shlib_accept_missing \
 22  		add_shlib_already_installed \
 23  		add_provides_requires \
 24  		add_shlib_stdin_skip \
 25  		add_shlib_dead_symlink
 26  
 27  initialize_pkg() {
 28  	touch a
 29  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg test test 1
 30  	cat << EOF >> test.ucl
 31  files: {
 32  	${TMPDIR}/a: ""
 33  }
 34  scripts: {
 35  	pre-install: <<EOD
 36  echo "pre-install"
 37  EOD
 38  	post-install: <<EOD
 39  echo "post-install"
 40  EOD
 41  }
 42  EOF
 43  
 44  	atf_check \
 45  		-o empty \
 46  		-e empty \
 47  		-s exit:0 \
 48  		pkg create -M test.ucl
 49  }
 50  
 51  add_body() {
 52  	initialize_pkg
 53  
 54  OUTPUT="${JAILED}Installing test-1...
 55  pre-install
 56  ${JAILED}Extracting test-1:  done
 57  post-install
 58  "
 59  	atf_check \
 60  		-o inline:"${OUTPUT}" \
 61  		-e empty \
 62  		pkg add test-1.pkg
 63  
 64  # test automatic is not set
 65  	atf_check \
 66  		-o inline:"0\n" \
 67  		-e empty \
 68  		pkg query "%a" test
 69  }
 70  
 71  add_automatic_body() {
 72  	initialize_pkg
 73  
 74  OUTPUT="${JAILED}Installing test-1...
 75  pre-install
 76  ${JAILED}Extracting test-1:  done
 77  post-install
 78  "
 79  	atf_check \
 80  		-o inline:"${OUTPUT}" \
 81  		-e empty \
 82  		pkg add -A test-1.pkg
 83  
 84  	atf_check \
 85  		-o inline:"1\n" \
 86  		-e empty \
 87  		pkg query "%a" test
 88  
 89  }
 90  
 91  add_noscript_body() {
 92  	initialize_pkg
 93  
 94  OUTPUT="${JAILED}Installing test-1...
 95  ${JAILED}Extracting test-1:  done
 96  "
 97  	cat test-1.pkg | atf_check \
 98  		-o inline:"${OUTPUT}" \
 99  		-e empty \
100  		pkg add -I test-1.pkg
101  }
102  
103  add_force_body() {
104  	initialize_pkg
105  }
106  
107  
108  add_accept_missing_body() {
109  	touch a
110  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg test test 1
111  	cat << EOF >> test.ucl
112  deps: {
113  	b: {
114  		origin: "wedontcare",
115  		version: "1"
116  	}
117  }
118  files: {
119  	${TMPDIR}/a: ""
120  }
121  scripts: {
122  	pre-install: <<EOD
123  echo "pre-install"
124  EOD
125  	post-install: <<EOD
126  echo "post-install"
127  EOD
128  }
129  EOF
130  
131  	atf_check \
132  		-o empty \
133  		-e empty \
134  		-s exit:0 \
135  		pkg create -M test.ucl
136  
137  	atf_check \
138  		-o inline:"${JAILED}Installing test-1...\n\nFailed to install the following 1 package(s): test-1.pkg\n" \
139  		-e inline:"${PROGNAME}: Missing dependency 'b'\n" \
140  		-s exit:1 \
141  		pkg add test-1.pkg
142  
143  OUTPUT="${JAILED}Installing test-1...
144  pre-install
145  ${JAILED}Extracting test-1:  done
146  post-install
147  "
148  	atf_check \
149  		-o inline:"${OUTPUT}" \
150  		-e inline:"${PROGNAME}: Missing dependency 'b'\n" \
151  		-s exit:0 \
152  		pkg add -M test-1.pkg
153  }
154  
155  add_quiet_body() {
156  	initialize_pkg
157  
158  	atf_check \
159  		-o inline:"pre-install\npost-install\n" \
160  		-e empty \
161  		pkg add -q ./test-1.pkg
162  }
163  
164  add_stdin_body() {
165  	initialize_pkg
166  
167  OUTPUT="${JAILED}Installing test-1...
168  pre-install
169  ${JAILED}Extracting test-1:  done
170  post-install
171  "
172  	cat test-1.pkg | atf_check \
173  		-o inline:"${OUTPUT}" \
174  		-e empty \
175  		pkg add -
176  }
177  
178  add_stdin_missing_body() {
179  	touch a
180  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg test test 1
181  	cat << EOF >> test.ucl
182  deps: {
183  	b: {
184  		origin: "wedontcare",
185  		version: "1"
186  	}
187  }
188  files: {
189  	${TMPDIR}/a: ""
190  }
191  scripts: {
192  	pre-install: <<EOD
193  echo "pre-install"
194  EOD
195  	post-install: <<EOD
196  echo "post-install"
197  EOD
198  }
199  EOF
200  
201  	atf_check \
202  		-o empty \
203  		-e empty \
204  		-s exit:0 \
205  		pkg create -M test.ucl
206  
207  	atf_check \
208  		-o inline:"${JAILED}Installing test-1...\n\nFailed to install the following 1 package(s): -\n" \
209  		-e inline:"${PROGNAME}: Missing dependency 'b'\n" \
210  		-s exit:1 \
211  		pkg add - < test-1.pkg
212  
213  OUTPUT="${JAILED}Installing test-1...
214  pre-install
215  ${JAILED}Extracting test-1:  done
216  post-install
217  "
218  	atf_check \
219  		-o inline:"${OUTPUT}" \
220  		-e inline:"${PROGNAME}: Missing dependency 'b'\n" \
221  		-s exit:0 \
222  		pkg add -M - < test-1.pkg
223  }
224  
225  add_no_version_body() {
226  	for p in test final ; do
227  		atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg ${p} ${p} 1
228  		if [ ${p} = "final" ]; then
229  			cat << EOF >> final.ucl
230  deps {
231  	test {
232  		origin = "test";
233  	}
234  }
235  EOF
236  		fi
237  		atf_check -o ignore -s exit:0 \
238  			pkg create -M ${p}.ucl
239  	done
240  	atf_check -o ignore -s exit:0 \
241  		pkg add final-1.pkg
242  }
243  
244  add_no_version_multi_body() {
245  	for p in test final ; do
246  		atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg ${p} ${p} 1
247  		if [ ${p} = "final" ]; then
248  			cat << EOF >> final.ucl
249  deps {
250  	test {
251  		origin = "test";
252  	},
253  	pkgnotfound {
254  		origin = "pkgnotfound";
255  	}
256  }
257  EOF
258  		fi
259  		atf_check -o ignore -s exit:0 \
260  			pkg create -M ${p}.ucl
261  	done
262  	atf_check -o ignore -e ignore -s exit:1 \
263  		pkg add final-1.pkg
264  }
265  
266  add_deps_multi_body() {
267  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg test test 2
268  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg final final 1
269  
270  	cat << EOF >> final.ucl
271  deps {
272  	test {
273  		origin = "test";
274  	},
275  }
276  EOF
277  	atf_check -o ignore -s exit:0 pkg create -M test.ucl
278  	atf_check -o ignore -s exit:0 pkg create -M final.ucl
279  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg test test 1
280  	atf_check -o ignore -s exit:0 pkg create -M test.ucl
281  	atf_check -o "match:.*test-2.*" -e empty -s exit:0 \
282  		pkg add final-1.pkg
283  }
284  
285  add_require_body() {
286  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg test test 1
287  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg final final 1
288  	cat << EOF >> final.ucl
289  requires: [functionA]
290  EOF
291  	cat << EOF >> test.ucl
292  provides: [functionA]
293  EOF
294  
295  	atf_check -o ignore -s exit:0 pkg create -M test.ucl
296  	atf_check  -s exit:0 pkg create -M final.ucl
297  	atf_check -o match:".*test-1.*" -e ignore -s exit:0 \
298  		pkg add final-1.pkg
299  }
300  
301  add_wrong_version_body() {
302  	for p in test final ; do
303  		atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg ${p} ${p} 1
304  		if [ ${p} = "final" ]; then
305  			cat << EOF >> final.ucl
306  deps {
307  	test {
308  		origin = "test";
309  		version = "2";
310  	}
311  }
312  EOF
313  		fi
314  		atf_check -o ignore -s exit:0 \
315  			pkg create -M ${p}.ucl
316  	done
317  	atf_check -o ignore -s exit:0 \
318  		pkg add final-1.pkg
319  }
320  
321  # Helper: create shared libraries for shlib tests.
322  # Creates libtest.so.1 (provider) and libconsumer.so.1 (requires libtest.so.1).
323  create_shlibs() {
324  	touch empty.c
325  	cc -shared -Wl,-soname=libtest.so.1 empty.c -o libtest.so.1
326  	ln -s libtest.so.1 libtest.so
327  	cc -shared -Wl,-soname=libconsumer.so.1 -Wl,--no-as-needed \
328  		empty.c -o libconsumer.so.1 -L. -ltest
329  }
330  
331  # Helper: set up the symlink directory layout for shlib tests.
332  # Creates real shared libs, packages in All/, and symlink dir.
333  setup_provider_layout() {
334  	atf_skip_on Darwin "The macOS linker uses different flags"
335  	atf_skip_on Linux "On linux (debian-like) the library are not on the scanned path for shlibs"
336  	mkdir -p All
337  	create_shlibs
338  
339  	# Provider package: contains libtest.so.1
340  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg provider provider 1 /usr/local
341  	cat << EOF >> provider.ucl
342  files: {
343  	$(pwd)/libtest.so.1: "",
344  }
345  EOF
346  	atf_check -o ignore -e empty -s exit:0 \
347  		pkg create -M provider.ucl
348  	mv provider-1.pkg All/
349  
350  	# Consumer package: contains libconsumer.so.1 (requires libtest.so.1)
351  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg consumer consumer 1 /usr/local
352  	cat << EOF >> consumer.ucl
353  files: {
354  	$(pwd)/libconsumer.so.1: "",
355  }
356  EOF
357  	atf_check -o ignore -e empty -s exit:0 \
358  		pkg create -M consumer.ucl
359  	mv consumer-1.pkg All/
360  
361  	# Set up symlink directory
362  	mkdir -p shlibs/libtest.so.1
363  	ln -s ../../All/provider-1.pkg shlibs/libtest.so.1/provider.pkg
364  }
365  
366  
367  add_shlib_provider_body() {
368  	setup_provider_layout
369  
370  	atf_check \
371  		-o match:"Installing provider-1" \
372  		-o match:"Installing consumer-1" \
373  		-e empty \
374  		-s exit:0 \
375  		pkg add $(pwd)/All/consumer-1.pkg
376  
377  	# Verify both packages are installed
378  	atf_check -o inline:"consumer\nprovider\n" -e empty -s exit:0 \
379  		pkg query -a "%n"
380  
381  	# Verify provider was installed as automatic
382  	atf_check -o inline:"1\n" -e empty -s exit:0 \
383  		pkg query "%a" provider
384  }
385  
386  
387  add_shlib_priority_body() {
388  	atf_skip_on Darwin "The macOS linker uses different flags"
389  	atf_skip_on Linux "On Linux (debian-like) the library are not on the scanned path for shlibs"
390  	mkdir -p All
391  	create_shlibs
392  
393  	# Create two provider packages (both provide libtest.so.1)
394  	for p in alpha bravo; do
395  		atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg ${p} ${p} 1 /usr/local
396  		cat << EOF >> ${p}.ucl
397  files: {
398  	$(pwd)/libtest.so.1: "",
399  }
400  EOF
401  		atf_check -o ignore -e empty -s exit:0 \
402  			pkg create -M ${p}.ucl
403  		mv ${p}-1.pkg All/
404  	done
405  
406  	# Consumer with libconsumer.so.1 (requires libtest.so.1)
407  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg consumer consumer 1 /usr/local
408  	cat << EOF >> consumer.ucl
409  files: {
410  	$(pwd)/libconsumer.so.1: "",
411  }
412  EOF
413  	atf_check -o ignore -e empty -s exit:0 \
414  		pkg create -M consumer.ucl
415  	mv consumer-1.pkg All/
416  
417  	# Symlink dir with priority prefixes: 00. = highest priority
418  	mkdir -p shlibs/libtest.so.1
419  	ln -s ../../All/bravo-1.pkg shlibs/libtest.so.1/00.bravo.pkg
420  	ln -s ../../All/alpha-1.pkg shlibs/libtest.so.1/01.alpha.pkg
421  
422  	# 00.bravo.pkg sorts first alphabetically → bravo wins
423  	atf_check \
424  		-o match:"Installing bravo-1" \
425  		-o match:"Installing consumer-1" \
426  		-o not-match:"Installing alpha-1" \
427  		-e empty \
428  		-s exit:0 \
429  		pkg add $(pwd)/All/consumer-1.pkg
430  }
431  
432  add_shlib_missing_body() {
433  	atf_skip_on Darwin "The macOS linker uses different flags"
434  	atf_skip_on Linux "On Linux (debian-like) the library are not on the scanned path for shlibs"
435  	mkdir -p All
436  	create_shlibs
437  
438  	# Consumer with libconsumer.so.1 (requires libtest.so.1)
439  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg consumer consumer 1 /usr/local
440  	cat << EOF >> consumer.ucl
441  files: {
442  	$(pwd)/libconsumer.so.1: "",
443  }
444  EOF
445  	atf_check -o ignore -e empty -s exit:0 \
446  		pkg create -M consumer.ucl
447  	mv consumer-1.pkg All/
448  
449  	# No shlibs/ directory at all → should fail
450  	atf_check \
451  		-o ignore \
452  		-e match:"Missing shlib libtest.so.1 required by consumer" \
453  		-s exit:1 \
454  		pkg add $(pwd)/All/consumer-1.pkg
455  }
456  
457  add_shlib_accept_missing_body() {
458  	atf_skip_on Darwin "The macOS linker uses different flags"
459  	atf_skip_on Linux "On Linux (debian-like) the library are not on the scanned path for shlibs"
460  	mkdir -p All
461  	create_shlibs
462  
463  	# Consumer with libconsumer.so.1 (requires libtest.so.1)
464  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg consumer consumer 1 /usr/local
465  	cat << EOF >> consumer.ucl
466  files: {
467  	$(pwd)/libconsumer.so.1: "",
468  }
469  EOF
470  	atf_check -o ignore -e empty -s exit:0 \
471  		pkg create -M consumer.ucl
472  	mv consumer-1.pkg All/
473  
474  	# With -M (accept missing), should succeed despite missing shlib
475  	atf_check \
476  		-o match:"Installing consumer-1" \
477  		-e match:"Missing shlib libtest.so.1 required by consumer" \
478  		-s exit:0 \
479  		pkg add -M $(pwd)/All/consumer-1.pkg
480  }
481  
482  add_shlib_already_installed_body() {
483  	setup_provider_layout
484  
485  	# Pre-install the provider
486  	atf_check \
487  		-o match:"Installing provider-1" \
488  		-e empty \
489  		-s exit:0 \
490  		pkg add $(pwd)/All/provider-1.pkg
491  
492  	# Now install the consumer; provider shlib is already satisfied
493  	# so provider should NOT be re-installed
494  	atf_check \
495  		-o match:"Installing consumer-1" \
496  		-o not-match:"Installing provider-1" \
497  		-e empty \
498  		-s exit:0 \
499  		pkg add $(pwd)/All/consumer-1.pkg
500  }
501  
502  add_provides_requires_body() {
503  	mkdir -p All
504  
505  	# Provider with abstract provides
506  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg myprovider myprovider 1 /usr/local
507  	cat << EOF >> myprovider.ucl
508  provides: [
509  	"vi-editor",
510  ]
511  EOF
512  	atf_check -o ignore -e empty -s exit:0 \
513  		pkg create -M myprovider.ucl
514  	mv myprovider-1.pkg All/
515  
516  	# Consumer with abstract requires
517  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg consumer consumer 1 /usr/local
518  	cat << EOF >> consumer.ucl
519  requires: [
520  	"vi-editor",
521  ]
522  EOF
523  	atf_check -o ignore -e empty -s exit:0 \
524  		pkg create -M consumer.ucl
525  	mv consumer-1.pkg All/
526  
527  	# Set up provides symlink directory
528  	mkdir -p provides/vi-editor
529  	ln -s ../../All/myprovider-1.pkg provides/vi-editor/myprovider.pkg
530  
531  	atf_check \
532  		-o match:"Installing myprovider-1" \
533  		-o match:"Installing consumer-1" \
534  		-e empty \
535  		-s exit:0 \
536  		pkg add $(pwd)/All/consumer-1.pkg
537  
538  	# Verify both installed
539  	atf_check -o inline:"consumer\nmyprovider\n" -e empty -s exit:0 \
540  		pkg query -a "%n"
541  }
542  
543  add_shlib_stdin_skip_body() {
544  	setup_provider_layout
545  
546  	# From stdin, shlib resolution should be skipped entirely
547  	# (no directory context to search), so it should succeed
548  	# without trying to resolve shlibs
549  	atf_check \
550  		-o match:"Installing consumer-1" \
551  		-e empty \
552  		-s exit:0 \
553  		pkg add - < All/consumer-1.pkg
554  }
555  
556  add_shlib_dead_symlink_body() {
557  	atf_skip_on Darwin "The macOS linker uses different flags"
558  	atf_skip_on Linux "On Linux (debian-like) the library are not on the scanned path for shlibs"
559  	mkdir -p All
560  	create_shlibs
561  
562  	# Provider package
563  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg provider provider 1 /usr/local
564  	cat << EOF >> provider.ucl
565  files: {
566  	$(pwd)/libtest.so.1: "",
567  }
568  EOF
569  	atf_check -o ignore -e empty -s exit:0 \
570  		pkg create -M provider.ucl
571  	mv provider-1.pkg All/
572  
573  	# Consumer package
574  	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg consumer consumer 1 /usr/local
575  	cat << EOF >> consumer.ucl
576  files: {
577  	$(pwd)/libconsumer.so.1: "",
578  }
579  EOF
580  	atf_check -o ignore -e empty -s exit:0 \
581  		pkg create -M consumer.ucl
582  	mv consumer-1.pkg All/
583  
584  	# Symlink dir with one dead symlink and one valid one
585  	mkdir -p shlibs/libtest.so.1
586  	ln -s ../../All/nonexistent-1.pkg shlibs/libtest.so.1/dead.pkg
587  	ln -s ../../All/provider-1.pkg shlibs/libtest.so.1/provider.pkg
588  
589  	# Dead symlink should be ignored, valid provider used
590  	atf_check \
591  		-o match:"Installing provider-1" \
592  		-o match:"Installing consumer-1" \
593  		-e empty \
594  		-s exit:0 \
595  		pkg add $(pwd)/All/consumer-1.pkg
596  }