PostgreSQL 回归测试

前端之家收集整理的这篇文章主要介绍了PostgreSQL 回归测试前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
回归测试是Postgresql的测试方法之一。
回归测试,需要事先定义好测试脚本(通常是sql脚本,放在sql目录中),同时定义好调用执行测试脚本的预期正确输出文件(通常放在expected目录中)。
测试使用make check或make installcheck进行,它会通过pg_regress程序调用sql目录中的sql,并收集输出结果(通常放到results目录中),最后pg_regress会对expected目录和results目录中的文件使用diff进行一一比较。
如果比较发现文件内容不一致,会将不一致的结果输出到regression.diffs文件中,并返回这个TEST CASE Failed
但是这种测试方法实际上有一些需要注意的地方,例如我们使用不同的本地化设置,时区可能得到的结果和期望的结果就不一样。另外有些不可预知的结果,例如随机值,数据的顺序,执行计划和优化器相关参数有关。这些因素都可能导致测试结果和预期不一致,那么我们就需要人为去修复这种Failed

Postgresql的主代码测试文件在src/test/regress目录中。
这个目录的结构如下:

postgres@digoal-> ll -rt
total 1.2M
rwr-- 1 postgres postgres 579 Jun1003:29 standby_schedule 测试standby的调度配置, 其实就是调度sql里的文件
2.3K serial_schedule 串行测试的调度配置
937 resultmap 不同的测试平台的结果映射文件,因为不同平台某些测试结果可能不相同,所以一个expected文件不能支持所有的平台。例如浮点数测试。
rwxrxrx 4.4K regressplans.sh
20K regressc
159 README
2.7K pg_regress_main1.6K pg_regressh
69K3.6K parallel_schedule 并行测试的调度配置
624Makefile
5.6KGNUmakefile
drwxrwxrwx24.0K38 output
drwxrwxrwx input
data 一些测试数据
Sep71451 sql 测试用到的sql
drwxrwxr52 results 通过pg_regress调用目录中的脚本,得到的结果
expected 执行目录中的文件对应的正确返回结果

上层目录结构如下,其中包含了一些其他的测试目标,例如隔离级别的测试,本地化测试,性能测试,线程安全测试。等。

cd /optsoft_bakpostgresql-9.4.4srctest
ll
36K
examples
441 isolation
6 locale
389Makefile
mb
performance
perl
1917 regress
thread

接下来我们看看Postgresql的回归测试程序pg_regress的用法,它不会安装到PGHOME/bin中,只在src/test/regress中存在。
$ cd srctestregress
$ srcregresspg_regress help
Postgresql regression test driver
Usage:
pg_regress [OPTION]...EXTRATEST]...
Optionsconfigauth=DATADIR update authentication settings for DATADIR
createroleROLE create the specified role before testing
dbnameDB use database DB (default "regression")
debug turn on debug mode in programs that are run
dlpathDIR look dynamic libraries DIR
encodingENCODING ENCODING as the encoding
inputdirDIR take input files from DIR "."launcherCMD CMD launcher of psql
loadextensionEXT load the named extension before running the
tests; can appear multiple times
languageLANG load the named language before running the
maxconnectionsN maximum number of concurrent connections
is0,0)"> meaning unlimitedoutputdirDIR place output files scheduleFILE test ordering schedule FILE
(can be used multiple times to concatenatetempinstallDIR create a temporary installation --useexisting an existing installation
Options"temp-install" modeextraDIR additional directory to install eg.,0)"> contribnolocale C locale
portPORT start postmaster on PORT
FILE append contents of FILE to temporary config
topbuilddirDIR relative) path to top level build directory
using an existing installationhostHOST postmaster running on HOST
PORT postmaster running at PORT
userUSER connect USER
psqldirDIR psql default: configured bindir)
Theexit status 0if all tests passed some tests Failedand2
if the tests could not be run some reason.
Report bugs to <pgsqlbugs@postgresqlorg>.

回归测试用法
在Postgresql源码根目录,或者源码的regress目录中执行如下:
make check // 测试时需要初始化数据库集群
make installcheck // 使用已经启动的数据库集群测试,不需要初始化数据库集群

以下同时测试主代码以及contrib的代码
make checkworld
make installcheckworld

如果要使用自定义的diff参数,可以设置一个环境变量,
例如:make check PG_REGRESS_DIFF_OPTS='-u'。
同时我们还可以使用不同的LOCALE进行测试。例如:
make check LANGde_DEutf8
make check NO_LOCALE=1
make check LANGC ENCODINGEUC_JP

当我们要测试调度中不包含的测试sql时,可以使用EXTRA_TESTS参数,至于这些脚本为什么默认不包含在调度中,可能是因为这些sql脚本可能对平台的依赖比较严重,所以没有放到默认的测试中。例如:
make check EXTRA_TESTScollatelinuxutf8 LANGen_USnumeric_big

接下来我们看看调度文件以及sql脚本目录:

pwd
regress
less serial_schedule
# src/test/regress/serial_schedule
# This should probably be in an order similar to parallel_schedule.
test: tablespace
test: boolean
test: char
test: name
test: varchar
test: text
test: int2
test: int4
test: int8

