diff --git a/project_task_sheets/phase_05/project_phase05_tasks/DurationTest.java b/project_task_sheets/phase_05/project_phase05_tasks/DurationTest.java index 3341ff1..4d4b64b 100644 --- a/project_task_sheets/phase_05/project_phase05_tasks/DurationTest.java +++ b/project_task_sheets/phase_05/project_phase05_tasks/DurationTest.java @@ -14,4 +14,32 @@ public class DurationTest { Assert.assertEquals("PT0.000000001S", new Duration(0, 1).toString()); } + + @Test + public void testToStringRORMutation() { + // Killed Mutation: Line 18: Unequal + Assert.assertEquals("PT0S", + new Duration(0, 0).toString()); + // Killed Mutation: Line 26: Equals, Line 35.1: Equals + Assert.assertEquals("PT-1S", + new Duration(-1, 0).toString()); + // Killed Mutation: Line 29: Less + Assert.assertEquals("PT1M", + new Duration(60, 0).toString()); + // Killed Mutation: Line 32.1: FalseOp, Line 32.2: Greater + Assert.assertEquals("PT0.000000001S", + new Duration(0, 1).toString()); + // Killed Mutation: Line 35.2: Less + Assert.assertEquals("PT1.000000001S", + new Duration(1, 1).toString()); + // Killed Mutation: Line 36: LessEquals + Assert.assertEquals("PT-58.999999999S", + new Duration(-59, 1).toString()); + // Killed Mutation: Line 46: GreaterEquals + Assert.assertEquals("PT-0.999999999S", + new Duration(-1, 1).toString()); + // Killed Mutation: Line 51: Unequal + Assert.assertEquals("PT0.0000001S", + new Duration(0, 100).toString()); + } } diff --git a/project_task_sheets/phase_05/project_phase05_tasks/Solution_Phase05_MichaelChen.tex b/project_task_sheets/phase_05/project_phase05_tasks/Solution_Phase05_MichaelChen.tex index 474424b..808fee9 100644 --- a/project_task_sheets/phase_05/project_phase05_tasks/Solution_Phase05_MichaelChen.tex +++ b/project_task_sheets/phase_05/project_phase05_tasks/Solution_Phase05_MichaelChen.tex @@ -14,6 +14,8 @@ \newacronym{dc}{DC}{derivation coverage} \newacronym{moc}{MOC}{mutation operator coverage} \newacronym{mpc}{MPC}{mutation production coverage} +\newacronym{wmc}{WMC}{weak mutant coverage} +\newacronym{smc}{SMC}{strong mutant coverage} \usepackage{pgf} \usepackage{tikz} @@ -159,7 +161,7 @@ 32 & \verb|buf.length() > 2| & \verb|buf.length() != 2| \\ 35 & \verb|nanos > 0| & \verb|nanos < 0| \\ 44 & \verb|nanos > 0| & \verb|true| \\ \hline - 18 & \verb|this == ZERO| & \verb|this > ZERO| \\ + 18 & \verb|this == ZERO| & \verb|this != ZERO| \\ 26 & \verb|hours != 0| & \verb|hours == 0| \\ 29 & \verb|minutes != 0| & \verb|minutes < 0| \\ 32 & \verb|secs == 0| & \verb|false| \\ @@ -167,7 +169,7 @@ 35 & \verb|secs < 0| & \verb|secs == 0| \\ 36 & \verb|secs == -1| & \verb|secs <= -1| \\ 46 & \verb|secs < 0| & \verb|secs >= 0| \\ - 20 & \verb|lastChar(buf) == '0'| & \verb|lastChar(buf) != '0'| + 51 & \verb|lastChar(buf) == '0'| & \verb|lastChar(buf) != '0'| \end{tabular} \end{center} \end{answer} @@ -196,17 +198,64 @@ \item For the \textit{other} set of method mutations, provide a minimum set of tests that kill the mutants only \textit{weakly}, but \textbf{not} \textit{strongly}. If that is not possible for a concrete mutant, explain why, and kill the mutants \textit{strongly} instead. If that is not possible as well, explain it. \begin{answer} - [TODO: Add answer here] + The mutant in line 32 \verb|buf.length() != 2| cannot be killed because the effect of the unequal operation in the context of buffer length is equal to the strictly greater than, because the buffer is always prefixed with \texttt{PT}. Of the remaining mutants, the following cannot be weakly killed (note, that all of those were optional as per your ROR definition): + \begin{center} + \begin{tabular}{r|c|l} + Line & Ground String & Mutant \\ \hline \hline + 26 & \verb|hours != 0| & \verb|hours == 0| \\ + 29 & \verb|minutes != 0| & \verb|minutes < 0| \\ + 36 & \verb|secs == -1| & \verb|secs <= -1| \\ + 46 & \verb|secs < 0| & \verb|secs >= 0| \\ + 51 & \verb|lastChar(buf) == '0'| & \verb|lastChar(buf) != '0'| + \end{tabular} + \end{center} + Most of them are not weakly killable for the same reason: if the line is reached and infection is observed during execution, it will \textbf{always} cause the control flow to change into another branch and infect the string builder buffer. Except for the mutant in line~51, where in addition an infection will likely cause IndexOutOfRangeExceptions for the following decimal point insertion in line~54. - \begin{lstlisting}[language=Java,belowskip=-0.8\baselineskip] -/* Add code here */ - \end{lstlisting} - % or: \lstinputlisting[language=Java,belowskip=-0.8\baselineskip]{file_name.java} + \lstinputlisting[language=Java,firstline=18,lastline=44,belowskip=-0.8\baselineskip]{DurationTest.java} \end{answer} \item For both applied operators, select one concrete mutation and describe the conditions that need to hold for the \textit{Reachability}, \textit{Infection}, and \textit{Propagation} of the induced change. \begin{answer} - [TODO: Add answer here] + \begin{itemize} + \item \verb+secs < 0 || nanos > 0+ mutation in line~35. In order for the control flow to reach this line the guard in line~32 must be false, which means, either the seconds (not total seconds) or nanoseconds are not zero and still have to be appended, or no hours and minutes have already been appended so we have to append seconds, regardless if they are zero or not. To infect this line we have to create a wrong output in the mutation: + \begin{center} + \begin{tabular}{c|c||c|c|c} + \verb+secs < 0+ & \verb+nanos > 0+ & \verb+&&+ & \verb+||+ & Infected \\ \hline \hline + F & F & F & F & F \\ + F & T & F & T & T \\ + T & F & F & T & T \\ + T & T & T & T & F + \end{tabular} + \end{center} + So, in order to infect the line we have have to make sure exactly one of the conditions from the above table is true. In this case the error will always propagate because in case of infection the buffer will be changed \textbf{or} returned immediately. + + The conditions for the RIP model are as follows: + \begin{itemize} + \item \textbf{Reachability:} $\texttt{secs} \neq 0 \lor \texttt{nanos} \neq 0 \lor (\texttt{hours} = 0 \land \texttt{minutes} = 0)$ + \item \textbf{Infection:} $\texttt{secs} < 0 \oplus \texttt{nanos} > 0$ + \item \textbf{Propagation:} $\top$ + \end{itemize} + + \item \verb+nanos < 0+ in line~35. Reachability is similar to the above (here I am conforming to what we discussed in a previous exercise, where I was told to ignore boolean short circuiting on high-level language view and I will only consider predicate logic). Reachability is similar to the above example, because the source code line is the same. + \begin{center} + \begin{tabular}{c||c|c|c} + \texttt{nanos} & \verb+nanos < 0+ & \verb+nanos > 0+ & Infected \\ \hline \hline + 0 & F & F & F \\ + positive & F & T & T \\ + negative & T & F & T + \end{tabular} + \end{center} + There are only three possible combinations of truth values for the infection matrix, because it is not possible for both to be true at the same time. So infection will always happen if the \texttt{nanos} are non-zero. + + The only possible propagation method for this predicate is the branch in line~35 that is indirectly decided by the mutated statement. If the seconds are negative the branch is directly decided by the infection. If the seconds are non-negative the infection does not change the outcome of the branch predicate and will not propagate. + + The conditions for the RIP model are as follows: + \begin{itemize} + \item \textbf{Reachability:} $\texttt{secs} \neq 0 \lor \texttt{nanos} \neq 0 \lor (\texttt{hours} = 0 \land \texttt{minutes} = 0)$ + \item \textbf{Infection:} $\texttt{nanos} \neq 0$ + \item \textbf{Propagation:} $\texttt{secs} < 0$ + \end{itemize} + \end{itemize} \end{answer} \begin{table}[t]