You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, @agroce and I did mutation testing of data.table, and here are some changes/mutants that we found, in lines which are apparently covered by tests, but when we ran tests and CRAN checks with the change/mutant, they still passed, and they look like significant changes, for which we may want to add tests.
This was run on 1.15.0 so the line numbers/links refer to that version of the code (first line original, second line mutated).
if (tmp>x[i-1]) continue; // x[i-1]==x[i] doesn't happen because x is unique
if (tmp>x[i-1]) continue; // x[i-1]==x[i] doesn't happen because x is unique
continue;
while (third<my_n && my_key[third]==my_key[second]) third++; // look for the last of the second value (which might be a repeat of the first)
while ((1==1) && my_key[third]==my_key[second]) third++; // look for the last of the second value (which might be a repeat of the first)
if (ch==eof && quoteRule!=2) { target->off--; target->len++; } // test 1324 where final field has open quote but not ending quote; include the open quote like quote rule 2
if ((1==1) && quoteRule!=2) { target->off--; target->len++; } // test 1324 where final field has open quote but not ending quote; include the open quote like quote rule 2
int MSBNbits = maxBit > 15 ? 16 : maxBit+1; // how many bits make up the MSB
int MSBNbits = maxBit > 15 ? 16 : maxBit+-1; // how many bits make up the MSB
if (length(tt) && length(vv)>=count[i]) { // length check added by Matt to avoid SEGV in #2767
if (length(tt) && length(vv)>=count[i]) { // length check added by Matt to avoid SEGV in #2767
continue;
rbindlist.c:60 Having zero columns itself invalidates the use of rbindlist (fillArg == FALSE) to return NULL, so having zero or more rows shouldn't matter
if (nrow==0 && ncol==0) return(R_NilValue);
if (nrow>=0 && ncol==0) return(R_NilValue);
if (!na_n && len3!=1 && len3!=len0)
if (!na_n && len3!=1 && len3<len0)
bmerge.R:92 not sure what other values xclass can take but "double">="integer64" is FALSE
if (xclass=="integer64" || iclass=="integer64") {
if (xclass>="integer64" || iclass=="integer64") {
data.table.R:770bysubl[[-1L]] is only valid in a list with two elements, so this can never fail. if length!=2 then first condition returns TRUE, if length=2 then second condition is valid and -1 (not first = second) is equivalent to 2.
if (!is.symbol(bysub) && (length(bysubl)!=2L || !is.symbol(bysubl[[2L]]) || !(bysubl[[1L]] %chin% c(".","c","list"))))
if (!is.symbol(bysub) && (length(bysubl)!=2L || !is.symbol(bysubl[[-1L]]) || !(bysubl[[1L]] %chin% c(".","c","list"))))
if (!isInteger(nqmaxgrpArg) || length(nqmaxgrpArg) != 1 || INTEGER(nqmaxgrpArg)[0] <= 0)
if (0==1)
bmerge.c:160 is a memory error (allGrp1 is logical/int pointer)
allGrp1[0] = TRUE;
allGrp1[-1] = TRUE;
Possibly relevant but difficult/obscure
assign.c:581 only runs when there is an index with name not starting with __, this is covered by test 1576, fix for #1396 logic is in a while loop ending with indexNo ++; s = CDR(s); so this can probably be bad if there is more than one index (test only has one)
indexNo++;
indexNo--;
Existing test:
# work around for issue introduced in v1.9.4, #1396X= data.table(x=5:1, y=6:10)
setattr(X, 'index', integer(0))
setattr(attr(X, 'index'), 'x', 5:1) # auto indexed attribute as created from v1.9.4
test(1576, X[, z:=1:5, verbose=TRUE],
output="Dropping index 'x' as.*beginning of its name.*very likely created by v1.9.4 of data.table")
I will be going through these mutants and classifying them based on how bad they are / and then I will create some new test PRs. If anyone else wants to help, that is great.
The text was updated successfully, but these errors were encountered:
Hi, @agroce and I did mutation testing of data.table, and here are some changes/mutants that we found, in lines which are apparently covered by tests, but when we ran tests and CRAN checks with the change/mutant, they still passed, and they look like significant changes, for which we may want to add tests.
This was run on 1.15.0 so the line numbers/links refer to that version of the code (first line original, second line mutated).
Not classified yet (TODO)
fmelt.c:517
forder.c:167
forder.c:335
forder.c:516
forder.c:806
forder.c:869
forder.c:917
fread.c:355
fread.c:365
fread.c:572
fread.c:712
fread.c:784
fread.c:784
fread.c:835
fread.c:1142
fread.c:1604
fread.c:1924
fread.c:1979
fread.c:2501
freadR.c:579
frolladaptive.c:219
frolladaptive.c:246
fsort.c:165
fsort.c:223
fsort.c:247
fwrite.c:284
gsumm.c:35
ijoin.c:182
ijoin.c:275
ijoin.c:495
ijoin.c:607
ijoin.c:677
rbindlist.c:107
rbindlist.c:160
subset.c:181
subset.c:207
uniqlist.c:79
uniqlist.c:112
uniqlist.c:158
uniqlist.c:237
utils.c:72
utils.c:255
utils.c:413 in internal fun
below to ignore (probably not significant)
rbindlist.c:60 Having zero columns itself invalidates the use of
rbindlist
(fillArg == FALSE
) to returnNULL
, so having zero or more rows shouldn't matterfifelse.c:27
!=
is a stronger check than<
bmerge.R:92 not sure what other values xclass can take but "double">="integer64" is FALSE
data.table.R:770
bysubl[[-1L]]
is only valid in a list with two elements, so this can never fail. if length!=2 then first condition returns TRUE, if length=2 then second condition is valid and -1 (not first = second) is equivalent to 2.data.table.R:2490 ul argument goes into ... in either case.
data.table.R:2536 split.data.table used as FUN in either case
data.table.R:2969 next line does
eval(name[[2L]]
which is probably ok to do even if name[[2]] is not a namefmelt.R:109 still works /equivalent because match.vec comes from regexpr which returns -1 for no match.
merge.R:118 probablye not a problem because setcolorder always puts un-mentioned columns at end.
setops.R:8 by.y becomes cols in either case.
transpose.R:63 type.convert becomes x in either case.
between.c:183 probably equivalent
bmerge.c:123 has #nocov
bmerge.c:160 is a memory error (allGrp1 is logical/int pointer)
Possibly relevant but difficult/obscure
assign.c:581 only runs when there is an index with name not starting with __, this is covered by test 1576, fix for #1396 logic is in a while loop ending with
indexNo ++; s = CDR(s);
so this can probably be bad if there is more than one index (test only has one)Existing test:
bmerge.c:69 could be tested, it!=LGLSXP should be TRUE for it>LGLSXP, but in the mutant it would be FALSE. https://github.com/r-devel/r-svn/blob/145c843da2856bf06c817b2831f4fcf9f515f2e7/src/include/Rinternals.h#L108-L141 says that LGLSXP is 10, CPLXSXP is 15 and VECSXP is 19
potential tests to add
coalesce.c:53 this code seems like it is setting values, so maybe the values are not being tested?
dogroups.c:345 looks like an estimate of number of rows returned in j, starts at -1, and incremented from there, so this could be an off by one?
fastmean.c:78 happens for REALSXP, seems like it should be important, why do test still pass with this change?
tests added
fread.R:341 added test with
fread(key=character())
#6115below source code
source code I used to create output above is shown below:
I will be going through these mutants and classifying them based on how bad they are / and then I will create some new test PRs. If anyone else wants to help, that is great.
The text was updated successfully, but these errors were encountered: