merge branch coverage of two or more runs with lcov - code-coverage

How can I merge branch coverage of two or more runs?
Is any tool or lcov command exist?
Let's say that I have two test runs and would like to see summary branch coverage
gcc -O0 --coverage main.c -o test-coverage
test-coverage param1
lcov --capture --rc lcov_branch_coverage=1 --directory . --config-file ./lcovrc --output coverage1.info
test-coverage param2
lcov --capture --rc lcov_branch_coverage=1 --directory . --config-file ./lcovrc --output coverage2.info
Looks like it is needed to parse and merge files coverage1.info and coverage2.info
Is any solution exist already or I have to develop my own?

Developed the python script, which merges a list of files (line coverage is not accurate here)
def merge(files):
if (len(files) == 0):
return 0
covs = [open(f, "r").readlines() for f in files]
result = []
branch_number = 0
for i, line in enumerate(covs[0]):
if ('end_of_record' in line):
result.append(line)
else:
tmp = line.split(':')
tag = tmp[0]
data = tmp[1]
if (tag == 'BRDA'):
c = data.split(',')[-1]
if (c == '1\n'):
branch_number += 1
result.append(line)
else:
flag = 0
for j in covs[1:]:
if j[i].split(',')[-1] == '1\n':
branch_number += 1
result.append(j[i])
flag = 1
break
if flag == 0:
result.append(line)
elif (tag == 'BRH'):
result.append(tag + ":" + str(branch_number)+'\n')
else:
result.append(line)
return result

Related

hf-tikz and sphinx are not playing well together

