Configuration Options#

              /\___/\              ,'.-.'.           .-"-.
              `)9 9('              '\~ o/`          /|6 6|\
              {_:Y:.}_              { @ }          {/(_0_)\}
--------------( )U-'( )----------oOo-----oOo------oOo--U--oO--------------------
____|_______|_______|_______|_______|_______|_______|_______|_______|_______|___

Configuration Module#

Poodle imports module poodle_config.py, if available, to set configuration options.

Configuration File#

Poodle will search for available configuration files, and use the first available file from this list:

  1. poodle.toml

  2. pyproject.toml

Command Line#

Usage: poodle [OPTIONS] [SOURCES]...

  Poodle Mutation Test Tool.

Options:
  -c PATH         Configuration File.
  -q              Quiet mode: q, qq, or qqq
  -v              Verbose mode: v, vv, or vvv
  -w INTEGER      Maximum number of parallel workers.
  --exclude TEXT  Add a regex exclude file filter. Multiple allowed.
  --only TEXT     Glob pattern for files to mutate. Multiple allowed.
  --help          Show this message and exit.

Command Line Options#

Quiet or Verbose#

The -q and -v flags control how quiet or verbose poodle will be. These flags influence the values of echo_enabled and log_level.

Command Line

echo_enabled

log_level

poodle -qqq

False

logging.CRITICAL

poodle -qq

False

logging.ERROR

poodle -q

False

logging.WARN

poodle (default)

True

logging.WARN

poodle -v

True

logging.INFO

poodle -vv

True

logging.DEBUG

poodle -vvv

True

logging.NOTSET

OPTIONS#

Unless otherwise stated, options are chosen in this priority order:

  1. Command Line options

  2. Module poodle_config.py

  3. Chosen Configuration File

config_file#

By default, Poodle will search for available configuration files, and use the first available file from this list:

  1. poodle.toml

  2. pyproject.toml

the config_file option is used to specify an alternate config file.

Do not use config_file for specifying location of poodle_config.py

Accepted formats: toml

poodle -c=config.toml

config_file = "config.toml"

source_folders#

Folder(s) that contain your modules and/or packages.

Default: [“src”, “lib”]

Running each Trial consists of 3 steps:

  1. Copy contents of a source folder to a temporary location.

  2. Apply a single mutation to the copy of the source file.

  3. Run test suite with the temporary folder added to the python path.

The list of source folders is a root folder that should be copied to a temporary location.

Typically, this is a folder like ‘src’ or ‘lib’. But could be almost anything depending on your project structure.

It should be the folder that contains your top level modules and/or packages. It should not be the package folder itself.

If the python files are in the working folder, specify this as ‘.’

More than one can be specified.

Note

Any folders specified in command line or in config files must exist. If none is specified, it will use ‘src’ and/or ‘lib’ only if they exist.

poodle myapp myotherapp
source_folders = ["myapp", "myotherapp"]
[poodle]
source_folders = ["myapp", "myotherapp"]
[tool.poodle]
source_folders = ["myapp", "myotherapp"]

only_files#

Only run mutation on files that match specified GLOB patterns.

When not specified, all python files that are in a source_folder, and don’t match a file_filter are mutated.

Default: None

poodle --only cli.py --only model_*.py
only_files = ["cli.py", "model_*.py"]
[poodle]
only_files = ["cli.py", "model_*.py"]
[tool.poodle]
only_files = ["cli.py", "model_*.py"]

file_filters#

Files that match these filters will NOT be mutated.

Poodle uses glob matching from the wcmatch package for matching and filtering files.

Default: ["test_*.py", "*_test.py"]

poodle --exclude sql_*.py --only text_*.py
file_filters = ["sql_*.py", "text_*.py"]
[poodle]
file_filters = ["sql_*.py", "text_*.py"]
[tool.poodle]
file_filters = ["sql_*.py", "text_*.py"]

file_flags#

This option is to set the flags used when searching source folders for files to mutate, and applying exclude filters. These flags are used either for searching with only_files or with file_filters.

