Many improvements in the V testsuite (#15722) ##test

* Kill some more tests using <<RUN
* Improve r2r.v quite a lot up to 0.2
* Delete stale temporal files in the unit test
* Use executable path instead of dbpath and more cleanup
* Move manpage and move old bins into the attic
This commit is contained in:
radare 2019-12-29 19:26:15 +01:00 committed by GitHub
parent bac525d8e9
commit 2b15e7421e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 443 additions and 217 deletions

View File

@ -1,18 +1,17 @@
#!/bin/sh
if test -z "${R2_MASTER}"; then
R2_MASTER=~/radare2/
fi
[ -z "${R2_MASTER}" ] && R2_MASTER="${PWD}/.."
COPIES=~/prg/r2-v
if ! test -d "${R2_MASTER}"; then
if ! test -d "${R2_MASTER}"; then
echo "Cannot find master copy of r2 at R2_MASTER=${R2_MASTER}"
exit 1
fi
if ! mkdir -p "${COPIES}"; then
echo "Cannot create COPIES=${COPIES}"
exit 1
echo "Cannot create COPIES=${COPIES}"
exit 1
fi
echo "Using R2_MASTER ${R2_MASTER}"
@ -20,17 +19,17 @@ echo "Using COPIES ${COPIES}"
Fail() {
printf "%s" "$1\n"
exit 1
printf "%s" "$1\n"
exit 1
}
Head() {
cd ${R2_MASTER} || Fail "cannot chdir to ${R2_MASTER}"
cd ${R2_MASTER} || Fail "cannot chdir to ${R2_MASTER}"
git rev-list HEAD | head -n1
}
Next() {
cd ${R2_MASTER} || Fail "cannot chdir to ${R2_MASTER}"
cd ${R2_MASTER} || Fail "cannot chdir to ${R2_MASTER}"
git rev-list HEAD | grep -C 1 $1 |head -n1
}
@ -88,7 +87,7 @@ init)
Clone `Head`
;;
log)
cd ${R2_MASTER} || Fail "cannot chdir to ${R2_MASTER}"
cd ${R2_MASTER} || Fail "cannot chdir to ${R2_MASTER}"
cur=`Cur`
for a in `git rev-list HEAD` ; do
NOTE=`cat ${COPIES}/radare2-${a}.note 2>/dev/null`
@ -147,7 +146,7 @@ note)
Note $2 $3
;;
diff)
cd ${R2_MASTER} || Fail "cannot chdir to ${R2_MASTER}"
cd ${R2_MASTER} || Fail "cannot chdir to ${R2_MASTER}"
git diff `Cur`^..`Cur`
;;
use)

View File

@ -1,19 +1,17 @@
VERSION=3.4.0
DESTDIR?=/
PREFIX?=/usr/local
BINDIR=$(DESTDIR)/$(PREFIX)/bin
PWD=$(shell pwd)
PKG=radare2-regressions
TAR=tar -cvf
TAREXT=tar.xz
CZ=xz -f
CWD=$(shell pwd)
TDIRS=$(shell ls -d t*| grep -v tmp) bins
LIBDIR=$(DESTDIR)/$(PREFIX)/lib
-include config.mk
all: js-tests unit_tests
all: js-tests unit_tests src/r2r
src/r2r:
$(MAKE) -C src
bins:
git clone --depth 1 https://github.com/radareorg/radare2-testbins bins
@ -23,41 +21,35 @@ fuzz/targets:
R2R=$(shell cd new ; npm bin)/r2r
RUNTEST=cd new && npm install ; $(R2R)
js-tests: bins
cd new && npm install
cd new && $(R2R)
${RUNTEST}
keystone: bins
cd new && npm install
cd new && $(R2R) db/extras/asm/x86.ks_
${RUNTEST} db/extras/asm/x86.ks_
swf: bins
cd new && npm install
cd new && $(R2R) db/extras/asm/swf
${RUNTEST} db/extras/asm/swf
m68k-extras: bins
cd new && npm install
cd new && $(R2R) db/extras/asm/m68k
${RUNTEST} db/extras/asm/m68k
mc6809: bins
cd new && npm install
cd new && $(R2R) db/extras/asm/x86.udis
${RUNTEST} db/extras/asm/x86.udis
microblaze: bins
cd new && npm install
cd new && $(R2R) db/extras/asm/microblaze.gnu
${RUNTEST} db/extras/asm/microblaze.gnu
udis86: bins
cd new && npm install
cd new && $(R2R) db/extras/asm/mc6809
${RUNTEST} db/extras/asm/mc6809
olly-extras: bins
cd new && npm install
cd new && $(R2R) db/extras/asm/x86.olly
${RUNTEST} db/extras/asm/x86.olly
dwarf: bins
cd new && npm install
cd new && $(R2R) db/extras/asm/dwarf
${RUNTEST} db/extras/asm/dwarf
broken:
grep BROKEN=1 t -r -l
@ -66,15 +58,11 @@ clean:
symstall:
mkdir -p $(BINDIR)
chmod +x r2-v r2r
ln -fs $(PWD)/r2-v $(BINDIR)/r2-v
ln -fs $(PWD)/r2r $(BINDIR)/r2r
ln -fs $(CWD)/r2r $(BINDIR)/r2r
install:
mkdir -p $(BINDIR)
sed -e 's,@R2RDIR@,$(LIBDIR)/radare2-regressions,g' < $(PWD)/r2-v > $(BINDIR)/r2-v
sed -e 's,@R2RDIR@,$(LIBDIR)/radare2-regressions,g' < $(PWD)/r2r > $(BINDIR)/r2r
chmod +x $(BINDIR)/r2-v
sed -e 's,@R2RDIR@,$(LIBDIR)/radare2-regressions,g' < $(CWD)/r2r > $(BINDIR)/r2r
chmod +x $(BINDIR)/r2r
mkdir -p $(LIBDIR)/radare2-regressions
cp -rf $(TDIRS) $(LIBDIR)/radare2-regressions
@ -101,10 +89,4 @@ untested: bins
allbins: bins
find bins -type f
dist:
git clone . $(PKG)-$(VERSION)
rm -rf $(PKG)-$(VERSION)/.git
$(TAR) "$(PKG)-${VERSION}.tar" "$(PKG)-$(VERSION)"
${CZ} "$(PKG)-${VERSION}.tar"
.PHONY: all clean allbins dist
.PHONY: all clean allbins