......
并行调度
postgres@digoal-> less parallel_schedule

# ----------
# src/test/regress/parallel_schedule
#
# By convention,we put no more than twenty tests in any one parallel group;
# this limits the number of connections needed to run the tests.
# ----------
# run tablespace by itself,and first,because it forces a checkpoint;
# we'd prefer not to have checkpoints later in the tests because that
# interferes with crash-recovery testing.
test: tablespace
# The first group of parallel tests
test: boolean char name varchar text int2 int4 int8 oid float4 float8 bit numeric txid uuid enum money rangetypes pg_lsn regproc

调度文件的test:后面跟的就是sql目录下的文件名(不含.sql后缀)。
less sql/
1940
postgres postgres 4096./
2234../
2237 abstimesql
4097 advisory_lock20295 aggregates24882 alter_generic54461 alter_table17244 arrays594 async1365 bitmapops6406 bit4164booleansql

所以前面提到的EXTRA_TESTS实际上也是sql目录中的文件名(不带.sql后缀)。
来实际的试一下吧:
pwd
make installcheckparallel //并行测试,使用已经开启的现有的数据库集群
make -C ../../../src/port all
......
../../../src/test/regress/pg_regress --inputdir=. --psqldir='/opt/pgsql9.4.4/bin' --dlpath=. --schedule=./parallel_schedule
(using postmaster on /data01/pg_root_1921,port 1921)
============== dropping database "regression" ==============
DROP DATABASE
============== creating database "regression" ==============
CREATE DATABASE
ALTER DATABASE
============== running regression test queries ==============
test tablespace ... ok
......
parallel group (19 tests): limit conversion sequence returning without_oid polymorphism copy2 xml prepare plancache rowtypes temp domain with truncate largeobject rangefuncs alter_table plpgsql
plancache ... ok
limit ... ok
plpgsql ... ok
copy2 ... ok
temp ... ok
domain ... ok
rangefuncs ... Failed
prepare ... ok
without_oid ... ok
conversion ... ok
truncate ... ok
alter_table ... ok
sequence ... ok
polymorphism ... Failed
rowtypes ... ok
returning ... ok
largeobject ... ok
with ... Failed
xml ... ok
test stats ... ok
=========================
22 of 145 tests Failed.
=========================
differences that caused some tests to fail can be viewed the
file "/opt/soft_bak/postgresql-9.4.4/src/test/regress/regression.diffs" A copy of the test summary that you see
above saved the file "/opt/soft_bak/postgresql-9.4.4/src/test/regress/regression.out".
make***installcheckparallel]Error1

