Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ checkbashisms

# output from runnin jacoco
jacoco.exec

.plume-scripts/
75 changes: 4 additions & 71 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,75 +9,8 @@ clean:
rm -rf "$GRT_TESTING_ROOT"/build/target/*


###
### Code style
###

# Dependencies are defined below.
style-fix:
style-check:

style-fix: markdownlint-fix
markdownlint-fix:
@markdownlint-cli2 --fix "**/*.md" "#node_modules"
style-check: markdownlint-check
markdownlint-check:
@markdownlint-cli2 "**/*.md" "#node_modules"

style-fix: python-style-fix
style-check: python-style-check python-typecheck
PYTHON_FILES:=$(wildcard **/*.py) $(shell grep -r -l --exclude-dir=.git --exclude-dir=.venv --exclude='*.py' --exclude='#*' --exclude='*~' --exclude='*.tar' --exclude=gradlew --exclude=lcb_runner '^\#! \?\(/bin/\|/usr/bin/\|/usr/bin/env \)python')
python-style-fix:
ifneq (${PYTHON_FILES},)
# @uvx ruff --version
@uvx ruff format ${PYTHON_FILES}
@uvx ruff check ${PYTHON_FILES} --fix
endif
python-style-check:
ifneq (${PYTHON_FILES},)
# @uvx ruff --version
@uvx ruff format --check ${PYTHON_FILES}
@uvx ruff check ${PYTHON_FILES}
endif
python-typecheck:
ifneq (${PYTHON_FILES},)
@uv run ty check
endif
showvars::
@echo "PYTHON_FILES=${PYTHON_FILES}"

style-fix: shell-style-fix
style-check: shell-style-check
SH_SCRIPTS := $(shell grep -r -l --exclude-dir=.git --exclude-dir=.plume-scripts --exclude-dir=build --exclude-dir=subject-programs --exclude='#*' --exclude='*~' --exclude='*.tar' --exclude=gradlew '^\#! \?\(/bin/\|/usr/bin/env \)sh' | grep -v addrfilter | grep -v cronic-orig | grep -v mail-stackoverflow.sh | sort)
BASH_SCRIPTS := $(shell grep -r -l --exclude-dir=.git --exclude-dir=.plume-scripts --exclude-dir=build --exclude-dir=subject-programs --exclude='#*' --exclude='*~' --exclude='*.tar' --exclude=gradlew '^\#! \?\(/bin/\|/usr/bin/env \)bash' | grep -v addrfilter | grep -v cronic-orig | grep -v mail-stackoverflow.sh | sort)
CHECKBASHISMS := $(shell if command -v checkbashisms > /dev/null ; then \
echo "checkbashisms" ; \
else \
wget -q -N https://homes.cs.washington.edu/~mernst/software/checkbashisms && \
mv checkbashisms .checkbashisms && \
chmod +x ./.checkbashisms && \
echo "./.checkbashisms" ; \
fi)
SHFMT_EXISTS := $(shell command -v shfmt 2> /dev/null)
shell-style-fix:
ifneq ($(SH_SCRIPTS)$(BASH_SCRIPTS),)
ifdef SHFMT_EXISTS
@shfmt -w -i 2 -ci -bn -sr ${SH_SCRIPTS} ${BASH_SCRIPTS}
endif
@shellcheck -x -P SCRIPTDIR --format=diff ${SH_SCRIPTS} ${BASH_SCRIPTS} | patch -p1
endif
shell-style-check:
ifneq ($(SH_SCRIPTS)$(BASH_SCRIPTS),)
ifdef SHFMT_EXISTS
@shfmt -d -i 2 -ci -bn -sr ${SH_SCRIPTS} ${BASH_SCRIPTS}
endif
@shellcheck -x -P SCRIPTDIR --format=gcc ${SH_SCRIPTS} ${BASH_SCRIPTS}
endif
ifneq ($(SH_SCRIPTS),)
@${CHECKBASHISMS} -l ${SH_SCRIPTS}
# Code style; defines `style-check` and `style-fix`.
ifeq (,$(wildcard .plume-scripts))
dummy != git clone -q https://github.com/plume-lib/plume-scripts.git .plume-scripts
endif
showvars::
@echo "SH_SCRIPTS=${SH_SCRIPTS}"
@echo "BASH_SCRIPTS=${BASH_SCRIPTS}"
@echo "CHECKBASHISMS=${CHECKBASHISMS}"
@echo "SHFMT_EXISTS=${SHFMT_EXISTS}"
include .plume-scripts/code-style.mak
31 changes: 14 additions & 17 deletions scripts/experiment-scripts/generate-grt-figures.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
This script defines utilities to generate plots and tables based on coverage and mutation score.
"""Define utilities to generate plots and tables based on coverage and mutation score.

This script is **not intended to be run directly**. Instead, use one of these scripts:
./mutation-fig6-table3.sh
./mutation-fig7.sh
Expand All @@ -14,25 +14,24 @@
- Figures 8-9: Line plots showing the progression of branch coverage over time for each GRT
component on two hand-picked subject programs.
- Table IV: Number of real bugs detected by GRT, Randoop, and EvoSuite on four Defects4J projects
under different time budgets (120s, 300s, and 600s). Results are aggregated over 10 runs per fault.
under different time budgets (120s, 300s, 600s). Results are aggregated over 10 runs per fault.

Usage (for reference only):
python generate-grt-figures.py { fig6-table3 | fig7 | fig8-9 | table4 }
"""

import matplotlib as mpl
import pandas as pd

import argparse
import sys

import matplotlib as mpl

mpl.use("Agg") # For headless environments (without GUI); execute before `import matplotlib.figure`
import matplotlib.figure
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from matplotlib.backends.backend_pdf import PdfPages

mpl.use("Agg") # For headless environments (without GUI)


def main():
"""Parse arguments, load and process data, and save the selected figure type."""
Expand All @@ -52,8 +51,7 @@ def main():


def load_data(csv_file: str) -> pd.DataFrame:
"""
Load a CSV file containing coverage and mutation score data.
"""Load a CSV file containing coverage and mutation score data.

Args:
csv_file: Path to the CSV file.
Expand Down Expand Up @@ -95,7 +93,6 @@ def generate_table_3(df: pd.DataFrame) -> mpl.figure.Figure:
Returns:
The composite figure representing Table III.
"""

grouped = (
df.groupby(["Version", "TimeLimit"])
.agg(
Expand Down Expand Up @@ -258,8 +255,9 @@ def generate_fig_8_9(df: pd.DataFrame) -> list[mpl.figure.Figure]:


def generate_table_4(df: pd.DataFrame) -> mpl.figure.Figure:
"""
Generate Table IV: Number of real faults detected by each tool (GRT, Randoop, EvoSuite)
"""Generate Table IV.

Table IV is: Number of real faults detected by each tool (GRT, Randoop, EvoSuite)
on different subject programs under different time budgets.

Args:
Expand Down Expand Up @@ -300,8 +298,8 @@ def generate_table_4(df: pd.DataFrame) -> mpl.figure.Figure:
plt.axis("off")

# Table headers.
headers = ["Project", "Time"] + list(table_data.columns[2:])
cell_data = [headers] + table_data.values.tolist()
headers = ["Project", "Time", *list(table_data.columns[2:])]
cell_data = [headers, *table_data.to_numpy().tolist()]

table = plt.table(cellText=cell_data, loc="center", cellLoc="center")
table.auto_set_font_size(False)
Expand All @@ -315,8 +313,7 @@ def generate_table_4(df: pd.DataFrame) -> mpl.figure.Figure:


def save_to_pdf(df: pd.DataFrame, fig_type: str):
"""
Save a figure/table of the given type to a PDF file.
"""Save a figure/table of the given type to a PDF file.

Args:
df: Data averaged over repeated runs (output of `average_over_loops`).
Expand Down
Loading