View File

@ -8,6 +8,7 @@ Originally based on work by and now in collaboration with pancake.
Directory Hierarchy
-------------------
* src/: SuperDuper new testsuite written in V.
* new/: New testsuite written in NodeJS.
* unit/: Unit tests (written in C, using minunit).
* bins/: Sample binaries.
@ -119,12 +120,11 @@ Example commands tests for the other `new/` folders:
You must end the test by adding RUN keyword
Advices
------------------
-------
* Never use shell pipes, use `~`
* For portability reasons Do not use shell pipes, use `~`
* dont use `pd` if not necessary, use `pi`
License
-------

View File

@ -1,34 +0,0 @@
#!/bin/sh
[ "$1" = git ] && shift
[ "$1" = pull ] && shift
RR=$1
RB=$2
N=$3
if ! git diff --exit-code >/dev/null 2>&1; then
echo "ERROR: There are local changes that must be commited or reseted"
echo "ERROR: Cherrypulling process stopped to avoid data loss."
exit 1
fi
if test -z "$N"; then
echo "Usage: sys/cherrypull.sh [url] [branch] [ncommits]"
exit 1
fi
git branch -D branch
git checkout -b branch
git reset --hard @~100
git pull $RR $RB
C=`git log | grep ^commit | head -n $N | cut -d ' ' -f2`
RC=""
git checkout master
for a in $C ; do
RC="$a $RC"
done
for a in $RC ; do
git cherry-pick $a
done
git branch -D branch

View File

