{ "cells": [ { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "slide" }, "tags": [], "toc-hr-collapsed": false }, "source": [ "# Testing Configurations\n", "\n", "The behavior of a program is not only governed by its data. The _configuration_ of a program – that is, the settings that govern the execution of a program on its (regular) input data, as set by options or configuration files – just as well influences behavior, and thus can and should be tested. In this chapter, we explore how to systematically _test_ and _cover_ software configurations. By _automatically inferring configuration options_, we can apply these techniques out of the box, with no need for writing a grammar. Finally, we show how to systematically cover _combinations_ of configuration options, quickly detecting unwanted interferences." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2023-01-07T14:21:08.892731Z", "iopub.status.busy": "2023-01-07T14:21:08.892346Z", "iopub.status.idle": "2023-01-07T14:21:08.949393Z", "shell.execute_reply": "2023-01-07T14:21:08.949672Z" }, "slideshow": { "slide_type": "skip" } }, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from bookutils import YouTubeVideo\n", "YouTubeVideo('L0ztoXVru2U')" ] }, { "cell_type": "markdown", "metadata": { "button": false, "new_sheet": false, "run_control": { "read_only": false }, "slideshow": { "slide_type": "skip" } }, "source": [ "**Prerequisites**\n", "\n", "* You should have read the [chapter on grammars](Grammars.ipynb).\n", "* You should have read the [chapter on grammar coverage](GrammarCoverageFuzzer.ipynb)." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2023-01-07T14:21:08.951919Z", "iopub.status.busy": "2023-01-07T14:21:08.951609Z", "iopub.status.idle": "2023-01-07T14:21:08.953036Z", "shell.execute_reply": "2023-01-07T14:21:08.953398Z" }, "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "import bookutils" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2023-01-07T14:21:08.955750Z", "iopub.status.busy": "2023-01-07T14:21:08.954932Z", "iopub.status.idle": "2023-01-07T14:21:08.957139Z", "shell.execute_reply": "2023-01-07T14:21:08.957337Z" }, "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "from typing import List, Union, Optional, Callable, Type" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "slideshow": { "slide_type": "skip" }, "tags": [] }, "source": [ "## Synopsis\n", "\n", "\n", "To [use the code provided in this chapter](Importing.ipynb), write\n", "\n", "```python\n", ">>> from fuzzingbook.ConfigurationFuzzer import \n", "```\n", "\n", "and then make use of the following features.\n", "\n", "\n", "This chapter provides two classes:\n", "\n", "* `OptionRunner` automatically extract command-line options from a Python program;\n", "* `OptionFuzzer` uses these to automatically test a Python program with a large variety of options.\n", "\n", "`OptionRunner` runs a program up to the point where it parses its arguments, and then extracts a grammar that describes its invocations:\n", "\n", "```python\n", ">>> autopep8_runner = OptionRunner(\"autopep8\", \"foo.py\")\n", "```\n", "The grammar can be extracted via the method `ebnf_grammar()`:\n", "\n", "```python\n", ">>> option_ebnf_grammar = autopep8_runner.ebnf_grammar()\n", ">>> option_ebnf_grammar\n", "{'': ['(