Poodle uses glob matching from the wcmatch package for matching and filtering files.

Default: wcmatch.glob.GLOBSTAR | wcmatch.glob.NODIR

from wcmatch import glob
file_flags = glob.GLOBSTAR | glob.NODIR | glob.DOTGLOB
[poodle]
file_flags = 16704
[tool.poodle]
file_flags = 16704

Tip

Recommend setting this value in poodle_config.py only. It must resolve to an int value.

Setting this in toml has to be resolved int value of combining the flags.

file_copy_filters#

Files that match these filters will NOT be copied to the temporary location.

Poodle uses glob matching from the wcmatch package for matching and filtering files.

Default: ["test_*.py", "*_test.py", "__pycache__/**"]

file_copy_filters = ["log.txt", "*.mdb"]
[poodle]
file_copy_filters = ["log.txt", "*.mdb"]
[tool.poodle]
file_copy_filters = ["log.txt", "*.mdb"]

file_copy_flags#

This option is to set the flags used when searching source folders for files copy to the temporary location. These flags are used for searching with file_copy_filters.

Poodle uses glob matching from the wcmatch package for matching and filtering files.

Default: wcmatch.glob.GLOBSTAR | wcmatch.glob.NODIR

from wcmatch import glob
file_copy_flags = glob.GLOBSTAR | glob.NODIR | glob.DOTGLOB
[poodle]
file_copy_flags = 16704
[tool.poodle]
file_copy_flags = 16704

Tip

Recommend setting this value in poodle_config.py only. It must resolve to an int value.

Setting this in toml has to be resolved int value of combining the flags.

work_folder#

Folder where temporary files will be stored. Folder is deleted before and after execution.

Default: .poodle-temp

work_folder = "temp-files"
[poodle]
work_folder = "temp-files"
[tool.poodle]
work_folder = "temp-files"

max_workers#

By default, poodle sets the number of workers to be one less than the available CPUs from os.sched_getaffinity or os.cpu_count. Use this option to manually set the number of workers. With too few workers, available CPU is underutilized. With too many workers, additional overhead of process switching slows execution.

poodle -w 4
max_workers = 4
[poodle]
max_workers = 4
[tool.poodle]
max_workers = 4

log_format#

Logging Format for python’s logging package.

Default: "%(levelname)s [%(process)d] %(name)s.%(funcName)s:%(lineno)d - %(message)s"

log_format = "%(levelname)s - %(message)s"
[poodle]
log_format = "%(levelname)s - %(message)s"
[tool.poodle]
log_format = "%(levelname)s - %(message)s"

log_level#

Logging Level for python’s logging package.

Default: logging.WARN

python -v

See: Quiet or Verbose

log_level = logging.INFO
[poodle]
log_level = "INFO"
[tool.poodle]
log_level = "INFO"

echo_enabled#

This determines if Poodle’s normal output should be enabled or not.

Default: True

python -q

See: Quiet or Verbose

echo_enabled = False
[poodle]
echo_enabled = "False"
[tool.poodle]
echo_enabled = "False"

add_mutators#

Additional mutators to be used when creating mutations. This list can contain any of the following:

  • Reference to the Mutator Class type

  • Reference to the Mutator Function

  • String fully qualified name of the Mutator Class

  • String fully qualified name of the Mutator Function

Default: []

from poodle import Mutator

class CustomMutator(Mutator):
  ...

def other_mutator(config, echo, parsed_ast, *_, *__,):
  ...

add_mutators = [
    CustomMutator,
    other_mutator,
    "poodle-ext.mutators.SpecialObjectMutator",
    "poodle-ext.mutators.my_object_mutator",
]
[poodle]
add_mutators = [
    "poodle-ext.mutators.SpecialObjectMutator",
    "poodle-ext.mutators.my_object_mutator",
]
[tool.poodle]
add_mutators = [
    "poodle-ext.mutators.SpecialObjectMutator",
    "poodle-ext.mutators.my_object_mutator",
]