@ -2703,7 +2703,7 @@ NAME=iSS (file x86)
FILE=../bins/elf/analysis/x86-helloworld-gcc
CMDS=<<EXPECT
iSS
EXPECT=<<RUN
EXPECT=<<EOF
[Segments]
nth paddr size vaddr vsize perm name
@ -2718,28 +2718,31 @@ nth paddr size vaddr vsize perm name
7 0x00000000 0x0 0x00000000 0x0 -rw- GNU_STACK
8 0x00000000 0x34 0x08048000 0x34 -rw- ehdr
EOF
RUN
NAME=iSj
FILE=../bins/elf/analysis/x86-helloworld-gcc
CMDS=<<EXPECT
iSj
EXPECT=<<RUN
EXPECT=<<EOF
[{"name":"","size":0,"vsize":0,"perm":"----","paddr":0,"vaddr":0},{"name":".interp","size":19,"vsize":19,"perm":"-r--","paddr":308,"vaddr":134512948},{"name":".note.ABI_tag","size":32,"vsize":32,"perm":"-r--","paddr":328,"vaddr":134512968},{"name":".note.gnu.build_id","size":36,"vsize":36,"perm":"-r--","paddr":360,"vaddr":134513000},{"name":".gnu.hash","size":32,"vsize":32,"perm":"-r--","paddr":396,"vaddr":134513036},{"name":".dynsym","size":80,"vsize":80,"perm":"-r--","paddr":428,"vaddr":134513068},{"name":".dynstr","size":74,"vsize":74,"perm":"-r--","paddr":508,"vaddr":134513148},{"name":".gnu.version","size":10,"vsize":10,"perm":"-r--","paddr":582,"vaddr":134513222},{"name":".gnu.version_r","size":32,"vsize":32,"perm":"-r--","paddr":592,"vaddr":134513232},{"name":".rel.dyn","size":8,"vsize":8,"perm":"-r--","paddr":624,"vaddr":134513264},{"name":".rel.plt","size":24,"vsize":24,"perm":"-r--","paddr":632,"vaddr":134513272},{"name":".init","size":35,"vsize":35,"perm":"-r-x","paddr":656,"vaddr":134513296},{"name":".plt","size":64,"vsize":64,"perm":"-r-x","paddr":704,"vaddr":134513344},{"name":".text","size":404,"vsize":404,"perm":"-r-x","paddr":768,"vaddr":134513408},{"name":".fini","size":20,"vsize":20,"perm":"-r-x","paddr":1172,"vaddr":134513812},{"name":".rodata","size":21,"vsize":21,"perm":"-r--","paddr":1192,"vaddr":134513832},{"name":".eh_frame_hdr","size":44,"vsize":44,"perm":"-r--","paddr":1216,"vaddr":134513856},{"name":".eh_frame","size":176,"vsize":176,"perm":"-r--","paddr":1260,"vaddr":134513900},{"name":".init_array","size":4,"vsize":4,"perm":"-rw-","paddr":1436,"vaddr":134518172},{"name":".fini_array","size":4,"vsize":4,"perm":"-rw-","paddr":1440,"vaddr":134518176},{"name":".jcr","size":4,"vsize":4,"perm":"-rw-","paddr":1444,"vaddr":134518180},{"name":".dynamic","size":232,"vsize":232,"perm":"-rw-","paddr":1448,"vaddr":134518184},{"name":".got","size":4,"vsize":4,"perm":"-rw-","paddr":1680,"vaddr":134518416},{"name":".got.plt","size":24,"vsize":24,"perm":"-rw-","paddr":1684,"vaddr":134518420},{"name":".data","size":8,"vsize":8,"perm":"-rw-","paddr":1708,"vaddr":134518444},{"name":".bss","size":0,"vsize":4,"perm":"-rw-","paddr":1716,"vaddr":134518452},{"name":".comment","size":17,"vsize":17,"perm":"----","paddr":1716,"vaddr":0},{"name":".shstrtab","size":262,"vsize":262,"perm":"----","paddr":1733,"vaddr":0},{"name":".symtab","size":1104,"vsize":1104,"perm":"----","paddr":3196,"vaddr":0},{"name":".strtab","size":599,"vsize":599,"perm":"----","paddr":4300,"vaddr":0}]
EOF
RUN
NAME=iSSj
FILE=../bins/elf/analysis/x86-helloworld-gcc
CMDS=<<EXPECT
iSSj
EXPECT=<<RUN
EXPECT=<<EOF
[{"name":"PHDR","size":256,"vsize":256,"perm":"-r-x","paddr":52,"vaddr":134512692},{"name":"INTERP","size":19,"vsize":19,"perm":"-r--","paddr":308,"vaddr":134512948},{"name":"LOAD0","size":1436,"vsize":1436,"perm":"-r-x","paddr":0,"vaddr":134512640},{"name":"LOAD1","size":280,"vsize":284,"perm":"-rw-","paddr":1436,"vaddr":134518172},{"name":"DYNAMIC","size":232,"vsize":232,"perm":"-rw-","paddr":1448,"vaddr":134518184},{"name":"NOTE","size":68,"vsize":68,"perm":"-r--","paddr":328,"vaddr":134512968},{"name":"GNU_EH_FRAME","size":44,"vsize":44,"perm":"-r--","paddr":1216,"vaddr":134513856},{"name":"GNU_STACK","size":0,"vsize":0,"perm":"-rw-","paddr":0,"vaddr":0},{"name":"ehdr","size":52,"vsize":52,"perm":"-rw-","paddr":0,"vaddr":134512640}]
EOF
RUN
NAME=iSq
FILE=../bins/elf/analysis/x86-helloworld-gcc
CMDS=iSq
EXPECT=<<RUN
EXPECT=<<EOF
0x0 0x0 ----
0x8048134 0x8048147 -r-- .interp
0x8048148 0x8048168 -r-- .note.ABI_tag
@ -2770,12 +2773,13 @@ EXPECT=<<RUN
0x0 0x106 ---- .shstrtab
0x0 0x450 ---- .symtab
0x0 0x257 ---- .strtab
EOF
RUN
NAME=iSSq
FILE=../bins/elf/analysis/x86-helloworld-gcc
CMDS=iSSq
EXPECT=<<RUN
EXPECT=<<EOF
0x8048034 0x8048134 -r-x PHDR
0x8048134 0x8048147 -r-- INTERP
0x8048000 0x804859c -r-x LOAD0
@ -2785,6 +2789,7 @@ EXPECT=<<RUN
0x80484c0 0x80484ec -r-- GNU_EH_FRAME
0x0 0x0 -rw- GNU_STACK
0x8048000 0x8048034 -rw- ehdr
EOF
RUN
NAME=section comment
@ -2792,19 +2797,20 @@ FILE=../bins/elf/analysis/x86-helloworld-gcc
CMDS=<<EXPECT
e asm.bytes = false
pd 1 @ 0x080495a8
EXPECT=<<RUN
EXPECT=<<EOF
;-- section..dynamic:
;-- segment.DYNAMIC:
;-- .dynamic:
;-- _DYNAMIC:
0x080495a8 add dword [eax], eax ; [21] -rw- section size 232 named .dynamic
EOF
RUN
NAME=bss section comment
FILE=../bins/elf/analysis/x86-helloworld-gcc
CMDS=<<EXPECT
pd 3 @ section..bss
EXPECT=<<RUN
EXPECT=<<EOF
;-- section..bss:
;-- .bss:
;-- completed.5979:
@ -2815,6 +2821,7 @@ EXPECT=<<RUN
0x080496b6 0000 add byte [eax], al
;-- _end:
0x080496b8 ff invalid
EOF
RUN
NAME=il (file x86)
@ -3175,7 +3182,7 @@ NAME=iSS (file x86_64)
FILE=../bins/elf/analysis/hello-linux-x86_64
CMDS=<<EXPECT
iSS
EXPECT=<<RUN
EXPECT=<<EOF
[Segments]
nth paddr size vaddr vsize perm name
@ -3190,6 +3197,7 @@ nth paddr size vaddr vsize perm name
7 0x00000000 0x0 0x00000000 0x0 -rw- GNU_STACK
8 0x00000000 0x40 0x00400000 0x40 -rw- ehdr
EOF
RUN
NAME=il (file x86_64)
@ -3755,19 +3763,20 @@ CMDS=<<EXPECT
iee~type=preinit
e asm.bytes=false
pd 1 @ 0x0804849f
EXPECT=<<RUN
EXPECT=<<EOF
vaddr=0x08048486 paddr=0x00000486 hvaddr=0x08049ed4 hpaddr=0x00000ed4 type=preinit
vaddr=0x0804849f paddr=0x0000049f hvaddr=0x08049ed8 hpaddr=0x00000ed8 type=preinit
;-- entry.preinit1:
;-- preinit2:
0x0804849f push ebp
EOF
RUN
NAME=iee* preinit
FILE=../bins/elf/before-after-main
CMDS=<<EXPECT
iee*
EXPECT=<<RUN
EXPECT=<<EOF
fs symbols
"f entry.preinit0 1 0x08048486"
"f entry.preinit0_hpaddr 1 0x00000ed4"
@ -3805,13 +3814,14 @@ fs symbols
"f entry.fini4 1 0x080485e7"
"f entry.fini4_hpaddr 1 0x00000f00"
"s entry.fini4"
EOF
RUN
NAME=iS entropy and iSS entropy
FILE=../bins/elf/crackme0x05
CMDS=<<EXPECT
iS entropy; iSS entropy
EXPECT=<<RUN
EXPECT=<<EOF
[Sections]
nth paddr size vaddr vsize perm name
@ -3861,6 +3871,7 @@ nth paddr size vaddr vsize perm name
8 0x00000000 0x0 0x00000000 0x0 ---- NONE
9 0x00000000 0x34 0x08048000 0x34 -rw- ehdr
EOF
RUN
NAME=is sht null
@ -3937,14 +3948,15 @@ RUN
NAME=ieej
FILE=../bins/elf/analysis/x86-helloworld-gcc
CMDS=ieej
EXPECT=<<RUN
EXPECT=<<EOF
[{"vaddr":134513616,"paddr":976,"baddr":134512640,"laddr":0,"hvaddr":134518172,"hpaddr":1436,"type":"init"},{"vaddr":134513584,"paddr":944,"baddr":134512640,"laddr":0,"hvaddr":134518176,"hpaddr":1440,"type":"fini"}]
EOF
RUN
NAME=ieeej
FILE=../bins/elf/analysis/x86-helloworld-gcc
CMDS=ieeej~{}
EXPECT=<<RUN
EXPECT=<<EOF
{
"initfini": [
{
@ -3978,6 +3990,7 @@ EXPECT=<<RUN
}
]
}
EOF
RUN
NAME=iee elf Cd (32-bit)
@ -3988,7 +4001,7 @@ pD $SS @ section..preinit_array
pD $SS @ section..init_array
?e
pD $SS @ section..fini_array
EXPECT=<<RUN
EXPECT=<<EOF
;-- section..preinit_array:
;-- segment.LOAD1:
;-- segment.GNU_RELRO:
@ -4021,6 +4034,7 @@ EXPECT=<<RUN
;-- __fini:
0x08049efc .dword 0x080485ce ; entry.fini3 ; sym.fini
0x08049f00 .dword 0x080485e7 ; entry.fini4 ; sym.destructor
EOF
RUN
NAME=iee elf Cd (64-bit)
@ -4041,25 +4055,28 @@ EXPECT=<<EXPECT_ERR
;-- section..fini_array:
0x0021bfb0 .qword 0x0000000000005ce0 ; entry.fini0 ; RELOC 64 ; [19] -rw- section size 8 named .fini_array
EXPECT_ERR=<<RUN
EXPECT_ERR=<<EOF
Cannot seek to unknown address 'section..preinit_array'
EOF
RUN
NAME=iX
FILE=../bins/elf/analysis/dwarf_load
CMDS=iX
EXPECT=<<RUN
EXPECT=<<EOF
[Source file]
/home/landley/work/ab7/build/temp-armv6l/gcc-core/gcc/config/arm/ieee754-df.S
/home/landley/work/ab7/build/temp-armv6l/gcc-core/gcc/config/arm/lib1funcs.asm
EOF
RUN
NAME=iM main sym
FILE=../bins/elf/before-after-main
CMDS=iM
EXPECT=<<RUN
EXPECT=<<EOF
[Main]
vaddr=0x0804854e paddr=0x0000054e
EOF
RUN
NAME=iSj
@ -4115,21 +4132,23 @@ RUN
NAME=ii dupped imports
FILE=../bins/elf/varsub
CMDS=ii
EXPECT=<<RUN
EXPECT=<<EOF
[Imports]
nth vaddr bind type name
---------------------------------
1 0x00000000 GLOBAL FUNC __libc_start_main
2 0x00000000 WEAK NOTYPE __gmon_start__
EOF
RUN
NAME=iI~laddr
FILE=../bins/mach0/fatmach0-3true
ARGS=-m 0x5000
CMDS=iI~laddr
EXPECT=<<RUN
EXPECT=<<EOF
laddr 0x0
EOF
RUN
NAME=ik-macho
@ -4137,8 +4156,9 @@ FILE=../bins/mach0/fatmach0-3true
CMDS=<<EOF
ik info/mach0.entry.vaddr~?0x100000ef8
EOF
EXPECT=<<RUN
EXPECT=<<EOF
1
EOF
RUN
NAME=ikv
@ -4146,8 +4166,9 @@ FILE=../bins/mach0/fatmach0-3true
CMDS=<<EOF
ikv info/mach0.entry.vaddr
EOF
EXPECT=<<RUN
EXPECT=<<EOF
0x100000ef8
EOF
RUN
NAME=ik.
@ -4155,29 +4176,32 @@ FILE=../bins/mach0/fatmach0-3true
CMDS=<<EOF
ik. info/mach0.entry.vaddr
EOF
EXPECT=<<RUN
EXPECT=<<EOF
0x100000ef8
EOF
RUN
NAME=ik*
FILE=../bins/mach0/fatmach0-3true
CMDS=ik*~?mach0_segment64_0
EXPECT=<<RUN
EXPECT=<<EOF
1
EOF
RUN
NAME=ik?
BROKEN=1
FILE=../bins/mach0/fatmach0-3true
CMDS=ik?~?Usage
EXPECT=<<RUN
EXPECT=<<EOF
1
EOF
RUN
NAME=iS=
FILE=../bins/mach0/fatmach0-3true
CMDS=iS=
EXPECT=<<RUN
EXPECT=<<EOF
0* 0x100000ef8 ######------------------------ 0x100000f3f r-x 71 0.__TEXT.__text
1 0x100000f40 ------#----------------------- 0x100000f46 r-x 6 1.__TEXT.__symbol_stub1
@ -4190,22 +4214,25 @@ EXPECT=<<RUN
8 0x100001048 ----------------------------## 0x100001068 rw- 32 8.__DATA.__data
=> 0x100000ef8 ------------------------------ 0x100000ef7
EOF
RUN
NAME=iSq.
FILE=../bins/mach0/fatmach0-3true
CMDS=iSq.
EXPECT=<<RUN
EXPECT=<<EOF
0x100000ef8 0x100000f3f -r-x 0.__TEXT.__text
EOF
RUN
NAME=isqq
FILE=../bins/mach0/fatmach0-3true
CMDS=isqq
EXPECT=<<RUN
EXPECT=<<EOF
__mh_execute_header
radr://5614542
imp.exit
EOF
RUN
NAME=iR*
@ -4223,8 +4250,9 @@ RUN
NAME=izzz*
FILE=../bins/mach0/fatmach0-3true
CMDS=izzz*~str.http:__www.apple.com_appleca_codesigning.crl0
EXPECT=<<RUN
EXPECT=<<EOF
f str.http:__www.apple.com_appleca_codesigning.crl0 48 @ 0x00002f3c
EOF
RUN
NAME=it
@ -4234,12 +4262,13 @@ CMDS=it ; wx 0x90 ; it
EXPECT=<<EXPECT_ERR
md5 bf619eac0cdf3f68d496ea9344137e8b
sha1 5c3eb80066420002bc3dcc7ca4ab6efad7ed4ae5
EXPECT_ERR=<<RUN
EXPECT_ERR=<<EOF
File has been modified.
- md5 bf619eac0cdf3f68d496ea9344137e8b
+ md5 afd010a5a5456c232dee59d59bd75cf6
- sha1 5c3eb80066420002bc3dcc7ca4ab6efad7ed4ae5
+ sha1 3bfd02bb4fac6499c89278254f04a081887c38ea
EOF
RUN
# XXX modifying files is a very bad idea
@ -4254,9 +4283,10 @@ EXPECT_ERR='File has been modified.
- sha1 9016e215a321184c42c28ab03847554851932713
+ sha1 17c5b6331a420fc3b48defe782090295294fee2e
'
EXPECT=<<RUN
EXPECT=<<EOF
md5 84144530144b53a704c84d9c65ab5f92
sha1 9016e215a321184c42c28ab03847554851932713
EOF
RUN
NAME=isq. (malloc)
@ -4275,19 +4305,21 @@ RUN
NAME=ic?~ (match all)
FILE=malloc://512
CMDS=ic?~List
EXPECT=<<RUN
EXPECT=<<EOF
| ic List classes, methods and fields
| icc List classes, methods and fields in Header Format
| icg List classes as agn/age commands to create class hirearchy graphs
| icq List classes, in quiet mode (just the classname)
| icqq List classes, in quieter mode (only show non-system classnames)
EOF
RUN
NAME=ic?~ (match one)
FILE=malloc://512
CMDS=ic?~Header
EXPECT=<<RUN
EXPECT=<<EOF
| icc List classes, methods and fields in Header Format
EOF
RUN
NAME=ic?~ (match none)
@ -4299,35 +4331,39 @@ RUN
NAME=ascii substring detection (#14499)
FILE=../bins/pe/Reborn_Stub-strings.exe
CMDS=izz~pomf
EXPECT=<<RUN
EXPECT=<<EOF
7168 0x00087f8a 0x00489d8a 26 53 .text utf16le http://pomf.cat/upload.php
7173 0x000880dd 0x00489edd 19 39 .text utf16le https://a.pomf.cat/
7336 0x00089bed 0x0048b9ed 26 53 .text utf16le http://pomf.cat/upload.php
7337 0x00089c22 0x0048ba22 19 40 .text utf16le https://a.pomf.cat/
EOF
RUN
NAME=ic (file Java)
FILE=../bins/java/Hello.class
CMDS=ic
EXPECT=<<RUN
EXPECT=<<EOF
0x00000000 [0x0000022b - 0x000002aa] 127 class 0 Hello :: java/lang/Object
0x0000022b method 0 <init>
0x00000263 method 1 say
0x000002aa method 2 main
EOF
RUN
NAME=icq (file Java)
FILE=../bins/java/Hello.class
CMDS=icq
EXPECT=<<RUN
EXPECT=<<EOF
0x00000000 [0x0000022b - 0x000002aa] Hello java/lang/Object
EOF
RUN
NAME=icqq (file Java)
FILE=../bins/java/Hello.class
CMDS=icqq
EXPECT=<<RUN
EXPECT=<<EOF
Hello
EOF
RUN
NAME=icqq (file x86)
@ -4340,8 +4376,9 @@ NAME=iqqc (file Java)
BROKEN=1
FILE=../bins/java/Hello.class
CMDS=iqqc
EXPECT=<<RUN
EXPECT=<<EOF
Hello
EOF
RUN
NAME=iqqc (file x86)
@ -4355,8 +4392,9 @@ NAME=iqcq (file Java)
BROKEN=1
FILE=../bins/java/Hello.class
CMDS=iqcq
EXPECT=<<RUN
EXPECT=<<EOF
Hello
EOF
RUN
NAME=iqcq (file x86)

View File

@ -1,8 +0,0 @@
all:
# v -g r2r.v
v -g r2r.v
./r2r -n
r:
v -prod r2r.v
./r2r

View File

@ -1,5 +1,8 @@
#!/bin/sh
# XXX: remove and just do 'r2r unit'
# TODO: seems like this KCOV thing should be implemented in V's r2r
# To run with kcov
# export KCOV="kcov /path/to/output"
# kcov output will be placed in the /path/to/output/index.html

27
test/src/Makefile Normal file
View File

@ -0,0 +1,27 @@
-include ../../config-user.mk
BINDIR=$(shell r2 -H R2_PREFIX)/bin
CWD=$(shell pwd)
V=v/v
all: $(V)
$(V) -prod r2r.v
#$(V) -g r2r.v
$(V): v
cd v && git pull
$(MAKE) -C v
$(V) install radare.r2
fmt:
$(V) fmt -w r2r.v
v:
git clone https://github.com/vlang/v
install:
v -prod r2r.v
rm -f $(BINDIR)/r2r
ln -fs $(CWD)/r2r $(shell r2 -H R2_PREFIX)/bin
mkdir -p "${DESTDIR}${MANDIR}/man1"
cp -rf r2r.1 "${DESTDIR}${MANDIR}/man1"

31
test/src/README.md Normal file
View File

@ -0,0 +1,31 @@
r2r rewrite in V
================
This is the full rewrite of the r2 regressions testsuite in the V programming language.
Reasons behind using V are:
* Go-like syntax: Easy to maintain and for newcomers
* Portability: Compiles to C with no dependencies
* Speed: Just use native apis instead of spawn all the things
The current testsuite is written in NodeJS and have some issues:
* Hard to architect structured js, ts helps, but its just layers on layers
* Some lost promises happen in travis which are hard to debug
* Simplify the testsuite to cleanup broken or badly written tests
* Have a single entrypoint to run ALL the tests (unit, fuzz, asm, ..)
* Latest versions of NodeJS don't run on net/open/free-BSD
Things to be done:
* Implement the interactive mode to fix failing tests
* Clone+build V if not in the $PATH
Stuff to improve:
* Proper error handling
* Timeouts without using rarun2
* Improve r2pipe.v performance
--pancake

41
test/src/r2r.1 Normal file
View File

@ -0,0 +1,41 @@
.Dd Dec 29, 2019
.Dt R2R 1
.Sh NAME
.Nm r2r
.Nd radare regression testsuite
.Sh SYNOPSIS
.Nm r2r
.Op Fl n
.Op Fl h
.Op Fl v
.Op Fl q
.Op Fl i
.Op Fl d Ar dbpath
.Op Fl r Ar r2path
.Op Fl j Ar jobs
.Op Fl t Ar timeout
.Op [keyword]
.Sh DESCRIPTION
Run all the radare2-regressions tests matching a specific word in the name.
.Pp
TODO: this manpage is work-in-progress
.Pp
You need radare2 to be available in $PATH.
.Sh OPTIONS
.Bl -tag -width Fl
.It Fl n
Do not run any test, just parse them
.El
.Sh USAGE
.Pp
Use the -n flag to dont run any test. Just load them.
.Pp
$ r2r -n
[r2r] Loading tests...
.Pp
.Sh SEE ALSO
.Pp
.Xr radare2(1) ,
.Sh AUTHORS
.Pp
Written by pancake <pancake@nopcode.org>.

View File

@ -5,60 +5,106 @@ import (
sync
time
term
json
flag
filepath
radare.r2
)
const (
default_threads = 1
default_jobs = 2
default_targets = 'arch json asm fuzz cmd unit'
default_timeout = 3
default_asm_bits = 32
default_radare2 = 'r2'
r2r_version = '0.1'
default_radare2 = 'radare2'
default_dbpath = 'new/db' // XXX use execpath as relative reference to it
r2r_version = '0.2'
)
fn autodetect_dbpath() string {
return filepath.join(r2r_home(),default_dbpath)
}
fn r2r_home() string {
home := filepath.basedir(os.realpath(os.executable()))
return filepath.join(home,'..')
}
pub fn main() {
mut r2r := R2R{
}
mut r2r := R2R{}
mut fp := flag.new_flag_parser(os.args)
fp.application(filepath.filename(os.executable()))
// fp.version(r2r_version)
show_norun := fp.bool_('norun', `n`, false, 'Dont run the tests')
run_tests := !show_norun
show_help := fp.bool_('help', `h`, false, 'Show this help screen')
r2r.threads = fp.int_('threads', `j`, default_threads, 'Spawn N threads in parallel to run tests')
r2r.jobs = fp.int_('jobs', `j`, default_jobs, 'Spawn N jobs in parallel to run tests ($default_jobs)')
r2r.timeout = fp.int_('timeout', `t`, default_timeout, 'How much time to wait to consider a fail ($default_timeout}')
show_version := fp.bool_('version', `v`, false, 'Show version information')
r2r.r2r_home = r2r_home()
r2r.show_quiet = fp.bool_('quiet', `q`, false, 'Silent output of OK tests')
r2r.interactive = fp.bool_('interactive', `i`, false, 'Prompt to manually fix failing tests (TODO)')
r2r.db_path = fp.string_('dbpath', `d`, autodetect_dbpath(), 'Set database path db/')
r2r.r2_path = fp.string_('r2', `r`, default_radare2, 'Set path/name to radare2 executable')
if show_help {
println(fp.usage())
println('ARGS:')
println(' ${default_targets}')
return
}
if show_version {
println(r2r_version)
return
}
if r2r.threads < 1 {
if r2r.jobs < 1 {
eprintln('Invalid number of thread selected with -j')
exit(1)
}
r2r.targets = fp.finalize() or {
args := fp.finalize() or {
eprintln('Error: ' + err)
exit(1)
}
for target in r2r.targets {
println(target)
}
println('Loading tests')
os.chdir('..')
r2r.load_tests()
// TODO: support specifying json, asm, fuzz tests to run and multiple specific tests, globbing
if run_tests {
if r2r.targets.len < 2 {
// WIP
r2r.run_jsn_tests()
r2r.run_asm_tests()
r2r.run_fuz_tests()
r2r.targets = args[1..]
if r2r.interactive {
eprintln('Warning: interactive mode not yet implemented in V. Use the node testsuite for this')
p := filepath.join(r2r.r2r_home,'new')
if !os.is_dir(filepath.join(p,'node_modules')) {
exit(1)
}
a := r2r.targets.join(' ')
_ = os.system('cd $p && npm i')
r := os.system('cd $p && node_modules/.bin/r2r -i $a')
exit(r)
}
if r2r.targets.index('help') != -1 {
eprintln(default_targets)
exit(0)
}
for target in r2r.targets {
println('target ${target}')
}
println('[r2r] Loading tests')
// os.chdir('..')
r2r.load_tests()
if !show_norun {
r2r.run_tests()
r2r.show_report()
}
}
fn (r2r mut R2R) run_tests() {
if r2r.wants('json') {
r2r.run_jsn_tests()
}
if r2r.wants('unit') {
r2r.run_unit_tests()
}
if r2r.wants('asm') {
r2r.run_asm_tests()
}
if r2r.wants('fuzz') {
r2r.run_fuz_tests()
}
if r2r.wants('arch') || r2r.wants('cmd') {
r2r.run_cmd_tests()
}
}
@ -77,15 +123,22 @@ fn mktmpdir(template string) string {
// ///////////////
struct R2R {
mut:
cmd_tests []R2RCmdTest
asm_tests []R2RAsmTest
targets []string
r2 &r2.R2
threads int
wg sync.WaitGroup
failed int
fixed int
broken int
cmd_tests []R2RCmdTest
asm_tests []R2RAsmTest
targets []string
r2 &r2.R2
jobs int
timeout int
wg sync.WaitGroup
success int
failed int
fixed int
broken int
db_path string
r2_path string
show_quiet bool
interactive bool
r2r_home string
}
struct R2RCmdTest {
@ -115,6 +168,12 @@ mut:
cpu string
}
// TODO: not yet used
struct R2JsonTest {
mut:
name string
}
fn (test R2RCmdTest) parse_slurp(v string) (string,string) {
mut res := ''
mut slurp_token := ''
@ -134,12 +193,10 @@ fn (test R2RCmdTest) parse_slurp(v string) (string,string) {
}
fn (r2r mut R2R) load_cmd_test(testfile string) {
if r2r.targets.len > 1 && !testfile.ends_with('/${r2r.targets[1]}') {
// WIP
if r2r.targets.len > 0 && !testfile.ends_with('/${r2r.targets[0]}') {
return
}
mut test := R2RCmdTest{
}
mut test := R2RCmdTest{}
lines := os.read_lines(testfile) or {
panic(err)
}
@ -242,13 +299,12 @@ fn (r2r mut R2R) load_cmd_test(testfile string) {
}
r2r.cmd_tests << test
}
test = R2RCmdTest{
}
test = R2RCmdTest{}
test.source = testfile
}
}
else {
}}
else {}
}
}
}
@ -279,6 +335,17 @@ fn (r2r mut R2R) test_failed(test R2RCmdTest, a string, b string) string {
return term.red('XX')
}
fn (r2r R2R) wants(s string) bool {
// eprintln('want ${s}')
if s.contains('/') {
return true
}
if r2r.targets.len < 1 {
return true
}
return r2r.targets.index(s) != -1
}
fn (r2r mut R2R) test_fixed(test R2RCmdTest) string {
r2r.fixed++
return 'FX'
@ -321,7 +388,9 @@ fn (r2r mut R2R) run_asm_test_native(test R2RAsmTest, dismode bool) {
}
time_end := time.ticks()
times := time_end - time_start
println('[${mark}] ${test.mode} (time ${times}) ${test.arch} ${test.bits} : ${test.data} ${test.inst}')
if !r2r.show_quiet || !mark.contains('OK') {
println('[${mark}] ${test.mode} (time ${times}) ${test.arch} ${test.bits} : ${test.data} ${test.inst}')
}
r2r.wg.done()
}
@ -390,7 +459,8 @@ fn (r2r mut R2R) run_cmd_test(test R2RCmdTest) {
tmp_output := filepath.join(tmp_dir,'output.txt')
os.write_file(tmp_script, test.cmds)
// TODO: handle timeout
os.system('radare2 -e scr.utf8=0 -e scr.interactive=0 -e scr.color=0 -NQ -i ${tmp_script} ${test.args} ${test.file} 2> ${tmp_stderr} > ${tmp_output}')
r2 := '${r2r.r2_path} -e scr.utf8=0 -e scr.interactive=0 -e scr.color=0 -NQ'
os.system('${r2} -i ${tmp_script} ${test.args} ${test.file} 2> ${tmp_stderr} > ${tmp_output}')
res := os.read_file(tmp_output) or {
panic(err)
}
@ -422,18 +492,22 @@ fn (r2r mut R2R) run_cmd_test(test R2RCmdTest) {
}
fn (r2r R2R) run_fuz_test(fuzzfile string) bool {
// cmd := '${default_radare2} -qq -A "${fuzzfile}"'
cmd := 'rarun2 timeout=${default_timeout} system="${default_radare2} -qq -A ${fuzzfile}"'
cmd := 'rarun2 timeout=${default_timeout} system="${r2r.r2_path} -qq -A ${fuzzfile}"'
// TODO: support timeout
res := os.system(cmd)
return res == 0
}
fn (r2r R2R) git_clone(ghpath, localpath string) {
os.system('cd ${r2r.db_path}/.. ; git clone --depth 1 https://github.com/${ghpath} ${localpath}')
}
fn (r2r R2R) run_fuz_tests() {
fuzz_path := '../bins/fuzzed'
// open and analyze all the files in bins/fuzzed
if !os.is_dir(fuzz_path) {
os.system('make -C .. bins')
r2r.git_clone('radareorg/radare2-testbins', 'bins')
r2r.git_clone('radareorg/radare2-fuzztargets', 'fuzz/targets')
}
files := os.ls(fuzz_path) or {
panic(err)
@ -455,8 +529,7 @@ fn (r2r mut R2R) load_asm_test(testfile string) {
}
words := line.split('"')
if words.len == 3 {
mut at := R2RAsmTest{
}
mut at := R2RAsmTest{}
at.mode = words[0].trim_space()
at.inst = words[1].trim_space()
data := words[2].trim_space()
@ -518,8 +591,47 @@ fn (r2r mut R2R) load_asm_tests(testpath string) {
r2r.wg.wait()
}
fn (r2r mut R2R) run_unit_tests() bool {
wd := os.getwd()
_ = os.system('make -C ${r2r.r2r_home}/unit')
unit_path := '${r2r.db_path}/../../unit/bin'
if !os.is_dir(unit_path) {
eprintln('Cannot open unit_path')
return false
}
os.chdir(unit_path)
println('[r2r] Running unit tests from ${unit_path}')
files := os.ls('.') or {
return false
}
for file in files {
if is_executable(file) {
// TODO: filter OK
cmd := if r2r.show_quiet { '(./$file ;echo \$? > .a) | grep -v OK || [ "\$(shell cat .a)" = 0 ]' } else { './$file' }
if os.system(cmd) == 0 {
r2r.success++
}
else {
r2r.failed++
}
}
}
os.chdir(wd)
return true
}
fn is_executable(f string) bool {
if f.starts_with('r2-') {
return false
}
if os.is_dir(f) {
return false
}
return true
}
fn (r2r mut R2R) run_asm_tests() {
mut c := r2r.threads
mut c := r2r.jobs
r2r.r2 = r2.new()
// assemble/disassemble and compare
for at in r2r.asm_tests {
@ -534,7 +646,7 @@ fn (r2r mut R2R) run_asm_tests() {
c--
if c < 1 {
r2r.wg.wait()
c = r2r.threads
c = r2r.jobs
}
}
if at.mode.contains('d') {
@ -548,7 +660,7 @@ fn (r2r mut R2R) run_asm_tests() {
c--
if c < 1 {
r2r.wg.wait()
c = r2r.threads
c = r2r.jobs
}
}
}
@ -556,7 +668,7 @@ fn (r2r mut R2R) run_asm_tests() {
}
fn (r2r mut R2R) run_jsn_tests() {
json_path := 'db/json'
json_path := '${r2r.db_path}/json'
files := os.ls(json_path) or {
panic(err)
}
@ -566,36 +678,56 @@ fn (r2r mut R2R) run_jsn_tests() {
panic(err)
}
for line in lines {
mark := if r2r.run_jsn_test(line) { term.green('OK') } else { term.red('XX') }
println('[${mark}] json ${line}')
ok := r2r.run_jsn_test(line)
mut mark := term.green('OK')
if ok {
r2r.success++
}
else {
if line.contains('BROKEN') {
mark = term.blue('BR')
r2r.broken++
}
else {
mark = term.red('XX')
r2r.failed++
}
}
if !ok || !r2r.show_quiet {
println('[${mark}] json ${line}')
}
}
}
}
fn (r2r mut R2R) run_cmd_tests() {
println('Running tests')
println('[r2r] Running cmd tests')
// r2r.r2 = r2.new()
// TODO: use lock
r2r.wg = sync.new_waitgroup()
println('Adding ${r2r.cmd_tests.len} watchgooses')
// r2r.wg.add(r2r.cmd_tests.len)
mut c := r2r.threads
mut c := r2r.jobs
for t in r2r.cmd_tests {
r2r.wg.add(1)
go r2r.run_cmd_test(t)
c--
if c < 1 {
r2r.wg.wait()
c = r2r.threads
c = r2r.jobs
}
}
r2r.wg.wait()
}
fn (r2r R2R) show_report() {
total := r2r.broken + r2r.fixed + r2r.failed + r2r.success
println('')
success := r2r.cmd_tests.len - r2r.failed
println('Broken: ${r2r.broken} / ${r2r.cmd_tests.len}')
println('Fixxed: ${r2r.fixed} / ${r2r.cmd_tests.len}')
println('Succes: ${success} / ${r2r.cmd_tests.len}')
println('Failed: ${r2r.failed} / ${r2r.cmd_tests.len}')
println('Broken: ${r2r.broken}')
println('Fixxed: ${r2r.fixed}')
println('Succes: ${r2r.success}')
println('Failed: ${r2r.failed}')
println('Tottal: ${total}')
}
fn (r2r mut R2R) load_cmd_tests(testpath string) {
@ -616,32 +748,55 @@ fn (r2r mut R2R) load_cmd_tests(testpath string) {
}
}
struct DummyStruct {
no string
}
fn (r2r mut R2R) run_jsn_test(cmd string) bool {
r2r.r2 = r2.new()
if isnil(r2r.r2) {
r2r.r2 = r2.new()
}
jsonstr := r2r.r2.cmd(cmd)
return os.system("echo '${jsonstr}' | jq . > /dev/null") == 0
// r2r.r2.free()
if jsonstr.trim_space() == '' {
return true
}
// verify json
_ = json.decode(DummyStruct,jsonstr) or {
eprintln('[r2r] json ${cmd} = ${jsonstr}')
return false
}
return true
// return os.system("echo '${jsonstr}' | jq . > /dev/null") == 0
}
fn (r2r R2R) load_jsn_tests(testpath string) {
// implementation is in run_jsn_tests
// nothing to load for now
}
fn (r2r mut R2R) load_tests() {
r2r.cmd_tests = []
db_path := 'db'
dirs := os.ls(db_path) or {
panic(err)
}
for dir in dirs {
if dir == 'archos' {
fn (r2r mut R2R) load_tests() {
r2r.cmd_tests = []
if !os.is_dir(r2r.db_path) {
eprintln('Cannot open -d ${r2r.db_path}')
return
}
if r2r.wants('json') {
r2r.load_jsn_tests('${r2r.db_path}/json')
}
if r2r.wants('asm') {
r2r.load_asm_tests('${r2r.db_path}/asm')
}
if r2r.wants('cmd') {
r2r.load_cmd_tests('${r2r.db_path}/cmd')
}
if r2r.wants('arch') {
$if x64 {
p := '${r2r.db_path}/archos'
$if linux {
r2r.load_cmd_tests('${db_path}/${dir}/linux-x64/')
r2r.load_cmd_tests('$p/linux-x64/')
} $else {
$if macos {
r2r.load_cmd_tests('${db_path}/${dir}/darwin-x64/')
r2r.load_cmd_tests('$p/darwin-x64/')
} $else {
eprintln('Warning: archos tests not supported for current platform')
}
@ -650,14 +805,4 @@ fn (r2r mut R2R) load_tests() {
eprintln('Warning: archos tests not supported for current platform')
}
}
else if dir == 'json' && r2r.targets.len < 2 {
r2r.load_jsn_tests('${db_path}/${dir}')
}
else if dir == 'asm' && r2r.targets.len < 2 {
r2r.load_asm_tests('${db_path}/${dir}')
}
else {
r2r.load_cmd_tests('${db_path}/${dir}')
}
}
}

View File

@ -158,11 +158,13 @@ bool test_r_buf_mmap(void) {
mu_assert_notnull (b, "r_buf_new_mmap failed");
if (test_buf (b) != MU_PASSED) {
unlink(filename);
mu_fail ("test failed");
}
// Cleanup
r_buf_free (b);
unlink(filename);
mu_end;
}