pax_global_header00006660000000000000000000000064150501213050014502gustar00rootroot0000000000000052 comment=d3e859a096d2526ac8b851acc67b7f3a698b79e3 vramsteg-1.1.1/000077500000000000000000000000001505012130500133325ustar00rootroot00000000000000vramsteg-1.1.1/.gitignore000066400000000000000000000002631505012130500153230ustar00rootroot00000000000000vramsteg CMakeFiles CMakeCache.txt cmake_install.cmake Makefile install_manifest.txt cmake.h commit.h CPackConfig.cmake CPackSourceConfig.cmake vramsteg.1 _CPack_Packages patches vramsteg-1.1.1/AUTHORS000066400000000000000000000007221505012130500144030ustar00rootroot00000000000000The development of vramsteg was made possible by the significant contributions of the following people: Paul Beckingham (Author) Federico Hernandez (Author) The following submitted code, packages or analysis, and deserve special thanks: Alejandro Garrido Mota Jakub Wilk Jason A. Pfeil Jörg Krause Ben Boeckel Paul J. Fenwick Michael Neumann Thanks to the following, who submitted detailed bug reports and excellent suggestions: hosaka vramsteg-1.1.1/CMakeLists.txt000066400000000000000000000036751505012130500161050ustar00rootroot00000000000000cmake_minimum_required (VERSION 2.8) set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") set (HAVE_CMAKE true) project (vramsteg) include (CXXSniffer) set (PROJECT_VERSION "1.1.1") set (PACKAGE "${PROJECT_NAME}") set (VERSION "${PROJECT_VERSION}") set (PACKAGE_BUGREPORT "support@taskwarrior.org") set (PACKAGE_NAME "${PACKAGE}") set (PACKAGE_TARNAME "${PACKAGE}") set (PACKAGE_VERSION "${VERSION}") set (PACKAGE_STRING "${PACKAGE} ${VERSION}") if (FREEBSD OR DRAGONFLY) SET (VRAMSTEG_MAN1DIR man/man1 CACHE STRING "Installation directory for man pages, section 1") else (FREEBSD OR DRAGONFLY) SET (VRAMSTEG_MAN1DIR share/man/man1 CACHE STRING "Installation directory for man pages, section 1") endif (FREEBSD OR DRAGONFLY) SET (VRAMSTEG_DOCDIR share/doc/clog CACHE STRING "Installation directory for doc files") SET (VRAMSTEG_BINDIR bin CACHE STRING "Installation directory for the binary") message ("-- Configuring cmake.h") configure_file ( ${CMAKE_SOURCE_DIR}/cmake.h.in ${CMAKE_SOURCE_DIR}/cmake.h) add_subdirectory (src) add_subdirectory (doc) add_subdirectory (examples) if (EXISTS ${CMAKE_SOURCE_DIR}/test) add_subdirectory (test EXCLUDE_FROM_ALL) endif (EXISTS ${CMAKE_SOURCE_DIR}/test) set (doc_FILES NEWS ChangeLog README INSTALL AUTHORS COPYING) foreach (doc_FILE ${doc_FILES}) install (FILES ${doc_FILE} DESTINATION ${VRAMSTEG_DOCDIR}) endforeach (doc_FILE) # --- set (CPACK_SOURCE_GENERATOR "TGZ") set (CPACK_SOURCE_PACKAGE_FILE_NAME ${PACKAGE_NAME}-${PACKAGE_VERSION}) set (CPACK_SOURCE_IGNORE_FILES "CMakeCache" "CMakeFiles" "CPackConfig" "CPackSourceConfig" "_CPack_Packages" "cmake_install" "install_manifest" "Makefile$" "test" "demo" "src/vramsteg$" "/\\\\.gitignore" "/\\\\.git/" "swp$") include (CPack) vramsteg-1.1.1/COPYING000066400000000000000000000022311505012130500143630ustar00rootroot00000000000000Vramsteg - a command line progress bar. Copyright 2010 - 2017, Paul Beckingham, Federico Hernandez. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. http://www.opensource.org/licenses/mit-license.php vramsteg-1.1.1/ChangeLog000066400000000000000000000025461505012130500151130ustar00rootroot00000000000000------ current release --------------------------- 1.1.1 () - - TD-120 Missing cmakedefine for HAVE_GET_CURRENT_DIR_NAME (Thanks to Jörg Krause, Ben Boeckel). - TI-91 Timewarrior does not compile on DragonFly (thanks to Michael Neumann). - TW-1845 Cygwin build fails, missing get_current_dir_name (thanks to hosaka). - TW-1936 Tweak tests to have fuller TAP compliance (thanks to Paul J. Fenwick) - Converted to C++11. - Improved compliance with CppCoreGuidelines. - Integated common CMake CXX module. - Updated test suite to Python. ------ old releases ------------------------------ 1.1.0 (2015-09-26) ce4a5b607786508d065fc9d92ecae65b3a3a9097 - TW-1296 make test/run_all exit with non-zero code if a test fail (thanks to Jakub Wilk). - Added an initial test suite. - Corrected copyright line in source. - Added support for 64-bit values for --min, --max, and --current arguments to avoid overflows caused by using int (thanks to Jason A. Pfeil). 1.0.1 (2013-09-02) c6030b2768bc94192ff042cdde42782f713c1050 - Fixed manpage typos (thanks to Alejandro Garrido Mota). - Fixed compiler warnings. 1.0.0 - Initial release supporting three bar styles, percentage, elapsed, remaining, labels and width settings. - When -width is not specified, uses the whole terminal width. Vramsteg project officially began 6th June, 2010. vramsteg-1.1.1/INSTALL000066400000000000000000000032431505012130500143650ustar00rootroot00000000000000Installation Instructions ------------------------- Please follow the instructions below to build vramsteg with cmake. Pre-requisites -------------- You will need the CMake build system installed in order to build vramsteg from source. More information on cmake can be obtained at http://cmake.org Basic Installation ------------------ Briefly, these shell commands will unpack, build and install vramsteg: $ tar xzf vramsteg-X.Y.Z.tar.gz [1] $ cd vramsteg-X.Y.Z [2] $ cmake . [3] $ make [4] $ sudo make install [5] $ cd .. ; rm -r vramsteg-X.Y.Z [6] These commands are explained below: 1. Unpacks the source tarball. This creates the directory vramsteg-X.Y.Z, containing all the code. 2. Change directory to the root of the distribution. 3. Invokes CMake to scan for dependencies and machine-specific details, then generate the makefiles. This may take a minute. 4. Builds vramsteg. This may take a minute. 5. Installs the program, documentation and other data files. 6. Removes the temporary directory. Build and configurations options -------------------------------- You can customize the configuration run with cmake variables. This will modify the installation process: To change the installation directory you use the following configuration variable: $ cmake -DCMAKE_INSTALL_PREFIX= . cmake configuration variables are applied with the -D option and consist of a and a : $ cmake -D= . vramsteg-1.1.1/LICENSE000066400000000000000000000022311505012130500143350ustar00rootroot00000000000000Vramsteg - a command line progress bar. Copyright 2010 - 2017, Paul Beckingham, Federico Hernandez. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. http://www.opensource.org/licenses/mit-license.php vramsteg-1.1.1/NEWS000066400000000000000000000012141505012130500140270ustar00rootroot00000000000000 New Features in vramsteg 1.1.1 - New commands in vramsteg 1.1.1 - New configuration options in vramsteg 1.1.1 - Newly deprecated features in vramsteg 1.1.1 - --- Please refer to the ChangeLog file for full details. --- Vramsteg has been built and tested on the following configurations: * macOS 10.12 Sierra * Debian 7.0 Wheezy (stable) and 6.0 Squeeze (oldstable) plus Sid (testing) --- While Vramsteg has undergone testing, bugs are sure to remain. If you encounter a bug, please send a message to: support@gothenburgbitfactory.org and check for updates at https://github.com/GothenburgBitFactory/vramsteg. Thank you. vramsteg-1.1.1/README000066400000000000000000000011111505012130500142040ustar00rootroot00000000000000Vramsteg ('progress' in Svenska, almost) Vramsteg is an open source, command line utility that provides shell scripts with a full-featured progress indicator. The progress bar can display elapsed time, remaining time estimate, percentage completed, and labels. The progress bar can have user-specified colors, and be rendered in multiple styles. See the man page (enter 'man vramsteg') for full details on how to use vramsteg or look in the examples directory for several shell scripts that illustrate usage. Check for updates at https://github.com/GothenburgBitFactory/vramsteg. vramsteg-1.1.1/cmake.h.in000066400000000000000000000016431505012130500151740ustar00rootroot00000000000000/* cmake.h.in. Creates cmake.h during a build */ /* Package information */ #define PACKAGE "${PACKAGE}" #define VERSION "${VERSION}" #define PACKAGE_BUGREPORT "${PACKAGE_BUGREPORT}" #define PACKAGE_NAME "${PACKAGE_NAME}" #define PACKAGE_TARNAME "${PACKAGE_TARNAME}" #define PACKAGE_VERSION "${PACKAGE_VERSION}" #define PACKAGE_STRING "${PACKAGE_STRING}" /* git information */ #cmakedefine HAVE_COMMIT /* Compiling platform */ #cmakedefine LINUX #cmakedefine DARWIN #cmakedefine KFREEBSD #cmakedefine FREEBSD #cmakedefine OPENBSD #cmakedefine NETBSD #cmakedefine DRAGONFLY #cmakedefine SOLARIS #cmakedefine GNUHURD #cmakedefine CYGWIN #cmakedefine UNKNOWN /* Found tm.tm_gmtoff struct member */ #cmakedefine HAVE_TM_GMTOFF /* Found st.st_birthtime struct member */ #cmakedefine HAVE_ST_BIRTHTIME /* Functions */ #cmakedefine HAVE_GET_CURRENT_DIR_NAME #cmakedefine HAVE_TIMEGM #cmakedefine HAVE_UUID_UNPARSE_LOWER vramsteg-1.1.1/cmake/000077500000000000000000000000001505012130500144125ustar00rootroot00000000000000vramsteg-1.1.1/cmake/CXXSniffer.cmake000066400000000000000000000042771505012130500174050ustar00rootroot00000000000000message ("-- Configuring C++11") message ("-- System: ${CMAKE_SYSTEM_NAME}") include (CheckCXXCompilerFlag) # NOTE: Phase out -std=gnu++0x and --std=c++0x as soon as realistically possible. CHECK_CXX_COMPILER_FLAG("-std=c++11" _HAS_CXX11) CHECK_CXX_COMPILER_FLAG("-std=c++0x" _HAS_CXX0X) CHECK_CXX_COMPILER_FLAG("-std=gnu++0x" _HAS_GNU0X) if (_HAS_CXX11) set (_CXX11_FLAGS "-std=c++11") elseif (_HAS_CXX0X) message (WARNING "Enabling -std=c++0x draft compile flag. Your compiler does not support the standard '-std=c++11' option. Consider upgrading.") set (_CXX11_FLAGS "-std=c++0x") elseif (_HAS_GNU0X) message (WARNING "Enabling -std=gnu++0x draft compile flag. Your compiler does not support the standard '-std=c++11' option. Consider upgrading.") set (_CXX11_FLAGS "-std=gnu++0x") else (_HAS_CXX11) message (FATAL_ERROR "C++11 support missing. Try upgrading your C++ compiler. If you have a good reason for using an outdated compiler, please let us know at support@taskwarrior.org.") endif (_HAS_CXX11) if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") set (LINUX true) elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set (DARWIN true) set (_CXX11_FLAGS "${_CXX11_FLAGS} -stdlib=libc++") elseif (${CMAKE_SYSTEM_NAME} MATCHES "kFreeBSD") set (KFREEBSD true) elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") set (FREEBSD true) elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") set (OPENBSD true) elseif (${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") set (NETBSD true) elseif (${CMAKE_SYSTEM_NAME} MATCHES "DragonFly") set (DRAGONFLY true) elseif (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") set (SOLARIS true) elseif (${CMAKE_SYSTEM_NAME} STREQUAL "GNU") set (GNUHURD true) elseif (${CMAKE_SYSTEM_NAME} STREQUAL "CYGWIN") set (CYGWIN true) # NOTE: Not setting -std=gnu++0x leads to compile errors even with # GCC 4.8.3, and debugging those leads to insanity. Adding this # workaround instead of fixing Cygwin. set (_CXX11_FLAGS "-std=gnu++0x") else (${CMAKE_SYSTEM_NAME} MATCHES "Linux") set (UNKNOWN true) endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") set (CMAKE_CXX_FLAGS "${_CXX11_FLAGS} ${CMAKE_CXX_FLAGS}") set (CMAKE_CXX_FLAGS "-Wall -Wextra -Wsign-compare -Wreturn-type ${CMAKE_CXX_FLAGS}") vramsteg-1.1.1/demo/000077500000000000000000000000001505012130500142565ustar00rootroot00000000000000vramsteg-1.1.1/demo/script000077500000000000000000000032221505012130500155070ustar00rootroot00000000000000echo You are watching an automated vramsteg demo. Vramsteg is an echo open source standalone progress bar utility for use by anything echo that runs at the command line. echo sleep 3 echo Here is a simple example: for i in {0..6} do ../src/vramsteg --width 60 --style text --min 0 --max 6 --current $i sleep 1 done ../src/vramsteg --width 60 --remove sleep 1 echo Here is another that includes percentage completion, a label, echo and estimated remaining time: sleep 2 START=$(../src/vramsteg --now) for i in {0..6} do ../src/vramsteg --width 60 --style text --min 0 --max 6 --current $i --label Demo --percentage --start $START --estimate sleep 1 done ../src/vramsteg --width 60 --remove sleep 1 echo Here is an example that uses a solid bar and elapsed time: sleep 2 START=$(../src/vramsteg --now) for i in {0..6} do ../src/vramsteg --width 60 --style mono --min 0 --max 6 --current $i --label Demo --percentage --start $START --elapsed sleep 1 done ../src/vramsteg --width 60 --remove sleep 1 echo Here is an example that uses the full terminal width; sleep 2 START=$(../src/vramsteg --now) for i in {0..6} do ../src/vramsteg --style mono --min 0 --max 6 --current $i --label Demo --percentage --start $START --elapsed sleep 1 done ../src/vramsteg --remove sleep 1 echo Here is a more colorful version, uses less space, and is echo not removed from the display after it is done: echo sleep 2 START=$(../src/vramsteg --now) for i in {0..6} do ../src/vramsteg --width 40 --min 0 --max 6 --current $i --label Demo --percentage --start $START --elapsed sleep 1 done echo echo sleep 1 echo Thanks for watching echo http://gothenburgbitfactory.org/ sleep 1 vramsteg-1.1.1/doc/000077500000000000000000000000001505012130500140775ustar00rootroot00000000000000vramsteg-1.1.1/doc/CMakeLists.txt000066400000000000000000000006021505012130500166350ustar00rootroot00000000000000cmake_minimum_required (VERSION 2.8) message ("-- Configuring man pages") set (man_FILES vramsteg.1) foreach (man_FILE ${man_FILES}) configure_file ( man/${man_FILE}.in man/${man_FILE}) endforeach (man_FILE) install (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/man/ DESTINATION ${VRAMSTEG_MAN1DIR} FILES_MATCHING PATTERN "*.1") vramsteg-1.1.1/doc/man/000077500000000000000000000000001505012130500146525ustar00rootroot00000000000000vramsteg-1.1.1/doc/man/vramsteg.1.in000066400000000000000000000137131505012130500171760ustar00rootroot00000000000000.TH vramsteg 1 2015-10-12 "${PACKAGE_STRING}" "User Manuals" .SH NAME vramsteg \- CLI progress bar .SH SYNOPSIS To display/update a progress bar: .B vramsteg --min --max --current [options] To remove a progress bar: .B vramsteg --remove To capture the start time: .B START=$(vramsteg --now) To include elapsed time (which requires a start time): .B vramsteg --start=$START --elapsed ... To include estimated remaining time (which requires a start time): .B vramsteg --start=$START --estimate ... To use a specific bar width: .B vramsteg --width 100 ... To show the percentage completed: .B vramsteg --percentage ... To show a label at the beginning of the bar: .B vramsteg --label "This is a label" ... To use an alternate rendering style: .B vramsteg --style ... .SH DESCRIPTION ('progress' in Swedish, almost) is an open source, command line utility that provides shell scripts with a full-featured progress indicator. The progress bar can display elapsed time, remaining time estimate, percentage completed, and labels. The progress bar can have user-specified colors, and be rendered in multiple styles. If you have a shell script, or in fact any command line program that needs a progress bar, vramsteg may be the right solution. Suppose you have a program that is performing a lengthy operation, provided that it has an opportunity to execute vramsteg frequently, then integrating a progress bar is simple. You may have seen progress bars used to good effect in the rsync or scp commands, among others. .SH EXAMPLES Here is a complete bash shell script illustrating how vramsteg works, in the simplest case: #! /bin/bash vramsteg \-\-min 0 \-\-max 4 \-\-current 0 sleep 1 vramsteg \-\-min 0 \-\-max 4 \-\-current 1 sleep 1 vramsteg \-\-min 0 \-\-max 4 \-\-current 2 sleep 1 vramsteg \-\-min 0 \-\-max 4 \-\-current 3 sleep 1 vramsteg \-\-min 0 \-\-max 4 \-\-current 4 echo Obviously this is a contrived example, but it illustrates how vramsteg is used to show a 4 step process. The \-\-min and \-\-max arguments specify what constitutes 0% and 100% of the work, and are integer values. The \-\-current argument represents where the progress bar is at any moment. The example takes 4 seconds to complete, but those sleep commands are proxies for whatever your program is doing. A more realistic example involves looping. Here is a simple shell script loop that will be used for a more complete example: #! /bin/bash for i in {0..10} do vramsteg \-\-min 0 \-\-max 10 \-\-current $i sleep 1 done echo Again, the sleep command represents the real work that is being done. Note that the 'echo' command at the end provides a newline character to prevent any text from overwriting the bar. To remove the bar when done, the script becomes: #! /bin/bash for i in {0..10} do vramsteg \-\-min 0 \-\-max 10 \-\-current $i sleep 1 done vramsteg \-\-remove Now the last list replaces the need for the 'echo' command. There are two features that require some additional code. In order to display the elapsed time, vramsteg needs to know the time when the process began. Because vramsteg is stateless, the start time needs to be specified on every call, but first the start time must be captured. There is a \-\-now option that causes the current time (in epoch form) to be displayed: vramsteg \-\-now 1276361315 This value needs to be captured by the shell script, like this: START=$(vramsteg \-\-now) or START=`vramsteg \-\-now` Then along with the \-\-elapsed option, the start time is provided to each call of vramsteg like this: #! /bin/bash START=$(../vramsteg \-\-now) for i in {0..10} do vramsteg \-\-min 0 \-\-max 10 \-\-current $i \-\-start $START \-\-elapsed sleep 1 done vramsteg \-\-remove Because vramsteg is stateless, which means it doesn't record any information on disk, the start time needs to be specified for every vramsteg call that makes use of it. The other feature is an estimate of the remaining time, which is used in a similar fashion: #! /bin/bash START=$(../vramsteg \-\-now) for i in {0..10} do vramsteg \-\-min 0 \-\-max 10 \-\-current $i \-\-start $START \-\-estimate sleep 1 done vramsteg \-\-remove The estimated time only displays whole numbers of seconds, and because the \-\-now option also only returns whole seconds, there can be inaccuracies in the elapsed and estimated time if process is fast. By default, vramsteg uses 80 columns to display the progress bar. You may override this by specifying a different width, but if you do, then you must also specify that width for all vramsteg calls, such as: vramsteg \-\-remove \-\-width 100 If you specify a width that is too small to include features like the label, percentage, elapsed and estimated time, an error is reported. If you enter the command: vramsteg without arguments, the command usage is displayed, including examples of progress bars in the supported styles. .SH FILES Vramsteg has no external dependencies, uses no files, and leaves no trace. It is, in fact, a completely stateless program, which is why there are required command line arguments for some features. .SH "CREDITS & COPYRIGHTS" Copyright (C) 2010 \- 2017 P. Beckingham, F. Hernandez Copyright (C) 2010 \- 2017 Gothenburg Bit Factory .br Vramsteg is distributed under the MIT license. See http://www.opensource.org/licenses/mit-license.php for more information. .SH SEE ALSO For more information regarding vramsteg, the following may be referenced: .TP The official site at .TP The official code repository at .TP You can contact the project by writing an email to .SH REPORTING BUGS .TP Bugs in vramsteg may be reported to vramsteg-1.1.1/examples/000077500000000000000000000000001505012130500151505ustar00rootroot00000000000000vramsteg-1.1.1/examples/CMakeLists.txt000066400000000000000000000007131505012130500177110ustar00rootroot00000000000000cmake_minimum_required (VERSION 2.8) install (FILES all_default all_mono all_text basic_default basic_mono basic_text elapsed_default elapsed_mono elapsed_text estimate_default estimate_mono estimate_text label_default label_mono label_text minimal_default minimal_mono minimal_text percentage_default percentage_mono percentage_text remove_default remove_mono remove_text DESTINATION ${VRAMSTEG_DOCDIR}/examples) vramsteg-1.1.1/examples/all_default000077500000000000000000000006301505012130500173510ustar00rootroot00000000000000#! /bin/bash echo Default style echo Default colors echo With width echo With percentage echo With elapsed time echo With estimated remaining time echo With label echo With remove START=$(../src/vramsteg --now) for i in {0..10} do ../src/vramsteg --width 80 --label label --min 0 --max 10 --current $i --percentage --elapsed --estimate --start $START sleep 1 done ../src/vramsteg --width 80 --remove vramsteg-1.1.1/examples/all_mono000077500000000000000000000006441505012130500167020ustar00rootroot00000000000000#! /bin/bash echo 'mono' style echo Default colors echo With width echo With percentage echo With elapsed time echo With estimated remaining time echo With label echo With remove START=$(../src/vramsteg --now) for i in {0..10} do ../src/vramsteg --style mono --width 80 --label label --min 0 --max 10 --current $i --percentage --elapsed --estimate --start $START sleep 1 done ../src/vramsteg --width 80 --remove vramsteg-1.1.1/examples/all_text000077500000000000000000000006441505012130500167160ustar00rootroot00000000000000#! /bin/bash echo 'text' style echo Default colors echo With width echo With percentage echo With elapsed time echo With estimated remaining time echo With label echo With remove START=$(../src/vramsteg --now) for i in {0..10} do ../src/vramsteg --style text --width 80 --label label --min 0 --max 10 --current $i --percentage --elapsed --estimate --start $START sleep 1 done ../src/vramsteg --width 80 --remove vramsteg-1.1.1/examples/basic_default000077500000000000000000000004101505012130500176560ustar00rootroot00000000000000#! /bin/bash echo Default style echo Default colors echo Default width echo No percentage echo No elapsed time echo No estimated remaining time echo No label echo No remove for i in {0..10} do ../src/vramsteg --min 0 --max 10 --current $i sleep 1 done echo vramsteg-1.1.1/examples/basic_mono000077500000000000000000000004241505012130500172070ustar00rootroot00000000000000#! /bin/bash echo 'mono' style echo Default colors echo Default width echo No percentage echo No elapsed time echo No estimated remaining time echo No label echo No remove for i in {0..10} do ../src/vramsteg --style mono --min 0 --max 10 --current $i sleep 1 done echo vramsteg-1.1.1/examples/basic_text000077500000000000000000000004241505012130500172230ustar00rootroot00000000000000#! /bin/bash echo 'text' style echo Default colors echo Default width echo No percentage echo No elapsed time echo No estimated remaining time echo No label echo No remove for i in {0..10} do ../src/vramsteg --style text --min 0 --max 10 --current $i sleep 1 done echo vramsteg-1.1.1/examples/elapsed_default000077500000000000000000000005021505012130500202140ustar00rootroot00000000000000#! /bin/bash echo Default style echo Default colors echo Default width echo No percentage echo With elapsed time echo No estimated remaining time echo No label echo No remove START=$(../src/vramsteg --now) for i in {0..10} do ../src/vramsteg --min 0 --max 10 --current $i --elapsed --start $START sleep 1 done echo vramsteg-1.1.1/examples/elapsed_mono000077500000000000000000000005161505012130500175450ustar00rootroot00000000000000#! /bin/bash echo 'mono' style echo Default colors echo Default width echo No percentage echo With elapsed time echo No estimated remaining time echo No label echo No remove START=$(../src/vramsteg --now) for i in {0..10} do ../src/vramsteg --style mono --min 0 --max 10 --current $i --elapsed --start $START sleep 1 done echo vramsteg-1.1.1/examples/elapsed_text000077500000000000000000000005161505012130500175610ustar00rootroot00000000000000#! /bin/bash echo 'text' style echo Default colors echo Default width echo No percentage echo With elapsed time echo No estimated remaining time echo No label echo No remove START=$(../src/vramsteg --now) for i in {0..10} do ../src/vramsteg --style text --min 0 --max 10 --current $i --elapsed --start $START sleep 1 done echo vramsteg-1.1.1/examples/estimate_default000077500000000000000000000005031505012130500204130ustar00rootroot00000000000000#! /bin/bash echo Default style echo Default colors echo Default width echo No percentage echo No elapsed time echo With estimated remaining time echo No label echo No remove START=$(../src/vramsteg --now) for i in {0..10} do ../src/vramsteg --min 0 --max 10 --current $i --estimate --start $START sleep 1 done echo vramsteg-1.1.1/examples/estimate_mono000077500000000000000000000005171505012130500177440ustar00rootroot00000000000000#! /bin/bash echo 'mono' style echo Default colors echo Default width echo No percentage echo No elapsed time echo With estimated remaining time echo No label echo No remove START=$(../src/vramsteg --now) for i in {0..10} do ../src/vramsteg --style mono --min 0 --max 10 --current $i --estimate --start $START sleep 1 done echo vramsteg-1.1.1/examples/estimate_text000077500000000000000000000005171505012130500177600ustar00rootroot00000000000000#! /bin/bash echo 'text' style echo Default colors echo Default width echo No percentage echo No elapsed time echo With estimated remaining time echo No label echo No remove START=$(../src/vramsteg --now) for i in {0..10} do ../src/vramsteg --style text --min 0 --max 10 --current $i --estimate --start $START sleep 1 done echo vramsteg-1.1.1/examples/label_default000077500000000000000000000004361505012130500176640ustar00rootroot00000000000000#! /bin/bash echo Default style echo Default colors echo Default width echo No percentage echo No elapsed time echo No estimated remaining time echo With label echo No remove for i in {0..10} do ../src/vramsteg --label "Bar label" --min 0 --max 10 --current $i sleep 1 done echo vramsteg-1.1.1/examples/label_mono000077500000000000000000000004521505012130500172060ustar00rootroot00000000000000#! /bin/bash echo 'mono' style echo Default colors echo Default width echo No percentage echo No elapsed time echo No estimated remaining time echo With label echo No remove for i in {0..10} do ../src/vramsteg --style mono --label "Bar label" --min 0 --max 10 --current $i sleep 1 done echo vramsteg-1.1.1/examples/label_text000077500000000000000000000004521505012130500172220ustar00rootroot00000000000000#! /bin/bash echo 'text' style echo Default colors echo Default width echo No percentage echo No elapsed time echo No estimated remaining time echo With label echo No remove for i in {0..10} do ../src/vramsteg --style text --label "Bar label" --min 0 --max 10 --current $i sleep 1 done echo vramsteg-1.1.1/examples/minimal_default000077500000000000000000000003751505012130500202350ustar00rootroot00000000000000#! /bin/bash ../src/vramsteg --min 0 --max 3 --current 0 sleep 1 ../src/vramsteg --min 0 --max 3 --current 1 sleep 1 ../src/vramsteg --min 0 --max 3 --current 2 sleep 1 ../src/vramsteg --min 0 --max 3 --current 3 sleep 1 ../src/vramsteg --remove echo vramsteg-1.1.1/examples/minimal_mono000077500000000000000000000004611505012130500175550ustar00rootroot00000000000000#! /bin/bash ../src/vramsteg --style mono --min 0 --max 3 --current 0 sleep 1 ../src/vramsteg --style mono --min 0 --max 3 --current 1 sleep 1 ../src/vramsteg --style mono --min 0 --max 3 --current 2 sleep 1 ../src/vramsteg --style mono --min 0 --max 3 --current 3 sleep 1 ../src/vramsteg --remove echo vramsteg-1.1.1/examples/minimal_text000077500000000000000000000004611505012130500175710ustar00rootroot00000000000000#! /bin/bash ../src/vramsteg --style text --min 0 --max 3 --current 0 sleep 1 ../src/vramsteg --style text --min 0 --max 3 --current 1 sleep 1 ../src/vramsteg --style text --min 0 --max 3 --current 2 sleep 1 ../src/vramsteg --style text --min 0 --max 3 --current 3 sleep 1 ../src/vramsteg --remove echo vramsteg-1.1.1/examples/percentage_default000077500000000000000000000004271505012130500207220ustar00rootroot00000000000000#! /bin/bash echo Default style echo Default colors echo Default width echo With percentage echo No elapsed time echo No estimated remaining time echo No label echo No remove for i in {0..10} do ../src/vramsteg --percentage --min=0 --max=10 --current=$i sleep 1 done echo vramsteg-1.1.1/examples/percentage_mono000077500000000000000000000004431505012130500202440ustar00rootroot00000000000000#! /bin/bash echo 'mono' style echo Default colors echo Default width echo With percentage echo No elapsed time echo No estimated remaining time echo No label echo No remove for i in {0..10} do ../src/vramsteg --style mono --percentage --min=0 --max=10 --current=$i sleep 1 done echo vramsteg-1.1.1/examples/percentage_text000077500000000000000000000004431505012130500202600ustar00rootroot00000000000000#! /bin/bash echo 'text' style echo Default colors echo Default width echo With percentage echo No elapsed time echo No estimated remaining time echo No label echo No remove for i in {0..10} do ../src/vramsteg --style text --percentage --min=0 --max=10 --current=$i sleep 1 done echo vramsteg-1.1.1/examples/remove_default000077500000000000000000000004371505012130500201030ustar00rootroot00000000000000#! /bin/bash echo Default style echo Default colors echo Default width echo No percentage echo No elapsed time echo No estimated remaining time echo No label echo With remove for i in {0..10} do ../src/vramsteg --min=0 --max=10 --current=$i sleep 1 done ../src/vramsteg --remove vramsteg-1.1.1/examples/remove_mono000077500000000000000000000004531505012130500174250ustar00rootroot00000000000000#! /bin/bash echo 'mono' style echo Default colors echo Default width echo No percentage echo No elapsed time echo No estimated remaining time echo No label echo With remove for i in {0..10} do ../src/vramsteg --style mono --min=0 --max=10 --current=$i sleep 1 done ../src/vramsteg --remove vramsteg-1.1.1/examples/remove_text000077500000000000000000000004531505012130500174410ustar00rootroot00000000000000#! /bin/bash echo 'text' style echo Default colors echo Default width echo No percentage echo No elapsed time echo No estimated remaining time echo No label echo With remove for i in {0..10} do ../src/vramsteg --style text --min=0 --max=10 --current=$i sleep 1 done ../src/vramsteg --remove vramsteg-1.1.1/src/000077500000000000000000000000001505012130500141215ustar00rootroot00000000000000vramsteg-1.1.1/src/CMakeLists.txt000066400000000000000000000006011505012130500166560ustar00rootroot00000000000000cmake_minimum_required (VERSION 2.8) include_directories (${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}) set (vramsteg_SRCS vramsteg.cpp Progress.cpp Progress.h) add_executable (vramsteg ${vramsteg_SRCS}) install (TARGETS vramsteg DESTINATION bin) #set (CMAKE_BUILD_TYPE debug) #set (CMAKE_C_FLAGS_DEBUG "-g") #set (CMAKE_C_FLAGS_RELEASE "-O3") vramsteg-1.1.1/src/Progress.cpp000066400000000000000000000241031505012130500164310ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // // Copyright 2010 - 2017, Paul Beckingham, Federico Hernandez. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // http://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include //////////////////////////////////////////////////////////////////////////////// void Progress::update (long value) { if (isatty (fileno (stdout)) && _current != value) { // Box the range. if (value < minimum) value = minimum; if (value > maximum) value = maximum; // Current value. _current = value; // Capable of supporting multiple styles. if (style == "") renderStyleDefault (); else if (style == "mono") renderStyleMono (); else if (style == "text") renderStyleText (); else throw std::string ("Style '") + style + "' not supported."; } } //////////////////////////////////////////////////////////////////////////////// void Progress::done () const { if (isatty (fileno (stdout))) { if (remove) std::cout << "\r" << std::setfill (' ') << std::setw (width) << ' '; std::cout << std::endl; } } //////////////////////////////////////////////////////////////////////////////// std::string Progress::formatTime (time_t t) const { char buffer [128]; int days = t / 86400; int hours = (t % 86400) / 3600; int minutes = (t % 3600) / 60; int seconds = t % 60; if (days) snprintf (buffer, 128, "%dd %d:%02d:%02d", days, hours, minutes, seconds); else if (hours) snprintf (buffer, 128, "%d:%02d:%02d", hours, minutes, seconds); else snprintf (buffer, 128, "%02d:%02d", minutes, seconds); return std::string (buffer); } //////////////////////////////////////////////////////////////////////////////// // Default style looks like this: // // label GGGGGGGGRRRRRRRRRRRRRRRRR 34% 0:12 0:35 // // ^^^^^ Label string // ^^^^^^^^ Completed bar (in green) // ^^^^^^^^^^^^^^^^^ Incomplete bar (in red) // ^^^^ Percentage complete // ^^^^ Elapsed time // ^^^^ Remaining estimate void Progress::renderStyleDefault () const { // Fraction completed. double fraction = (1.0 * (_current - minimum)) / (maximum - minimum); // Elapsed time. auto now = time (nullptr); std::string elapsed_time; if (elapsed && start != 0) elapsed_time = formatTime (now - start); // Estimated remaining time. std::string estimate_time; if (estimate && start != 0) { if (fraction >= 1e-6) estimate_time = formatTime ((time_t) (int) (((now - start) * (1.0 - fraction)) / fraction)); else estimate_time = formatTime (0); } // Calculate bar width. auto bar = width - (label.length () ? label.length () + 1 : 0) - (percentage ? 5 : 0) - (elapsed ? elapsed_time.length () + 1 : 0) - (estimate ? estimate_time.length () + 1 : 0); if (bar < 1) throw std::string ("The specified width is insufficient."); int visible = (int) (fraction * bar); // Render. if (label.length ()) std::cout << label << ' '; if (visible > 0) std::cout << "\033[42m" // Green << std::setfill (' ') << std::setw (visible) << ' '; if (bar - visible > 0) std::cout << "\033[41m" // Red << std::setfill (' ') << std::setw (bar - visible) << ' '; std::cout << "\033[0m"; if (percentage) std::cout << " " << std::setfill (' ') << std::setw (3) << (int) (fraction * 100) << "%"; if (elapsed && start != 0) std::cout << " " << elapsed_time; if (estimate && start != 0 && fraction > 0.2) std::cout << " " << estimate_time; std::cout << "\r" << std::flush; } //////////////////////////////////////////////////////////////////////////////// // Mono style looks like this: // // label WWWWWWWWBBBBBBBBBBBBBBBBB 34% 0:12 0:35 // // ^^^^^ Label string // ^^^^^^^^ Completed bar (in white) // ^^^^^^^^^^^^^^^^^ Incomplete bar (in black) // ^^^^ Percentage complete // ^^^^ Elapsed time // ^^^^ Remaining estimate void Progress::renderStyleMono () const { // Fraction completed. double fraction = (1.0 * (_current - minimum)) / (maximum - minimum); // Elapsed time. auto now = time (nullptr); std::string elapsed_time; if (elapsed && start != 0) elapsed_time = formatTime (now - start); // Estimated remaining time. std::string estimate_time; if (estimate && start != 0) { if (fraction >= 1e-6) estimate_time = formatTime ((time_t) (int) (((now - start) * (1.0 - fraction)) / fraction)); else estimate_time = formatTime (0); } // Calculate bar width. auto bar = width - (label.length () ? label.length () + 1 : 0) - (percentage ? 5 : 0) - (elapsed ? elapsed_time.length () + 1 : 0) - (estimate ? estimate_time.length () + 1 : 0); if (bar < 1) throw std::string ("The specified width is insufficient."); int visible = (int) (fraction * bar); // Render. if (label.length ()) std::cout << label << ' '; if (visible > 0) std::cout << "\033[47m" // White << std::setfill (' ') << std::setw (visible) << ' '; if (bar - visible > 0) std::cout << "\033[40m" // Black << std::setfill (' ') << std::setw (bar - visible) << ' '; std::cout << "\033[0m"; if (percentage) std::cout << " " << std::setfill (' ') << std::setw (3) << (int) (fraction * 100) << "%"; if (elapsed && start != 0) std::cout << " " << elapsed_time; if (estimate && start != 0) std::cout << " " << estimate_time; std::cout << "\r" << std::flush; } //////////////////////////////////////////////////////////////////////////////// // Text style looks like this: // // label [******** ] 34% 0:12 0:35 // // ^^^^^ Label string // ^^^^^^^^ Completed bar // ^^^^^^^^^^^^^^^^^ Incomplete bar // ^^^^ Percentage complete // ^^^^ Elapsed time // ^^^^ Remaining estimate void Progress::renderStyleText () const { // Fraction completed. double fraction = (1.0 * (_current - minimum)) / (maximum - minimum); // Elapsed time. auto now = time (nullptr); std::string elapsed_time; if (elapsed && start != 0) elapsed_time = formatTime (now - start); // Estimated remaining time. std::string estimate_time; if (estimate && start != 0) { if (fraction >= 1e-6) estimate_time = formatTime ((time_t) (int) (((now - start) * (1.0 - fraction)) / fraction)); else estimate_time = formatTime (0); } // Calculate bar width. auto bar = width - 2 // The [ and ] - (label.length () ? label.length () + 1 : 0) - (percentage ? 5 : 0) - (elapsed ? elapsed_time.length () + 1 : 0) - (estimate ? estimate_time.length () + 1 : 0); if (bar < 1) throw std::string ("The specified width is insufficient."); int visible = (int) (fraction * bar); // Render. if (label.length ()) std::cout << label << ' '; std::cout << '['; if (visible > 0) std::cout << std::setfill ('*') << std::setw (visible) << '*'; if (bar - visible > 0) std::cout << std::setfill (' ') << std::setw (bar - visible) << ' '; std::cout << ']'; if (percentage) std::cout << " " << std::setfill (' ') << std::setw (3) << (int) (fraction * 100) << "%"; if (elapsed && start != 0) std::cout << " " << elapsed_time; if (estimate && start != 0) std::cout << " " << estimate_time; std::cout << "\r" << std::flush; } //////////////////////////////////////////////////////////////////////////////// vramsteg-1.1.1/src/Progress.h000066400000000000000000000040341505012130500160770ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // // Copyright 2010 - 2017, Paul Beckingham, Federico Hernandez. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // http://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// #ifndef INCLUDED_PROGRESS #define INCLUDED_PROGRESS #include #include class Progress { public: void update (long); void done () const; private: std::string formatTime (time_t) const; void renderStyleDefault () const; void renderStyleMono () const; void renderStyleText () const; public: std::string style {}; std::string label {}; int width {80}; long minimum {0}; long maximum {0}; bool percentage {true}; bool remove {true}; time_t start {0}; bool estimate {false}; bool elapsed {false}; private: long _current {-1}; }; #endif //////////////////////////////////////////////////////////////////////////////// vramsteg-1.1.1/src/vramsteg.cpp000066400000000000000000000210771505012130500164640ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // // Copyright 2010 - 2017, Paul Beckingham, Federico Hernandez. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // http://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include extern char *optarg; extern int optind; extern int optopt; extern int opterr; extern int optreset; //////////////////////////////////////////////////////////////////////////////// void showUsage () { std::cout << "\n" << "Usage: vramsteg [options]\n" << "\n" << " -y, --style Style of bar rendering\n" << " -l, --label Progress bar label\n" << " -m, --min Equivalent to 0%\n" << " -x, --max Equivalent to 100%\n" << " -c, --current Current value of progress bar\n" << " -p, --percentage Show percentage\n" << " -s, --start Start time epoch\n" << " -w, --width Width of progress bar, default full width\n" << " -n, --now Returns current time as epoch\n" << " -r, --remove Removes the progress bar\n" << " -e, --elapsed Show elapsed time (needs --start)\n" << " -t, --estimate Show estimated remaining time (needs --start)\n" << " -v, --version Show vramsteg version\n" << " -h, --help Show command options\n" << "\n" << "Supported styles are:\n" << " (default) label \033[42m \033[41m \033[0m 40%\n" << " mono label \033[47m \033[40m \033[0m 20%\n" << " text label [************ ] 60%\n" << "\n"; exit (0); } //////////////////////////////////////////////////////////////////////////////// void showVersion () { std::cout << "\n" << "\033[1m" << PACKAGE_STRING << "\033[0m\n" << "Copyright (C) 2010 - 2017, Gothenburg Bit Factory\n" << "Copyright (C) 2010 - 2017, P. Beckingham, F. Hernandez.\n" << "\n" << "Vramsteg may be copied only under the terms of the MIT license, " << "which may be found in the taskwarrior source kit.\n" << "\n" << "Documentation for vramsteg can be found using 'man vramsteg', or " << "at https://gotenburgbitfactory.org/vramsteg.\n" << "\n"; exit (0); } //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { try { // We don't want any signals causing the program to quit in mid output, as // this would lead to odd colors persisting in the terminal. signal (SIGHUP, SIG_IGN); signal (SIGINT, SIG_IGN); signal (SIGPIPE, SIG_IGN); signal (SIGTERM, SIG_IGN); signal (SIGUSR1, SIG_IGN); signal (SIGUSR2, SIG_IGN); long arg_current {0}; bool arg_elapsed {false}; bool arg_estimate {false}; std::string arg_label {}; long arg_max {0}; long arg_min {0}; bool arg_percentage {false}; bool arg_remove {false}; time_t arg_start {0}; int arg_width {80}; std::string arg_style {}; // Dynamically determine terminal width. unsigned short buff[4]; if (ioctl (fileno(stdout), TIOCGWINSZ, &buff) != -1) arg_width = buff[1]; static struct option longopts[] = { { "current", required_argument, nullptr, 'c' }, { "elapsed", no_argument, nullptr, 'e' }, { "estimate", no_argument, nullptr, 't' }, { "label", required_argument, nullptr, 'l' }, { "max", required_argument, nullptr, 'x' }, { "min", required_argument, nullptr, 'm' }, { "now", no_argument, nullptr, 'n' }, { "percentage", no_argument, nullptr, 'p' }, { "remove", no_argument, nullptr, 'r' }, { "start", required_argument, nullptr, 's' }, { "version", no_argument, nullptr, 'v' }, { "width", required_argument, nullptr, 'w' }, { "style", required_argument, nullptr, 'y' }, { "help", no_argument, nullptr, 'h' }, { nullptr, 0, nullptr, 0 } }; int ch; while ((ch = getopt_long (argc, argv, "c:etl:x:m:nprs:vw:h", longopts, nullptr)) != -1) { switch (ch) { case 'c': arg_current = atol (optarg); break; case 'e': arg_elapsed = true; break; case 't': arg_estimate = true; break; case 'l': arg_label = optarg; break; case 'x': arg_max = atol (optarg); break; case 'm': arg_min = atol (optarg); break; case 'n': std::cout << time (nullptr) << std::endl; exit (0); case 'p': arg_percentage = true; break; case 'r': arg_remove = true; break; case 's': arg_start = atoi (optarg); break; case 'v': showVersion (); break; case 'w': arg_width = atoi (optarg); break; case 'y': arg_style = optarg; break; case 'h': showUsage (); break; default: std::cout << "" << std::endl; break; } } argc -= optind; argv += optind; // Sanity check arguments. if (arg_min || arg_max) if (arg_min > arg_max) throw std::string ("The --max value must not be less than the --min value."); if (arg_min || arg_max || arg_current) if (arg_min > arg_current || arg_current > arg_max) throw std::string ("The --current value must not lie outside the --min/--max range."); if (arg_width && arg_label.length ()) if (arg_label.length () >= static_cast (arg_width)) throw std::string ("The --label string is longer than the allowed --width value."); if (! arg_remove && ! (arg_min || arg_current || arg_max)) showUsage (); if (arg_elapsed && arg_start == 0) throw std::string ("To use the --elapsed feature, --start must be provided."); if (arg_estimate && arg_start == 0) throw std::string ("To use the --estimate feature, --start must be provided."); // Disallow signals from stopping the program while it is displaying color codes // Set up and render Progress object. Progress p; p.style = arg_style; p.label = arg_label; p.width = arg_width; p.minimum = arg_min; p.maximum = arg_max; p.percentage = arg_percentage; p.remove = arg_remove; p.start = arg_start; p.elapsed = arg_elapsed; p.estimate = arg_estimate; p.remove = arg_remove; p.update (arg_current); if (p.remove) p.done (); } catch (const std::string& e) { std::cerr << "Error: " << e << std::endl; } catch (...) { std::cerr << "Unknown error occurred - please report." << std::endl; } return 0; } //////////////////////////////////////////////////////////////////////////////// vramsteg-1.1.1/test/000077500000000000000000000000001505012130500143115ustar00rootroot00000000000000vramsteg-1.1.1/test/.gitignore000066400000000000000000000000161505012130500162760ustar00rootroot00000000000000all.log *.pyc vramsteg-1.1.1/test/CMakeLists.txt000066400000000000000000000016271505012130500170570ustar00rootroot00000000000000cmake_minimum_required (VERSION 2.8) if(POLICY CMP0037) cmake_policy(SET CMP0037 OLD) endif() include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/test ${VRAMSTEG_INCLUDE_DIRS}) set (test_SRCS ) add_custom_target (test ./run_all --verbose DEPENDS ${test_SRCS} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/test) add_custom_target (build_tests DEPENDS ${test_SRCS} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/test) foreach (src_FILE ${test_SRCS}) add_executable (${src_FILE} "${src_FILE}.cpp" ../src/Progress.cpp test.cpp) target_link_libraries (${src_FILE} ${VRAMSTEG_LIBRARIES}) endforeach (src_FILE) configure_file(run_all run_all COPYONLY) configure_file(problems problems COPYONLY) vramsteg-1.1.1/test/basetest/000077500000000000000000000000001505012130500161235ustar00rootroot00000000000000vramsteg-1.1.1/test/basetest/__init__.py000066400000000000000000000001751505012130500202370ustar00rootroot00000000000000# -*- coding: utf-8 -*- from .testing import TestCase from .vramsteg import Vramsteg # flake8:noqa # vim: ai sts=4 et sw=4 vramsteg-1.1.1/test/basetest/compat.py000066400000000000000000000002131505012130500177540ustar00rootroot00000000000000# -*- coding: utf-8 -*- try: STRING_TYPE = basestring except NameError: # Python 3 STRING_TYPE = str # vim: ai sts=4 et sw=4 vramsteg-1.1.1/test/basetest/exceptions.py000066400000000000000000000030261505012130500206570ustar00rootroot00000000000000# -*- coding: utf-8 -*- import signal sig_names = dict((k, v) for v, k in reversed(sorted(signal.__dict__.items())) if v.startswith('SIG') and not v.startswith('SIG_')) class CommandError(Exception): def __init__(self, cmd, code, out, err=None, msg=None): DEFAULT = ("Command '{{0}}' was {signal}'ed. " "SIGABRT usually means program timed out.\n") if msg is None: msg_suffix = "\n*** Start STDOUT ***\n{2}\n*** End STDOUT ***\n" if err is not None: msg_suffix += ( "\n*** Start STDERR ***\n{3}\n*** End STDERR ***\n" ) if code < 0: self.msg = DEFAULT.format(signal=sig_names[abs(code)]) else: self.msg = ("Command '{0}' finished with unexpected exit " "code '{1}'.\n") self.msg += msg_suffix else: self.msg = msg self.cmd = cmd self.out = out self.err = err self.code = code def __str__(self): return self.msg.format(self.cmd, self.code, self.out, self.err) class HookError(Exception): pass class TimeoutWaitingFor(object): def __init__(self, name): self.name = name def __repr__(self): return "*** Timeout reached while waiting for {0} ***".format( self.name) class StreamsAreMerged(object): def __repr__(self): return "*** Streams are merged, STDERR is not available ***" # vim: ai sts=4 et sw=4 vramsteg-1.1.1/test/basetest/meta.py000066400000000000000000000022311505012130500174210ustar00rootroot00000000000000# -*- coding: utf-8 -*- from __future__ import print_function, division class MetaTest(type): """Helper metaclass to simplify dynamic test creation Creates test_methods in the TestCase class dynamically named after the arguments used. """ @staticmethod def make_function(classname, *args, **kwargs): def test(self): # ### Body of the usual test_testcase ### # # Override and redefine this method # pass # Title of test in report test.__doc__ = "{0}".format(args[0]) return test def __new__(meta, classname, bases, dct): tests = dct.get("TESTS") kwargs = dct.get("EXTRA", {}) for i, args in enumerate(tests): func = meta.make_function(classname, *args, **kwargs) # Rename the function after a unique identifier # Name of function must start with test_ to be ran by unittest func.__name__ = "test_{0}".format(i) # Attach the new test to the testclass dct[func.__name__] = func return super(MetaTest, meta).__new__(meta, classname, bases, dct) # vim: ai sts=4 et sw=4 vramsteg-1.1.1/test/basetest/testing.py000066400000000000000000000005631505012130500201560ustar00rootroot00000000000000# -*- coding: utf-8 -*- import unittest import sys class BaseTestCase(unittest.TestCase): def tap(self, out): sys.stderr.write("--- tap output start ---\n") for line in out.splitlines(): sys.stderr.write(line + '\n') sys.stderr.write("--- tap output end ---\n") class TestCase(BaseTestCase): pass # vim: ai sts=4 et sw=4 vramsteg-1.1.1/test/basetest/utils.py000066400000000000000000000260061505012130500176410ustar00rootroot00000000000000# -*- coding: utf-8 -*- from __future__ import division import os import sys import socket import signal import functools import atexit import tempfile from subprocess import Popen, PIPE, STDOUT from threading import Thread try: from Queue import Queue, Empty except ImportError: from queue import Queue, Empty from time import sleep try: import simplejson as json except ImportError: import json from .exceptions import CommandError, TimeoutWaitingFor ON_POSIX = 'posix' in sys.builtin_module_names # Directory relative to basetest module location CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) # Location of binary files (usually the src/ folder) BIN_PREFIX = os.path.abspath( os.path.join(CURRENT_DIR, "..", "..", "src") ) # Default location of test certificates DEFAULT_CERT_PATH = os.path.abspath( os.path.join(CURRENT_DIR, "..", "test_certs") ) # Default location of test extensions DEFAULT_EXTENSION_PATH = os.path.abspath( os.path.join(CURRENT_DIR, "..", "test_extensions") ) # Environment flags to control skipping of vramsteg tests VRAMSTEG_SKIP = os.environ.get("VRAMSTEG_SKIP", False) # Environment flags to control use of PATH or in-tree binaries VRAMSTEG_USE_PATH = os.environ.get("VRAMSTEG_USE_PATH", False) UUID_REGEXP = ("[0-9A-Fa-f]{8}-" + ("[0-9A-Fa-f]{4}-" * 3) + "[0-9A-Fa-f]{12}") def vramsteg_binary_location(cmd="vramsteg"): """ ../src/ is used by default. """ return os.path.join(BIN_PREFIX, cmd) return binary_location(cmd, VRAMSTEG_USE_PATH) def binary_location(cmd, USE_PATH=False): """ ../src/ is used by default. """ return os.path.join(BIN_PREFIX, cmd) def wait_condition(cond, timeout=1, sleeptime=.01): """Wait for condition to return anything other than None """ # NOTE Increasing sleeptime can dramatically increase testsuite runtime # It also reduces CPU load significantly if timeout is None: timeout = 1 if timeout < sleeptime: print("Warning, timeout cannot be smaller than", sleeptime) timeout = sleeptime # Max number of attempts until giving up tries = int(timeout / sleeptime) for i in range(tries): val = cond() if val is not None: break sleep(sleeptime) return val def wait_process(pid, timeout=None): """Wait for process to finish """ def process(): try: os.kill(pid, 0) except OSError: # Process is dead return True else: # Process is still ticking return None return wait_condition(process, timeout) def _queue_output(arguments, pidq, outputq): """Read/Write output/input of given process. This function is meant to be executed in a thread as it may block """ kwargs = arguments["process"] input = arguments["input"] try: proc = Popen(**kwargs) except OSError as e: # pid None is read by the main thread as a crash of the process pidq.put(None) outputq.put(( "", ("Unexpected exception caught during execution: '{0}' . ".format(e)), 255)) # false exitcode return # Put the PID in the queue for main process to know. pidq.put(proc.pid) # Send input and wait for finish out, err = proc.communicate(input) if sys.version_info > (3,): out, err = out.decode('utf-8'), err.decode('utf-8') # Give the output back to the caller outputq.put((out, err, proc.returncode)) def _retrieve_output(thread, timeout, queue, thread_error): """Fetch output from binary subprocess queues """ # Try to join the thread on failure abort thread.join(timeout) if thread.isAlive(): # Join should have killed the thread. This is unexpected raise TimeoutWaitingFor(thread_error + ". Unexpected error") # Thread died so we should have output try: # data = (stdout, stderr, exitcode) data = queue.get(timeout=timeout) except Empty: data = TimeoutWaitingFor("streams from program") return data def _get_output(arguments, timeout=None): """Collect output from the subprocess without blocking the main process if subprocess hangs. """ # NOTE Increase this value if tests fail with None being received as # stdout/stderr instead of the expected content output_timeout = 0.1 # seconds pidq = Queue() outputq = Queue() t = Thread(target=_queue_output, args=(arguments, pidq, outputq)) t.daemon = True t.start() try: pid = pidq.get(timeout=timeout) except Empty: pid = None # Process crashed or timed out for some reason if pid is None: return _retrieve_output(t, output_timeout, outputq, "Program to start") # Wait for process to finish (normal execution) state = wait_process(pid, timeout) if state: # Process finished return _retrieve_output(t, output_timeout, outputq, "Program thread to join") # If we reach this point we assume the process got stuck or timed out for sig in (signal.SIGABRT, signal.SIGTERM, signal.SIGKILL): # Start with lower signals and escalate if process ignores them try: os.kill(pid, signal.SIGABRT) except OSError as e: # 3 means the process finished/died between last check and now if e.errno != 3: raise # Wait for process to finish (should die/exit after signal) state = wait_process(pid, timeout) if state: # Process finished return _retrieve_output(t, output_timeout, outputq, "Program to die") # This should never happen but in case something goes really bad raise OSError("Program stopped responding and couldn't be killed") def run_cmd_wait(cmd, input=None, stdout=PIPE, stderr=PIPE, merge_streams=False, env=os.environ, timeout=None): "Run a subprocess and wait for it to finish" if input is None: stdin = None else: stdin = PIPE if merge_streams: stderr = STDOUT else: stderr = PIPE arguments = { "process": { "args": cmd, "stdin": stdin, "stdout": stdout, "stderr": stderr, "bufsize": 1, "close_fds": ON_POSIX, "env": env, }, "input": input, } out, err, exit = _get_output(arguments, timeout) if merge_streams: if exit != 0: raise CommandError(cmd, exit, out) else: return exit, out else: if exit != 0: raise CommandError(cmd, exit, out, err) else: return exit, out, err def run_cmd_wait_nofail(*args, **kwargs): "Same as run_cmd_wait but silence the exception if it happens" try: return run_cmd_wait(*args, **kwargs) except CommandError as e: return e.code, e.out, e.err def memoize(obj): """Keep an in-memory cache of function results given it's inputs """ cache = obj.cache = {} @functools.wraps(obj) def memoizer(*args, **kwargs): key = str(args) + str(kwargs) if key not in cache: cache[key] = obj(*args, **kwargs) return cache[key] return memoizer try: from shutil import which which = memoize(which) except ImportError: # NOTE: This is shutil.which backported from python-3.3.3 @memoize def which(cmd, mode=os.F_OK | os.X_OK, path=None): """Given a command, mode, and a PATH string, return the path which conforms to the given mode on the PATH, or None if there is no such file. `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result of os.environ.get("PATH"), or can be overridden with a custom search path. """ # Check that a given file can be accessed with the correct mode. # Additionally check that `file` is not a directory, as on Windows # directories pass the os.access check. def _access_check(fn, mode): return (os.path.exists(fn) and os.access(fn, mode) and not os.path.isdir(fn)) # If we're given a path with a directory part, look it up directly # rather than referring to PATH directories. This includes checking # relative to the current directory, e.g. ./script if os.path.dirname(cmd): if _access_check(cmd, mode): return cmd return None if path is None: path = os.environ.get("PATH", os.defpath) if not path: return None path = path.split(os.pathsep) if sys.platform == "win32": # The current directory takes precedence on Windows. if os.curdir not in path: path.insert(0, os.curdir) # PATHEXT is necessary to check on Windows. pathext = os.environ.get("PATHEXT", "").split(os.pathsep) # See if the given file matches any of the expected path # extensions. This will allow us to short circuit when given # "python.exe". If it does match, only test that one, otherwise we # have to try others. if any(cmd.lower().endswith(ext.lower()) for ext in pathext): files = [cmd] else: files = [cmd + ext for ext in pathext] else: # On other platforms you don't have things like PATHEXT to tell you # what file suffixes are executable, so just pass on cmd as-is. files = [cmd] seen = set() for dir in path: normdir = os.path.normcase(dir) if normdir not in seen: seen.add(normdir) for thefile in files: name = os.path.join(dir, thefile) if _access_check(name, mode): return name return None def parse_datafile(file): """Parse .data files, treating files as JSON """ data = [] with open(file) as fh: for line in fh: line = line.rstrip("\n") # Turn [] strings into {} to be treated properly as JSON hashes if line.startswith('[') and line.endswith(']'): line = '{' + line[1:-1] + '}' if line.startswith("{"): data.append(json.loads(line)) else: data.append(line) return data def mkstemp(data): """ Create a temporary file that is removed at process exit """ def rmtemp(name): try: os.remove(name) except OSError: pass f = tempfile.NamedTemporaryFile(delete=False) f.write(data) f.close() # Ensure removal at end of python session atexit.register(rmtemp, f.name) return f.name def mkstemp_exec(data): """Create a temporary executable file that is removed at process exit """ name = mkstemp(data) os.chmod(name, 0o755) return name # vim: ai sts=4 et sw=4 vramsteg-1.1.1/test/basetest/vramsteg.py000066400000000000000000000160241505012130500203300ustar00rootroot00000000000000# -*- coding: utf-8 -*- import atexit import json import os import shlex import shutil import tempfile import unittest from .exceptions import CommandError from .utils import run_cmd_wait, run_cmd_wait_nofail, which, vramsteg_binary_location, DEFAULT_EXTENSION_PATH from .compat import STRING_TYPE class Vramsteg(object): """Manage a Vramsteg instance A temporary folder is used as data store of vramsteg. A vramsteg client should not be used after being destroyed. """ DEFAULT_VRAMSTEG = vramsteg_binary_location() def __init__(self, vramsteg=DEFAULT_VRAMSTEG): """Initialize a vramsteg (client). The program runs in a temporary folder. :arg vramsteg: Vramsteg binary to use as client (defaults: vramsteg in PATH) """ self.vramsteg = vramsteg # Used to specify what command to launch (and to inject faketime) self._command = [self.vramsteg] # Configuration of the isolated environment self._original_pwd = os.getcwd() self.datadir = tempfile.mkdtemp(prefix="vramsteg_") self.vramstegrc = os.path.join (self.datadir, 'vramstegrc') self._command.extend(['-f', self.vramstegrc]) # Ensure any instance is properly destroyed at session end atexit.register(lambda: self.destroy()) self.reset_env() def add_default_extension(self, filename): """Add default extension to current instance """ if not os.path.isdir(self.extdir): os.mkdir(self.extdir) extfile = os.path.join(self.extdir, filename) if os.path.isfile(extfile): raise "{} already exists".format(extfile) shutil.copy(os.path.join(DEFAULT_EXTENSION_PATH, filename), extfile) def __repr__(self): txt = super(Vramsteg, self).__repr__() return "{0} running from {1}>".format(txt[:-1], self.datadir) def __call__(self, *args, **kwargs): "aka t = Vramsteg() ; t() which is now an alias to t.runSuccess()" return self.runSuccess(*args, **kwargs) def reset_env(self): """Set a new environment derived from the one used to launch the test """ # Copy all env variables to avoid clashing subprocess environments self.env = os.environ.copy() def config(self, line): """Add 'line' to self.vramstegrc. """ with open(self.vramstegrc, "a") as f: f.write(line + "\n") @property def vramstegrc_content(self): """ Returns the contents of the vramstegrc file. """ with open(self.vramstegrc, "r") as f: return f.readlines() @staticmethod def _split_string_args_if_string(args): """Helper function to parse and split into arguments a single string argument. The string is literally the same as if written in the shell. """ # Enable nicer-looking calls by allowing plain strings if isinstance(args, STRING_TYPE): args = shlex.split(args) return args def runSuccess(self, args="", input=None, merge_streams=False, timeout=5): """Invoke vramsteg with given arguments and fail if exit code != 0 Use runError if you want exit_code to be tested automatically and *not* fail if program finishes abnormally. If you wish to pass instructions to vramsteg such as confirmations or other input via stdin, you can do so by providing a input string. Such as input="y\ny\n". If merge_streams=True stdout and stderr will be merged into stdout. timeout = number of seconds the test will wait for every vramsteg call. Defaults to 1 second if not specified. Unit is seconds. Returns (exit_code, stdout, stderr) if merge_streams=False (exit_code, output) if merge_streams=True """ # Create a copy of the command command = self._command[:] args = self._split_string_args_if_string(args) command.extend(args) output = run_cmd_wait_nofail(command, input, merge_streams=merge_streams, env=self.env, timeout=timeout) if output[0] != 0: raise CommandError(command, *output) return output def runError(self, args=(), input=None, merge_streams=False, timeout=5): """Invoke vramsteg with given arguments and fail if exit code == 0 Use runSuccess if you want exit_code to be tested automatically and *fail* if program finishes abnormally. If you wish to pass instructions to vramsteg such as confirmations or other input via stdin, you can do so by providing a input string. Such as input="y\ny\n". If merge_streams=True stdout and stderr will be merged into stdout. timeout = number of seconds the test will wait for every vramsteg call. Defaults to 1 second if not specified. Unit is seconds. Returns (exit_code, stdout, stderr) if merge_streams=False (exit_code, output) if merge_streams=True """ # Create a copy of the command command = self._command[:] args = self._split_string_args_if_string(args) command.extend(args) output = run_cmd_wait_nofail(command, input, merge_streams=merge_streams, env=self.env, timeout=timeout) # output[0] is the exit code if output[0] == 0 or output[0] is None: raise CommandError(command, *output) return output def destroy(self): """Cleanup the data folder and release server port for other instances """ try: shutil.rmtree(self.datadir) except OSError as e: if e.errno == 2: # Directory no longer exists pass else: raise # Prevent future reuse of this instance self.runSuccess = self.__destroyed self.runError = self.__destroyed # self.destroy will get called when the python session closes. # If self.destroy was already called, turn the action into a noop self.destroy = lambda: None def __destroyed(self, *args, **kwargs): raise AttributeError("Program instance has been destroyed. " "Create a new instance if you need a new client.") def faketime(self, faketime=None): """Set a faketime using libfaketime that will affect the following command calls. If faketime is None, faketime settings will be disabled. """ cmd = which("faketime") if cmd is None: raise unittest.SkipTest("libfaketime/faketime is not installed") if self._command[0] == cmd: self._command = self._command[3:] if faketime is not None: # Use advanced time format self._command = [cmd, "-f", faketime] + self._command # vim: ai sts=4 et sw=4 vramsteg-1.1.1/test/problems000077500000000000000000000105131505012130500160620ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import sys import re import argparse from collections import defaultdict def color(text, c): """ Add color on the keyword that identifies the state of the test """ if sys.stdout.isatty(): clear = "\033[0m" colors = { "red": "\033[1m\033[91m", "yellow": "\033[1m\033[93m", "green": "\033[1m\033[92m", } return colors[c] + text + clear else: return text def parse_args(): parser = argparse.ArgumentParser(description="Report on test results") parser.add_argument('--summary', action="store_true", help="Display only the totals in each category") parser.add_argument('tapfile', default="all.log", nargs="?", help="File containing TAP output") return parser.parse_args() def print_category(tests): if not cmd_args.summary: for key in sorted(tests): print("%-32s %4d" % (key, tests[key])) def pad(i): return " " * i if __name__ == "__main__": cmd_args = parse_args() errors = defaultdict(int) skipped = defaultdict(int) expected = defaultdict(int) unexpected = defaultdict(int) passed = defaultdict(int) file = re.compile("^# (?:./)?(\S+\.t)(?:\.exe)?$") timestamp = re.compile("^# (\d+(?:\.\d+)?) ==>.*$") expected_fail = re.compile(r"^not ok.*?#\s*TODO", re.I) unexpected_pass = re.compile(r"^ok .*?#\s*TODO", re.I) skip = re.compile(r"^ok .*?#\s*skip", re.I) ok = re.compile(r"^ok ", re.I) not_ok = re.compile(r"^not ok", re.I) comment = re.compile(r"^#") plan = re.compile(r"^1..\d+\s*(?:#.*)?$") start = None stop = None with open(cmd_args.tapfile) as fh: for line in fh: if start is None: # First line contains the starting timestamp start = float(timestamp.match(line).group(1)) continue match = file.match(line) if match: filename = match.group(1) elif expected_fail.match(line): expected[filename] += 1 elif unexpected_pass.match(line): unexpected[filename] += 1 elif skip.match(line): skipped[filename] += 1 # It's important these come last, since they're subpatterns of the above elif ok.match(line): passed[filename] += 1 elif not_ok.match(line): errors[filename] += 1 elif comment.match(line): pass elif plan.match(line): pass else: # Uncomment if you want to see malformed things we caught as well... # print(color("Malformed TAP (" + filename + "): " + line, "red")) pass # Last line contains the ending timestamp stop = float(timestamp.match(line).group(1)) v = "{0:>5d}" passed_str = "Passed:" + pad(24) passed_int = v.format(sum(passed.values())) error_str = "Failed:" + pad(24) error_int = v.format(sum(errors.values())) unexpected_str = "Unexpected successes:" + pad(10) unexpected_int = v.format(sum(unexpected.values())) skipped_str = "Skipped:" + pad(23) skipped_int = v.format(sum(skipped.values())) expected_str = "Expected failures:" + pad(13) expected_int = v.format(sum(expected.values())) runtime_str = "Runtime:" + pad(20) runtime_int = "{0:>8.2f} seconds".format(stop - start) if cmd_args.summary: print(color(passed_str, "green"), passed_int) print(color(error_str, "red"), error_int) print(color(unexpected_str, "red"), unexpected_int) print(color(skipped_str, "yellow"), skipped_int) print(color(expected_str, "yellow"), expected_int) print(runtime_str, runtime_int) else: print(color(error_str, "red")) print_category(errors) print() print(color(unexpected_str, "red")) print_category(unexpected) print() print(color(skipped_str, "yellow")) print_category(skipped) print() print(color(expected_str, "yellow")) print_category(expected) # If we encoutered any failures, return non-zero code sys.exit(1 if int(error_int) or int(unexpected_int) else 0) vramsteg-1.1.1/test/run_all000077500000000000000000000154411505012130500157000ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import print_function import os import sys import glob import argparse import logging import time from multiprocessing import cpu_count from threading import Thread from subprocess import call, Popen, PIPE if sys.version_info > (3,): import codecs try: # python 2 from Queue import Queue, Empty except ImportError: # python 3 from queue import Queue, Empty TIMEOUT = .2 def run_test(testqueue, outqueue, threadname): start = time.time() while True: try: test = testqueue.get(block=True, timeout=TIMEOUT) except Empty: break log.info("Running test %s", test) try: p = Popen(os.path.abspath(test), stdout=PIPE, stderr=PIPE, env=os.environ) out, err = p.communicate() except Exception as e: log.exception(e) # Premature end break if sys.version_info > (3,): out, err = out.decode('utf-8'), err.decode('utf-8') output = ("# {0}\n".format(os.path.basename(test)), out, err) log.debug("Collected output %s", output) outqueue.put(output) testqueue.task_done() log.warning("Finished %s thread after %s seconds", threadname, round(time.time() - start, 3)) class TestRunner(object): def __init__(self): self.threads = [] if sys.version_info > (3,): self.tap = open(cmd_args.tapfile, 'w', errors='ignore') else: self.tap = open(cmd_args.tapfile, 'w') self._parallelq = Queue() self._serialq = Queue() self._outputq = Queue() def _find_tests(self): for test in glob.glob("*.t") + glob.glob("*.t.exe"): if os.access(test, os.X_OK): # Executables only if self._is_parallelizable(test): log.debug("Treating as parallel: %s", test) self._parallelq.put(test) else: log.debug("Treating as serial: %s", test) self._serialq.put(test) else: log.debug("Ignored test %s as it is not executable", test) log.info("Parallel tests: %s", self._parallelq.qsize()) log.info("Serial tests: %s", self._serialq.qsize()) def _prepare_threads(self): # Serial thread self.threads.append( Thread(target=run_test, args=(self._serialq, self._outputq, "Serial")) ) # Parallel threads self.threads.extend([ Thread(target=run_test, args=(self._parallelq, self._outputq, "Parallel")) for i in range(cpu_count()) ]) log.info("Spawned %s threads to run tests", len(self.threads)) def _start_threads(self): for thread in self.threads: # Threads die when main thread dies log.debug("Starting thread %s", thread) thread.daemon = True thread.start() def _print_timestamp_to_tap(self): now = time.time() timestamp = "# {0} ==> {1}\n".format( now, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(now)), ) log.debug("Adding timestamp %s to TAP file", timestamp) self.tap.write(timestamp) def _is_parallelizable(self, test): if cmd_args.serial: return False # This is a pretty weird way to do it, and not realiable. # We are dealing with some binary tests though. with open(test, 'rb') as fh: header = fh.read(100).split(b"\n") if len(header) >= 2 and \ ((b"/usr/bin/env python" in header[0]) or \ (header[1][-14:] == b"bash_tap_tw.sh")): return True else: return False def _get_remaining_tests(self): return self._parallelq.qsize() + self._serialq.qsize() def is_running(self): for thread in self.threads: if thread.is_alive(): return True return False def start(self): self._find_tests() self._prepare_threads() self._print_timestamp_to_tap() finished = 0 total = self._get_remaining_tests() self._start_threads() while self.is_running() or not self._outputq.empty(): try: outputs = self._outputq.get(block=True, timeout=TIMEOUT) except Empty: continue log.debug("Outputting to TAP: %s", outputs) for output in outputs: self.tap.write(output) if cmd_args.verbose: sys.stdout.write(output) self._outputq.task_done() finished += 1 log.warning("Finished %s out of %s tests", finished, total) self._print_timestamp_to_tap() if not self._parallelq.empty() or not self._serialq.empty(): raise RuntimeError( "Something went wrong, not all tests were ran. {0} " "remaining.".format(self._get_remaining_tests())) def show_report(self): self.tap.flush() sys.stdout.flush() sys.stderr.flush() log.debug("Calling 'problems --summary' for report") return call([os.path.abspath("problems"), "--summary", cmd_args.tapfile]) def parse_args(): parser = argparse.ArgumentParser(description="Run Taskwarrior tests") parser.add_argument('--verbose', '-v', action="store_true", help="Also send TAP output to stdout") parser.add_argument('--logging', '-l', action="count", default=0, help="Logging level. -lll is the highest level") parser.add_argument('--serial', action="store_true", help="Do not run tests in parallel") parser.add_argument('--tapfile', default="all.log", help="File to use for TAP output") return parser.parse_args() def main(): if sys.version_info > (3,): sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach()) runner = TestRunner() runner.start() # Propagate the return code return runner.show_report() if __name__ == "__main__": cmd_args = parse_args() if cmd_args.logging == 1: level = logging.WARN elif cmd_args.logging == 2: level = logging.INFO elif cmd_args.logging >= 3: level = logging.DEBUG else: level = logging.ERROR logging.basicConfig( format="%(asctime)s - %(levelname)s - %(message)s", level=level, ) log = logging.getLogger(__name__) log.debug("Parsed commandline arguments: %s", cmd_args) try: sys.exit(main()) except Exception as e: log.exception(e) sys.exit(1) # vim: ai sts=4 et sw=4 vramsteg-1.1.1/test/simpletap/000077500000000000000000000000001505012130500163075ustar00rootroot00000000000000vramsteg-1.1.1/test/simpletap/__init__.py000066400000000000000000000220021505012130500204140ustar00rootroot00000000000000############################################################################### # taskwarrior - a command line task list manager. # # Copyright 2006 - 2017, Paul Beckingham, Federico Hernandez. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # # http://www.opensource.org/licenses/mit-license.php # ############################################################################### # Original version by Renato Alves import os import sys import unittest import warnings import traceback import inspect def color(text, c): """ Add color on the keyword that identifies the state of the test """ if sys.stdout.isatty(): clear = "\033[0m" colors = { "red": "\033[1m\033[91m", "yellow": "\033[1m\033[93m", "green": "\033[1m\033[92m", } return colors[c] + text + clear else: return text class TAPTestResult(unittest.result.TestResult): def __init__(self, stream, descriptions, verbosity): super(TAPTestResult, self).__init__(stream, descriptions, verbosity) self.stream = stream self.descriptions = descriptions self.verbosity = verbosity # Buffer stdout and stderr self.buffer = True def getDescription(self, test): doc_first_line = test.shortDescription() if self.descriptions and doc_first_line: return doc_first_line else: try: method = test._testMethodName except AttributeError: return "Preparation error on: {0}".format(test.description) else: return "{0} ({1})".format(method, test.__class__.__name__) def startTestRun(self, total="unk"): self.stream.writeln("1..{0}".format(total)) def stopTest(self, test): """Prevent flushing of stdout/stderr buffers until later""" pass def _restoreStdout(self): """Restore sys.stdout and sys.stderr, don't merge buffered output yet """ if self.buffer: sys.stdout = self._original_stdout sys.stderr = self._original_stderr @staticmethod def _do_stream(data, stream): """Helper function for _mergeStdout""" for line in data.splitlines(True): # newlines should be taken literally and be comments in TAP line = line.replace("\\n", "\n# ") # Add a comment sign before each line if line.startswith("#"): stream.write(line) else: stream.write("# " + line) if not line.endswith('\n'): stream.write('\n') def _mergeStdout(self): """Merge buffered output with main streams """ if self.buffer: output = self._stdout_buffer.getvalue() error = self._stderr_buffer.getvalue() if output: self._do_stream(output, sys.stdout) if error: self._do_stream(error, sys.stderr) self._stdout_buffer.seek(0) self._stdout_buffer.truncate() self._stderr_buffer.seek(0) self._stderr_buffer.truncate() # Needed to fix the stopTest override self._mirrorOutput = False def report(self, test, status=None, err=None): # Restore stdout/stderr but don't flush just yet self._restoreStdout() desc = self.getDescription(test) try: exception, msg, tb = err except (TypeError, ValueError): exception_name = "" msg = err tb = None else: exception_name = exception.__name__ msg = str(msg) trace_msg = "" # Extract line where error happened for easier debugging trace = traceback.extract_tb(tb) for t in trace: # t = (filename, line_number, function_name, raw_line) if t[2].startswith("test"): trace_msg = " on file {0} line {1} in {2}: '{3}'".format(*t) break # Retrieve the name of the file containing the test filename = os.path.basename(inspect.getfile(test.__class__)) if status: if status == "SKIP": self.stream.writeln("{0} {1} - {2}: {3} # skip".format( color("ok", "yellow"), self.testsRun, filename, desc) ) elif status == "EXPECTED_FAILURE": self.stream.writeln("{0} {1} - {2}: {3} # TODO".format( color("not ok", "yellow"), self.testsRun, filename, desc) ) else: self.stream.writeln("{0} {1} - {2}: {3}".format( color("not ok", "red"), self.testsRun, filename, desc) ) if exception_name: self.stream.writeln("# {0}: {1}{2}:".format( status, exception_name, trace_msg) ) else: self.stream.writeln("# {0}:".format(status)) # Magic 3 is just for pretty indentation padding = " " * (len(status) + 3) for line in msg.splitlines(): # Force displaying new-line characters as literal new lines line = line.replace("\\n", "\n# ") self.stream.writeln("#{0}{1}".format(padding, line)) else: self.stream.writeln("{0} {1} - {2}: {3}".format( color("ok", "green"), self.testsRun, filename, desc) ) # Flush all buffers to stdout self._mergeStdout() def addSuccess(self, test): super(TAPTestResult, self).addSuccess(test) self.report(test) def addError(self, test, err): super(TAPTestResult, self).addError(test, err) self.report(test, "ERROR", err) def addFailure(self, test, err): super(TAPTestResult, self).addFailure(test, err) self.report(test, "FAIL", err) def addSkip(self, test, reason): super(TAPTestResult, self).addSkip(test, reason) self.report(test, "SKIP", reason) def addExpectedFailure(self, test, err): super(TAPTestResult, self).addExpectedFailure(test, err) self.report(test, "EXPECTED_FAILURE", err) def addUnexpectedSuccess(self, test): super(TAPTestResult, self).addUnexpectedSuccess(test) self.report(test, "UNEXPECTED_SUCCESS", str(test)) class TAPTestRunner(unittest.runner.TextTestRunner): """A test runner that displays results using the Test Anything Protocol syntax. Inherits from TextTestRunner the default runner. """ resultclass = TAPTestResult def run(self, test): result = self._makeResult() unittest.signals.registerResult(result) result.failfast = self.failfast # TAP requires output is on STDOUT. # TODO: Define this at __init__ time result.stream = unittest.runner._WritelnDecorator(sys.stdout) with warnings.catch_warnings(): if getattr(self, "warnings", None): # if self.warnings is set, use it to filter all the warnings warnings.simplefilter(self.warnings) # if the filter is 'default' or 'always', special-case the # warnings from the deprecated unittest methods to show them # no more than once per module, because they can be fairly # noisy. The -Wd and -Wa flags can be used to bypass this # only when self.warnings is None. if self.warnings in ['default', 'always']: warnings.filterwarnings( 'module', category=DeprecationWarning, message='Please use assert\w+ instead.') startTestRun = getattr(result, 'startTestRun', None) if startTestRun is not None: startTestRun(test.countTestCases()) try: test(result) finally: stopTestRun = getattr(result, 'stopTestRun', None) if stopTestRun is not None: stopTestRun() return result vramsteg-1.1.1/test/template.t000066400000000000000000000076561505012130500163270ustar00rootroot00000000000000#!/usr/bin/env python2.7 # -*- coding: utf-8 -*- ############################################################################### # # Copyright 2006 - 2017, Paul Beckingham, Federico Hernandez. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # # http://www.opensource.org/licenses/mit-license.php # ############################################################################### import sys import os import unittest from datetime import datetime # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) from basetest import Timew, TestCase # Test methods available: # self.assertEqual(a, b) # self.assertNotEqual(a, b) # self.assertTrue(x) # self.assertFalse(x) # self.assertIs(a, b) # self.assertIsNot(substring, text) # self.assertIsNone(x) # self.assertIsNotNone(x) # self.assertIn(substring, text) # self.assertNotIn(substring, text # self.assertRaises(e) # self.assertRegexpMatches(text, pattern) # self.assertNotRegexpMatches(text, pattern) # self.tap("") class TestBugNumber(TestCase): @classmethod def setUpClass(cls): """Executed once before any test in the class""" # Used to initialize objects that can be shared across tests # Also useful if none of the tests of the current TestCase performs # data alterations. See tw-285.t for an example def setUp(self): """Executed before each test in the class""" # Used to initialize objects that should be re-initialized or # re-created for each individual test self.t = Vramsteg() def test_foo(self): """Test foo""" code, out, err = self.t("foo") self.tap(out) self.tap(err) def test_faketime(self): """Running tests using libfaketime WARNING: faketime version 0.9.6 and later correctly propagates non-zero exit codes. Please don't combine faketime tests and self.t.runError(). https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=750721 """ self.t.faketime("-2y") command = ("insert test here") self.t(command) # Remove FAKETIME settings self.t.faketime() code, out, err = self.t("insert test here") expected = "2.0y" self.assertIn(expected, out) @unittest.skipIf(1 != 0, "This machine has sane logic") def test_skipped(self): """Test all logic of the world""" @unittest.expectedFailure def test_expected_failure(self): """Test something that fails and we know or expect that""" self.assertEqual(1, 0) def tearDown(self): """Executed after each test in the class""" @classmethod def tearDownClass(cls): """Executed once after all tests in the class""" if __name__ == "__main__": from simpletap import TAPTestRunner unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python vramsteg-1.1.1/test/test.cpp000066400000000000000000000272221505012130500160010ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // // Copyright 2006 - 2017, Paul Beckingham, Federico Hernandez. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // http://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include /////////////////////////////////////////////////////////////////////////////// UnitTest::UnitTest () : _planned (0) , _counter (0) , _passed (0) , _failed (0) , _skipped (0) { } /////////////////////////////////////////////////////////////////////////////// UnitTest::UnitTest (int planned) : _planned (planned) , _counter (0) , _passed (0) , _failed (0) , _skipped (0) { std::cout << "1.." << _planned << '\n'; } /////////////////////////////////////////////////////////////////////////////// UnitTest::~UnitTest () { float percentPassed = 0.0; if (_planned > 0) percentPassed = (100.0 * _passed) / std::max (_planned, _passed + _failed + _skipped); if (_counter < _planned) { std::cout << "# Only " << _counter << " tests, out of a planned " << _planned << " were run.\n"; _skipped += _planned - _counter; } else if (_counter > _planned) std::cout << "# " << _counter << " tests were run, but only " << _planned << " were planned.\n"; std::cout << "# " << _passed << " passed, " << _failed << " failed, " << _skipped << " skipped. " << std::setprecision (3) << percentPassed << "% passed.\n"; exit (_failed > 0); } /////////////////////////////////////////////////////////////////////////////// void UnitTest::plan (int planned) { _planned = planned; _counter = 0; _passed = 0; _failed = 0; _skipped = 0; std::cout << "1.." << _planned << '\n'; } /////////////////////////////////////////////////////////////////////////////// void UnitTest::planMore (int extra) { _planned += extra; std::cout << "1.." << _planned << '\n'; } /////////////////////////////////////////////////////////////////////////////// void UnitTest::ok (bool expression, const std::string& name) { ++_counter; if (expression) { ++_passed; std::cout << green ("ok") << " " << _counter << " - " << name << '\n'; } else { ++_failed; std::cout << red ("not ok") << " " << _counter << " - " << name << '\n'; } } /////////////////////////////////////////////////////////////////////////////// void UnitTest::notok (bool expression, const std::string& name) { ++_counter; if (!expression) { ++_passed; std::cout << green ("ok") << " " << _counter << " - " << name << '\n'; } else { ++_failed; std::cout << red ("not ok") << " " << _counter << " - " << name << '\n'; } } /////////////////////////////////////////////////////////////////////////////// void UnitTest::is (bool actual, bool expected, const std::string& name) { ++_counter; if (actual == expected) { ++_passed; std::cout << green ("ok") << " " << _counter << " - " << name << '\n'; } else { ++_failed; std::cout << red ("not ok") << " " << _counter << " - " << name << "\n# expected: " << expected << "\n# got: " << actual << '\n'; } } /////////////////////////////////////////////////////////////////////////////// void UnitTest::is (size_t actual, size_t expected, const std::string& name) { ++_counter; if (actual == expected) { ++_passed; std::cout << green ("ok") << " " << _counter << " - " << name << '\n'; } else { ++_failed; std::cout << red ("not ok") << " " << _counter << " - " << name << "\n# expected: " << expected << "\n# got: " << actual << '\n'; } } /////////////////////////////////////////////////////////////////////////////// void UnitTest::is (int actual, int expected, const std::string& name) { ++_counter; if (actual == expected) { ++_passed; std::cout << green ("ok") << " " << _counter << " - " << name << '\n'; } else { ++_failed; std::cout << red ("not ok") << " " << _counter << " - " << name << "\n# expected: " << expected << "\n# got: " << actual << '\n'; } } /////////////////////////////////////////////////////////////////////////////// void UnitTest::is (double actual, double expected, const std::string& name) { ++_counter; if (actual == expected) { ++_passed; std::cout << green ("ok") << " " << _counter << " - " << name << '\n'; } else { ++_failed; std::cout << red ("not ok") << " " << _counter << " - " << name << "\n# expected: " << expected << "\n# got: " << actual << '\n'; } } /////////////////////////////////////////////////////////////////////////////// void UnitTest::is (double actual, double expected, double tolerance, const std::string& name) { ++_counter; if (fabs (actual - expected) <= tolerance) { ++_passed; std::cout << green ("ok") << " " << _counter << " - " << name << '\n'; } else { ++_failed; std::cout << red ("not ok") << " " << _counter << " - " << name << "\n# expected: " << expected << "\n# got: " << actual << '\n'; } } /////////////////////////////////////////////////////////////////////////////// void UnitTest::is (unsigned char actual, unsigned char expected, const std::string& name) { ++_counter; if (actual == expected) { ++_passed; std::cout << green ("ok") << " " << _counter << " - " << name << '\n'; } else { ++_failed; std::cout << red ("not ok") << " " << _counter << " - " << name << "\n# expected: " << expected << "\n# got: " << actual << '\n'; } } /////////////////////////////////////////////////////////////////////////////// void UnitTest::is ( const std::string& actual, const std::string& expected, const std::string& name) { ++_counter; if (actual == expected) { ++_passed; std::cout << green ("ok") << " " << _counter << " - " << name << '\n'; } else { ++_failed; std::cout << red ("not ok") << " " << _counter << " - " << name << "\n# expected: '" << expected << "'" << "\n# got: '" << actual << "'\n"; } } /////////////////////////////////////////////////////////////////////////////// void UnitTest::is ( const char* actual, const char* expected, const std::string& name) { ++_counter; if (! strcmp (actual, expected)) { ++_passed; std::cout << green ("ok") << " " << _counter << " - " << name << '\n'; } else { ++_failed; std::cout << red ("not ok") << " " << _counter << " - " << name << "\n# expected: '" << expected << "'" << "\n# got: '" << actual << "'\n"; } } /////////////////////////////////////////////////////////////////////////////// void UnitTest::diag (const std::string& text) { auto start = text.find_first_not_of (" \t\n\r\f"); auto end = text.find_last_not_of (" \t\n\r\f"); if (start != std::string::npos && end != std::string::npos) std::cout << "# " << text.substr (start, end - start + 1) << '\n'; } /////////////////////////////////////////////////////////////////////////////// void UnitTest::pass (const std::string& text) { ++_counter; ++_passed; std::cout << green ("ok") << " " << _counter << " - " << text << '\n'; } /////////////////////////////////////////////////////////////////////////////// void UnitTest::fail (const std::string& text) { ++_counter; ++_failed; std::cout << red ("not ok") << " " << _counter << " - " << text << '\n'; } /////////////////////////////////////////////////////////////////////////////// void UnitTest::skip (const std::string& text) { ++_counter; ++_skipped; std::cout << yellow ("ok") << " " << _counter << " - " << text << " # skip" << '\n'; } /////////////////////////////////////////////////////////////////////////////// std::string UnitTest::red (const std::string& input) { if (isatty (fileno (stdout))) return std::string ("\033[31m" + input + "\033[0m"); return input; } /////////////////////////////////////////////////////////////////////////////// std::string UnitTest::green (const std::string& input) { if (isatty (fileno (stdout))) return std::string ("\033[32m" + input + "\033[0m"); return input; } /////////////////////////////////////////////////////////////////////////////// std::string UnitTest::yellow (const std::string& input) { if (isatty (fileno (stdout))) return std::string ("\033[33m" + input + "\033[0m"); return input; } /////////////////////////////////////////////////////////////////////////////// vramsteg-1.1.1/test/test.h000066400000000000000000000047221505012130500154460ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////////////// // // Copyright 2006 - 2017, Paul Beckingham, Federico Hernandez. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // http://www.opensource.org/licenses/mit-license.php // //////////////////////////////////////////////////////////////////////////////// #ifndef INCLUDED_UNITTEST #define INCLUDED_UNITTEST #include class UnitTest { public: UnitTest (); UnitTest (int); ~UnitTest (); void plan (int); void planMore (int); void ok (bool, const std::string&); void notok (bool, const std::string&); void is (bool, bool, const std::string&); void is (size_t, size_t, const std::string&); void is (int, int, const std::string&); void is (double, double, const std::string&); void is (double, double, double, const std::string&); void is (unsigned char, unsigned char, const std::string&); void is (const std::string&, const std::string&, const std::string&); void is (const char*, const char*, const std::string&); void diag (const std::string&); void pass (const std::string&); void fail (const std::string&); void skip (const std::string&); private: std::string red (const std::string&); std::string green (const std::string&); std::string yellow (const std::string&); private: int _planned; int _counter; int _passed; int _failed; int _skipped; }; #endif //////////////////////////////////////////////////////////////////////////////// vramsteg-1.1.1/test/version.t000077500000000000000000000047671505012130500162040ustar00rootroot00000000000000#!/usr/bin/env python2.7 # -*- coding: utf-8 -*- ############################################################################### # # Copyright 2006 - 2017, Paul Beckingham, Federico Hernandez. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # # http://www.opensource.org/licenses/mit-license.php # ############################################################################### import sys import os import unittest import re # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) from basetest import Vramsteg, TestCase from basetest.utils import run_cmd_wait # Test methods available: # self.assertEqual(a, b) # self.assertNotEqual(a, b) # self.assertTrue(x) # self.assertFalse(x) # self.assertIs(a, b) # self.assertIsNot(substring, text) # self.assertIsNone(x) # self.assertIsNotNone(x) # self.assertIn(substring, text) # self.assertNotIn(substring, text # self.assertRaises(e) # self.assertRegexpMatches(text, pattern) # self.assertNotRegexpMatches(text, pattern) # self.tap("") class TestVersion(TestCase): def setUp(self): self.t = Vramsteg() def test_version_option(self): """Verify that 'vramsteg --version' returns something valid""" code, out, err = self.t("--version") self.assertRegexpMatches(out, r'vramsteg \d+\.\d+\.\d+') if __name__ == "__main__": from simpletap import TAPTestRunner unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python