kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #38088
Re: [PATCH] Fuzzable PCB parsing test harness
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 7294063045b31e930d27981cbcc3a05a52676486 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 1/2] 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..fc79f932b
--- /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 );
+
+ 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