I am trying to add some color to my matrices in sphinx. I was using hf-tikz for it before. However, when I add it to Sphinx, it renders it incorrectly.
The result that I am trying to get is
The result I am getting is
Here is the code that I have.
main.rst:
.. math::
\left(\begin{array}{cc}
\tikzmarkin[style red]{a}a\tikzmarkend{a}
& \tikzmarkin[style green]{b}b\tikzmarkend{b} \\
\tikzmarkin[style blue]{c}c\tikzmarkend{c}
& \tikzmarkin[style orange]{d}d\tikzmarkend{d} \\
\end{array}\right)
\star
\left(\begin{array}{cc}
\tikzmarkin[style red]{w}w\tikzmarkend{w}
& \tikzmarkin[style green]{x}x\tikzmarkend{x} \\
\tikzmarkin[style blue]{y}y\tikzmarkend{y}
& \tikzmarkin[style orange]{z}z\tikzmarkend{z} \\
\end{array}\right)
=
\left(\begin{array}{cc}
\tikzmarkin[hor=style red]{aw}{a\star w}\tikzmarkend{aw}
& \tikzmarkin[hor=style green]{bx}b\star x\tikzmarkend{bx} \\
\tikzmarkin[hor=style blue]{cy}c\star y\tikzmarkend{cy}
& \tikzmarkin[hor=style orange]{dz}d\star z\tikzmarkend{dz} \\
\end{array}\right)
conf.py
extensions = [
'sphinx.ext.imgmath',
]
# Math configurations (https://tex.stackexchange.com/a/69770/51173)
imgmath_image_format = 'svg'
imgmath_use_preview = True
imgmath_latex_preamble = r'''
\usepackage{xcolor}
\usepackage[customcolors]{hf-tikz}
\colorlet{myred}{red!50!purple!30}
\colorlet{mygreen}{green!50!lime!60}
\colorlet{myblue}{blue!50!white!50}
\colorlet{myorange}{orange!80!red!60}
\colorlet{mycyan}{cyan!90!blue!60}
\colorlet{mymagenta}{magenta!90!red!60}
\tikzset{
style red/.style={
set fill color=myred,
set border color=white,
},
style green/.style={
set fill color=mygreen,
set border color=white,
},
style blue/.style={
set fill color=myblue,
set border color=white,
},
style orange/.style={
set fill color=myorange,
set border color=white,
},
style cyan/.style={
set fill color=mycyan,
set border color=white,
},
style magenta/.style={
set fill color=mymagenta,
set border color=white,
},
%
hor/.style={
above left offset={-0.15,0.31},
below right offset={0.15,-0.125},
#1
},
ver/.style={
above left offset={-0.1,0.3},
below right offset={0.15,-0.15},
#1
}
}
'''
Makefile
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
#$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
#$(SPHINXBUILD) -M $# "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
make.bat
#ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
EDIT: Added makefile used to build the rst's
I think I found why this was happening: the problem was in the sphinx.ext.imgmath extension + hf-tikz not working well with the DVI files.
When converting the math equations, sphinx creates a very basic latex document, and compiles it using latexpdf into a DVI file. After that the file is converted into an SVG, and the resulting svg file is copied to the sphinx's _build directory. The problem is that dvisvgm (used by imgmath) cannot convert tikz stuff. Alternative would be using extended DVI, but that doesn't work well either.
The solution is to compile everything into PDF, and convert that pdf into SVG. This is slightly problematic, and the only way I found is to use pdf2svg + pdfcrop. I ended up modifying the imgmath.py into a custom extension. Below are the changes that I put in the imgmath.py. The changes require the use of external applications, so I don't think there is a merit in creating a pull request (at least not with a more scalable solution).
Changes in the imgmath.py:
Create a new method:
def convert_pdf_to_svg(pdfpath, builder):
# type: (str, Builder) -> Tuple[str, int]
"""Convert DVI file to SVG image."""
tempdir = ensure_tempdir(builder)
filename = path.join(tempdir, 'math.svg')
name = 'pdfcrop'
command = [name, pdfpath, pdfpath]
run_external_command(command, name)
name = 'pdf2svg'
command = [name, pdfpath, filename]
run_external_command(command, name)
return filename, None
In the compile_math function, inside the try block, replace the return statement with the following
if builder.config.imgmath_pdf2svg:
return path.join(tempdir, 'math.pdf')
else:
return path.join(tempdir, 'math.dvi')
Inside the render_math method, in the block titles # .dvi -> .png/svg, replace the try block with the following
try:
if image_format == 'png':
imgpath, depth = convert_dvi_to_png(dvipath, self.builder)
elif image_format == 'svg':
if self.builder.config.imgmath_pdf2svg:
imgpath, depth = convert_pdf_to_svg(dvipath, self.builder)
else:
imgpath, depth = convert_dvi_to_svg(dvipath, self.builder)
except InvokeError:
self.builder._imgmath_warned_image_translator = True # type: ignore
return None, None
Finally, add a new configuration entry in the very end of the imgmath.py:
app.add_config_value('imgmath_pdf2svg', False, 'html')
After that, you can write in the conf.py to enable the tikz images.
imgmath_image_format = 'svg'
imgmath_latex = 'latexmk'
imgmath_latex_args = ['-pdf']
imgmath_pdf2svg = True # Available only in the custom `imgmath.py`
patch for imgmath extension. Includes some other stuff :)
The patch goes a->b.
--- a/imgmath.py
+++ b/imgmath.py
## -15,7 +15,7 ##
import sys
import tempfile
from hashlib import sha1
-from os import path
+from os import path, symlink
from subprocess import CalledProcessError, PIPE
from typing import Any, Dict, List, Tuple
## -157,6 +157,11 ##
with open(filename, 'w', encoding='utf-8') as f:
f.write(latex)
+ for add_file in builder.config.imgmath_latex_additional_files:
+ filename = path.join(tempdir, path.basename(add_file))
+ if not path.exists(filename):
+ symlink(path.join(builder.confdir, add_file), filename)
+
# build latex command; old versions of latex don't have the
# --output-directory option, so we have to manually chdir to the
# temp dir to run it.
## -165,9 +170,15 ##
command.extend(builder.config.imgmath_latex_args)
command.append('math.tex')
+ output_extension = 'dvi'
+ if builder.config.imgmath_latex == 'xelatex':
+ output_extension = 'xdv'
+ if builder.config.imgmath_pdf2svg:
+ output_extension = 'pdf'
+
try:
subprocess.run(command, stdout=PIPE, stderr=PIPE, cwd=tempdir, check=True)
- return path.join(tempdir, 'math.dvi')
+ return path.join(tempdir, 'math.' + output_extension)
except OSError:
logger.warning(__('LaTeX command %r cannot be run (needed for math '
'display), check the imgmath_latex setting'),
## -177,7 +188,7 ##
raise MathExtError('latex exited with error', exc.stderr, exc.stdout)
-def convert_dvi_to_image(command: List[str], name: str) -> Tuple[bytes, bytes]:
+def run_external_command(command: List[str], name: str) -> Tuple[bytes, bytes]:
"""Convert DVI file to specific image format."""
try:
ret = subprocess.run(command, stdout=PIPE, stderr=PIPE, check=True)
## -203,7 +214,7 ##
command.append('--depth')
command.append(dvipath)
- stdout, stderr = convert_dvi_to_image(command, name)
+ stdout, stderr = run_external_command(command, name)
depth = None
if builder.config.imgmath_use_preview:
## -227,7 +238,7 ##
command.extend(builder.config.imgmath_dvisvgm_args)
command.append(dvipath)
- stdout, stderr = convert_dvi_to_image(command, name)
+ stdout, stderr = run_external_command(command, name)
depth = None
if builder.config.imgmath_use_preview:
## -239,6 +250,21 ##
break
return filename, depth
+
+def convert_pdf_to_svg(pdfpath, builder):
+ # type: (str, Builder) -> Tuple[str, int]
+ """Convert DVI file to SVG image."""
+ tempdir = ensure_tempdir(builder)
+ filename = path.join(tempdir, 'math.svg')
+
+ name = 'pdfcrop'
+ command = [name, pdfpath, pdfpath]
+ run_external_command(command, name)
+
+ name = 'pdf2svg'
+ command = [name, pdfpath, filename]
+ run_external_command(command, name)
+ return filename, None
def render_math(self: HTMLTranslator, math: str) -> Tuple[str, int]:
## -291,7 +317,10 ##
if image_format == 'png':
imgpath, depth = convert_dvi_to_png(dvipath, self.builder)
elif image_format == 'svg':
- imgpath, depth = convert_dvi_to_svg(dvipath, self.builder)
+ if self.builder.config.imgmath_pdf2svg:
+ imgpath, depth = convert_pdf_to_svg(dvipath, self.builder)
+ else:
+ imgpath, depth = convert_dvi_to_svg(dvipath, self.builder)
except InvokeError:
self.builder._imgmath_warned_image_translator = True # type: ignore
return None, None
## -396,8 +425,10 ##
['-gamma', '1.5', '-D', '110', '-bg', 'Transparent'],
'html')
app.add_config_value('imgmath_dvisvgm_args', ['--no-fonts'], 'html')
+ app.add_config_value('imgmath_pdf2svg', False, 'html')
app.add_config_value('imgmath_latex_args', [], 'html')
app.add_config_value('imgmath_latex_preamble', '', 'html')
+ app.add_config_value('imgmath_latex_additional_files', [], 'html')
app.add_config_value('imgmath_add_tooltips', True, 'html')
app.add_config_value('imgmath_font_size', 12, 'html')
app.connect('build-finished', cleanup_tempdir)