skip_mutators#

Disables selected builtin mutators. Specify the name of the mutator. See Poodle’s Mutators

Default: []

skip_mutators = ["FuncCall","DictArray"]
[poodle]
skip_mutators = ["FuncCall","DictArray"]
[tool.poodle]
skip_mutators = ["FuncCall","DictArray"]

mutator_opts#

This dict contains options that are used by various mutators. Options for builtin mutators are listed below, and detailed on the Mutator page.

Default: {}

mutator_opts = {"operator_level":"min"}
[poodle.mutator_opts]
operator_level = "min"
[tool.poodle.mutator_opts]
operator_level = "min"

Builtin mutator_opts#

runner#

Indicates which trial runner to use. Can be any of the following:

  • Name of a builtin Runner Function

  • Reference to the Runner Function

  • String fully qualified name of the Runner Function

Default: “command_line”

def my_runner(config, echo, run_folder, mutant, timeout, *_, *__,):
  ...

runner = my_runner
runner = "poodle-ext.runners.cool_runner"
[poodle]
runner = "poodle-ext.runners.cool_runner"
[tool.poodle]
runner = "poodle-ext.runners.cool_runner"

runner_opts#

This dict contains options that are used by various runners. Options for builtin runners are listed below, and detailed on the Runner page.

Default: {"command_line": "pytest -x --assert=plain -o pythonpath="}

runner_opts = {
  "command_line":"pytest -x --assert=plain -o pythonpath= --sort-mode=fastest",
  "command_line_env":{"RUN_MODE":"MUTATION"},
}
[poodle.runner_opts]
command_line = "pytest -x --assert=plain -o pythonpath= --sort-mode=fastest"

[poodle.runner_opts.command_line_env]
RUN_MODE = "MUTATION"
[tool.poodle.runner_opts]
command_line = "pytest -x --assert=plain -o pythonpath= --sort-mode=fastest"

[tool.poodle.runner_opts.command_line_env]
RUN_MODE = "MUTATION"

Builtin runner_opts#

min_timeout#

Default: 10 (seconds)

Shortest timeout value, in seconds, that can be used in the runner.

Timeout value is calculated as longest run from clean run tests, multiplied by timeout_multiplier.

If this calculated value is smaller than min_timeout, min_timeout is used instead.

min_timeout = 15
[poodle]
min_timeout = 15
[tool.poodle]
min_timeout = 15

timeout_multiplier#

Used to calculate timeout value to use in runner. Timeout value is calculated as longest run from clean run tests, multiplied by timeout_multiplier.

Default: 10

timeout_multiplier = 2
[poodle]
timeout_multiplier = 2
[tool.poodle]
timeout_multiplier = 2

reporters#

List of all mutators to be used after all trials are completed. This list can contain any of the following:

  • Name of a Builtin Reporter

  • Reference to the Mutator Class type

  • Reference to the Mutator Function

  • String fully qualified name of the Mutator Class

  • String fully qualified name of the Mutator Function

Default: ["summary", "not_found"]

def my_reporter(config, echo, testing_results, *_, **__):
   ...

reporters = [
    "summary",
    my_reporter,
    "poodle-ext.reporters.UploadToResultsServer",
    "poodle-ext.reporters.text_errors_file",
]
[poodle]
add_mutators = [
    "summary",
    "poodle-ext.reporters.UploadToResultsServer",
    "poodle-ext.reporters.text_errors_file",
]
[tool.poodle]
add_mutators = [
    "summary",
    "poodle-ext.reporters.UploadToResultsServer",
    "poodle-ext.reporters.text_errors_file",
]

reporter_opts#

This dict contains options that are used by various reporters. Options for builtin reporters are listed below, and detailed on the Reporter page.

Default: {}

reporter_opts = {"not_found_file":"mutants-not-found.txt"}
[poodle.reporter_opts]
not_found_file = "mutants-not-found.txt"
[tool.poodle.reporter_opts]
not_found_file = "mutants-not-found.txt"

Builtin reporter_opts#