From: Jiri Vlasak Date: Fri, 23 Jul 2021 14:34:59 +0000 (+0200) Subject: Remove ut X-Git-Tag: v0.8.0~1^2~1 X-Git-Url: https://rtime.felk.cvut.cz/gitweb/hubacji1/rrts.git/commitdiff_plain/117006229a26ccca9abafaedc1e6f39de34ceb5f Remove ut --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 910678f..0165814 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,9 +30,3 @@ add_library(rrts STATIC src/reeds_shepp.cpp ) target_include_directories(rrts PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/incl) - -if (SKIP_UT) - return() -endif() -add_executable(test0 ut/template.cc) -target_link_libraries(test0 rrts) diff --git a/ut/rrtext.t.cc b/ut/rrtext.t.cc deleted file mode 100644 index 4e01c4f..0000000 --- a/ut/rrtext.t.cc +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include "wvtest.h" - -#include "rrtext.h" -#include "reeds_shepp.h" - -WVTEST_MAIN("RRT extensions") -{ - RRTNode n1; - RRTNode n2; - RRTExt1 e1; - BicycleCar bc; - e1.goals().push_back(RRTNode()); - // Test Matej's heuristics. - n2.h(M_PI); - e1.next(); - WVPASSEQ_DOUBLE(e1.cost_search(n1, n2), M_PI * bc.mtr(), 0.00001); - // Test Reeds and Shepp path length. - n2.h(0.3); - double q0[] = {n1.x(), n1.y(), n1.h()}; - double q1[] = {n2.x(), n2.y(), n2.h()}; - ReedsSheppStateSpace rsss(bc.mtr()); - WVPASSEQ_DOUBLE(e1.cost_build(n1, n2), rsss.distance(q0, q1), 0.00001); -} diff --git a/ut/rrts.t.cc b/ut/rrts.t.cc deleted file mode 100644 index 894ec8e..0000000 --- a/ut/rrts.t.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include "wvtest.h" - -#include "rrts.h" - -WVTEST_MAIN("RRT node basic tests") -{ - RRTNode n1; - RRTNode n2; -} - -WVTEST_MAIN("RRT* basic tests") -{ - RRTS rrts; - rrts.goals().push_back(RRTNode()); - rrts.goals().back().x(10); - rrts.goals().back().y(10); - rrts.goals().back().h(0); - WVPASSEQ_DOUBLE(cc(rrts.nodes().front()), 0, 0.00001); - WVPASSEQ(rrts.nodes().size(), 1); - rrts.next(); - WVPASSLT(1, rrts.nodes().size()); - WVPASSEQ(rrts.samples().size(), 1); - WVPASSLT(0, rrts.goals().size()); - rrts.set_sample(0, 10, 0, 10, 0, 2 * M_PI); - Obstacle o; - o.poly().push_back(std::make_tuple(5, 5)); - o.poly().push_back(std::make_tuple(6, 5)); - o.poly().push_back(std::make_tuple(6, 6)); - o.poly().push_back(std::make_tuple(5, 6)); - o.poly().push_back(std::make_tuple(5, 5)); - rrts.obstacles().push_back(o); - while (rrts.next()) {} - WVPASS(rrts.path().size() > 0); - WVPASS( - rrts.nodes().size() > 0 - && rrts.path().size() > 0 - && &rrts.nodes().front() == rrts.path().front() - ); - WVPASS( - rrts.goals().size() > 0 - && rrts.path().size() > 0 - && &rrts.goals().front() == rrts.path().back() - ); -} diff --git a/wvtest/.gitignore b/wvtest/.gitignore deleted file mode 100644 index 2a7de39..0000000 --- a/wvtest/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*~ -*.o -*.a -*.lib -*.dll -*.exe -*.so -*.so.* -*.pyc -*.mdb diff --git a/wvtest/LICENSE b/wvtest/LICENSE deleted file mode 100644 index eb685a5..0000000 --- a/wvtest/LICENSE +++ /dev/null @@ -1,481 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/wvtest/Makefile b/wvtest/Makefile deleted file mode 100644 index e8640d5..0000000 --- a/wvtest/Makefile +++ /dev/null @@ -1,28 +0,0 @@ - -DIRS=cpp - -all: build - @echo - @echo "Try: make test" - -build: - set -e; for d in $(DIRS); do \ - if [ "$$d" = "dotnet" ] && ! runnable gmcs; then continue; fi; \ - $(MAKE) -C $$d all; \ - done - -runtests: build - set -e; for d in $(DIRS); do \ - if [ "$$d" = "dotnet" ] && ! runnable gmcs; then continue; fi; \ - $(MAKE) -C $$d runtests; \ - done - - -test: build - ./wvtestrun $(MAKE) runtests - -clean:: - rm -f *~ .*~ - set -e; for d in $(DIRS); do \ - $(MAKE) -C $$d clean; \ - done diff --git a/wvtest/README b/wvtest/README deleted file mode 100644 index 39bb852..0000000 --- a/wvtest/README +++ /dev/null @@ -1,420 +0,0 @@ - -WvTest: the dumbest cross-platform test framework that could possibly work -========================================================================== - -I have a problem with your unit testing framework. Yes, you. -The person reading this. No, don't look away guiltily. You -know your unit testing framework sucks. You know it has a -million features you don't understand. You know you hate it, -and it hates you. Don't you? - -Okay, fine. Let's be honest. Actually, I don't know who you -are or how you feel about your unit testing framework, but I've -tried a lot of them, and I don't like any of them. WvTest is -the first one I don't hate, at least sort of. That might be -because I'm crazy and I only like things I design, or it might -be because I'm crazy and therefore I'm the only one capable of -designing a likable unit testing framework. Who am I to say? - -Here are the fundamental design goals of WvTest: - - - Be the stupidest thing that can possibly work. People are - way, way too serious about their testing frameworks. Some - people build testing frameworks as their *full time job*. - This is ridiculous. A test framework, at its core, only does - one thing: it runs a program that returns true or false. If - it's false, you lose. If it's true, you win. Everything - after that is gravy. And WvTest has only a minimal amount of - gravy. - - - Be a protocol, not an API. If you don't like my API, you can - write your own, and it can still be WvTest and it can still - integrate with other WvTest tools. If you're stuck with - JUnit or NUnit, you can just make your JUnit/NUnit test - produce WvTest-compatible output if you want (although I've - never done this, so you'll have to do it yourself). I'll - describe the protocol below. - - - Work with multiple languages on multiple operating systems. - I'm a programmer who programs on Linux, MacOS, and Windows, - to name just three, and I write in lots of programming - languages, including C, C++, C#, Python, Perl, and others. - And worse, some of my projects use *multiple* languages and I - want to have unit tests for *all* of them. I don't know of - any unit testing framework - except maybe some horrendously - overdesigned ones - that work with multiple languages at - once. WvTest does. - - - NO UNNECESSARY OBJECT ORIENTATION. The big unit testing - craze seems to have been started by JUnit in Java, which is - object-oriented. Now, that's not a misdesign in JUnit; it's - a misdesign in Java. You see, you can't *not* encapsulate - absolutely everything in Java in a class, so it's perfectly - normal for JUnit to require you to encapsulate everything in - a class. That's not true of almost any other language - (except C#), and yet *every* clone of JUnit in *every* - language seems to have copied its classes and objects. Well, - that's stupid. WvTest is designed around the simple idea of - test *functions*. WvTest runs your function, it checks a - bunch of stuff and it returns or else it dies horribly. If - your function wants to instantiate some objects while it does - that, then that's great; WvTest doesn't care. And yes, you - can assert whether two variables are equal even if your - function *isn't* in a particular class, just as God intended. - - - Don't make me name or describe my individual tests. How many - times have you seen this? - - assertTrue(thing.works(), "thing didn't work!"); - - The reasoning there is that if the test fails, we want to be - able to print a user-friendly error message that describes - why. Right? NO!! That is *awful*. That just *doubled* the - amount of work you have to do in order to write a test. - Instead, WvTest auto-generates output including the line - number of the test and the code on that line. So you get a - message like this: - - ! mytest.t.cc:431 thing.works() FAILED - - and all you have to write is this: - - WVPASS(thing.works()); - - (WVPASS is all-caps because it's a macro in C++, but also - because you want your tests to stand out. That's what - you'll be looking for when it fails, after all. And don't - even get me started about the 'True' in assertTrue. Come - on, *obviously* you're going to assert that the condition is - true!) - - - No setup() and teardown() functions or fixtures. "Ouch!" you - say. "I'm going to have so much duplicated code!" No, only - if you're an idiot. You know what setup() and teardown() are - code names for? Constructor and destructor. Create some - objects and give them constructors and destructors, and I - think you'll find that, like magic, you've just invented - "test fixtures." Nothing any test framework can possibly do - will make that any easier. In fact, everything test - frameworks *try* to do with test fixtures just makes it - harder to write, read, and understand. Forget it. - - - Big long scary test functions. Some test frameworks are - insistent about the rule that "every function should test - only one thing." Nobody ever really explains why. I can't - understand this; it just causes uncontrolled - hormone-imbalance hypergrowth in your test files, and you - have to type more stuff... and run test fixtures over and - over. - - My personal theory for why people hate big long test - functions: it's because their assertTrue() implementation - doesn't say which test failed, so they'd like the *name of - the function* to be the name of the failed test. Well, - that's a cute workaround to a problem you shouldn't have had - in the first place. With WvTest, WVPASS() actually tells you - exactly what passed and what failed, so it's perfectly okay - - and totally comprehensible - to have a sequence of five - things in a row where only thing number five failed. - - -The WvTest Protocol -------------------- - -WvTest is a protocol, not really an API. As it happens, the -WvTest project includes several (currently five) -implementations of APIs that produce data in the WvTest format, -but it's super easy to add your own. - -The format is really simple too. It looks like this: - - Testing "my test function" in mytest.t.cc: - ! mytest.t.cc:432 thing.works() ok - This is just some crap that I printed while counting to 3. - ! mytest.t.cc.433 3 < 4 FAILED - -There are only four kinds of lines in WvTest, and each of the -lines above corresponds to one of them: - - - Test function header. A line that starts with the word - Testing (no leading whitespace) and then has a test function - name in double quotes, then "in", then the filename, and then - colon, marks the beginning of a test function. - - - A passing assertion. Any line that starts with ! and ends with - " ok" (whitespace, the word "ok", and a newline) indicates - one assertion that passed. The first "word" on that line is - the "name" of that assertion (which can be anything, as long - as it doesn't contain any whitespace). Everything between the - name and the ok is just some additional user-readable detail - about the test that passed. - - - Random filler. If it doesn't start with an ! and it doesn't - look like a header, then it's completely ignored by anything - using WvTest. Your program can print all the debug output it - wants, and WvTest won't care, except that you can retrieve it - later in case you're wondering why a test failed. Naturally, - random filler *before* an assertion is considered to be - associated with that assertion; the assertion itself is the - last part of a test. - - - A failing assertion. This is just like an 'ok' line, except - augmented with extra detail. A more advanced parser could choose to - parse the extra string to count partial failures: - - xfail ok - test was marked as known to fail and failed - (i.e. a known breakage) - - xpass ok - test was marked as known to fail and passed - (i.e. previously known breakage is fixed) - - skip ok - test was skipped. - - and it could be something else instead, if you invent a new and improved way - to fail. - - -Reading the WvTest Protocol: wvtestrun --------------------------------------- - -WvTest provides a simple perl script called wvtestrun, which -runs a test program and parses its output. It works like this: - - cd python - ../wvtestrun ./wvtest.py t/twvtest.py - -(Why can't we just pipe the output to wvtestrun, instead of - having wvtestrun run the test program? Three reasons: first, a - fancier version of wvtestrun could re-run the tests several - times or give a GUI that lets you re-run the test when you push - a button. Second, it handles stdout and stderr separately. - And third, it can kill the test program if it gets stuck - without producing test output for too long.) - -If we put the sample output from the previous section through -wvtestrun (and changed the FAILED to ok), it would produce this: - - $ ./wvtestrun cat sample-ok - - Testing "all" in cat sample-ok: - ! mytest.t.cc my ok test function: ..... 0.010s ok - - WvTest: 5 tests, 0 failures, total time 0.010s. - WvTest: 0 tests skipped, 0 known breakages, 0 fixed breakages. - - WvTest result code: 0 - -What happened here? Well, wvtestrun took each test header (in -this case, there's just one, which said we're testing "my test -function" in mytest.t.cc) and turns it into a single test line. -Then it prints a dot for each assertion in that test function, -tells you the total time to run that function, and prints 'ok' -if the entire test function failed. - -Note that the output of wvtestrun is *also* valid WvTest output. -That means you can use wvtestrun in your 'make test' target in a -subdirectory, and still use wvtestrun as the 'make test' runner -in the parent directory as well. As long as your top-level -'make test' runs in wvtestrun, all the WvTest output will be -conveniently summarized into a *single* test output. - -Now, what if the test had failed? Then it would look like this: - - $ ./wvtestrun cat sample-error - - Testing "all" in cat sample-error: - ! mytest.t.cc my error test function: . - ! mytest.t.cc:432 thing.works() ok - This is just some crap that I printed while counting to 3. - ! mytest.t.cc.433 3 < 4 FAILED - fXs 0.000s ok - - WvTest: 5 tests, 1 failure, total time 0.000s. - WvTest: 1 test skipped, 1 known breakage, 1 fixed breakage. - - WvTest result code: 0 - -What happened there? Well, because there were failed tests, -wvtestrun decided you'd probably want to see the detailed output -for that test function, so it expanded it out for you. The line -with the dots is still there, but since it doesn't have an 'ok', -it's considered a failure too, just in case. - -Watch what happens if we run a test with both the passing, and -then the failing, test functions: - - $ ./wvtestrun cat sample-ok sample-error - - Testing "all" in cat sample-ok sample-error: - ! mytest.t.cc my ok test function: ..... 0.000s ok - ! mytest.t.cc my error test function: . - ! mytest.t.cc:432 thing.works() ok - This is just some crap that I printed while counting to 3. - ! mytest.t.cc.433 3 < 4 FAILED - fXs 0.000s ok - - WvTest: 10 tests, 1 failure, total time 0.000s. - WvTest: 1 test skipped, 1 known breakage, 1 fixed breakage. - - WvTest result code: 0 - -Notice how the messages from sample-ok are condensed; only the -details from sample-error are expanded out, because only that -output is interesting. - - -How do I actually write WvTest tests? -------------------------------------- - -Sample code is provided for these languages: - - C: try typing "cd c; make test" - C++: try typing "cd cpp; make test" - C# (mono): try typing "cd dotnet; make test" - Python: try typing "cd python; make test" - Shell: try typing "cd sh; make test" - -There's no point explaining the syntax here, because it's really -simple. Just look inside the cpp, dotnet, python, and sh -directories to learn how the tests are written. - - -How should I embed WvTest into my own program? ----------------------------------------------- - -The easiest way is to just copy the WvTest source files for your -favourite language into your project. The WvTest protocol is -unlikely to ever change - at least not in a -backwards-incompatible way - so it's no big deal if you end up -using an "old" version of WvTest in your program. It should -still work with updated versions of wvtestrun (or wvtestrun-like -programs). - -Another way is to put the WvTest project in a subdirectory of -your project, for example, using 'svn:externals', -'git submodule', or 'git subtree'. - - -How do I run just certain tests? --------------------------------- - -Unfortunately, the command-line syntax for running just *some* -of your tests varies depending which WvTest language you're using. -For C, C++ or C#, you link an executable with wvtestmain.c or -wvtestmain.cc or wvtestmain.cs, respectively, and then you can -provide strings on the command line. Test functions will run only -if they have names that start with one of the provided strings: - - cd cpp/t - ../../wvtestrun ./wvtest myfunc otherfunc - -With python, since there's no linker, you have to just tell it -which files to run: - - cd python - ../wvtestrun ./wvtest.py ...filenames... - - -What else can parse WvTest output? ----------------------------------- - -It's easy to parse WvTest output however you like; for example, -you could write a GUI program that does it. We had a tcl/tk -program that did it once, but we threw it away since the -command-line wvtestrun is better anyway. - -One other program that can parse WvTest output is gitbuilder -(http://github.com/apenwarr/gitbuilder/), an autobuilder tool -for git. It reports a build failure automatically if there are -any WvTest-style failed tests in the build output. - - -Other Assorted Questions ------------------------- - - -What does the "Wv" stand for? - - Either "Worldvisions" or "Weaver", both of which were part of the - name of the Nitix operating system before it was called Nitix, and - *long* before it was later purchased by IBM and renamed to Lotus - Foundations. - - It does *not* stand for World Vision (sigh) or West Virginia. - -Who owns the copyright? - - While I (Avery) wrote most of the WvTest framework in C++, C#, and - Python, and I also wrote wvtestrunner, the actual code I wrote is - owned by whichever company I wrote it for at the time. For the most - part, this means: - - C++: Net Integration Technologies, Inc. (now part of IBM) - C#: Versabanq Innovations Inc. - Python: EQL Data Inc. - -What can I do with it? - - WvTest is distributed under the terms of the GNU LGPLv2. See the - file LICENSE for more information. - - Basically this means you can use it for whatever you want, but if - you change it, you probably need to give your changes back to the - world. If you *use* it in your program (which is presumably a test - program) you do *not* have to give out your program, only - WvTest itself. But read the LICENSE in detail to be sure. - -Where did you get the awesome idea to use a protocol instead of an API? - - The perl source code (not to be confused with perlunit) - did a similar trick for the perl interpreter's unit - test, although in a less general way. Naturally, you - shouldn't blame them for how I mangled their ideas, but - I never would have thought of it if it weren't for them. - -Why are xfail/xpass/skip needed at all? - - Suppose you have a test which you expect to pass, but which is - failing (in the usual sense). You have two choices: 1) fix it right - now, or 2) defer fixing. Sometimes at the start we have lots of - tests failing, and in order to make gradual progress, it makes sense - to mark those presently-failing tests as "I know, it fails". - - Another use case is when tests always pass on e.g. Linux, but some - of them fail on Win32 due to differences in environment, and one - does not want to concentrate on fixing win32 yet. - - So when you run tests again, you'd like to differentiate between - failing tests marked as xfail (known to fail) and new failing tests. - The latter should produce real FAILURE with details. xfail on the - other hand should produce just a small warning/reminder (I'm failing - here, please don't forget to fix me). - - That's the idea. - - So now what happens when a test marked as xfail passes anyway - instead of the expected failure? That's not a failure - quite - differently, it _was_ a failure, and now it passes, so what should - we do? Right, we should tell the user that "hey, a test which used - to fail now passes! You probably would want to mark it back as - PASS". - - This is how xfail/xpass works. - - With introduction of xfail tests are no longer strictly true or - false, but you can ignore the additional information if you want - (the last word is still either "ok" or not). - -Who should I complain to about WvTest? - - Email me at: Avery Pennarun - - I will be happy to read your complaints, because I actually really - like it when people use my programs, especially if they hate them. - It fills the loneliness somehow and prevents me from writing bad - poetry like this: - - Testing makes me gouge out my eyes - But with WvTest, it takes fewer tries. - WvTest is great, wvtest is fun! - Don't forget to call wvtestrun. diff --git a/wvtest/cpp/Makefile b/wvtest/cpp/Makefile deleted file mode 100644 index e9f2b40..0000000 --- a/wvtest/cpp/Makefile +++ /dev/null @@ -1,14 +0,0 @@ - -all: t/wvtest - -t/wvtest: wvtestmain.cc wvtest.cc t/wvtest.t.cc - g++ -D WVTEST_CONFIGURED -o $@ -I. $^ - -runtests: all - t/wvtest - -test: all - ../wvtestrun $(MAKE) runtests - -clean:: - rm -f *~ t/*~ *.o t/*.o t/wvtest diff --git a/wvtest/cpp/t/.gitignore b/wvtest/cpp/t/.gitignore deleted file mode 100644 index 160e518..0000000 --- a/wvtest/cpp/t/.gitignore +++ /dev/null @@ -1 +0,0 @@ -wvtest diff --git a/wvtest/cpp/t/wvtest.t.cc b/wvtest/cpp/t/wvtest.t.cc deleted file mode 100644 index cfe0833..0000000 --- a/wvtest/cpp/t/wvtest.t.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include "wvtest.h" - -WVTEST_MAIN("wvtest tests") -{ - WVPASS(1); - WVXFAIL(0); - WVXFAIL(1); - WVSKIP(non-existent); - - WVPASSEQ(1, 1); - WVPASSNE(1, 2); - WVPASSEQ(1, 1); - WVPASSLT(1, 2); - - WVPASSEQ("hello", "hello"); - WVPASSNE("hello", "hello2"); - - WVPASSEQ(std::string("hello"), std::string("hello")); - WVPASSNE(std::string("hello"), std::string("hello2")); -} - -WVTEST_MAIN("wvtest type double tests") -{ - /* WVPASSEQ_DOUBLE(actual,expected,tolerance) */ - WVPASSEQ_DOUBLE(10, 10.000001, 0.00001); - WVPASSEQ_DOUBLE(10, 10.000001, -0.00001); - WVPASSEQ_DOUBLE(-10,-10.000001, 0.00001); - WVPASSEQ_DOUBLE(-10, -10.000001, -0.00001); - - WVPASSEQ_DOUBLE(10, 10.000001, 0.000001); - WVPASSEQ_DOUBLE(10, 10.000001, -0.000001); - WVPASSEQ_DOUBLE(-10, -10.000001, 0.000001); - WVPASSEQ_DOUBLE(-10, -10.000001, -0.000001); - - WVPASSNE_DOUBLE(10, 10.00001, 0.000001); - WVPASSNE_DOUBLE(10, 10.00001, -0.000001); - WVPASSNE_DOUBLE(-10, -10.00001, 0.000001); - WVPASSNE_DOUBLE(-10, -10.00001, -0.000001); - - WVPASSNE_DOUBLE(10, 10.0001, 0.000001); - WVPASSNE_DOUBLE(10, 10.0001, -0.000001); - WVPASSNE_DOUBLE(-10, -10.0001, 0.000001); - WVPASSNE_DOUBLE(-10, -10.0001, -0.000001); -} diff --git a/wvtest/cpp/wvtest.cc b/wvtest/cpp/wvtest.cc deleted file mode 100644 index 5a7527b..0000000 --- a/wvtest/cpp/wvtest.cc +++ /dev/null @@ -1,494 +0,0 @@ -/* - * WvTest: - * Copyright (C)1997-2012 Net Integration Technologies and contributors. - * Licensed under the GNU Library General Public License, version 2. - * See the included file named LICENSE for license information. - * You can get wvtest from: http://github.com/apenwarr/wvtest - */ -#include "wvtest.h" -#include -#include -#include -#include -#ifdef _WIN32 -#include -#else -#include -#include -#endif -#include -#include - -#include - -#ifdef HAVE_VALGRIND_MEMCHECK_H -# include -# include -#else -# define VALGRIND_COUNT_ERRORS 0 -# define VALGRIND_DO_LEAK_CHECK -# define VALGRIND_COUNT_LEAKS(a,b,c,d) (a=b=c=d=0) -#endif - -#define MAX_TEST_TIME 40 // max seconds for a single test to run -#define MAX_TOTAL_TIME 120*60 // max seconds for the entire suite to run - -#define TEST_START_FORMAT "! %s:%-5d %-40s " - -static int memerrs() -{ - return (int)VALGRIND_COUNT_ERRORS; -} - -static int memleaks() -{ - int leaked = 0, dubious = 0, reachable = 0, suppressed = 0; - VALGRIND_DO_LEAK_CHECK; - VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed); - printf("memleaks: sure:%d dubious:%d reachable:%d suppress:%d\n", - leaked, dubious, reachable, suppressed); - fflush(stdout); - - // dubious+reachable are normally non-zero because of globals... - // return leaked+dubious+reachable; - return leaked; -} - -// Return 1 if no children are running or zombies, 0 if there are any running -// or zombie children. -// Will wait for any already-terminated children first. -// Passes if no rogue children were running, fails otherwise. -// If your test gets a failure in here, either you're not killing all your -// children, or you're not calling waitpid(2) on all of them. -static bool no_running_children() -{ -#ifndef _WIN32 - pid_t wait_result; - - // Acknowledge and complain about any zombie children - do - { - int status = 0; - wait_result = waitpid(-1, &status, WNOHANG); - - if (wait_result > 0) - { - char buf[256]; - snprintf(buf, sizeof(buf) - 1, "%d", wait_result); - buf[sizeof(buf)-1] = '\0'; - WVFAILEQ("Unclaimed dead child process", buf); - } - } while (wait_result > 0); - - // There should not be any running children, so waitpid should return -1 - WVPASSEQ(errno, ECHILD); - WVPASSEQ(wait_result, -1); - return (wait_result == -1 && errno == ECHILD); -#endif - return true; -} - - -WvTest *WvTest::first, *WvTest::last; -int WvTest::fails, WvTest::runs, WvTest::xpasses, WvTest::xfails, WvTest::skips; -time_t WvTest::start_time; -bool WvTest::run_twice = false; - -void WvTest::alarm_handler(int) -{ - printf("\n! WvTest Current test took longer than %d seconds! FAILED\n", - MAX_TEST_TIME); - fflush(stdout); - abort(); -} - - -static const char *pathstrip(const char *filename) -{ - const char *cptr; - cptr = strrchr(filename, '/'); - if (cptr) filename = cptr + 1; - cptr = strrchr(filename, '\\'); - if (cptr) filename = cptr + 1; - return filename; -} - - -WvTest::WvTest(const char *_descr, const char *_idstr, MainFunc *_main, - int _slowness) : - descr(_descr), - idstr(pathstrip(_idstr)), - main(_main), - slowness(_slowness), - next(NULL) -{ - if (first) - last->next = this; - else - first = this; - last = this; -} - - -static bool prefix_match(const char *s, const char * const *prefixes) -{ - for (const char * const *prefix = prefixes; prefix && *prefix; prefix++) - { - if (!strncasecmp(s, *prefix, strlen(*prefix))) - return true; - } - return false; -} - - -int WvTest::run_all(const char * const *prefixes) -{ - int old_valgrind_errs = 0, new_valgrind_errs; - int old_valgrind_leaks = 0, new_valgrind_leaks; - -#ifdef _WIN32 - /* I should be doing something to do with SetTimer here, - * not sure exactly what just yet */ -#else - char *disable(getenv("WVTEST_DISABLE_TIMEOUT")); - if (disable != NULL && disable[0] != '\0' && disable[0] != '0') - signal(SIGALRM, SIG_IGN); - else - signal(SIGALRM, alarm_handler); - alarm(MAX_TEST_TIME); -#endif - start_time = time(NULL); - - // make sure we can always start out in the same directory, so tests have - // access to their files. If a test uses chdir(), we want to be able to - // reverse it. - char wd[1024]; - if (!getcwd(wd, sizeof(wd))) - strcpy(wd, "."); - - const char *slowstr1 = getenv("WVTEST_MIN_SLOWNESS"); - const char *slowstr2 = getenv("WVTEST_MAX_SLOWNESS"); - int min_slowness = 0, max_slowness = 65535; - if (slowstr1) min_slowness = atoi(slowstr1); - if (slowstr2) max_slowness = atoi(slowstr2); - -#ifdef _WIN32 - run_twice = false; -#else - char *parallel_str = getenv("WVTEST_PARALLEL"); - if (parallel_str) - run_twice = atoi(parallel_str) > 0; -#endif - - // there are lots of fflush() calls in here because stupid win32 doesn't - // flush very often by itself. - fails = runs = xpasses = xfails = skips = 0; - for (WvTest *cur = first; cur; cur = cur->next) - { - if (cur->slowness <= max_slowness - && cur->slowness >= min_slowness - && (!prefixes - || prefix_match(cur->idstr, prefixes) - || prefix_match(cur->descr, prefixes))) - { -#ifndef _WIN32 - // set SIGPIPE back to default, helps catch tests which don't set - // this signal to SIG_IGN (which is almost always what you want) - // on startup - signal(SIGPIPE, SIG_DFL); - - pid_t child = 0; - if (run_twice) - { - // I see everything twice! - printf("Running test in parallel.\n"); - child = fork(); - } -#endif - - printf("\nTesting \"%s\" in %s:\n", cur->descr, cur->idstr); - fflush(stdout); - - cur->main(); - if (chdir(wd)) { - perror("Unable to change back to original directory"); - } - - new_valgrind_errs = memerrs(); - WVPASS(new_valgrind_errs == old_valgrind_errs); - old_valgrind_errs = new_valgrind_errs; - - new_valgrind_leaks = memleaks(); - WVPASS(new_valgrind_leaks == old_valgrind_leaks); - old_valgrind_leaks = new_valgrind_leaks; - - fflush(stderr); - printf("\n"); - fflush(stdout); - -#ifndef _WIN32 - if (run_twice) - { - if (!child) - { - // I see everything once! - printf("Child exiting.\n"); - _exit(0); - } - else - { - printf("Waiting for child to exit.\n"); - int result; - while ((result = waitpid(child, NULL, 0)) == -1 && - errno == EINTR) - printf("Waitpid interrupted, retrying.\n"); - } - } -#endif - - WVPASS(no_running_children()); - } - } - - WVPASS(runs > 0); - - if (prefixes && *prefixes && **prefixes) - printf("WvTest: WARNING: only ran tests starting with " - "specifed prefix(es).\n"); - else - printf("WvTest: ran all tests.\n"); - printf("WvTest: %d test%s, %d failure%s.\n", - runs, runs==1 ? "" : "s", - fails, fails==1 ? "": "s"); - printf("WvTest: %d test%s skipped, %d known breakage%s, %d fixed breakage%s.\n", - skips, skips==1 ? "" : "s", - xfails, xfails==1 ? "" : "s", - xpasses, xpasses==1 ? "" : "s"); - fflush(stdout); - - return fails != 0; -} - - -// If we aren't running in parallel, we want to output the name of the test -// before we run it, so we know what happened if it crashes. If we are -// running in parallel, outputting this information in multiple printf()s -// can confuse parsers, so we want to output everything in one printf(). -// -// This function gets called by both start() and check(). If we're not -// running in parallel, just print the data. If we're running in parallel, -// and we're starting a test, save a copy of the file/line/description until -// the test is done and we can output it all at once. -// -// Yes, this is probably the worst API of all time. -void WvTest::print_result(bool start, const char *_file, int _line, - const char *_condstr, const char *result) -{ - static char *file; - static char *condstr; - static int line; - - if (start) - { - if (file) - free(file); - if (condstr) - free(condstr); - file = strdup(pathstrip(_file)); - condstr = strdup(_condstr); - line = _line; - - for (char *cptr = condstr; *cptr; cptr++) - { - if (!isprint((unsigned char)*cptr)) - *cptr = '!'; - } - } - - if (run_twice) - { - if (!start) - printf(TEST_START_FORMAT "%s\n", file, line, condstr, result); - } - else - { - if (start) - printf(TEST_START_FORMAT, file, line, condstr); - else - printf("%s\n", result); - } - fflush(stdout); - - if (!start) - { - if (file) - free(file); - if (condstr) - free(condstr); - file = condstr = NULL; - } -} - - -void WvTest::start(const char *file, int line, const char *condstr) -{ - // Either print the file, line, and condstr, or save them for later. - print_result(true, file, line, condstr, NULL); -} - - -void WvTest::check_prologue() -{ -#ifndef _WIN32 - alarm(MAX_TEST_TIME); // restart per-test timeout -#endif - if (!start_time) start_time = time(NULL); - - if (time(NULL) - start_time > MAX_TOTAL_TIME) - { - printf("\n! WvTest Total run time exceeded %d seconds! FAILED\n", - MAX_TOTAL_TIME); - fflush(stdout); - abort(); - } - - runs++; - -} - - -void WvTest::check(bool cond) -{ - check_prologue(); - print_result(false, NULL, 0, NULL, cond ? "ok" : "FAILED"); - - if (!cond) - { - fails++; - - if (getenv("WVTEST_DIE_FAST")) - abort(); - } -} - - -void WvTest::check_xfail(bool cond) -{ - check_prologue(); - print_result(false, NULL, 0, NULL, cond ? "xpass ok" : "xfail ok"); - - if (cond) - xpasses++; - else - xfails++; -} - - -void WvTest::skip(const char *file, int line, const char *condstr) -{ - start(file, line, condstr); - print_result(false, NULL, 0, NULL, "skip ok"); - skips++; -} - - -bool WvTest::start_check_eq(const char *file, int line, - const char *a, const char *b, bool expect_pass) -{ - if (!a) a = ""; - if (!b) b = ""; - - size_t len = strlen(a) + strlen(b) + 8 + 1; - char *str = new char[len]; - sprintf(str, "[%s] %s [%s]", a, expect_pass ? "==" : "!=", b); - - start(file, line, str); - delete[] str; - - bool cond = !strcmp(a, b); - if (!expect_pass) - cond = !cond; - - check(cond); - return cond; -} - - -bool WvTest::start_check_eq(const char *file, int line, - const std::string &a, const std::string &b, - bool expect_pass) -{ - return start_check_eq(file, line, a.c_str(), b.c_str(), expect_pass); -} - - -bool WvTest::start_check_eq(const char *file, int line, - int a, int b, bool expect_pass) -{ - size_t len = 128 + 128 + 8 + 1; - char *str = new char[len]; - sprintf(str, "%d %s %d", a, expect_pass ? "==" : "!=", b); - - start(file, line, str); - delete[] str; - - bool cond = (a == b); - if (!expect_pass) - cond = !cond; - - check(cond); - return cond; -} - - -bool WvTest::start_check_eq(const char *file, int line, - double a, double b, double c, bool expect_pass) -{ - size_t len = 128 + 128 + 128 + 8 + 1; - char *str = new char[len]; - sprintf(str, "%f %s %f eps %f", a, expect_pass ? "==" : "!=", b, c); - - start(file, line, str); - delete[] str; - - bool cond = ( WVABS(a - b) <= WVABS(c) ); - if (!expect_pass) - cond = !cond; - - check(cond); - return cond; -} - - -bool WvTest::start_check_lt(const char *file, int line, - const char *a, const char *b) -{ - if (!a) a = ""; - if (!b) b = ""; - - size_t len = strlen(a) + strlen(b) + 8 + 1; - char *str = new char[len]; - sprintf(str, "[%s] < [%s]", a, b); - - start(file, line, str); - delete[] str; - - bool cond = strcmp(a, b) < 0; - check(cond); - return cond; -} - - -bool WvTest::start_check_lt(const char *file, int line, int a, int b) -{ - size_t len = 128 + 128 + 8 + 1; - char *str = new char[len]; - sprintf(str, "%d < %d", a, b); - - start(file, line, str); - delete[] str; - - bool cond = a < b; - check(cond); - return cond; -} diff --git a/wvtest/cpp/wvtest.h b/wvtest/cpp/wvtest.h deleted file mode 100644 index f96ce40..0000000 --- a/wvtest/cpp/wvtest.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -*- Mode: C++ -*- - * WvTest: - * Copyright (C)1997-2012 Net Integration Technologies and contributors. - * Licensed under the GNU Library General Public License, version 2. - * See the included file named LICENSE for license information. - * You can get wvtest from: http://github.com/apenwarr/wvtest - */ -#ifndef __WVTEST_H -#define __WVTEST_H - -#ifndef WVTEST_CONFIGURED -# error "Missing settings: HAVE_VALGRIND_MEMCHECK_H HAVE_WVCRASH WVTEST_CONFIGURED" -#endif - -#include -#include - -class WvTest -{ - typedef void MainFunc(); - const char *descr, *idstr; - MainFunc *main; - int slowness; - WvTest *next; - static WvTest *first, *last; - static int fails, runs, xpasses, xfails, skips; - static time_t start_time; - static bool run_twice; - - static void alarm_handler(int sig); - - static void print_result(bool start, const char *file, int line, - const char *condstr, const char *result); - - static void check_prologue(); -public: - WvTest(const char *_descr, const char *_idstr, MainFunc *_main, int _slow); - static int run_all(const char * const *prefixes = NULL); - static void start(const char *file, int line, const char *condstr); - static void check(bool cond); - static void check_xfail(bool cond); - static void skip(const char *file, int line, const char *condstr); - static inline bool start_check(const char *file, int line, - const char *condstr, bool cond) - { start(file, line, condstr); check(cond); return cond; } - static bool start_check_eq(const char *file, int line, - const char *a, const char *b, bool expect_pass); - static bool start_check_eq(const char *file, int line, - const std::string &a, const std::string &b, - bool expect_pass); - static bool start_check_eq(const char *file, int line, int a, int b, - bool expect_pass); - static bool start_check_eq(const char *file, int line, double a, double b, double c, - bool expect_pass); - static bool start_check_lt(const char *file, int line, - const char *a, const char *b); - static bool start_check_lt(const char *file, int line, int a, int b); -}; - - -#define WVPASS(cond) \ - WvTest::start_check(__FILE__, __LINE__, #cond, (cond)) -#define WVPASSEQ(a, b) \ - WvTest::start_check_eq(__FILE__, __LINE__, (a), (b), true) -#define WVPASSEQ_DOUBLE(a, b, c) \ - WvTest::start_check_eq(__FILE__, __LINE__, (a), (b), (c), true) -#define WVPASSLT(a, b) \ - WvTest::start_check_lt(__FILE__, __LINE__, (a), (b)) -#define WVFAIL(cond) \ - WvTest::start_check(__FILE__, __LINE__, "NOT(" #cond ")", !(cond)) -#define WVFAILEQ(a, b) \ - WvTest::start_check_eq(__FILE__, __LINE__, (a), (b), false) -#define WVFAILEQ_DOUBLE(a, b, c) \ - WvTest::start_check_eq(__FILE__, __LINE__, (a), (b), (c), false) -#define WVPASSNE(a, b) WVFAILEQ(a, b) -#define WVPASSNE_DOUBLE(a, b, c) WVFAILEQ_DOUBLE(a, b, c) -#define WVFAILNE(a, b) WVPASSEQ(a, b) -#define WVABS(x) ((x)<0 ? -(x) : (x)) - -#define WVXFAIL(cond) do { \ - WvTest::start(__FILE__, __LINE__, #cond); \ - WvTest::check_xfail(cond); \ -} while (0) - -#define WVSKIP(cond) \ - WvTest::skip(__FILE__, __LINE__, #cond) - - - -#define WVTEST_MAIN3(descr, ff, ll, slowness) \ - static void _wvtest_main_##ll(); \ - static WvTest _wvtest_##ll(descr, ff, _wvtest_main_##ll, slowness); \ - static void _wvtest_main_##ll() -#define WVTEST_MAIN2(descr, ff, ll, slowness) \ - WVTEST_MAIN3(descr, ff, ll, slowness) -#define WVTEST_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 0) -#define WVTEST_SLOW_MAIN(descr) WVTEST_MAIN2(descr, __FILE__, __LINE__, 1) - - -#endif // __WVTEST_H diff --git a/wvtest/cpp/wvtestmain.cc b/wvtest/cpp/wvtestmain.cc deleted file mode 100644 index f6298d5..0000000 --- a/wvtest/cpp/wvtestmain.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * WvTest: - * Copyright (C)1997-2012 Net Integration Technologies and contributors. - * Licensed under the GNU Library General Public License, version 2. - * See the included file named LICENSE for license information. - * You can get wvtest from: http://github.com/apenwarr/wvtest - */ -#include "wvtest.h" -#ifdef HAVE_WVCRASH -# include "wvcrash.h" -#endif -#include -#include -#ifdef _WIN32 -#include -#include -#else -#include -#include -#endif - -static bool fd_is_valid(int fd) -{ -#ifdef _WIN32 - if ((HANDLE)_get_osfhandle(fd) != INVALID_HANDLE_VALUE) return true; -#endif - int nfd = dup(fd); - if (nfd >= 0) - { - close(nfd); - return true; - } - return false; - -} - - -static int fd_count(const char *when) -{ - int count = 0; - - printf("fds open at %s:", when); - - for (int fd = 0; fd < 1024; fd++) - { - if (fd_is_valid(fd)) - { - count++; - printf(" %d", fd); - fflush(stdout); - } - } - printf("\n"); - - return count; -} - - -int main(int argc, char **argv) -{ - char buf[200]; -#if defined(_WIN32) && defined(HAVE_WVCRASH) - setup_console_crash(); -#endif - - // test wvtest itself. Not very thorough, but you have to draw the - // line somewhere :) - WVPASS(true); - WVPASS(1); - WVFAIL(false); - WVFAIL(0); - int startfd, endfd; - char * const *prefixes = NULL; - - if (argc > 1) - prefixes = argv + 1; - - startfd = fd_count("start"); - int ret = WvTest::run_all(prefixes); - - if (ret == 0) // don't pollute the strace output if we failed anyway - { - endfd = fd_count("end"); - - WVPASS(startfd == endfd); -#ifndef _WIN32 - if (startfd != endfd) - { - sprintf(buf, "ls -l /proc/%d/fd", getpid()); - if (system(buf) == -1) { - fprintf(stderr, "Unable to list open fds\n"); - } - } -#endif - } - - // keep 'make' from aborting if this environment variable is set - if (getenv("WVTEST_NO_FAIL")) - return 0; - else - return ret; -} diff --git a/wvtest/runnable b/wvtest/runnable deleted file mode 100755 index ecd7134..0000000 --- a/wvtest/runnable +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -# Returns 0 (success) if the given program is runnable. -# -# This is better than using [ -x /usr/bin/program ] because it avoids -# the need to hardcode the program's path; it searches $PATH instead. -# -if [ $# != 1 ]; then - echo "usage: $0 " >&2 - exit 1 -fi -type "$1" >/dev/null 2>&1 diff --git a/wvtest/sample-error b/wvtest/sample-error deleted file mode 100644 index 58bd432..0000000 --- a/wvtest/sample-error +++ /dev/null @@ -1,8 +0,0 @@ -Testing "my error test function" in mytest.t.cc: -! mytest.t.cc:432 thing.works() ok -This is just some crap that I printed while counting to 3. -! mytest.t.cc.433 3 < 4 FAILED -! mytest.t.cc.435 3 < 5 xfail ok -! mytest.t.cc.437 3 < 6 xpass ok -! mytest.t.cc.439 3 < 7 skip ok - diff --git a/wvtest/sample-ok b/wvtest/sample-ok deleted file mode 100644 index 016a1cb..0000000 --- a/wvtest/sample-ok +++ /dev/null @@ -1,8 +0,0 @@ -Testing "my ok test function" in mytest.t.cc: -! mytest.t.cc:432 thing.works() ok -This is just some crap that I printed while counting to 3. -! mytest.t.cc.433 3 < 4 ok -! mytest.t.cc.435 3 < 5 ok -! mytest.t.cc.437 3 < 6 ok -! mytest.t.cc.439 3 < 7 ok - diff --git a/wvtest/wvtestrun b/wvtest/wvtestrun deleted file mode 100755 index b802e20..0000000 --- a/wvtest/wvtestrun +++ /dev/null @@ -1,219 +0,0 @@ -#!/usr/bin/perl -w -# -# WvTest: -# Copyright (C)2007-2012 Versabanq Innovations Inc. and contributors. -# Licensed under the GNU Library General Public License, version 2. -# See the included file named LICENSE for license information. -# You can get wvtest from: http://github.com/apenwarr/wvtest -# -use strict; -use Time::HiRes qw(time); - -# always flush -$| = 1; - -if (@ARGV < 1) { - print STDERR "Usage: $0 \n"; - exit 127; -} - -print STDERR "Testing \"all\" in @ARGV:\n"; - -my $pid = open(my $fh, "-|"); -if (!$pid) { - # child - setpgrp(); - open STDERR, '>&STDOUT' or die("Can't dup stdout: $!\n"); - exec(@ARGV); - exit 126; # just in case -} - -my $istty = -t STDOUT && $ENV{'TERM'} ne "dumb"; -my @log = (); -my ($gpasses, $gfails, $gxpasses, $gxfails, $gskips) = (0,0,0,0,0); - -sub bigkill($) -{ - my $pid = shift; - - if (@log) { - print "\n" . join("\n", @log) . "\n"; - } - - print STDERR "\n! Killed by signal FAILED\n"; - - ($pid > 0) || die("pid is '$pid'?!\n"); - - local $SIG{CHLD} = sub { }; # this will wake us from sleep() faster - kill 15, $pid; - sleep(2); - - if ($pid > 1) { - kill 9, -$pid; - } - kill 9, $pid; - - exit(125); -} - -# parent -local $SIG{INT} = sub { bigkill($pid); }; -local $SIG{TERM} = sub { bigkill($pid); }; -local $SIG{ALRM} = sub { - print STDERR "Alarm timed out! No test results for too long.\n"; - bigkill($pid); -}; - -sub colourize_as($$) -{ - my ($result, $text) = @_; - - if ($istty) { - my $colour; - - if ($result eq "ok") { $colour = "\e[32m"; } # green - elsif ($result eq "xpass") { $colour = "\e[34;1m"; } # *blue* - elsif ($result eq "xfail") { $colour = "\e[33m"; } # yellow - elsif ($result eq "skip") { $colour = "\e[36m"; } # cyan - else { $colour = "\e[31;1m"; } # *red* - - return "$colour$text\e[0m"; - } else { - return $text; - } -} - -sub colourize($) -{ - my $result = shift; - return colourize_as($result, $result); -} - - -sub mstime($$$) -{ - my ($floatsec, $warntime, $badtime) = @_; - my $ms = int($floatsec * 1000); - my $str = sprintf("%d.%03ds", $ms/1000, $ms % 1000); - - if ($istty && $ms > $badtime) { - return "\e[31;1m$str\e[0m"; - } elsif ($istty && $ms > $warntime) { - return "\e[33;1m$str\e[0m"; - } else { - return "$str"; - } -} - -sub resultline($$) -{ - my ($name, $result) = @_; - return sprintf("! %-65s %s", $name, colourize($result)); -} - -my $allstart = time(); -my ($start, $stop); - -sub endsect() -{ - $stop = time(); - if ($start) { - printf " %s %s\n", mstime($stop - $start, 500, 1000), colourize("ok"); - } -} - -while (<$fh>) -{ - chomp; - s/\r//g; - - if (/^\s*Testing "(.*)" in (.*):\s*$/) - { - alarm(120); - my ($sect, $file) = ($1, $2); - - endsect(); - - printf("! %s %s: ", $file, $sect); - @log = (); - $start = $stop; - } - elsif (/^!\s*(.*?\s(?:(\S+)\s)?)(\S+)\s*$/) - { - alarm(120); - - my ($name, $result2, $result) = ($1, $2, $3); - $result2 ||= ""; - - if (!$start) { - printf("\n! Startup: "); - $start = time(); - } - - push @log, resultline($name, $result); - - if ($result eq "ok") { - if ($result2 eq "xpass") { - $gxpasses++; - print colourize_as("xpass", "X"); - } elsif ($result2 eq "xfail") { - $gxfails++; - print colourize_as("xfail", "f"); - } elsif ($result2 eq "skip") { - $gskips++; - print colourize_as("skip", "s"); - } else { - $gpasses++; - print "."; - } - } else { - $gfails++; - if (@log) { - print "\n" . join("\n", @log) . "\n"; - @log = (); - } - } - } - else - { - push @log, $_; - } -} - -endsect(); - -my $newpid = waitpid($pid, 0); -if ($newpid != $pid) { - die("waitpid returned '$newpid', expected '$pid'\n"); -} - -my $code = $?; -my $ret = ($code >> 8); - -# return death-from-signal exits as >128. This is what bash does if you ran -# the program directly. -if ($code && !$ret) { $ret = $code | 128; } - -if ($ret && @log) { - print "\n" . join("\n", @log) . "\n"; -} - -if ($code != 0) { - print resultline("Program returned non-zero exit code ($ret)", "FAILED"); -} - -my $gtotal = $gpasses+$gfails+$gxpasses+$gxfails+$gskips; -printf("\nWvTest: %d test%s, %s failure%s, total time %s.\n", - $gtotal, $gtotal==1 ? "" : "s", - $gfails>0 ? colourize_as("fail", "$gfails") : "$gfails", - $gfails==1 ? "" : "s", - mstime(time() - $allstart, 2000, 5000)); -printf("WvTest: %s test%s skipped, %s known breakage%s, %s fixed breakage%s.\n", - $gskips>0 ? colourize_as("skip", "$gskips") : "$gskips", - $gskips==1 ? "" : "s", - $gxfails>0 ? colourize_as("xfail", "$gxfails"): "$gxfails", - $gxfails==1 ? "" : "s", - $gxpasses>0 ? colourize_as("xpass", "$gxpasses") : "$gxpasses", - $gxpasses==1 ? "" : "s"); -print STDERR "\nWvTest result code: $ret\n"; -exit( $ret ? $ret : ($gfails ? 125 : 0) );