Parsing Lua strings, more specifically newlines

I'm trying to parse Lua 5.3 strings. However, I encountered an issue. For example,
$ lua
Lua 5.3.4 Copyright (C) 1994-2017 Lua.org, PUC-Rio
> print(load('return "\\z \n\r \n\r \r\n \n \n \\x"', "#test"))
nil test:6: hexadecimal digit expected near '"\x"'
>
> print(load('return "\\z\n\r\n\r\r\n\n\n\\x"', "#test"))
nil test:6: hexadecimal digit expected near '"\x"'
Both of these error on line 6, and the logic behind that is pretty simple: eat newline characters (\r or \n) if they're different from the current one (I believe this to be an accurate description of how the lua lexer works, but I may be wrong).
I have this code, which should do it:
local ln = 1
local skip = false
local mode = 0
local prev
for at, crlf in eaten:gmatch('()[\r\n]') do
local last = eaten:sub(at-1, at-1)
if skip and prev == last and last ~= crlf then
skip = false
else
skip = true
ln = ln + 1
end
prev = crlf
end
It decides whether to eat newlines based on the previous char. Now, from what I can tell, this should work, but no matter what I do it doesn't seem to work. Other attempts have made it report 5 lines, while this one makes it report 9(!). What am I missing here? I'm running this on Lua 5.2.4.
This is part of a routine for parsing \z:
local function parse52(s)
local startChar = string.sub(s,1,1)
if startChar~="'" and startChar~='"' then
error("not a string", 0)
end
local c = 0
local ln = 1
local t = {}
local nj = 1
local eos = #s
local pat = "^(.-)([\\" .. startChar .. "\r\n])"
local mkerr = function(emsg, ...)
error(string.format('[%s]:%d: ' .. emsg, s, ln, ...), 0)
end
local lnj
repeat
lnj = nj
local i, j, part, k = string.find(s, pat, nj + 1, false)
if i then
c = c + 1
t[c] = part
if simpleEscapes[v] then
--[[ some code, some elseifs, some more code ]]
elseif v == "z" then
local eaten, np = s:match("^([\t\n\v\f\r ]*)%f[^\t\n\v\f\r ]()", nj+1)
local p=np
nj = p-1
--[[ the newline counting routine above ]]
--[[ some other elseifs ]]
end
else
nj = nil
end
until not nj
if s:sub(-1, -1) ~= startChar then
mkerr("unfinished string near <eof>")
end
return table.concat(t)
end
Compact code for iterating lines of Lua script:
local text = "First\n\r\n\r\r\n\n\nSixth"
local ln = 1
for line, newline in text:gmatch"([^\r\n]*)([\r\n]*)" do
print(ln, line)
ln = ln + #newline:gsub("\n+", "\0%0\0"):gsub(".%z.", "."):gsub("%z", "")
end
Efficient code for iterating lines of Lua script:
local text = "First\n\r\n\r\r\n\n\nSixth"
local sub = string.sub
local ln = 1
for line, newline in text:gmatch'([^\r\n]*)([\r\n]*)' do
print(ln, line)
local pos, max_pos = 1, #newline
while pos <= max_pos do
local crlf = sub(newline, pos, pos + 1)
if crlf == "\r\n" or crlf == "\n\r" then
pos = pos + 2
else
pos = pos + 1
end
ln = ln + 1
end
end

