commit 1db6440eb38789bcb59451cb8adb39f2084f9443 Author: Marek 'marx' Grac Date: Mon Oct 21 12:44:39 2013 +0200 testing: Check if fence agent uses only valid keys in options["--???"] Valid keys are defined in fencing library or fence agent itself. This check will be run at every build, so we should be protected against case when developer unintentionally use new key (e.g. typo). These type of bugs are usually not detected by static analyzers. diff --git a/fence/agents/lib/check_used_options.py b/fence/agents/lib/check_used_options.py new file mode 100755 index 0000000..2d75756 --- /dev/null +++ b/fence/agents/lib/check_used_options.py @@ -0,0 +1,65 @@ +#!/usr/bin/python + +## Check if fence agent uses only options["--??"] which are defined in fencing library or +## fence agent itself +## +## Usage: ./check_used_options.py fence-agent (e.g. lpar/fence_lpar.py) +## + +import sys, re +sys.path.append("@FENCEAGENTSLIBDIR@") +from fencing import all_opt + +def main(): + agent = sys.argv[1] + + available = { } + + ## all_opt from fencing library are imported + for k in all_opt.keys(): + if all_opt[k].has_key("longopt"): + available["--" + all_opt[k]["longopt"]] = True + + ## add UUID which is derived automatically from --plug if possible + available["--uuid"] = True + + ## all_opt defined in fence agent are found + agent_file = open(agent) + opt_re = re.compile("\s*all_opt\[\"([^\"]*)\"\] = {") + opt_longopt_re = re.compile("\s*\"longopt\" : \"([^\"]*)\"") + + in_opt = False + for line in agent_file: + if opt_re.search(line) != None: + in_opt = True + if in_opt and opt_longopt_re.search(line) != None: + available["--" + opt_longopt_re.search(line).group(1)] = True + in_opt = False + + ## check if all options are defined + agent_file = open(agent) + option_use_re = re.compile("options\[\"(--[^\"]*)\"\]") + option_has_re = re.compile("options.has_key\(\"(--[^\"]*)\"\)") + + counter = 0 + without_errors = True + for line in agent_file: + counter += 1 + + for x in option_use_re.findall(line): + if not available.has_key(x): + print "ERROR on line %d in %s: option %s is not defined" % (counter, agent, option_use_re.search(line).group(1)) + without_errors = False + + for x in option_has_re.findall(line): + if not available.has_key(x): + print "ERROR on line %d in %s: option %s is not defined" % (counter, agent, option_has_re.search(line).group(1)) + without_errors = False + + if without_errors: + sys.exit(0) + else: + sys.exit(1) + +if __name__ == "__main__": + main() diff --git a/make/fencebuild.mk b/make/fencebuild.mk index e86d03c..d775e92 100644 --- a/make/fencebuild.mk +++ b/make/fencebuild.mk @@ -1,4 +1,8 @@ $(TARGET): $(SRC) + if [ 0 -eq `echo "$(SRC)" | grep fence_ &> /dev/null; echo $$?` ]; then \ + PYTHONPATH=$(abs_srcdir)/../lib:$(abs_builddir)/../lib $(top_srcdir)/fence/agents/lib/check_used_options.py $(SRC); \ + else true ; fi + bash $(top_srcdir)/scripts/fenceparse \ $(top_srcdir)/make/copyright.cf REDHAT_COPYRIGHT \ $(VERSION) \