有些测试失败了,diff文件已经输出到/opt/soft_bak/postgresql-9.4.4/src/test/regress/regression.diffs,我们可以查看一下看看为什么测试结果和预期结果不一致。
less regressiondiffs
pg_lsn.out2015062938.000000000+0800
---results09074504.413922536***************
7292****
generate_series(15 k
WHERE i <= AND j >10
ORDER BY f;
! QUERY PLAN
--------------------------------------------------------------------------
Sort
SortKey(((((i)::text ||'/'::textj))::)
HashAggregate
Group((((pg_lsn
NestedLoop
FunctionScan on generate_series k
Materialize
Loop
on generate_series j
Filter((j AND 10))
on generate_series i
i 12 rows)
SELECT DISTINCT '/' jpg_lsn f
FROM generate_series i90----
;
......

对于主代码,如果我们需要自定义测试sql,我们可以修改regress/sql目录下的文件,或者新增文件。同时修改regress/expected目录下的对应期望文件,或者现在期望文件
如果是新增文件的情况,我们还需要修改调度文件regress/serial_schedule和regress/parallel_schedule,把测试加入调度。
最后,再以ltree插件为例,看看如何配置一个外加插件的回归测试。
ltree的源码目录:
cd contrib cd ltreert
1.1M
517Makefile
2.4K ltxtquery_opc
11K ltxtquery_io7.9K ltreeunpackaged--1.0994 ltreetest13K ltree_op6.9K _ltree_op14K ltree_io7.3Kh
16K ltree_gist _ltree_gist155control
18K7.1K lquery_op263 crc324.1Kc
sql
expected
data

contrib/ltree的Makefile如下(在这里配置回归测试的调度,用到变量REGRESS,对应sql目录中的脚本文件名):

# contrib/ltree/Makefile
MODULE_big ltree
OBJS o ltree_opo lquery_opo _ltree_opo crc32o \
ltxtquery_ioo ltxtquery_opo ltree_gisto _ltree_gisto
PG_CPPFLAGS DLOWER_NODE
EXTENSION DATA sql ltreesql
REGRESS ltree
ifdef USE_PGXS
PG_CONFIG pg_config
PGXS := $shell $PG_CONFIGpgxs)
include $PGXSelse
subdir ltree
top_builddir ../..
top_builddir)//Makefileglobal
top_srcdircontrib-globalmk
endif

其中:

)

global

都指向了:

makefilesmk

这个makefile中会用到回归测试相关的两个变量:

# REGRESS -- list of regression test cases (without suffix)
# REGRESS_OPTS -- additional switches to pass to pg_regress

引用src/makefiles/pgxs.mk的部分内容如下:

ifdef REGRESS
# Select database to use for running the tests
ifneq ($(USE_MODULE_DB),)
REGRESS_OPTS += --dbname=$(CONTRIB_TESTDB_MODULE)
else
REGRESS_OPTS += --dbname=$(CONTRIB_TESTDB)
endif
# where to find psql for running the tests
PsqlDIR = $(bindir)
# When doing a VPATH build,must copy over the data files so that the
# driver script can find them. We have to use an absolute path for
# the targets,because otherwise make will try to locate the missing
# files using VPATH,and will find them in $(srcdir),but the point
# here is that we want to copy them from $(srcdir) to the build
# directory.
ifdef VPATH
abs_builddirshell pwdtest_files_src wildcard $srcdirdata/*.data)
test_files_build := $(patsubst $(srcdir)/%,$(abs_builddir)/%,$(test_files_src))
all: $(test_files_build)
$(test_files_build): $(abs_builddir)/%: $(srcdir)/%
$(MKDIR_P) $(dir $@)
ln -s $< $@
endif # VPATH
.PHONY: submake
submake:
ifndef PGXS
$(MAKE) -C $(top_builddir)/src/test/regress pg_regress$(X)
# against installed postmaster
installcheck: submake $(REGRESS_PREP)
$(pg_regress_installcheck) $(REGRESS_OPTS) $(REGRESS)
ifdef PGXS
check:
@echo '"$(MAKE) check" is not supported.'
@echo 'Do "$(MAKE) install",then "$(MAKE) installcheck" instead.'
check: all submake $(REGRESS_PREP)
$(pg_regress_check) --extra-install=$(subdir) $(REGRESS_OPTS) $(REGRESS)
endif
endif # REGRESS

这里用到了ltree中Makefile中定义的subdir和 REGRESS变量,如下:
../..
ltree
ltree

所以我们在contrib/ltree中执行make check会执行:(指PGXS未定义时)
$pg_regress_check$subdirREGRESS_OPTSREGRESS)
pg_regress_check这个变量在src/Makefile.global中定义了,其实就是pg_regress命令的调用
global
srcdir .
pg_regress_locale_flags ENCODING),--))NOLOCALEpg_regress_check =./tmp_check pg_regress_locale_flagsEXTRA_REGRESS_OPTS)

在contrib/ltree中执行make check最终执行的是(没有定义的变量直接忽略):

../../=.=../..--extra-install=contrib/ltreeltree

我们可以直接到ltree的源码目录测试这条命令:
root@digoal ~]# chown -R postgres:postgres /opt/soft_bak/postgresql-9.4.4
[root@digoal ~]# su - postgres
postgres@digoal-> cd /opt/soft_bak/postgresql-9.4.4/contrib/ltree/
postgres@digoal-> ../../src/test/regress/pg_regress --inputdir=. --temp-install=./tmp_check --top-builddir=../.. --extra-install=contrib/ltree ltree
============== removing existing temp installation ==============
============== creating temporary installation ==============
============== initializing database system ==============
============== starting postmaster ==============
running on port 57636 with PID 27852
============== creating database "regression" ==============
CREATE DATABASE
ALTER DATABASE
============== running regression test queries ==============
test ltree ... ok
============== shutting down postmaster ==============
============== removing temporary installation ==============
=====================
All tests passed
=====================

另外一种测试时installcheck,和check不同的是,installcheck不需要初始化数据库,是在我们开启了数据库集群的情况下的测试。
同样的方法,我们可以发现它调用的是:
pg_regress_installcheck)
 
 
 
 

通过src/Makefile.global的定义:
pg_regress_installcheck ='$(PsqlDIR)'bindir bindir 以及
mk
PsqlDIR 最终转换为:

'/opt/pgsql/bin' ltree

启动数据库后,就可以进行测试了。同样需要注意(PGPORT PGHOST PGDATABASE PGUSER等)环境变量。
pg_ctl start
ltree
postmaster on data01pg_root_1921 port 1921)
============== dropping database "regression"==============
DROP DATABASE
creating database CREATE DATABASE
ALTER DATABASE
running regression test queries test ltree ... ok
所以插件的回归测试配置也很简单,同样需要sql,expected目录,以及通过配置Makefile来指定需要回归测试的sql脚本。
[参考]
1. @L_502_0@
2. http://www.postgresql.org/docs/devel/static/regress-variant.html
各种Makefile
src/Makefile.global
src/Makefile
src/makefiles/pgxs.mk
contrib/contrib-global.mk
contrib/xx/Makefile
代码覆盖率测试见我另一篇BLOG

http://blog.163.com/digoal@126/blog/static/1638770402015875295989/

原文地址:http://blog.163.com/digoal@126/blog/static/16387704020158774344267/

pg官方手册对应章节:http://www.postgres.cn/docs/9.3/regress.html

原文链接:https://www.f2er.com/postgresql/194613.html

猜你在找的Postgre SQL相关文章