# rpmmacro.at: test rpm macros # AT_BANNER([RPM macros]) AT_SETUP([macro path]) AT_KEYWORDS([macros]) RPMDB_INIT # .rpmmacros exists, new directory not RPMTEST_CHECK([[ rm -f ~/.config/rpm touch ~/.rpmmacros runroot rpm --showrc | awk '/^Macro path/{print(a[split($0,a,":")])}' ]], [0], [~/.rpmmacros ], []) # prefer new style if it exists RPMTEST_CHECK([[ mkdir -p ~/.config/rpm runroot rpm --showrc | awk '/^Macro path/{print(a[split($0,a,":")])}' ]], [0], [~/.config/rpm/macros ], []) # prefer new style if no config exists RPMTEST_CHECK([[ rm -f ~/.config/rpm/macros ~/.rpmmacros runroot --setenv XDG_CONFIG_HOME "~/.zzz" rpm --showrc | awk '/^Macro path/{print(a[split($0,a,":")])}' ]], [0], [~/.zzz/rpm/macros ], []) RPMTEST_CLEANUP # ------------------------------ AT_SETUP([macro path: skip editor backups]) AT_KEYWORDS([macros]) RPMTEST_SETUP RPMTEST_CHECK([ echo '%this that' > $RPMTEST/$RPM_CONFIGDIR_PATH/macros.d/macros.this runroot rpm --eval '%{this}' mv $RPMTEST/$RPM_CONFIGDIR_PATH/macros.d/macros.this{,~} runroot rpm --eval '%{this}' ], [0], [that %{this} ], []) RPMTEST_CLEANUP # ------------------------------ AT_SETUP([simple rpm --eval]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm --define "this that" --eval '%{this}' --eval '%not_defined' --eval '%{not_defined}' --eval '%{}' ], [0], [that %not_defined %{not_defined} %{} ]) # This behavior is relied on by countless specs and various rpm internals # too, and most likely can never be changed. RPMTEST_CHECK([ runroot rpm --eval '%{not_defined}' ], [0], [%{not_defined} ], []) RPMTEST_CLEANUP # ------------------------------ AT_SETUP([invalid rpm --eval]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm --eval '%define _ that' ], [1], [], [error: Macro %_ has illegal name (%define) ]) RPMTEST_CLEANUP # ------------------------------ AT_SETUP([invalid rpm --define]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm --define "_ that" runroot rpm --define "undefine that" ], [1], [], [error: Macro %_ has illegal name (%define) error: Macro %undefine is a built-in (%define) ]) RPMTEST_CLEANUP AT_SETUP([rpm --undefine]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm --define "this that" --eval '1. %{this}' --undefine 'this' --eval '2. %{this'} runroot rpm --eval '1. %{this}' --define "this that" --eval '2. %{this}' --undefine 'this' --eval '3. %{this'} ], [0], [1. that 2. %{this} 1. %{this} 2. that 3. %{this} ]) RPMTEST_CLEANUP AT_SETUP([simple true conditional rpm --eval]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm --define "this that" --eval '%{?this}' ], [0], [that ]) RPMTEST_CLEANUP AT_SETUP([simple false conditional rpm --eval]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm --define "this that" --eval '%{?that}' ], [0], [ ]) RPMTEST_CLEANUP AT_SETUP([nested macro in name]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm --define "this that" --define "that_that foo" --eval '%{expand:%{%{this}_that}}' ], [0], [foo ]) RPMTEST_CLEANUP AT_SETUP([recursive macro]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm --define 'aaa %aaa' --eval '%aaa' ], [1], [], [error: Too many levels of recursion in macro expansion. It is likely caused by recursive macro declaration. ]) RPMTEST_CLEANUP AT_SETUP([recursive expression]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm --define 'aaa %\\[%aaa\\]' --eval '%aaa' ], [1], [], [error: Too many levels of recursion in macro expansion. It is likely caused by recursive macro declaration. ]) RPMTEST_CLEANUP AT_SETUP([parametrized macro 1]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ RPMDB_INIT cat << EOF > ${RPMTEST}/mtest %bar() bar %foo()\\ %bar\\ foo 1\\ %{bar}\\ foo 2\\ %bar x\\ foo 3\\ %{bar x}\\ foo 4\\ %bar \\ foo 5 EOF runroot rpm --eval '%{load:/mtest}%{foo}' ], [0], [ bar foo 1 bar foo 2 bar foo 3 bar foo 4 bar foo 5 ], []) RPMTEST_CLEANUP AT_SETUP([parametrized macro 2]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --define '%bar() "Bar %#: %{?1} %{?2}"' \ --define '%foo() "Foo %#: %{?1} %{?2}" %bar a' \ --eval '%foo 1 2' ], [0], ["Foo 2: 1 2" "Bar 1: a " ]) RPMTEST_CLEANUP AT_SETUP([parametrized macro 3]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --define '%foo() 1:%1 2:%2' \ --eval '%foo %nil bar' ], [0], [1:bar 2:%2 ]) RPMTEST_CLEANUP AT_SETUP([parametrized macro 4]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --define '%bar yyy' \ --define '%foo() %1' \ --eval '%foo %bar' \ --eval '%foo %%bar' ], [0], [yyy %bar ]) RPMTEST_CLEANUP AT_SETUP([parametrized macro 5]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --define '%foo() %#:%{?1:"%1"}%{?2: "%2"}' \ --define 'bar zzz' \ --eval '%foo 1' \ --eval '%foo 2 ' \ --eval '%foo 1 2' \ --eval '%foo %{nil}' \ --eval '%foo %{nil} xx' \ --eval '%foo %{bar} xx' \ --eval '%foo %{quote: 2 3 5} %{quote:%{nil}}' \ --eval '%foo %{quote 1 2}' \ --eval '%foo x%{quote:y}z 123' \ --eval '%foo x%{quote:%{nil}}z' \ --eval '%foo 1 \ bar' \ --eval '%foo 1 \' \ ], [0], [1:"1" 1:"2" 2:"1" "2" 0: 1:"xx" 2:"zzz" "xx" 2:" 2 3 5" "" 2:"1" "2" 2:"xyz" "123" 1:"xz" 2:"1" "\"bar 2:"1" "\" ]) RPMTEST_CLEANUP AT_SETUP([parametrized macro 6]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --define '%foo(-) %{*}' \ --eval '%foo 5 a -z -b2' ], [0], [5 a -z -b2 ]) RPMTEST_CLEANUP AT_SETUP([parametrized macro 7]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --define '%foo(zb:) %{**}' \ --eval '%foo 5 a -z -b2' ], [0], [5 a -z -b2 ]) RPMTEST_CLEANUP AT_SETUP([parametrized macro 8]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --define 'foo(e:) %global bar %(/bin/echo %**)' \ --eval '%{foo arg}' \ --eval '%bar' ], [0], [ arg ]) RPMTEST_CLEANUP AT_SETUP([uncompress macro 1]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --define "__rpmuncompress /my/bin/rpmuncompress" \ --eval "%{uncompress:/data/SOURCES/hello-2.0.tar.gz}" ], [0], [/my/bin/rpmuncompress /data/SOURCES/hello-2.0.tar.gz ]) RPMTEST_CLEANUP AT_SETUP([uncompress 1]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ RPMDB_INIT runroot_other ${RPM_CONFIGDIR_PATH}/rpmuncompress /data/SOURCES/hello-2.0.tar.gz | tar t ], [0], [hello-2.0/ hello-2.0/COPYING hello-2.0/hello.spec hello-2.0/hello.c hello-2.0/Makefile hello-2.0/README hello-2.0/FAQ ]) RPMTEST_CLEANUP AT_SETUP([uncompress 2]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ RPMDB_INIT echo xxxxxxxxxxxxxxxxxxxxxxxxx > ${RPMTEST}/tmp/"some%%ath" runroot_other ${RPM_CONFIGDIR_PATH}/rpmuncompress "/tmp/some%%ath" ], [0], [xxxxxxxxxxxxxxxxxxxxxxxxx ]) RPMTEST_CLEANUP AT_SETUP([uncompress 3]) AT_KEYWORDS([macros rpmuncompress]) RPMDB_INIT RPMTEST_CHECK([ runroot_other ${RPM_CONFIGDIR_PATH}/rpmuncompress -x -C /tmp/test-1.2.3 /data/SOURCES/test-1.2.3.zip ], [0], []) RPMTEST_CHECK([ runroot_other ${RPM_CONFIGDIR_PATH}/rpmuncompress -x -C /tmp/test-1.2.3-7 /data/SOURCES/test-1.2.3.7z ], [0], []) RPMTEST_CHECK([ runroot_other find /tmp/test-1.2.3 | sort ], [0], [/tmp/test-1.2.3 /tmp/test-1.2.3/.gitignore /tmp/test-1.2.3/README.txt /tmp/test-1.2.3/src /tmp/test-1.2.3/src/README.txt ]) RPMTEST_CHECK([ runroot_other find /tmp/test-1.2.3-7 | sort ], [0], [/tmp/test-1.2.3-7 /tmp/test-1.2.3-7/.gitignore /tmp/test-1.2.3-7/README.txt /tmp/test-1.2.3-7/src /tmp/test-1.2.3-7/src/README.txt ]) RPMTEST_CLEANUP AT_SETUP([uncompress 4]) AT_KEYWORDS([macros rpmuncompress]) RPMDB_INIT RPMTEST_CHECK([ runroot_other mkdir -p /tmp/1 runroot_other --chdir /tmp/1 ${RPM_CONFIGDIR_PATH}/rpmuncompress -x /data/SOURCES/test-1.2.3.zip runroot_other --chdir /tmp/1 ${RPM_CONFIGDIR_PATH}/rpmuncompress -x /data/SOURCES/test-1.2.3.zip ], [0], [], [ignore]) RPMTEST_CHECK([ runroot_other --chdir /tmp/1 find . | sort ], [0], [. ./test-1.2.3-beta ./test-1.2.3-beta/.gitignore ./test-1.2.3-beta/README.txt ./test-1.2.3-beta/src ./test-1.2.3-beta/src/README.txt ], [ignore]) RPMTEST_CHECK([ runroot_other mkdir -p /tmp/2 runroot_other --chdir /tmp/2 ${RPM_CONFIGDIR_PATH}/rpmuncompress -x /data/SOURCES/test-1.2.3.7z runroot_other --chdir /tmp/2 ${RPM_CONFIGDIR_PATH}/rpmuncompress -x /data/SOURCES/test-1.2.3.7z ], [0], [], [ignore]) RPMTEST_CHECK([ runroot_other --chdir /tmp/2 find . | sort ], [0], [. ./test-1.2.3-beta ./test-1.2.3-beta/.gitignore ./test-1.2.3-beta/README.txt ./test-1.2.3-beta/src ./test-1.2.3-beta/src/README.txt ], [ignore]) RPMTEST_CLEANUP AT_SETUP([getncpus macro]) AT_KEYWORDS([macros]) # skip if nproc not available AT_SKIP_IF([test -z "$(nproc 2>/dev/null)"]) RPMTEST_CHECK([ mem=$(expr $(getconf PAGESIZE) \* $(getconf _PHYS_PAGES) / 1024 / 1024) expr $(runroot rpm --eval "%{getncpus}") = $(nproc) expr $(runroot rpm --define "_smp_tasksize_thread ${mem}" --eval "%{getncpus:thread}") = 1 expr $(runroot rpm --define "_smp_tasksize_proc ${mem}" --eval "%{getncpus:proc}") = 1 ], [ignore], [1 1 1 ], []) RPMTEST_CLEANUP AT_SETUP([basename macro]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --eval "%{basename:/data/SOURCES/hello-2.0.tar.gz}" ], [0], [hello-2.0.tar.gz ]) RPMTEST_CLEANUP AT_SETUP([shrink macro]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --eval "%{shrink: h e l lo }" ], [0], [h e l lo ]) RPMTEST_CLEANUP AT_SETUP([suffix macro]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --eval "%{suffix:/data/SOURCES/hello-2.0.tar.gz}" ], [0], [gz ]) RPMTEST_CLEANUP AT_SETUP([url2path macro]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --eval "%{url2path:http://hello.org/releases/hello-2.0.tar.gz}" ], [0], [/releases/hello-2.0.tar.gz ]) RPMTEST_CLEANUP AT_SETUP([macrobody macro]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --define "somedir %{_exec_prefix}/%{_lib}" \ --eval "%{macrobody:somedir}" runroot rpm \ --define "something somedir" \ --define "somedir %{_exec_prefix}/%{_lib}" \ --eval "%{macrobody:%{something}}" ], [0], [%{_exec_prefix}/%{_lib} %{_exec_prefix}/%{_lib} ]) RPMTEST_CLEANUP AT_SETUP([rpmversion macro]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm --eval "%{rpmversion}" ], [0], [AT_PACKAGE_VERSION ], []) RPMTEST_CLEANUP AT_SETUP([builtin macro arguments]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm --eval "%{dirname}" runroot rpm --eval "%{dirname:}" runroot rpm --eval "%{dirname:dir}" runroot rpm --eval "%{dirname dir}" runroot rpm --eval "%dirname" runroot rpm --eval "%dirname dir" runroot rpm --eval "%dirname /" runroot rpm --eval "%dirname ./" runroot rpm --eval "%dirname .." runroot rpm --eval "%dirname ../" runroot rpm --eval "%dirname ../foo" runroot rpm --eval "%dirname /foo" runroot rpm --eval "%dirname /foo/" runroot rpm --eval "%dirname /foo/foobar" runroot rpm --eval "%dirname /foo/foobar/" runroot rpm --eval "%basename /foo/foobar" runroot rpm --eval "%basename /foo/foobar/" runroot rpm --eval "%basename /" runroot rpm --eval "%basename foobar/" runroot rpm --eval "%basename foobar" runroot rpm --define '%xxx /hello/%%%%/world' --eval '%{dirname:%xxx}' runroot rpm --eval "%{uncompress}" runroot rpm --eval "%{uncompress:}" runroot rpm --eval "%{getconfdir:}" runroot rpm --eval "%{getconfdir:5}" runroot rpm --eval "%{define:}" runroot rpm --eval "%{define:foo}" runroot rpm --eval "%{define:foo bar}%{foo}" runroot rpm --eval "%{define foo}" runroot rpm --eval "%{define foo bar baz\baz}%{foo}" runroot rpm --eval "%{dump:foo}" runroot rpm --eval "%{shrink:%%%%}" runroot rpm --eval "%{shrink %%%%}" runroot rpm --eval "%shrink %%%%" runroot rpm --eval "%verbose foo" ], [0], [. . . . / . . . .. / / /foo /foo foobar foobar / foobar foobar /hello/%% bar bar baz\baz %% %% %% 0 foo ], [error: %dirname: argument expected error: %dirname: argument expected error: %uncompress: argument expected error: %getconfdir: unexpected argument error: %getconfdir: unexpected argument error: Macro % has illegal name (%define) error: Macro %foo has empty body error: Macro %foo has empty body error: %dump: unexpected argument ]) RPMTEST_CLEANUP AT_SETUP([macro arguments]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --define 'zzz xxx' \ --eval '%{defined zzz}' \ --eval '%{defined:zzz}' \ --eval '%defined zzz' \ --eval '%{defined aaa}' \ --eval '%{defined:aaa}' \ --eval '%defined aaa' ], [0], [1 1 1 0 0 0 ]) RPMTEST_CHECK([ runroot rpm \ --define 'zzz xxx' \ --eval '%zzz' \ --eval '%{zzz}' \ --eval '%{zzz:}' \ --eval '%{zzz }' \ --eval '%{zzz aa}' ], [0], [xxx xxx xxx xxx xxx ], [warning: unexpected argument to non-parametric macro %zzz warning: unexpected argument to non-parametric macro %zzz warning: unexpected argument to non-parametric macro %zzz ]) RPMTEST_CLEANUP AT_SETUP([string functions]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --eval "%sub cd6317ba61e6c27b92d6bbdf2702094ff3c0c732 1 7" \ --eval "%sub cd6317ba61e6c27b92d6bbdf2702094ff3c0c732 7 -7" \ --eval "%sub cd6317ba61e6c27b92d6bbdf2702094ff3c0c732 -7" \ --eval "%len cd6317ba61e6c27b92d6bbdf2702094ff3c0c732" \ --eval "%upper abba" \ --eval "%lower Beatles" \ --eval "%rep ai 2" \ --eval "%reverse live" \ --eval "%reverse a'b" \ --eval "%reverse a\"b" \ --eval "%gsub aaa a b 2" ], [0], [cd6317b ba61e6c27b92d6bbdf2702094ff3 3c0c732 40 ABBA beatles aiai evil b'a b"a bba ], []) RPMTEST_CLEANUP AT_SETUP([expr macro 1]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --define "aaa 5" \ --define "bbb 0" \ --eval '%{expr:4*1024}' \ --eval '%{expr:5 < 1}' \ --eval '%{expr:(4 + 5) * 2 == 18}' \ --eval '%{expr:%{aaa} || %{bbb}}' \ --eval '%{expr:%{aaa} && %{bbb}}' \ --eval '%{expr:! ""}' \ --eval '%{expr:! "foo"}' \ --eval '%{expr: 0 || 3}' \ --eval '%{expr: 2 || 3}' \ --eval '%{expr: "" || "foo"}' \ --eval '%{expr: "bar" || "foo"}' \ --eval '%{expr: 0 && 3}' \ --eval '%{expr: 2 && 3}' \ --eval '%{expr: "" && "foo"}' \ --eval '%{expr: "bar" && "foo"}' ], [0], [4096 0 1 5 0 1 0 3 2 foo bar 0 3 foo ], []) RPMTEST_CLEANUP AT_SETUP([expr macro 2]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm --eval '%{expr:"a"*1}' runroot rpm --eval '%{expr:(5+1)*4)}' runroot rpm --eval '%{expr:"a"=!"b"}' runroot rpm --eval '%{expr:4+}' runroot rpm --eval '%{expr:bare}' runroot rpm --eval '%{expr:1/0}' runroot rpm --eval '%{expr:0 < 1 ? 2 : 1*"a"}' runroot rpm --eval '%{expr:0 < 1 ? 1*"a" : 2}' runroot rpm --eval '%{expr:0 < 1 ? 2 : "a"}' runroot rpm --eval '%{expr:0 < 1 ? "a" : 2}' ], [1], [], [error: types must match: "a"*1 error: syntax error in expression: (5+1)*4) error: ^ error: syntax error while parsing ==: "a"=!"b" error: ^ error: unexpected end of expression: 4+ error: ^ error: bare words are no longer supported, please use "...": bare error: ^ error: division by zero: 1/0 error: ^ error: types must match: 0 < 1 ? 2 : 1*"a" error: types must match: 0 < 1 ? 1*"a" : 2 error: types must match: 0 < 1 ? 2 : "a" error: types must match: 0 < 1 ? "a" : 2 ]) RPMTEST_CLEANUP AT_SETUP([ternary expressions]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --eval '%{expr: 0 ? 2 : 3}' \ --eval '%{expr: 1 ? 2 : 3}' \ --eval '%{expr: 0 ? 0 ? 3 : 4 : 0 ? 6 : 7}' \ --eval '%{expr: 0 ? 0 ? 3 : 4 : 5 ? 6 : 7}' \ --eval '%{expr: 0 ? 2 ? 3 : 4 : 0 ? 6 : 7}' \ --eval '%{expr: 0 ? 2 ? 3 : 4 : 5 ? 6 : 7}' \ --eval '%{expr: 1 ? 0 ? 3 : 4 : 0 ? 6 : 7}' \ --eval '%{expr: 1 ? 0 ? 3 : 4 : 5 ? 6 : 7}' \ --eval '%{expr: 1 ? 2 ? 3 : 4 : 0 ? 6 : 7}' \ --eval '%{expr: 1 ? 2 ? 3 : 4 : 5 ? 6 : 7}' \ ], [0], [3 2 7 6 7 6 4 4 3 3 ], []) RPMTEST_CLEANUP AT_SETUP([expression macro level]) AT_KEYWORDS([macros]) RPMTEST_CHECK([[ runroot rpm \ --define 'expopt(r) %[%{undefined yyy} ? "aa " : "bb "]%{-r:the -r option was set}%{!-r:the -r option was not set}' \ --eval '%expopt' \ --eval '%expopt -r' \ --define 'yyy 1' \ --eval '%expopt' \ --eval '%expopt -r' ]], [0], [aa the -r option was not set aa the -r option was set bb the -r option was not set bb the -r option was set ], []) RPMTEST_CHECK([[ runroot rpm \ --define 'expopt(r) %{expr:%{undefined yyy} ? "aa " : "bb "}%{-r:the -r option was set}%{!-r:the -r option was not set}' \ --eval '%expopt' \ --eval '%expopt -r' \ --define 'yyy 1' \ --eval '%expopt' \ --eval '%expopt -r' ]], [0], [aa the -r option was not set aa the -r option was set bb the -r option was not set bb the -r option was set ], []) RPMTEST_CLEANUP AT_SETUP([short circuiting]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --eval '%{expr: 0 && 1 / 0}' \ --eval '%{expr: 1 || 1 / 0}' \ --eval '%{expr: 1 ? 2 : 1 / 0}' \ ], [0], [0 1 2 ], []) RPMTEST_CLEANUP AT_SETUP([shell expansion]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --eval "%(echo foo)" ], [0], [foo ]) RPMTEST_CLEANUP AT_SETUP([expression expansion 1]) AT_KEYWORDS([macros]) RPMTEST_CHECK([[ runroot rpm \ --define "aaa 5" \ --define "bbb 0" \ --eval '%[4*1024]' \ --eval '%[5 < 1]' \ --eval '%[%aaa]' \ --eval '%[%{aaa}]' \ --eval '%["%{aaa}"]' \ --eval '%[%{?ccc}]' \ --eval '%[v"1:2.3-4"]' \ --eval '%[v"0" && v"0"]' \ ]], [0], [4096 0 5 5 5 0 1:2.3-4 0 ], []) RPMTEST_CLEANUP AT_SETUP([expression expansion 2]) AT_KEYWORDS([macros]) RPMTEST_CHECK([[ runroot rpm --define "aaa hello" --eval '%[%aaa]' runroot rpm --eval '%[%{foo]' runroot rpm --eval '%[v""]' runroot rpm --eval '%[v"1" + v"2"]' runroot rpm --eval '%[v"1" / v"2"]' ]], [1], [], [error: macro expansion returned a bare word, please use "...": %aaa error: ^ error: expanded string: hello error: Unterminated {: {foo error: invalid version: v"" error: ^ error: + and - not supported for versions: v"1" + v"2" error: ^ error: * and / not supported for versions: v"1" / v"2" error: ^ ]) RPMTEST_CLEANUP AT_SETUP([expression version comparison]) AT_KEYWORDS([macros]) RPMTEST_CHECK([[ runroot rpm \ --eval '%[v"1.0" == v"1.0"]' \ --eval '%[v"1.0~rc" < v"1.0"]' \ --eval '%[v"1.0~rc" > v"1.0"]' \ --eval '%[v"1.0-rc" > v"1.0"]' \ ]], [0], [1 1 0 1 ], []) RPMTEST_CLEANUP AT_SETUP([simple lua --eval]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([ runroot rpm --eval '%{lua:print(5*5)}' ], [0], [25 ]) RPMTEST_CLEANUP AT_SETUP([lua glob]) RPMTEST_CHECK([ RPMDB_INIT runroot_other mkdir -p aaa/{123,223,323,322,321} runroot rpm --eval "%{lua:for i,p in ipairs(rpm.glob('aaa/3*')) do print(p..'\\n') end}" runroot rpm --eval "%{lua:for i,p in ipairs(rpm.glob('aaa/b*', 'c')) do print(p..'\\n') end}" ], [0], [aaa/321 aaa/322 aaa/323 aaa/b* ], []) RPMTEST_CLEANUP AT_SETUP([lua macro arguments]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([[ runroot rpm \ --define "foo(a:) %{lua:print(opt.a, arg[1])}" \ --define "bar() %{lua:print(rpm.expand('%foo -a'..arg[2]..' '..arg[1]))}" \ --eval '%bar 5 3' ]], [0], [3 5 ]) RPMTEST_CLEANUP AT_SETUP([lua macros table]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([[ runroot rpm \ --define "qtst() %{lua:for i=1, #arg do print(' '..i..':'..arg[i]) end}"\ --eval "%{lua:print(macros.with('zap'), macros.without('zap'))}" \ --eval "%{lua:print(macros.aaa)}" \ --eval "%{lua:macros.aaa='bbb'; macros['yyy']='zzz'}" \ --eval "%{lua:print(macros['aaa'], macros.yyy)}" \ --eval "%{lua:macros.aaa=nil"} \ --eval "%{lua:print(macros.aaa)}" \ --eval "%{lua:print(macros.qtst('a c'))}" \ --eval "%{lua:print(macros.qtst({'a', '', 'c'}))}" \ --eval "%{lua:print(macros.qtst('%{?aaa} %{yyy}'))}" \ --eval "%{lua:print(macros.qtst({'%{?aaa}', '%{yyy}'}))}" \ --eval "%{lua:macros.define({'this', 'that'}); print(macros.this)}" ]], [0], [0 1 nil bbb zzz nil 1:a 2:c 1:a 2: 3:c 1:zzz 1:%{?aaa} 2:%{yyy} that ]) RPMTEST_CHECK([[ runroot rpm \ --eval "%{lua:macros.defined({1,2,{}})}" ]], [1], [], [[error: lua script failed: [string ""]:1: bad argument #3 to 'defined' (cannot convert to string) ]]) RPMTEST_CLEANUP AT_SETUP([lua macros recursion]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([[ runroot rpm \ --define "%recurse() %{lua:io.write(' '..#arg); if #arg < 16 then table.insert(arg, #arg); macros.recurse(arg) end;}" \ --eval "%recurse" ]], [0], [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ]) RPMTEST_CLEANUP AT_SETUP([lua rpm extensions 1]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([ runroot rpm --eval '%{lua: rpm.define("foo bar") print(rpm.expand("%{foo}"))}' ], [0], [bar ]) RPMTEST_CLEANUP AT_SETUP([lua rpm extensions 2]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([ runroot rpm --eval '%{lua: print(rpm.vercmp("1.0", "2.0"))}' ], [0], [-1 ]) RPMTEST_CLEANUP AT_SETUP([lua rpm isdefined]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([ runroot rpm \ --eval '%{lua: print(rpm.isdefined("with"))}' \ --eval '%{lua: print(rpm.isdefined("nil"))}' \ --eval '%{lua: print(rpm.isdefined("ponies"))}' ], [0], [true true true false false false ]) RPMTEST_CLEANUP AT_SETUP([lua rpm split/unsplitargs]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([[ runroot rpm \ --eval '%{lua: local a=rpm.splitargs("1 2 3");a[2]=" " .. a[2] .. " ";print(rpm.unsplitargs(a))}' \ | tr '\037' : ]], [0], [:1: : 2 : :3: ]) RPMTEST_CLEANUP AT_SETUP([lua posix extensions]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([ runroot rpm \ --eval '%{lua: posix.putenv("LUATEST=ok") print(posix.getenv("LUATEST"))}' ], [0], [ok ]) RPMTEST_CLEANUP AT_SETUP([lua script exit behavior]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([ runroot rpm \ --eval '%{lua: os.exit()}))}' ], [1], [], [error: lua script failed: [[string ""]]:1: exit not permitted in this context] ) RPMTEST_CLEANUP AT_SETUP([lua script redirect2null]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([ runroot rpm \ --eval '%{lua: posix.redirect2null()}))}' ], [1], [], [warning: rpm.redirect2null(): .fork(), .exec(), .wait() and .redirect2null() are deprecated, use rpm.spawn() or rpm.execute() instead error: lua script failed: [[string ""]]:1: redirect2null not permitted in this context] ) RPMTEST_CLEANUP AT_SETUP([lua library path]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([ RPMDB_INIT f=$(run rpm --eval "%{_rpmconfigdir}/lua/foo.lua") echo "bar = 'graak'" > ${RPMTEST}/${f} runroot rpm \ --eval '%{lua:require "foo"; print(bar)}' rm -f ${RPMTEST}/${f} ], [0], [graak ]) RPMTEST_CLEANUP AT_SETUP([lua auto-print]) AT_KEYWORDS([macros lua]) RPMDB_INIT RPMTEST_CHECK([[ runroot rpm \ --define 'foo() %{lua:return string.reverse(arg[1])}' \ --eval '%foo hello' \ --eval '%{lua:return 1, 2, 3}' ]], [0], [olleh 1 2 3 ]) RPMTEST_CLEANUP AT_SETUP([lua rpm version objects]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([ runroot rpm \ --eval '%{lua: v1 = rpm.ver("1:4.16-5"); print(v1, v1.e, v1.v, v1.r)}' \ --eval '%{lua: v1 = rpm.ver("4.16-1"); print(v1, v1.e, v1.v, v1.r)}' \ --eval '%{lua: v1 = rpm.ver("4.16"); print(v1, v1.e, v1.v, v1.r)}' \ --eval '%{lua: v1 = rpm.ver("1:4.16-5"); v2 = rpm.ver("4.4-1"); print(v1 < v2, v1 == v2, v1 > v2, v1 == v1)}' ], [0], [1:4.16-5 1 4.16 5 4.16-1 nil 4.16 1 4.16 nil 4.16 nil false false true true ]) RPMTEST_CLEANUP AT_SETUP([lua rpm io stream]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([ RPMDB_INIT runroot rpm \ --eval '%{lua: local f = rpm.open("zzz", "w+"); f:write("gggg"); print(f:seek("cur")); f:close()}' \ --eval '%{lua: local f = rpm.open("zzz"); print(f:read()); f:close()}' \ --eval '%{lua: local f = rpm.open("/data/SOURCES/hello-2.0.tar.gz"); f:reopen("r.gzip"); f:seek("cur", 6); print(f:read(3)); f:close()}' ], [0], [4 gggg 2.0 ]) RPMTEST_CLEANUP AT_SETUP([lua functions in expressions]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([[ runroot rpm \ --eval '%[lua:string.reverse("hello")]' ]], [0], [olleh ]) RPMTEST_CLEANUP AT_SETUP([lua hooks]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([[ runroot rpm \ --eval '%{lua: function regtest(n) for _,v in ipairs(n) do print(" "..type(v)..":"..v);end;end local h = rpm.register("test", regtest) rpm.call("test", "foo", 6, 29 / 4) rpm.unregister("test", h) rpm.call("test", "foo", 6, 29 / 4) }' ]], [0], [ string:foo number:6 number:7.25 ]) RPMTEST_CLEANUP AT_SETUP([%define + %undefine in nested levels 1]) AT_KEYWORDS([macros define undefine]) RPMTEST_CHECK([ # basic %define in nested scoping level runroot rpm \ --define '%foo() %{expand:%define xxx 1} %{echo:%xxx} %{expand:%undefine xxx} %{echo:%xxx}' \ --eval .'%foo'. ], [0], [1 %xxx . . ]) RPMTEST_CLEANUP AT_SETUP([%define + %undefine in nested levels 2]) AT_KEYWORDS([macros define]) RPMTEST_CHECK([ # %define macro once in a nested scope runroot rpm \ --define '%foo() %{expand:%define xxx 1} %{echo:%xxx}' \ --eval .'%foo'. \ --eval '%xxx' ], [0], [1 . . %xxx ]) RPMTEST_CLEANUP AT_SETUP([%define + %undefine in nested levels 3]) AT_KEYWORDS([macros define]) RPMTEST_CHECK([ # %define macro twice in a nested scope runroot rpm \ --define '%foo() %{expand:%define xxx 1} %{echo:%xxx} %{expand: %define xxx 2} %{echo:%xxx}' \ --eval .'%foo'. \ --eval '%xxx' ], [0], [1 2 . . %xxx ]) RPMTEST_CHECK([ runroot rpm --define "aa 0" --define "my() %{define:aa 1}%{define:aa 2}" --eval "%my" --eval "%aa" ], [0], [ 0 ], [ignore]) RPMTEST_CLEANUP AT_SETUP([%define + %undefine in nested levels 4]) AT_KEYWORDS([macros define global]) RPMTEST_CHECK([ AT_XFAIL_IF([test $RPM_XFAIL -ne 0]) # %define in a nested level covered by %global runroot rpm \ --define '%foo() %{expand:%define xxx 1} %{echo:%xxx} %{expand: %global xxx 2} %{echo:%xxx}' \ --eval .'%foo'. \ --eval '%xxx' \ --eval '%undefine xxx' \ --eval '%xxx' ], [0], [1 2 . . 2 %xxx ]) RPMTEST_CLEANUP AT_SETUP([%define in conditional macro]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --define 'dofoo() true'\ --eval '.%{!?foo: %define foo bar}.'\ --eval '%foo' \ --eval '%dofoo'\ --eval '%foo' ], [0], [. . bar true bar ]) RPMTEST_CLEANUP AT_SETUP([%verbose macro]) AT_KEYWORDS([macros verbose]) RPMTEST_CHECK([ runroot rpm --eval '%{verbose}' runroot rpm -v --eval '%{verbose}' runroot rpm --eval '%{verbose:zzz}' runroot rpm -v --eval '%{verbose:zzz}' ], [0], [0 1 zzz ]) RPMTEST_CLEANUP AT_SETUP([%exists macro]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --eval "%{exists:/data}" \ --eval "%{exists:/zzz}" \ --eval "%{exists}" ], [1], [1 0 ], [error: %exists: argument expected ]) RPMTEST_CLEANUP AT_SETUP([%shescape macro]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --eval "%{shescape:foo's}" ], [0], ['foo'\''s' ], []) RPMTEST_CLEANUP AT_SETUP([%shescape macro with multiple arguments]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --eval "%{shescape foo bar's}" ], [0], ['foo' 'bar'\''s' ], []) RPMTEST_CLEANUP AT_SETUP([macro with a line starting by "{"]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm --macros "/data/macros.testfile" \ --eval "%first" --eval "%second"], [0], [macro_1 macro_2 ]) RPMTEST_CLEANUP AT_SETUP([macro with %if-%endif]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpmspec -q --qf "%{summary}\n%{description}\n" /data/SPECS/iftest.spec ], [0], [macro 1 ccc0 ccc1 ]) RPMTEST_CLEANUP AT_SETUP([macro file errors]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ cat << EOF > macros.bad %1 foo %multi \\ line\\ thing %foo bar %bad-name 123 EOF run rpm --macros "macros.bad" --eval "%foo" ], [0], [bar ], [error: macros.bad: line 1: Macro %1 has illegal name (%define) warning: macros.bad: line 8: Macro %bad needs whitespace before body ]) RPMTEST_CLEANUP AT_SETUP([macro comments]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --macros /data/macros.testfile \ --eval "%{comment1}" \ --eval "%{comment2}" ], [0], [ read me see this ], []) RPMTEST_CLEANUP AT_SETUP([macro comments 2]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --macros /data/macros.testfile \ --eval "%{comment3}" ], [0], [ read ' change this meaning ], []) RPMTEST_CLEANUP AT_SETUP([macro file empty lines]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm \ --macros /data/macros.testfile \ --eval "%{empty0}" ], [0], [ some thing ], []) RPMTEST_CLEANUP AT_SETUP([macro traceback]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ for o in "-v" ""; do runroot rpm $o \ --define "err %{error:bad}" \ --define "bar %err" \ --define "foo %bar zz" \ --eval "xxx%{foo}yyy" done ], [1], [], [error: bad 3< (%error) 2< (%err) 1< (%bar) 0< (%foo) xxx error: bad ]) RPMTEST_CLEANUP AT_SETUP([error macro return]) AT_KEYWORDS([macros lua]) RPMTEST_CHECK([ runroot rpm --eval '%{error:fail}' ], [1], [], [error: fail ]) RPMTEST_CHECK([ runroot rpm --eval '%{lua:rpm.expand("%{error:fail}")}' ], [1], [], [[error: fail error: lua script failed: [string ""]:1: error expanding macro ]]) RPMTEST_CHECK([ runroot rpm --eval '%{lua:macros.error({"fail"})}' ], [1], [], [[error: fail error: lua script failed: [string ""]:1: error expanding macro ]]) RPMTEST_CLEANUP AT_SETUP([no space left on stdout]) AT_KEYWORDS([macros]) RPMTEST_CHECK([ runroot rpm --eval 1 >/dev/full ], [1], [], [Error writing to stdout: No space left on device ]) RPMTEST_CLEANUP AT_SETUP([rpmlua]) AT_KEYWORDS([lua]) RPMTEST_SETUP RPMTEST_CHECK([ runroot_other rpmlua /data/t1.lua a b ], [0], [hello world opts: args: /data/t1.lua a b ], []) RPMTEST_CHECK([ runroot_other rpmlua --opts=ot: /data/t1.lua -- -t1 a ], [0], [hello world opts: t 1 args: a ], []) RPMTEST_CHECK([ runroot_other rpmlua -e "print(macros.basename('/some/thing'))" ], [0], [thing ], []) RPMTEST_CHECK([ runroot_other rpmlua -e "for i, v in ipairs({'true', 'false', 'grue'}) do print(rpm.execute('/bin/'..v)) end" ], [0], [0.0 nil exit code 1.0 nil No such file or directory 2.0 ], []) RPMTEST_CHECK([ runroot_other rpmlua -e 'pid = posix.fork(); if pid == 0 then a,b,c=rpm.redirect2null(-1); print(string.format("%s\t%s\t%s", a,b,c)); io.flush() else posix.wait(pid) end' ], [0], [nil Bad file descriptor 9.0 ], [stderr]) # stderr output from the above is flaky due to the fork, post-processing # ought to be more reliable RPMTEST_CHECK([ cat stderr | sort ], [0], [warning: posix.fork(): .fork(), .exec(), .wait() and .redirect2null() are deprecated, use rpm.spawn() or rpm.execute() instead warning: posix.wait(): .fork(), .exec(), .wait() and .redirect2null() are deprecated, use rpm.spawn() or rpm.execute() instead warning: rpm.redirect2null(): .fork(), .exec(), .wait() and .redirect2null() are deprecated, use rpm.spawn() or rpm.execute() instead warning: runaway fork() in Lua script ], []) RPMTEST_CLEANUP AT_SETUP([lua rpm spawn]) AT_KEYWORDS([macros lua]) RPMDB_INIT RPMTEST_CHECK([ runroot_other rpmlua -e "rpm.spawn({'echo', '1', '2', '3'})" ], [0], [1 2 3 ], []) RPMTEST_CHECK([ runroot_other rpmlua \ -e "rpm.spawn({'echo', '1', '2', '3'}, {stdout='/dev/null'})" ], [0], [], []) RPMTEST_CHECK([ runroot_other rpmlua \ -e "rpm.spawn({'ls', '/notthere'})" ], [0], [], [ls: cannot access '/notthere': No such file or directory ]) RPMTEST_CHECK([ runroot_other rpmlua \ -e "rpm.spawn({'ls', '/notthere'}, {stderr='/dev/null'})" ], [0], [], []) RPMTEST_CHECK([ runroot_other rpmlua \ -e "rpm.spawn({'ls', '/notthere'}, {garbage='bbb'})" ], [255], [], [[error: lua script failed: [string ""]:1: invalid spawn directive: garbage ]]) RPMTEST_CHECK([ runroot_other rpmlua -e "rpm.spawn('echo', '1', '2', '3')" ], [255], [], [[error: lua script failed: [string ""]:1: bad argument #1 to 'spawn' (table expected, got string) ]]) RPMTEST_CHECK([ runroot_other rpmlua -e "print(rpm.spawn({'cat'}, {stdin='aaa'}))" ], [0], [nil No such file or directory 2.0 ], []) RPMTEST_CHECK([ echo 1 2 3 > ${RPMTEST}/aaa runroot_other rpmlua -e "rpm.spawn({'cat'}, {stdin='aaa'})" ], [0], [1 2 3 ], []) RPMTEST_CLEANUP AT_SETUP([rpmlua hooks]) AT_KEYWORDS([lua]) RPMTEST_CHECK([ run rpm --load /data/macros.hooks \ --eval "%hook_this" ], [0], [1: string(whee) 2: number(3) 3: userdata(userdata: (nil)) 4: number(1.2) ], []) RPMTEST_CLEANUP