diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2017-03-04 16:08:27 +0000 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2017-03-04 17:35:18 +0000 |
commit | b609d07be3b37f81f5c05ae56bd427d16bb6f5c9 (patch) | |
tree | c38a7b0c0bd126e989cb7582a1f9fbd30333adb5 | |
parent | f2f5b4e6229532f3ba69e9f32bc3305e37b20f4c (diff) | |
download | gitano-b609d07be3b37f81f5c05ae56bd427d16bb6f5c9.tar.gz |
adds support for coverage testing
-rw-r--r-- | .editorconfig | 2 | ||||
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | .luacov | 22 | ||||
-rw-r--r-- | Makefile | 66 | ||||
-rw-r--r-- | lib/gitano/coverage.lua.in | 52 | ||||
-rw-r--r-- | utils/install-lua-bin | 38 | ||||
-rw-r--r-- | utils/merge-luacov-stats | 66 |
7 files changed, 235 insertions, 15 deletions
diff --git a/.editorconfig b/.editorconfig index 0dc0e75..b0bee21 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,7 +11,7 @@ charset = utf-8 trim_trailing_whitespace = true # Lua code should be space indented, to 3 spaces -[{*.lua,bin/*.in,testing/gitano-test-tool.in,utils/install-lua-bin}] +[{*.lua,bin/*.in,testing/gitano-test-tool.in,utils/install-lua-bin,utils/merge-luacov-stats,.luacov}] indent_style = space indent_size = 3 @@ -1,3 +1,7 @@ *~ run t +.coverage +luacov.stats.out +luacov.report.out +lib/gitano/coverage.lua @@ -0,0 +1,22 @@ +-- -*- Lua -*- +return { + statsfile = "luacov.stats.out", + reportfile = "luacov.report.out", + tick = false, + savestepsize = 100, + runreport = false, + deletestats = false, + codefromstrings = false, + include = { }, + exclude = { + "^/usr/share", + "%.conf$", + "%.clod$", + "clod%-config", "^hooks/", "supple%-transfer", + "lang/[^/]+$", + "lib/gitano$", + "plugins/demo$", + "gitano/coverage$", + }, + modules = {}, +} @@ -86,12 +86,24 @@ TESTS := $(patsubst %,testing/%.yarn,$(TESTS)) GEN_BIN := utils/install-lua-bin RUN_GEN_BIN := $(LUA) $(GEN_BIN) $(LUA) + +COVERAGE := no + +ifeq ($(COVERAGE),yes) +define GEN_LOCAL_BIN + +$(RUN_GEN_BIN) $(shell pwd) $(shell pwd)/bin $(shell pwd)/lib $(shell pwd)/plugins $1 $2 $(shell pwd)/extras/luacov/src $(shell pwd)/.coverage/ +chmod 755 $2 + +endef +else define GEN_LOCAL_BIN $(RUN_GEN_BIN) $(shell pwd) $(shell pwd)/bin $(shell pwd)/lib $(shell pwd)/plugins $1 $2 chmod 755 $2 endef +endif define GEN_INSTALL_BIN @@ -113,23 +125,51 @@ install -m 644 $1 $2 endef -local: $(LOCAL_BINS) - $(LUAC) -p $(LOCAL_BINS) +define GEN_LOCAL_MOD -clean: - @echo "CLEAN: local binaries" - @$(RM) $(LOCAL_BINS) +$(RUN_GEN_BIN) $(shell pwd) $(shell pwd)/bin $(shell pwd)/lib $(shell pwd)/plugins $1 $2 + +endef + +LOCAL_MODS := lib/gitano/coverage.lua + +local: $(LOCAL_BINS) $(LOCAL_MODS) + @$(LUAC) -p $(LOCAL_BINS) $(LOCAL_MODS) + @mkdir -p .coverage +ifeq ($(COVERAGE),yes) + @echo NOTE: Coverage gathering enabled + @if ! test -r extras/luacov/src/luacov; then \ + echo "CANNOT COVERAGE TEST, LUACOV MODULE NOT AVAILABLE"; \ + echo "Please run: git submodule init && git submodule update"; \ + fi +else + @echo NOTE: Coverage gathering is not enabled +endif + +clean: cleanbins + @echo "CLEAN: coverage stats and reports" + @$(RM) -r .coverage luacov.stats.out luacov.report.out + +cleanbins: + @echo "CLEAN: local binaries and modules" + @$(RM) $(LOCAL_BINS) $(LOCAL_MODS) @echo "CLEAN: test binaries" @$(RM) $(TEST_BINS) distclean: clean @find . -name "*~" -delete -bin/%: bin/%.in $(GEN_BIN) - $(call GEN_LOCAL_BIN,$<,$@) +bin/%: bin/%.in $(GEN_BIN) FORCE + @$(call GEN_LOCAL_BIN,$<,$@) -testing/%: testing/%.in $(GEN_BIN) - $(call GEN_LOCAL_BIN,$<,$@) +testing/%: testing/%.in $(GEN_BIN) FORCE + @$(call GEN_LOCAL_BIN,$<,$@) + +lib/gitano/%.lua: lib/gitano/%.lua.in $(GEN_BIN) FORCE + @$(call GEN_LOCAL_MOD,$<,$@) + +FORCE: +.PHONY: FORCE install: install-bins install-lib-bins install-mods install-skel install-man install-plugins install-lang @@ -242,3 +282,11 @@ testing/%: testing/%.in $(GEN_BIN) $(call GEN_LOCAL_BIN,$<,$@) check: test + +coverage-report: + @echo "COVERAGE: Merge stats..." + @env LUA_PATH="$(shell pwd)/extras/luacov/src/?.lua;;" $(LUA) utils/merge-luacov-stats .coverage/luacov.stats-*.out + @echo "COVERAGE: Generate report..." + @env LUA_PATH="$(shell pwd)/extras/luacov/src/?.lua;;" $(LUA) extras/luacov/src/bin/luacov + @echo "COVERAGE: Summary:" + @sed '0,/^Summary/d' < luacov.report.out | tail -n +2 | sed -e's/^/COVERAGE: /' diff --git a/lib/gitano/coverage.lua.in b/lib/gitano/coverage.lua.in new file mode 100644 index 0000000..65d7682 --- /dev/null +++ b/lib/gitano/coverage.lua.in @@ -0,0 +1,52 @@ +-- gitano.coverage +-- +-- Coverage generation for when running Gitano under test. +-- NOTE: Not to be installed as part of Gitano, not to be loaded from the +-- top level gitano module +-- +-- Copyright 2017 Daniel Silverstone <dsilvers@digital-scurf.org> +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- 1. Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Neither the name of the author nor the names of their contributors +-- may be used to endorse or promote products derived from this software +-- without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +-- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +-- SUCH DAMAGE. +-- + +local ok, runner = pcall(require, "luacov.runner") + +local luxio = require("luxio") + +local conf = assert(loadfile("@@.luacov@@"))() + +local function begin(basepath, part) + if not ok then return end + basepath = basepath or "./" + local pidstr = (".%d"):format(luxio.getpid()) + part = (part or "general") .. pidstr + conf.statsfile = basepath .. "luacov.stats-" .. part .. ".out" + runner.init(conf) +end + +return { + begin = begin, +} diff --git a/utils/install-lua-bin b/utils/install-lua-bin index 41a7bd2..1f27a49 100644 --- a/utils/install-lua-bin +++ b/utils/install-lua-bin @@ -27,7 +27,9 @@ -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- SUCH DAMAGE. -local lua_bin, inst_share_path, inst_bin_path, inst_mod_path, inst_plugin_path, input_name, output_name = ... +local lua_bin, inst_share_path, inst_bin_path, inst_mod_path, inst_plugin_path, input_name, output_name, coverage_path, report_path = ... + +local luxio = require("luxio") local input_fh = assert(io.open(input_name, "r")) local output_fh = assert(io.open(output_name, "w")) @@ -39,6 +41,22 @@ if not inst_mod_path:match("%?") then inst_mod_path = inst_mod_path:gsub("/+", "/") end +if coverage_path and coverage_path == "" then + coverage_path = nil +end + +if coverage_path and not coverage_path:match("%?") then + coverage_path = coverage_path .. "/?.lua" + coverage_path = coverage_path:gsub("/+", "/") +end + +local coverage_part +if coverage_path then + -- We are generating coverage, the part is the leafname of the + -- output binary + coverage_part = output_name:gsub("^.+/", "") +end + local mod_path_present = false for path_elem in package.path:gmatch("([^;]+)") do if path_elem == inst_mod_path then @@ -65,12 +83,20 @@ while line do elseif token == "GITANO_LUA_PATH" then if not mod_path_present then output_fh:write(("package.path = ('%%s;%%s'):" .. - "format(%q, package.path)" .. - "\n"):format(inst_mod_path)) + "format(%q, package.path)" + ):format(inst_mod_path)) else - output_fh:write("-- Gitano modules installed into " .. - inst_mod_path .. "\n") + output_fh:write("--[[Gitano modules installed into " .. + inst_mod_path .. "]]") + end + if coverage_path then + output_fh:write((" package.path = ('%%s;%%s'):" .. + "format(%q, package.path)" + ):format(coverage_path)) + output_fh:write((" require('gitano.coverage').begin(%q, %q)" + ):format(report_path, coverage_part)) end + output_fh:write("\n") elseif token == "GITANO_BIN_PATH" then output_fh:write(("gitano.config.lib_bin_path(%q)\n"):format(inst_bin_path)) elseif token == "GITANO_SHARE_PATH" then @@ -82,6 +108,8 @@ while line do else output_fh:write("-- Unknown token: " .. token .. "\n") end + elseif line:match("@@%.luacov@@") then + output_fh:write(line:gsub("@@%.luacov@@", luxio.getcwd() .. "/.luacov") .. "\n") else output_fh:write(line .. "\n") end diff --git a/utils/merge-luacov-stats b/utils/merge-luacov-stats new file mode 100644 index 0000000..f4b28ae --- /dev/null +++ b/utils/merge-luacov-stats @@ -0,0 +1,66 @@ +-- Run this explicitly through -*- Lua -*- + +-- Copyright 2017 Daniel Silverstone <dsilvers@digital-scurf.org> +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- 1. Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Neither the name of the author nor the names of their contributors +-- may be used to endorse or promote products derived from this software +-- without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +-- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +-- SUCH DAMAGE. + +local infiles = {...} + +local stats = require("luacov.stats") + +-- Step 1, merge all the coverage files together into a single one... + +local merged = {} + +function merge_data(fname) + local subdata = stats.load(fname) + for fname, fdat in pairs(subdata) do + if not merged[fname] then + merged[fname] = fdat + else + for i = 1, fdat.max do + merged[fname][i] = (merged[fname][i] or 0) + (fdat[i] or 0) + end + end + end +end + +local percent = 0 +for i = 1, #infiles do + merge_data(infiles[i]) + local newpercent = math.floor((i*100) / #infiles) + if (newpercent - percent > 0) or (newpercent == 100) then + io.stdout:write(("COVERAGE: %3d%% merged.\r"):format(newpercent)) + percent = newpercent + io.stdout:flush(); + end +end +io.stdout:write("\n"); + +-- Step 2, write it all out + +print("Saving merged stats") +stats.save("luacov.stats.out", merged) |