kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #38107
Re: [PATCH] Fuzzable PCB parsing test harness
Hi Wayne,
Hmm, didn't expect that to be an issue! Try a ToStdString() for size?
Cheers,
John
On Mon, Oct 22, 2018 at 2:39 PM Wayne Stambaugh <stambaughw@xxxxxxxxx> wrote:
>
> Hey John,
>
> You not giving up on this are you ;). I builds fine for mingw32 and
> passes all of the tests. However, the mingw64 build fails with:
>
> C:/msys64/home/wstambaugh/src/kicad-trunk/qa/pcb_parse_input/main.cpp:
> In function 'int main(int, char**)':
> C:/msys64/home/wstambaugh/src/kicad-trunk/qa/pcb_parse_input/main.cpp:148:32:
> error: call of overloaded 'open(const wxString&)' is ambiguous
> fin.open( filename );
> ^
> In file included from
> C:/msys64/home/wstambaugh/src/kicad-trunk/qa/qa_utils/stdstream_line_reader.h:32,
> from
> C:/msys64/home/wstambaugh/src/kicad-trunk/qa/pcb_parse_input/main.cpp:32:
> C:/msys64/mingw64/include/c++/8.2.0/fstream:653:7: note: candidate:
> 'void std::basic_ifstream<_CharT, _Traits>::open(const char*,
> std::ios_base::openmode) [with _CharT = char; _Traits =
> std::char_traits<char>; std::ios_base::openmode = std::_Ios_Openmode]'
> open(const char* __s, ios_base::openmode __mode = ios_base::in)
> ^~~~
> C:/msys64/mingw64/include/c++/8.2.0/fstream:673:7: note: candidate:
> 'void std::basic_ifstream<_CharT, _Traits>::open(const wchar_t*,
> std::ios_base::openmode) [with _CharT = char; _Traits =
> std::char_traits<char>; std::ios_base::openmode = std::_Ios_Openmode]'
> open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in)
> ^~~~
>
> On 10/22/2018 4:57 AM, John Beard wrote:
> > Hi Wayne,
> >
> > Since I'm out of better ideas and can't replicate the link failure on
> > Jenkins, here's a patch that uses the long list from pcb_test_window.
> > Presumably it's there for some reason, though there is no comment or
> > Git log clue that I can see.
> >
> > Could you see if that works for you?
> >
> > Cheers,
> >
> > John
> > On Fri, Oct 19, 2018 at 12:09 PM John Beard <john.j.beard@xxxxxxxxx> wrote:
> >>
> >> Hi Wayne,
> >>
> >> That's pretty odd, the incantations are practically the same.
> >>
> >> The only other difference between this and the other pcb-based
> >> programs is this line:
> >>
> >> add_dependencies( pnsrouter pcbcommon pcad2kicadpcb
> >> ${GITHUB_PLUGIN_LIBRARIES} )
> >>
> >> Which I can't really see making the difference (I think it's there for
> >> a header dependency).
> >>
> >> And the very long target_link_libraries list that lists everything 4
> >> times and then a bit more. I thing replicating that long list might
> >> fix it, but it doesn't seem very tidy. The list from test_window:
> >>
> >> polygon pnsrouter common pcbcommon bitmaps polygon pnsrouter
> >> common pcbcommon bitmaps polygon pnsrouter common pcbcommon bitmaps
> >> polygon pnsrouter common pcbcommon 3d-viewer bitmaps gal pcad2kicadpcb
> >> common
> >>
> >> Cheers,
> >>
> >> John
> >> On Thu, Oct 18, 2018 at 2:22 PM Wayne Stambaugh <stambaughw@xxxxxxxxx> wrote:
> >>>
> >>> Hey John,
> >>>
> >>> Below is the verbose output. I hope it helps.
> >>>
> >>> [ 98%] Linking CXX executable qa_pcb_parse_input.exe
> >>> cd
> >>> /C/msys64/home/wstambaugh/build32/kicad/trunk-release/qa/pcb_parse_input
> >>> && /C/msys64/mingw32/bin/cmake.exe -E remove -f
> >>> CMakeFiles/qa_pcb_parse_input.dir/objects.a
> >>> cd
> >>> /C/msys64/home/wstambaugh/build32/kicad/trunk-release/qa/pcb_parse_input
> >>> && /C/msys64/mingw32/bin/ar.exe cr
> >>> CMakeFiles/qa_pcb_parse_input.dir/objects.a
> >>> @CMakeFiles/qa_pcb_parse_input.dir/objects1.rsp
> >>> cd
> >>> /C/msys64/home/wstambaugh/build32/kicad/trunk-release/qa/pcb_parse_input
> >>> && /C/msys64/mingw32/bin/g++.exe -Wall -Wsuggest-override
> >>> -Wno-unused-local-typedefs -Wno-strict-aliasing -mthreads -fpermissive
> >>> -O3 -DNDEBUG -s -Wl,--whole-archive
> >>> CMakeFiles/qa_pcb_parse_input.dir/objects.a -Wl,--no-whole-archive -o
> >>> qa_pcb_parse_input.exe
> >>> -Wl,--major-image-version,0,--minor-image-version,0
> >>> ../../common/libpcbcommon.a ../../common/liblegacy_wx.a
> >>> ../../common/libcommon.a ../../bitmaps_png/libbitmaps.a
> >>> ../../polygon/libpolygon.a ../../common/libgal.a
> >>> ../../pcbnew/pcad2kicadpcb_plugin/libpcad2kicadpcb.a
> >>> ../../pcbnew/github/libgithub_plugin.a ../qa_utils/libqa_utils.a
> >>> -LC:/msys64/mingw32/lib -pipe -Wl,--subsystem,windows -mwindows
> >>> -lwx_mswu_gl-3.0 -lwx_mswu_aui-3.0 -lwx_mswu_adv-3.0 -lwx_mswu_html-3.0
> >>> -lwx_mswu_core-3.0 -lwx_baseu_net-3.0 -lwx_baseu-3.0 -lwx_baseu_xml-3.0
> >>> -lwx_mswu_stc-3.0 -lws2_32 ../../common/libcommon.a
> >>> ../../common/libgal.a -lglew32 -lcairo -lpixman-1 -lopengl32 -lglu32
> >>> -lcurl -lssl -lcrypto -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32
> >>> -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
> >>> C:/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/7.3.0/../../../../i686-w64-mingw32/bin/ld.exe:
> >>> ../../common/libcommon.a(marker_base.cpp.obj):marker_base.cpp:(.text+0xee9):
> >>> undefined reference to `DRC_ITEM::ShowHtml(EDA_UNITS_T) const'
> >>> collect2.exe: error: ld returned 1 exit status
> >>> make[2]: ***
> >>> [qa/pcb_parse_input/CMakeFiles/qa_pcb_parse_input.dir/build.make:163:
> >>> qa/pcb_parse_input/qa_pcb_parse_input.exe] Error 1
> >>> make[2]: Leaving directory '/home/wstambaugh/build32/kicad/trunk-release'
> >>> make[1]: *** [CMakeFiles/Makefile2:3431:
> >>> qa/pcb_parse_input/CMakeFiles/qa_pcb_parse_input.dir/all] Error 2
> >>> make[1]: Leaving directory '/home/wstambaugh/build32/kicad/trunk-release'
> >>> make: *** [Makefile:141: all] Error 2
> >>>
> >>>
> >>> On 10/17/2018 6:42 PM, John Beard wrote:
> >>>> Hi Wayne,
> >>>>
> >>>> Could you try to build with VERBOSE=1 so I can see what the failed link
> >>>> command line looks like and compare to Jenkins?
> >>>>
> >>>> Cheers,
> >>>>
> >>>> John
> >>>>
> >>>> On 17 October 2018 13:17:34 BST, Wayne Stambaugh <stambaughw@xxxxxxxxx>
> >>>> wrote:
> >>>>
> >>>> Hey John,
> >>>>
> >>>> Close but no cigar. I'm still getting a single link error.
> >>>>
> >>>> C:/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/7.3.0/../../../../i686-w64-mingw32/bin/ld.exe:
> >>>> ../../common/libcommon.a(marker_base.cpp.obj):marker_base.cpp:(.text+0xee9):
> >>>> undefined reference to `DRC_ITEM::ShowHtml(EDA_UNITS_T) const'
> >>>> collect2.exe: error: ld returned 1 exit status
> >>>> [100%] Built target eeschema
> >>>> make[2]: ***
> >>>> [qa/pcb_parse_input/CMakeFiles/qa_pcb_parse_input.dir/build.make:163:
> >>>> qa/pcb_parse_input/qa_pcb_parse_input.exe] Error 1
> >>>> make[1]: *** [CMakeFiles/Makefile2:3431:
> >>>> qa/pcb_parse_input/CMakeFiles/qa_pcb_parse_input.dir/all] Error 2
> >>>> make[1]: *** Waiting for unfinished jobs....
> >>>> [100%] Built target pcbnew_kiface
> >>>> make: *** [Makefile:141: all] Error 2
> >>>>
> >>>>
> >>>> On 10/16/2018 9:28 AM, John Beard wrote:
> >>>>
> >>>> Hi Wayne,
> >>>>
> >>>> I think I might have fixed the ordering in the link libraries (at
> >>>> least, it now builds on Jenkins).
> >>>>
> >>>> This is just the first patch to focus on the build error, I'll
> >>>> rebase
> >>>> the other docs stuff later if/when it works.
> >>>>
> >>>> Cheers,
> >>>>
> >>>> John
> >>>> On Fri, Oct 12, 2018 at 7:58 PM Wayne Stambaugh
> >>>> <stambaughw@xxxxxxxxx> wrote:
> >>>>
> >>>>
> >>>> John,
> >>>>
> >>>> This patch fails to link on windows. I've attached the build
> >>>> error.
> >>>>
> >>>> Wayne
> >>>>
> >>>> On 10/9/2018 9:53 AM, John Beard wrote:
> >>>>
> >>>> Hi,
> >>>>
> >>>> Here is an update patch that rebases over the commenting
> >>>> out of
> >>>> pcb_test_window, polygon_triangulation and
> >>>> polygon_generator and fixes
> >>>> a link error to do with base_screen.cpp.
> >>>>
> >>>> Cheers,
> >>>>
> >>>> John
> >>>> On Mon, Oct 8, 2018 at 5:27 PM John Beard
> >>>> <john.j.beard@xxxxxxxxx> wrote:
> >>>>
> >>>>
> >>>> Sorry,
> >>>>
> >>>> I wrote "ms", I meant "us" - the times are in the
> >>>> handful-of-millsecond range.
> >>>>
> >>>> Cheers,
> >>>>
> >>>> John
> >>>> On Mon, Oct 8, 2018 at 5:24 PM John Beard
> >>>> <john.j.beard@xxxxxxxxx> wrote:
> >>>>
> >>>>
> >>>> Hi,
> >>>>
> >>>> This is a patch to add a test program that
> >>>> allows to parse a Pcbnew
> >>>> file from command line params or stdin. This
> >>>> means you can use it for
> >>>> fuzz testing.
> >>>>
> >>>> I have done a little bit of fuzz testing so far
> >>>> (8 million execs,
> >>>> about 70% of a cycle), and have not found any
> >>>> crashes, but I can make
> >>>> it hang in a few ways. These all seem to be in
> >>>> streams which contain
> >>>> nul's. This is actually not reachable from the
> >>>> UI due to reading files
> >>>> into wxStrings first (nut quite sure why),
> >>>> whereas this program uses
> >>>> the parser directly. Thus, the bug is probably
> >>>> not very critical.
> >>>> Example hanging input attached (note there's a
> >>>> nul in it, so your
> >>>> editor may or may not like that).
> >>>>
> >>>> This program can also be fed a number of files,
> >>>> which means it could
> >>>> be used for automated testing that all files in
> >>>> a batch can be parsed
> >>>> successfully, and also provides a handy way to
> >>>> put GDB on a program
> >>>> when debugging the parser against specific input.
> >>>>
> >>>> There is timing on the parsing too, mostly for
> >>>> interest (use the -v
> >>>> flag). It takes about 150-3000ms per FP on my
> >>>> machine for the FPs in
> >>>> Connector_PinSocket_2.54mm.pretty.
> >>>>
> >>>> There's also some centralisation of some
> >>>> QA-related utils into a
> >>>> qa_utils library.
> >>>>
> >>>> Cheers,
> >>>>
> >>>> John
> >>>> ------------------------------------------------------------------------
> >>>> Mailing list:
> >>>> https://launchpad.net/~kicad-developers
> >>>> Post to : kicad-developers@xxxxxxxxxxxxxxxxxxx
> >>>> Unsubscribe :
> >>>> https://launchpad.net/~kicad-developers
> >>>> More help : https://help.launchpad.net/ListHelp
> >>>>
> >>>> ------------------------------------------------------------------------
> >>>> Mailing list: https://launchpad.net/~kicad-developers
> >>>> Post to : kicad-developers@xxxxxxxxxxxxxxxxxxx
> >>>> Unsubscribe : https://launchpad.net/~kicad-developers
> >>>> More help : https://help.launchpad.net/ListHelp
> >>>>
From 94deb0f1668e982bb382e363e020ea741d8f5977 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Sat, 6 Oct 2018 15:35:17 +0100
Subject: [PATCH] QA: PCB file input parse test program (fuzzable)
This adds a test program which can be used to test the
parsing of a given KiCad PCB file. This interface is
useful for both manual or automated debugging of given
files, as well as providing an interface suitable for
fuzz-testing tools.
Also adds to the testing docs to detail how fuzzing can
be used.
Also moves some useful re-usable code from io-benchmark
to a new library qa_utils, which can contain code that
isn't need in the actual KiCad libs.
---
Documentation/development/testing.md | 47 +++++-
qa/CMakeLists.txt | 4 +
qa/pcb_parse_input/CMakeLists.txt | 90 ++++++++++
qa/pcb_parse_input/main.cpp | 158 ++++++++++++++++++
qa/qa_utils/CMakeLists.txt | 40 +++++
qa/qa_utils/scoped_timer.h | 62 +++++++
.../qa_utils}/stdstream_line_reader.cpp | 8 +-
.../qa_utils}/stdstream_line_reader.h | 8 +-
tools/io_benchmark/CMakeLists.txt | 2 +-
9 files changed, 410 insertions(+), 9 deletions(-)
create mode 100644 qa/pcb_parse_input/CMakeLists.txt
create mode 100644 qa/pcb_parse_input/main.cpp
create mode 100644 qa/qa_utils/CMakeLists.txt
create mode 100644 qa/qa_utils/scoped_timer.h
rename {tools/io_benchmark => qa/qa_utils}/stdstream_line_reader.cpp (91%)
rename {tools/io_benchmark => qa/qa_utils}/stdstream_line_reader.h (92%)
diff --git a/Documentation/development/testing.md b/Documentation/development/testing.md
index 4726ca536..cf0d4c129 100644
--- a/Documentation/development/testing.md
+++ b/Documentation/development/testing.md
@@ -103,6 +103,51 @@ You can run the tests in GDB to trace this:
If the test segfaults, you will get a familiar backtrace, just like
if you were running pcbnew under GDB.
+## Fuzz testing ##
+
+It is possible to run fuzz testing on some parts of KiCad. To do this for a
+generic function, you need to be able to pass some kind of input from the fuzz
+testing tool to the function under test.
+
+For example, to use the [AFL fuzzing tool][], you will need:
+
+* A test executable that can:
+** Receive input from `stdin` to be run by `afl-fuzz`.
+** Optional: process input from a filename to allow `afl-tmin` to minimise the
+ input files.
+* To compile this executable with an AFL compiler, to enable the instrumentation
+ that allows the fuzzer to detect the fuzzing state.
+
+For example, the `qa_pcb_parse_input` executable can be compiled like this:
+
+ mkdir build
+ cd build
+ cmake -DCMAKE_CXX_COMPILER=/usr/bin/afl-clang-fast++ -DCMAKE_C_COMPILER=/usr/bin/afl-clang-fast ../kicad_src
+ make qa_pcb_parse_input
+
+You may need to disable core dumps and CPU frequency scaling on your system (AFL
+will warn you if you should do this). For example, as root:
+
+ # echo core >/proc/sys/kernel/core_pattern
+ # echo performance | tee cpu*/cpufreq/scaling_governor
+
+To fuzz:
+
+ afl-fuzz -i fuzzin -o fuzzout -m500 qa/pcb_parse_input/qa_pcb_parse_input
+
+where:
+
+* `-i` is a directory of files to use as fuzz input "seeds"
+* `-o` is a directory to write the results (including inputs that provoke crashes
+ or hangs)
+* `-t` is the maximum time that a run is allowed to take before being declared a "hang"
+* `-m` is the memory allowed to use (this often needs to be bumped, as KiCad code
+ tends to use a lot of memory to initialise)
+
+The AFL TUI will then display the fuzzing progress, and you can use the hang- or
+crash-provoking inputs to debug code as needed.
+
[CTest]: https://cmake.org/cmake/help/latest/module/CTest.html
[Boost Unit Test framework]: https://www.boost.org/doc/libs/1_68_0/libs/test/doc/html/index.html
-[boost-test-functions]: https://www.boost.org/doc/libs/1_68_0/libs/test/doc/html/boost_test/utf_reference/testing_tool_ref.html
\ No newline at end of file
+[boost-test-functions]: https://www.boost.org/doc/libs/1_68_0/libs/test/doc/html/boost_test/utf_reference/testing_tool_ref.html
+[AFL fuzzing tool]: http://lcamtuf.coredump.cx/afl/
\ No newline at end of file
diff --git a/qa/CMakeLists.txt b/qa/CMakeLists.txt
index 36aa7b601..ae30e1a38 100644
--- a/qa/CMakeLists.txt
+++ b/qa/CMakeLists.txt
@@ -12,8 +12,12 @@ if( KICAD_SCRIPTING_MODULES )
endif()
+# common QA helpers
+add_subdirectory( qa_utils )
+
add_subdirectory( common )
add_subdirectory( shape_poly_set_refactor )
+add_subdirectory( pcb_parse_input )
# add_subdirectory( pcb_test_window )
# add_subdirectory( polygon_triangulation )
# add_subdirectory( polygon_generator )
\ No newline at end of file
diff --git a/qa/pcb_parse_input/CMakeLists.txt b/qa/pcb_parse_input/CMakeLists.txt
new file mode 100644
index 000000000..75ce4baff
--- /dev/null
+++ b/qa/pcb_parse_input/CMakeLists.txt
@@ -0,0 +1,90 @@
+# This program source code file is part of KiCad, a free EDA CAD application.
+#
+# Copyright (C) 2018 KiCad Developers, see CHANGELOG.TXT for contributors.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, you may find one here:
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# or you may search the http://www.gnu.org website for the version 2 license,
+# or you may write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+
+if( BUILD_GITHUB_PLUGIN )
+ set( GITHUB_PLUGIN_LIBRARIES github_plugin )
+endif()
+
+add_dependencies( pnsrouter pcbcommon pcad2kicadpcb ${GITHUB_PLUGIN_LIBRARIES} )
+
+add_executable( qa_pcb_parse_input
+ # This is needed for the global mock objects
+ ../qa_utils/mocks.cpp
+
+ main.cpp
+
+ ../../common/base_units.cpp
+ ../../common/xnode.cpp
+ ../../common/base_screen.cpp
+)
+
+include_directories( BEFORE ${INC_BEFORE} )
+include_directories(
+ ${CMAKE_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_SOURCE_DIR}/polygon
+ ${CMAKE_SOURCE_DIR}/pcbnew
+ ${CMAKE_SOURCE_DIR}/common
+ ${CMAKE_SOURCE_DIR}/pcbnew/router
+ ${CMAKE_SOURCE_DIR}/pcbnew/tools
+ ${CMAKE_SOURCE_DIR}/pcbnew/dialogs
+ ${Boost_INCLUDE_DIR}
+ ${INC_AFTER}
+)
+
+target_link_libraries( qa_pcb_parse_input
+ pcbcommon
+ legacy_wx
+ polygon
+ pnsrouter
+ common
+ pcbcommon
+ bitmaps
+ polygon
+ pnsrouter
+ common
+ pcbcommon
+ bitmaps
+ polygon
+ pnsrouter
+ common
+ pcbcommon
+ bitmaps
+ polygon
+ pnsrouter
+ common
+ pcbcommon
+ 3d-viewer
+ bitmaps
+ gal
+ pcad2kicadpcb
+ common
+ pcbcommon
+ ${GITHUB_PLUGIN_LIBRARIES}
+ qa_utils
+ ${wxWidgets_LIBRARIES}
+)
+
+# we need to pretend to be something to appease the units code
+target_compile_definitions( qa_pcb_parse_input
+ PRIVATE PCBNEW
+)
\ No newline at end of file
diff --git a/qa/pcb_parse_input/main.cpp b/qa/pcb_parse_input/main.cpp
new file mode 100644
index 000000000..421439128
--- /dev/null
+++ b/qa/pcb_parse_input/main.cpp
@@ -0,0 +1,158 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2018 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <kicad_plugin.h>
+#include <pcb_parser.h>
+#include <richio.h>
+#include <class_board_item.h>
+
+#include <wx/cmdline.h>
+
+#include <stdstream_line_reader.h>
+#include <scoped_timer.h>
+
+using PARSE_DURATION = std::chrono::microseconds;
+
+/**
+ * Parse a PCB or footprint file from the given input stream
+ *
+ * @param aStream the input stream to read from
+ * @return success, duration (in us)
+ */
+bool parse(std::istream& aStream, bool aVerbose )
+{
+ // Take input from stdin
+ STDISTREAM_LINE_READER reader;
+ reader.SetStream( aStream );
+
+ PCB_PARSER parser;
+
+ parser.SetLineReader( &reader );
+
+ BOARD_ITEM* board = nullptr;
+
+ PARSE_DURATION duration {};
+
+ try
+ {
+ SCOPED_TIMER<PARSE_DURATION> timer( duration );
+ board = parser.Parse();
+ }
+ catch( const IO_ERROR& parse_error )
+ {
+ std::cerr << parse_error.Problem() << std::endl;
+ std::cerr << parse_error.Where() << std::endl;
+ }
+
+ if( aVerbose )
+ {
+ std::cout << "Took: " << duration.count() << "us" << std::endl;
+ }
+
+ return board != nullptr;
+}
+
+
+static const wxCmdLineEntryDesc g_cmdLineDesc [] =
+{
+ { wxCMD_LINE_SWITCH, "h", "help",
+ _( "displays help on the command line parameters" ),
+ wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
+ { wxCMD_LINE_SWITCH, "v", "verbose",
+ _( "print parsing information") },
+ { wxCMD_LINE_PARAM, nullptr, nullptr,
+ _( "input file" ),
+ wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE },
+ { wxCMD_LINE_NONE }
+};
+
+
+enum RET_CODES
+{
+ OK = 0,
+ BAD_CMDLINE = 1,
+ PARSE_FAILED = 2,
+};
+
+
+int main(int argc, char** argv)
+{
+#ifdef __AFL_COMPILER
+ __AFL_INIT();
+#endif
+
+ wxMessageOutput::Set(new wxMessageOutputStderr);
+ wxCmdLineParser cl_parser( argc, argv );
+ cl_parser.SetDesc( g_cmdLineDesc );
+ cl_parser.AddUsageText( _("This program parses PCB files, either from the "
+ "stdin stream or from the given filenames. This can be used either for "
+ "standalone testing of the parser or for fuzz testing." ) );
+
+ int cmd_parsed_ok = cl_parser.Parse();
+ if( cmd_parsed_ok != 0 )
+ {
+ // Help and invalid input both stop here
+ return ( cmd_parsed_ok == -1 ) ? RET_CODES::OK : RET_CODES::BAD_CMDLINE;
+ }
+
+ const bool verbose = cl_parser.Found( "verbose" );
+
+ bool ok = true;
+ PARSE_DURATION duration;
+
+ const auto file_count = cl_parser.GetParamCount();
+
+ if ( file_count == 0 )
+ {
+ // Parse the file provided on stdin - used by AFL to drive the
+ // program
+ // while (__AFL_LOOP(2))
+ {
+ ok = parse( std::cin, verbose );
+ }
+ }
+ else
+ {
+ // Parse 'n' files given on the command line
+ // (this is useful for input minimisation (e.g. afl-tmin) as
+ // well as manual testing
+ for( unsigned i = 0; i < file_count; i++ )
+ {
+ const auto filename = cl_parser.GetParam( i ).ToStdString();
+
+ if( verbose )
+ std::cout << "Parsing: " << filename << std::endl;
+
+ std::ifstream fin;
+ fin.open( filename );
+
+ ok = ok && parse( fin, verbose );
+ }
+ }
+
+ if( !ok )
+ return RET_CODES::PARSE_FAILED;
+
+ return RET_CODES::OK;
+}
\ No newline at end of file
diff --git a/qa/qa_utils/CMakeLists.txt b/qa/qa_utils/CMakeLists.txt
new file mode 100644
index 000000000..b5befaeee
--- /dev/null
+++ b/qa/qa_utils/CMakeLists.txt
@@ -0,0 +1,40 @@
+# This program source code file is part of KiCad, a free EDA CAD application.
+#
+# Copyright (C) 2018 KiCad Developers, see CHANGELOG.TXT for contributors.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, you may find one here:
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# or you may search the http://www.gnu.org website for the version 2 license,
+# or you may write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+set( QA_UTIL_COMMON_SRC
+ stdstream_line_reader.cpp
+)
+
+# A generic library of useful functions for various testing purposes
+add_library( qa_utils
+ ${QA_UTIL_COMMON_SRC}
+)
+
+include_directories( BEFORE ${INC_BEFORE} )
+
+target_link_libraries( qa_utils
+ common
+ ${wxWidgets_LIBRARIES}
+)
+
+target_include_directories( qa_utils PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
\ No newline at end of file
diff --git a/qa/qa_utils/scoped_timer.h b/qa/qa_utils/scoped_timer.h
new file mode 100644
index 000000000..028bfef46
--- /dev/null
+++ b/qa/qa_utils/scoped_timer.h
@@ -0,0 +1,62 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef SCOPED_TIMER_H
+#define SCOPED_TIMER_H
+
+#include <chrono>
+
+/**
+ * A simple RAII class to measure the time of an operation.
+ *
+ * ON construction, a timer is started, and on destruction, the timer is
+ * ended, and the time difference is written into the given duration
+ */
+template<typename DURATION>
+class SCOPED_TIMER
+{
+ using CLOCK = std::chrono::steady_clock;
+ using TIME_PT = std::chrono::time_point<CLOCK>;
+
+public:
+ SCOPED_TIMER( DURATION& aDuration ):
+ m_duration( aDuration )
+ {
+ m_start = CLOCK::now();
+ }
+
+ ~SCOPED_TIMER()
+ {
+ const auto end = CLOCK::now();
+
+ // update the output
+ m_duration = std::chrono::duration_cast<DURATION>( end - m_start );
+ }
+
+private:
+
+ DURATION& m_duration;
+ TIME_PT m_start;
+};
+
+#endif // SCOPED_TIMER_h
\ No newline at end of file
diff --git a/tools/io_benchmark/stdstream_line_reader.cpp b/qa/qa_utils/stdstream_line_reader.cpp
similarity index 91%
rename from tools/io_benchmark/stdstream_line_reader.cpp
rename to qa/qa_utils/stdstream_line_reader.cpp
index cb8ddabdc..3f6596fdb 100644
--- a/tools/io_benchmark/stdstream_line_reader.cpp
+++ b/qa/qa_utils/stdstream_line_reader.cpp
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
- * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -58,10 +58,10 @@ char* STDISTREAM_LINE_READER::ReadLine()
}
-void STDISTREAM_LINE_READER::setStream( std::istream& aStream )
+void STDISTREAM_LINE_READER::SetStream( std::istream& aStream )
{
// Could be done with a virtual getStream function, but the
- // virtual function call is a noticable (but minor) penalty within
+ // virtual function call is a noticeable (but minor) penalty within
// ReadLine() in tight loops
m_stream = &aStream;
}
@@ -77,7 +77,7 @@ IFSTREAM_LINE_READER::IFSTREAM_LINE_READER( const wxFileName& aFileName ) :
THROW_IO_ERROR( msg );
}
- setStream( m_fStream );
+ SetStream( m_fStream );
m_source = aFileName.GetFullName();
}
diff --git a/tools/io_benchmark/stdstream_line_reader.h b/qa/qa_utils/stdstream_line_reader.h
similarity index 92%
rename from tools/io_benchmark/stdstream_line_reader.h
rename to qa/qa_utils/stdstream_line_reader.h
index 5ccf86f3c..81c238dc6 100644
--- a/tools/io_benchmark/stdstream_line_reader.h
+++ b/qa/qa_utils/stdstream_line_reader.h
@@ -44,9 +44,11 @@ public:
char* ReadLine() override;
-protected:
-
- void setStream( std::istream& aStream );
+ /**
+ * Set the stream for this line reader.
+ * @param aStream a stream to read
+ */
+ void SetStream( std::istream& aStream );
private:
std::string m_buffer;
diff --git a/tools/io_benchmark/CMakeLists.txt b/tools/io_benchmark/CMakeLists.txt
index 2e50d5901..bbab2a9c6 100644
--- a/tools/io_benchmark/CMakeLists.txt
+++ b/tools/io_benchmark/CMakeLists.txt
@@ -3,7 +3,6 @@ include_directories( BEFORE ${INC_BEFORE} )
set( IOBENCHMARK_SRCS
io_benchmark.cpp
- stdstream_line_reader.cpp
)
add_executable( io_benchmark
@@ -12,6 +11,7 @@ add_executable( io_benchmark
target_link_libraries( io_benchmark
common
+ qa_utils
${wxWidgets_LIBRARIES}
)
--
2.19.0
Follow ups
References
-
[PATCH] Fuzzable PCB parsing test harness
From: John Beard, 2018-10-08
-
Re: [PATCH] Fuzzable PCB parsing test harness
From: John Beard, 2018-10-08
-
Re: [PATCH] Fuzzable PCB parsing test harness
From: John Beard, 2018-10-09
-
Re: [PATCH] Fuzzable PCB parsing test harness
From: Wayne Stambaugh, 2018-10-12
-
Re: [PATCH] Fuzzable PCB parsing test harness
From: John Beard, 2018-10-16
-
Re: [PATCH] Fuzzable PCB parsing test harness
From: Wayne Stambaugh, 2018-10-17
-
Re: [PATCH] Fuzzable PCB parsing test harness
From: John Beard, 2018-10-17
-
Re: [PATCH] Fuzzable PCB parsing test harness
From: Wayne Stambaugh, 2018-10-18
-
Re: [PATCH] Fuzzable PCB parsing test harness
From: John Beard, 2018-10-19
-
Re: [PATCH] Fuzzable PCB parsing test harness
From: John Beard, 2018-10-22
-
Re: [PATCH] Fuzzable PCB parsing test harness
From: Wayne Stambaugh, 2018-10-22