check50 not working properly

check50 gives weird output please help
#include <cs50.h>
#include <stdio.h>
#include <math.h>
int main(void)
{
int amount,n25,n10,n5,n1,total;
int rem;
float gamount;
printf("O hai!");
do{
printf("How much change is owed?\n");
gamount = GetFloat();
}while(gamount<0);
amount = (int) round(gamount *100.00);
rem = round(amount);
n25 =(int) rem /25;
rem = rem %25;
n10 = rem /10;
rem = rem%10;
n5 = rem /5;
rem = rem%5;
n1 = rem /1;
rem = rem%1;
total = n25+n10+n5+n1;
printf("%d",total);
return 0;
}
check50 output:
*~/workspace/pset1/ $ check50 2015.fall.pset1.greedy greedy.c
:) greedy.c exists
:) greedy.c compiles
:( input of 0.41 yields output of 4
\ expected output, but not "4"
:( input of 0.01 yields output of 1
\ expected output, but not "1"
:( input of 0.15 yields output of 2
\ expected output, but not "2"
:( input of 1.6 yields output of 7
\ expected output, but not "7"
:( input of 23 yields output of 92
\ expected output, but not "92"
:( input of 4.2 yields output of 18
\ expected output, but not "18"
:) rejects a negative input like -.1
:) rejects a non-numeric input of "foo"
:) rejects a non-numeric input of ""
https://sandbox.cs50.net/checks/f9c8501c99a848df82d8bd0df231a6ea
i tried changing the printf("%d",total) statement to printf(total) but it results in compile error
compiling using
clang -ggdb3 -O0 -std=c11 -Wall -Werror -Wshadow greedy.c -lcs50 -lm -o greedy
Instead of this:
printf("%d",total);
try using this:
printf("%d\n",total);

Get the number of times a test has failed in Jenkins

We have some tests that fail periodically for no reason, mainly, JUnit times out. I want to know if I can get the number of times each test has failed. With that, I can see if it is certain tests that keep have issues, or it is not tied to tricky tests and more an issue with the stability of Jenkins on that server.
I encountered the same problems and we made a python that can grab the failings tests in the last N builds :
# -*- coding: utf-8 -*-
#! /usr/bin/python
import urllib
import re
import sys
project = "HERE_THE_PROJECT_NAME"
jenkin_host = "http://path.to.your.jenkins/jenkins/job/%s" % project
last_build = int(re.search("%s #(\d+)" % project, urllib.urlopen(jenkin_host + "/rssAll").read()).group(1))
start_build = last_build
nb_build = 200
REG_EXP = """All Failed Tests(.*)All Tests"""
FAILURE_REG_EXP = """javascript:hideStackTrace\(([^<]*)\)"""
all_failures = {}
last_seen = {}
print "Loading %s builds starting from build number %s" % (nb_build, start_build)
build_ok = 0
for build_id in range(start_build - nb_build, start_build + 1):
test_page = jenkin_host + "/%s/testReport/" % build_id
sys.stdout.write(".")
sys.stdout.flush()
failures = set()
for line in urllib.urlopen(test_page).readlines():
line_piece = re.search(REG_EXP, line)
if line_piece:
piece = line_piece.group(1)
match = re.search(FAILURE_REG_EXP, piece)
while (match):
failures.add(match.group(1))
match = re.search(FAILURE_REG_EXP, piece[match.start():match.end()])
if not failures:
build_ok += 1
for failure in failures:
all_failures[failure] = all_failures.get(failure, 0) + 1
last_seen[failure] = build_id
print
print "Done (found %s build OK)" % build_ok
nbs = [ x for x in list(set(all_failures.values())) if x > 1]
nbs.sort(reverse=True)
for i in nbs:
for test, nb in all_failures.iteritems():
if nb == i :
print "%d : %s (last seen : %s)" % (nb, test, last_seen[test])
And I obtain :
Loading 200 builds starting from build number 11032
.........................................................................................................................................................................................................
Done (found 148 build OK)
8 : 'one failing test' (last seen : 10906)
7 : 'another-failing-test' (last seen : 11019)

How to use some text processing(awk etc..) to put some character in a text file at certain lines

I have a text file which has hex values, one value on one separate line. A file has many such values one below another. I need to do some analysis of the values for which i need to but some kind of delimiter/marker say a '#' in this file before line numbers 32,47,62,77... difference between two line numbers in this patterin is 15 always.
I am trying to do it using awk. I tried few things but didnt work.
What is the command in awk to do it?
Any other solution involving some other language/script/tool is also welcome.
Thank you.
-AD
This is how you can use AWK for it,
awk 'BEGIN{ i=0; } \
{if (FNR<31) {print $0} \
else {i++; if (i%15) {print $0} else {printf "#%s\n",$0}}\
}' inputfile.txt > outputfile.txt
How it works,
BEGIN sets an iterator for counting from your starting line 32
FNR<31 starts counting from the 31st record (the next record needs a #)
input lines are called records and FNR is an AWK variable that counts them
Once we start counting, the i%15 prefixes a # on every 15th line
$0 prints the record (the line) as is
You can type all the text with white spaces skipping the trailing '\' on a single command line.
Or, you can use it as an AWK file,
# File: comment.awk
BEGIN{ i=0; }
$0 ~ {\
if (FNR<31) {print $0} \
else {\
i++; \
if (i%15) {\
print $0
}\
else {\
printf "#%s\n",$0
}\
}\
}
And run it as,
awk -f comment.awk inputfile.txt > outputfile.txt
Hope this will help you to use more AWK.
Python:
f_in = open("file.txt")
f_out = open("file_out.txt","w")
offset = 4 # 0 <= offset < 15 ; first marker after fourth line in this example
for num,line in enumerate(f_in):
if not (num-offset) % 15:
f_out.write("#\n")
f_out.write(line)
Haskell:
offset = 31;
chunk_size = 15;
main = do
{
(h, t) <- fmap (splitAt offset . lines) getContents;
mapM_ putStrLn h;
mapM_ ((putStrLn "#" >>) . mapM_ putStrLn) $
map (take chunk_size) $
takeWhile (not . null) $
iterate (drop chunk_size) t;
}

Resources