├── .ci ├── Jenkinsfile ├── README.md ├── artifacts.sh ├── matrix_job.yaml ├── proj_jjb.yaml └── windows │ ├── build.cmd │ └── windows_proj_jjb.yaml ├── .gitignore ├── Makefile.am ├── README.md ├── authors ├── autogen.sh ├── build ├── build-rpm-to-deb.sh ├── build-rpm.sh ├── sockperf.spec.in └── versioning.sh ├── config └── m4 │ ├── arg-bool.m4 │ ├── ax_cxx_compile_stdcxx.m4 │ ├── checkflags.m4 │ └── tls.m4 ├── configure.ac ├── contrib ├── jenkins_tests │ ├── build.sh │ ├── compiler.sh │ ├── copyright-check-map.yaml │ ├── copyrights.sh │ ├── cov.sh │ ├── cppcheck.sh │ ├── csbuild.sh │ ├── globals.sh │ ├── gtest.sh │ ├── rpm.sh │ ├── style.conf │ ├── style.sh │ └── test.sh └── test_jenkins.sh ├── copying ├── debian ├── README.Debian ├── changelog ├── compat ├── control ├── copyright ├── patches │ └── series ├── rules └── source │ ├── format │ └── local-options ├── doc ├── Doxyfile.in └── main.dox ├── news ├── sockperf-version ├── src ├── aopt.cpp ├── aopt.h ├── client.cpp ├── client.h ├── clock.h ├── common.cpp ├── common.h ├── defs.cpp ├── defs.h ├── input_handlers.h ├── iohandlers.cpp ├── iohandlers.h ├── ip_address.cpp ├── ip_address.h ├── message.cpp ├── message.h ├── message_parser.h ├── os_abstract.cpp ├── os_abstract.h ├── packet.cpp ├── packet.h ├── playback.cpp ├── playback.h ├── port_descriptor.h ├── server.cpp ├── server.h ├── sockperf.cpp ├── switches.h ├── ticks.cpp ├── ticks.h ├── ticks_os.h ├── tls.cpp ├── tls.h ├── vma-xlio-redirect.cpp └── vma-xlio-redirect.h ├── tests ├── Makefile.am ├── avner-analyze.awk ├── avner-master-test.sh ├── avner-test-orig ├── avner-test.sh ├── gtest │ ├── Makefile.am │ ├── common │ │ └── tap.h │ ├── googletest │ │ ├── LICENSE │ │ ├── README.md │ │ ├── include │ │ │ └── gtest │ │ │ │ ├── gtest-death-test.h │ │ │ │ ├── gtest-message.h │ │ │ │ ├── gtest-param-test.h │ │ │ │ ├── gtest-printers.h │ │ │ │ ├── gtest-spi.h │ │ │ │ ├── gtest-test-part.h │ │ │ │ ├── gtest-typed-test.h │ │ │ │ ├── gtest.h │ │ │ │ ├── gtest_pred_impl.h │ │ │ │ ├── gtest_prod.h │ │ │ │ └── internal │ │ │ │ ├── gtest-death-test-internal.h │ │ │ │ ├── gtest-filepath.h │ │ │ │ ├── gtest-internal.h │ │ │ │ ├── gtest-linked_ptr.h │ │ │ │ ├── gtest-param-util-generated.h │ │ │ │ ├── gtest-param-util.h │ │ │ │ ├── gtest-port.h │ │ │ │ ├── gtest-string.h │ │ │ │ ├── gtest-tuple.h │ │ │ │ └── gtest-type-util.h │ │ └── src │ │ │ ├── gtest-all.cc │ │ │ ├── gtest-death-test.cc │ │ │ ├── gtest-filepath.cc │ │ │ ├── gtest-internal-inl.h │ │ │ ├── gtest-port.cc │ │ │ ├── gtest-printers.cc │ │ │ ├── gtest-test-part.cc │ │ │ ├── gtest-typed-test.cc │ │ │ ├── gtest.cc │ │ │ └── gtest_main.cc │ ├── main.cpp │ └── message_parser_tests.cpp ├── verifier │ ├── README │ ├── doc │ │ └── Test Matrix.xls │ ├── lib │ │ ├── TE │ │ │ ├── Common.pm │ │ │ ├── Funclet.pm │ │ │ ├── Progress.pm │ │ │ ├── Utility.pm │ │ │ └── VERSION.pm │ │ ├── TPB.pm │ │ ├── TPP.pm │ │ ├── TTP.pm │ │ ├── TUL.pm │ │ ├── UDS.pm │ │ ├── UPB.pm │ │ ├── UPP.pm │ │ ├── UTP.pm │ │ └── UUL.pm │ └── verifier.pl ├── vma_multiplexers_test.sh └── vma_perf_envelope.sh ├── tools ├── Makefile.am ├── filter.awk ├── gen1.awk └── gen2.awk └── win ├── README.txt └── project └── sockperf.vcxproj /.ci/Jenkinsfile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/groovy 2 | 3 | // load pipeline functions 4 | // Requires pipeline-github-lib plugin to load library from github 5 | @Library('github.com/Mellanox/ci-demo@stable_media') 6 | def matrix = new com.mellanox.cicd.Matrix() 7 | 8 | matrix.main() 9 | -------------------------------------------------------------------------------- /.ci/README.md: -------------------------------------------------------------------------------- 1 | # Continuous Integration 2 | 3 | ## Retrigger 4 | 5 | Put a comment with "bot:retest" 6 | 7 | ## More details 8 | 9 | After create Pull Request CI runs automatically within 5 mins. 10 | The CI results can be found under link Details on PR page in github. 11 | 12 | There are two main sections: Build Artifacts and Blue Ocean. 13 | 14 | * Build Artifacts has log files with output each stage. 15 | * On Blue Ocean page you can see a graph with CI steps. Each stage can be success(green) or fail(red). 16 | 17 | ## CI/CD 18 | 19 | This CD/CD pipeline based on ci-demo. All information can be found in main ci-demo repository. 20 | This is Jenkins CI/CD based project. You can create custom workflows to automate your project software life cycle process. 21 | 22 | You need to configure workflows using YAML syntax, and save them as workflow files in your repository. 23 | Once you've successfully created a YAML workflow file and triggered the workflow - Jenkins parse flow and execute it. 24 | 25 | [Read more](https://github.com/Mellanox/ci-demo/blob/master/README.md) 26 | 27 | ## Update Jenkins 28 | 29 | If proj_jjb.yaml was changed pipline configuration should be updated 30 | 31 | ``` 32 | cd .ci 33 | make jjb 34 | ``` 35 | 36 | ## Job Matrix yaml 37 | 38 | The main CI steps are describe in `job_matrix.yaml` file. 39 | Full list of supported features and syntax is given below. 40 | For more information please refer to [official ci-demo repository](https://github.com/Mellanox/ci-demo/) 41 | 42 | ## How to run Docker image on local machine 43 | 1. Make sure you have docker engine installed: `docker --version` 44 | 2. If there is no docker, please install it this way ): 45 | ```sh 46 | apt update && apt install -y apt-transport-https ca-certificates curl software-properties-common 47 | curl -sSL https://get.docker.com/ | sh 48 | ``` 49 | 3. Pull and run container by the following command (use correct image for your case): 50 | ```sh 51 | # Find top level dir of the git project: 52 | WORKSPACE=$(git rev-parse --show-toplevel) 53 | 54 | # run ubuntu2004 image on x86_64: 55 | docker run -it -d --rm --privileged -e WORKSPACE=$WORKSPACE -v $WORKSPACE:$WORKSPACE -v /var/lib/hugetlbfs:/var/lib/hugetlbfs --ulimit memlock=819200000:819200000 -v /auto/mtrswgwork:/auto/mtrswgwork -v /hpc/local/commercial:/hpc/local/commercial -v /auto/sw_tools/Commercial:/auto/sw_tools/Commercial -v /hpc/local/etc/modulefiles:/hpc/local/etc/modulefiles harbor.mellanox.com/swx-infra/x86_64/ubuntu20.04/builder:mofed-5.2-2.2.0.0 bash 56 | 57 | # run toolbox image on x86_64: 58 | docker run -it -d --rm --privileged -e WORKSPACE=$WORKSPACE -v $WORKSPACE:$WORKSPACE -v /var/lib/hugetlbfs:/var/lib/hugetlbfs --ulimit memlock=819200000:819200000 -v /auto/mtrswgwork:/auto/mtrswgwork -v /hpc/local/commercial:/hpc/local/commercial -v /auto/sw_tools/Commercial:/auto/sw_tools/Commercial -v /hpc/local/etc/modulefiles:/hpc/local/etc/modulefiles harbor.mellanox.com/toolbox/ngci-centos:7.9.2009.2 bash 59 | ``` 60 | 4. Login to running docker image: 61 | ```sh 62 | docker exec -it ${IMAGE_NAME} bash 63 | ``` 64 | Navigate to `$WORKSPACE` directory inside the image 65 | 66 | -------------------------------------------------------------------------------- /.ci/artifacts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xl 2 | 3 | if [ -d jenkins ]; then 4 | gzip -f ./jenkins/*.tar 2>/dev/null || true 5 | cd ./jenkins/ ; 6 | for f in *.tar.gz ; do [ -e "$f" ] && mv "$f" "${flags}/arch-${name}-$f" ; done ; 7 | cd .. 8 | cd ./jenkins/${flags}; 9 | for f in *.tap ; do [ -e "$f" ] && mv "$f" "${flags}-${name}-$f" ; done ; 10 | for f in *.xml ; do [ -e "$f" ] && mv "$f" "${flags}-${name}-$f" ; done ; 11 | cd ../.. 12 | fi 13 | -------------------------------------------------------------------------------- /.ci/proj_jjb.yaml: -------------------------------------------------------------------------------- 1 | - job-template: 2 | name: "{jjb_proj}" 3 | project-type: pipeline 4 | folder: sockperf 5 | properties: 6 | - github: 7 | url: "https://github.com/Mellanox/sockperf" 8 | - build-discarder: 9 | days-to-keep: 50 10 | num-to-keep: 20 11 | - inject: 12 | keep-system-variables: true 13 | properties-content: | 14 | jjb_proj={jjb_proj} 15 | description: Do NOT edit this job through the Web GUI ! 16 | concurrent: false 17 | parameters: 18 | - string: 19 | name: "sha1" 20 | default: master 21 | description: "Commit to be checked, set by PR" 22 | - bool: 23 | name: "build_dockers" 24 | default: false 25 | description: "Rebuild docker containers. Check this box if .ci/DockerFile* was changed" 26 | - string: 27 | name: "conf_file" 28 | default: ".ci/matrix_job.yaml" 29 | description: "Regex to select job config file. Do not change it" 30 | - string: 31 | name: "DEBUG" 32 | default: 0 33 | description: "Enable debug prints and traces, valid values are 0-9." 34 | - bool: 35 | name: "do_build" 36 | default: true 37 | description: "This verifies different configuration using gcc compiler." 38 | - bool: 39 | name: "do_compiler" 40 | default: true 41 | description: "Check ability to be built under icc, clang." 42 | - bool: 43 | name: "do_package" 44 | default: true 45 | description: "Check tar, source and binary packages." 46 | - bool: 47 | name: "do_cppcheck" 48 | default: true 49 | description: "Run static analysis using cppcheck tool." 50 | - bool: 51 | name: "do_csbuild" 52 | default: false 53 | description: "Run static analysis using csbuild tool." 54 | - bool: 55 | name: "do_style" 56 | default: false 57 | description: "Analysis source code for coding style." 58 | - bool: 59 | name: "do_coverity" 60 | default: false 61 | description: "Launch coverity verification." 62 | - bool: 63 | name: "do_test" 64 | default: true 65 | description: "Use runtime verification." 66 | - bool: 67 | name: "do_gtest" 68 | default: true 69 | description: "Use google tests." 70 | - bool: 71 | name: "do_artifact" 72 | default: true 73 | description: "Collect artifacts." 74 | - bool: 75 | name: "do_blackduck" 76 | default: true 77 | description: "Run BlackDuck." 78 | - bool: 79 | name: "do_copyrights" 80 | default: true 81 | description: "Check source file headers for correct copyrights." 82 | triggers: 83 | - github-pull-request: 84 | cron: 'H/5 * * * *' 85 | trigger-phrase: '.*\bbot:(?:lin:)?retest\b.*' 86 | status-context: "{jjb_proj}" 87 | success-status: "[PASS]" 88 | failure-status: "[FAIL]" 89 | error-status: "[FAIL]" 90 | status-add-test-results: true 91 | # svc-nbu-swx-media from GitHub Pull Request Builder 92 | auth-id: 'svc-nbu-swx-media_GHPRB_ID' 93 | org-list: ["Mellanox"] 94 | white-list: ["swx-jenkins","swx-jenkins2","swx-jenkins3","mellanox-github"] 95 | allow-whitelist-orgs-as-admins: true 96 | cancel-builds-on-update: true 97 | pipeline-scm: 98 | scm: 99 | - git: 100 | url: "{jjb_git}" 101 | credentials-id: 'swx-jenkins_ssh_key' 102 | branches: ['$sha1'] 103 | shallow-clone: true 104 | depth: 2 105 | refspec: "+refs/pull/*:refs/remotes/origin/pr/*" 106 | browser: githubweb 107 | browser-url: "{jjb_git}" 108 | script-path: ".ci/Jenkinsfile" 109 | - project: 110 | name: sockperf 111 | jjb_email: 'nwolfer@nvidia.com' 112 | jjb_proj: 'sockperf-ci-linux' 113 | jjb_git: 'git@github.com:Mellanox/sockperf' 114 | jjb_owner: 'Nir Wolfer' 115 | jobs: 116 | - "{jjb_proj}" 117 | -------------------------------------------------------------------------------- /.ci/windows/build.cmd: -------------------------------------------------------------------------------- 1 | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat" 2 | 3 | set SolutionDir=%WORKSPACE% 4 | msbuild %SolutionDir%\win\project\sockperf.vcxproj /t:Build /p:Configuration=Release;Platform=x64 5 | if %errorlevel% neq 0 exit /b %errorlevel% 6 | -------------------------------------------------------------------------------- /.ci/windows/windows_proj_jjb.yaml: -------------------------------------------------------------------------------- 1 | - job-template: 2 | name: "{jjb_proj}" 3 | project-type: freestyle 4 | node: r-aa-fatty27 5 | folder: sockperf 6 | properties: 7 | - github: 8 | url: "https://github.com/Mellanox/sockperf" 9 | - build-discarder: 10 | days-to-keep: 50 11 | num-to-keep: 20 12 | - inject: 13 | keep-system-variables: true 14 | properties-content: | 15 | jjb_proj={jjb_proj} 16 | description: Do NOT edit this job through the Web GUI ! 17 | parameters: 18 | - string: 19 | name: "sha1" 20 | default: "sockperf_v2" 21 | description: "Commit to be checked, usualy controlled by PR" 22 | - string: 23 | name: "DEBUG" 24 | default: 0 25 | description: "Enable debug prints and traces, valid values are 0-9" 26 | 27 | triggers: 28 | - github-pull-request: 29 | cron: 'H/5 * * * *' 30 | trigger-phrase: '.*\bbot:(?:win:)?retest\b.*' 31 | status-context: "sockperf-ci-windows" 32 | success-status: "[PASS]" 33 | failure-status: "[FAIL]" 34 | error-status: "[FAIL]" 35 | status-add-test-results: true 36 | # svc-nbu-swx-media from GitHub Pull Request Builder 37 | auth-id: 'svc-nbu-swx-media_GHPRB_ID' 38 | org-list: ["Mellanox", "mellanox-hpc", "Mellanox-lab"] 39 | allow-whitelist-orgs-as-admins: true 40 | cancel-builds-on-update: true 41 | 42 | wrappers: 43 | - workspace-cleanup 44 | - credentials-binding: 45 | - username-password-separated: 46 | username: NFS_USER 47 | password: NFS_PASSWORD 48 | credential-id: windevqa_svc 49 | 50 | builders: 51 | - batch: | 52 | call %WORKSPACE%\.ci\windows\build.cmd 53 | 54 | scm: 55 | - git: 56 | url: "{jjb_git}" 57 | # swx-jenkins3 GH user/pass 58 | credentials-id: 'swx-jenkins_ssh_key' 59 | branches: ['$sha1'] 60 | shallow-clone: true 61 | depth: 10 62 | do-not-fetch-tags: false 63 | # honor-refspec: true 64 | refspec: "+refs/pull/*:refs/remotes/origin/pr/*" 65 | browser: githubweb 66 | browser-url: "{jjb_git}" 67 | script-path: "$script" 68 | 69 | - project: 70 | name: sockperf 71 | jjb_email: 'nwolfer@nvidia.com' 72 | jjb_proj: 'sockperf-ci-windows' 73 | jjb_git: 'git@github.com:Mellanox/sockperf.git' 74 | jjb_owner: 'Nir Wolfer' 75 | jjb_jenkinsfile: '.ci/Jenkinsfile.shlib' 76 | jobs: 77 | - "{jjb_proj}" 78 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | aclocal.m4 3 | config.h 4 | config.h.in 5 | config.log 6 | config.status 7 | config/aux/ 8 | configure 9 | doc/Doxyfile 10 | sockperf 11 | src/.dirstamp 12 | *~ 13 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | if TEST 2 | TEST_SUBDIR = tests 3 | endif 4 | 5 | if TOOL 6 | TOOL_SUBDIR = tools 7 | endif 8 | 9 | SUBDIRS = ${TEST_SUBDIR} ${TOOL_SUBDIR} 10 | 11 | ACLOCAL_AMFLAGS = -I config/m4 12 | AM_LDFLAGS = -rdynamic 13 | AM_CPPFLAGS = -imacros $(builddir)/config.h 14 | AM_CXXFLAGS = $(OUR_CXXFLAGS) 15 | 16 | bin_PROGRAMS = sockperf 17 | 18 | sockperf_SOURCES = \ 19 | src/aopt.cpp \ 20 | src/aopt.h \ 21 | src/client.cpp \ 22 | src/client.h \ 23 | src/clock.h \ 24 | src/common.cpp \ 25 | src/common.h \ 26 | src/defs.cpp \ 27 | src/defs.h \ 28 | src/input_handlers.h \ 29 | src/iohandlers.cpp \ 30 | src/iohandlers.h \ 31 | src/ip_address.cpp \ 32 | src/ip_address.h \ 33 | src/message.cpp \ 34 | src/message.h \ 35 | src/message_parser.h \ 36 | src/os_abstract.cpp \ 37 | src/os_abstract.h \ 38 | src/packet.cpp \ 39 | src/packet.h \ 40 | src/playback.cpp \ 41 | src/playback.h \ 42 | src/port_descriptor.h \ 43 | src/server.cpp \ 44 | src/server.h \ 45 | src/sockperf.cpp \ 46 | src/switches.h \ 47 | src/ticks.cpp \ 48 | src/ticks.h \ 49 | src/ticks_os.h \ 50 | src/tls.cpp \ 51 | src/tls.h \ 52 | src/vma-xlio-redirect.cpp \ 53 | src/vma-redirect.h 54 | 55 | dist_doc_DATA = \ 56 | README.md \ 57 | authors \ 58 | news \ 59 | sockperf-version \ 60 | copying 61 | 62 | EXTRA_DIST = \ 63 | build \ 64 | contrib \ 65 | debian \ 66 | doc/Doxyfile.in \ 67 | doc/main.dox 68 | 69 | if DOC 70 | .PHONY: doxygen 71 | 72 | doxygen: doc/man/man/man3/sockperf.3 73 | 74 | doc/man/man/man3/sockperf.3: doc/Doxyfile $(srcdir)/doc/main.dox 75 | doxygen doc/Doxyfile 76 | 77 | install-data-local: 78 | $(mkinstalldirs) ${DESTDIR}$(docdir) 79 | cp -rf doc/man/html/ ${DESTDIR}$(docdir) 80 | 81 | uninstall-local: 82 | rm -rf ${DESTDIR}$(docdir)/html 83 | 84 | clean-local: 85 | rm -rf doc/man doc/doxygen.log 86 | 87 | man_MANS = doc/man/man/man3/sockperf.3 88 | 89 | endif 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | **sockperf** is a network benchmarking utility over socket API that was designed for testing performance (latency and throughput) of high-performance systems (it is also good for testing performance of regular networking systems). It covers most of the socket API calls and options. 4 | 5 | Specifically, in addition to the standard throughput tests, **sockperf** does the following: 6 | 7 | * Measure latency of each discrete packet at sub-nanosecond resolution (using TSC register that counts CPU ticks with very low overhead). 8 | 9 | * Does the above for both ping-pong mode and latency under load mode. This means that we measure latency of single packets even under load of millions of Packets Per Second (without waiting for reply of packet before sending subsequent packet on time) 10 | 11 | * Enable spike analysis by providing histogram, with various percentiles of the packets’ latencies (for example: median, min, max, 99% percentile, and more), (this is in addition to average and standard deviation). Also, **sockperf** provides a full log with all packet’s tx/rx times that can be further analyzed with external tools, such as MS-Excel or matplotlib - All this without affecting the benchmark itself. 12 | 13 | * Support MANY optional settings for good coverage of socket API and network configurations, while still keeping very low overhead in the fast path to allow cleanest results. 14 | 15 | ## Prereqs: What you will need to compile sockperf on Unix systems 16 | 17 | * Perl 5.8+ (used by the automake tools) 18 | 19 | * GNU make tools: automake 1.7+, autoconf 2.57+, m4 1.4+ and libtool 1.4+ 20 | 21 | * A C++11 Compiler, among those tested are: 22 | 23 | * GCC 24 | * Clang 25 | * icc 26 | 27 | Linux (Debian/Ubuntu): `sudo apt install perl make automake autoconf m4 libtool-bin g++` 28 | 29 | FreeBSD: `sudo pkg install gmake automake libtool` 30 | 31 | ## How to install 32 | 33 | The sockperf package uses the GNU autotools compilation and installation 34 | framework. 35 | ``` 36 | ./autogen.sh (only when cloning from repository) 37 | ./configure --prefix= 38 | make 39 | make install 40 | ``` 41 | ### Configuration 42 | 43 | Type `./configure --help` for a list of all the configure 44 | options. Some of the options are generic autoconf options, while the sockperf 45 | specific options are prefixed with "SOCKPERF:" in the help text. 46 | 47 | * To enable TLS support 48 | * `./configure --prefix= --with-tls=` 49 | * Use OpenSSL 3.0.0 or higher 50 | 51 | * To enable unit tests 52 | * `./configure --prefix= --enable-test` 53 | 54 | * To enable the documentation 55 | * `./configure --prefix= --enable-doc` 56 | 57 | * To enable the special scripts 58 | * `./configure --prefix= --enable-tool` 59 | 60 | * To compile with debug symbols and information: 61 | * `./configure --prefix= --enable-debug` 62 | * This will define the DEBUG variable at compile time. 63 | 64 | ### To build for ARM 65 | 66 | 1) Define CROSS_COMPILE in the environment to point to the cross compilation tools, e.g. 67 | set `CROSS_COMPILE=/opt/gcc-linaro-arm-linux-gnueabihf-4.7-2012.11-20121123_linux/bin/arm-linux-gnueabihf-` 68 | 2) Use `./autogen.sh` to create the configure script. 69 | 3) Invoke `./configure` with the following options: 70 | `./configure CXX=${CROSS_COMPILE}g++ STRIP=${CROSS_COMPILE}strip 71 | LD=${CROSS_COMPILE}ld CC=${CROSS_COMPILE}gcc --host i386` 72 | 4) Invoke `make` 73 | 74 | ### To build for FreeBSD 75 | 76 | * Make sure automake tools are installed. 77 | 78 | ## Licensing 79 | 80 | [View Here](https://github.com/Mellanox/sockperf/blob/sockperf_v2/copying) 81 | 82 | ~Good luck! 83 | 84 | -------------------------------------------------------------------------------- /authors: -------------------------------------------------------------------------------- 1 | Avner BenHanoch 2 | Igor Ivanov 3 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -ex 3 | 4 | oldpwd=$(pwd) 5 | topdir=$(dirname "$0") 6 | cd "$topdir" 7 | 8 | CURRENT_VERSION_FILE=./build/current-version 9 | . ./build/versioning.sh 10 | echo ${VERSION}-${RELEASE} > $CURRENT_VERSION_FILE 11 | echo $GIT_REF >> $CURRENT_VERSION_FILE 12 | 13 | rm -rf autom4te.cache 14 | mkdir -p config/m4 config/aux 15 | autoreconf -v --install || exit 1 16 | rm -rf autom4te.cache 17 | 18 | cd "$oldpwd" 19 | 20 | if [ "x$1" = "xc" ]; then 21 | shift 22 | $topdir/configure CXXFLAGS='-g -O0 -Wall -Werror' $@ 23 | make clean 24 | else 25 | printf "\nNow run '$topdir/configure' and 'make'.\n\n" 26 | fi 27 | 28 | rm -f $CURRENT_VERSION_FILE 29 | exit 0 30 | -------------------------------------------------------------------------------- /build/build-rpm-to-deb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | ############################################################################## 3 | # this script will extract content of a given *.src.rpm file (that its tarball 4 | # contains ./debian/ subfolder) and will compile it into *.deb binary 5 | ############################################################################## 6 | 7 | APP_NAME=sockperf 8 | SRCRPM_EXT=.src.rpm 9 | TARBALL_EXT=.tar.gz 10 | BASE_DIR=`pwd` 11 | if [ $# -lt 1 ]; then 12 | echo -e "Usage is:\n\t $0 " > /dev/stderr 13 | exit 1 14 | fi 15 | 16 | SRCRPM_FILE=`readlink -f $1` 17 | APP_NAME_VER=`basename $SRCRPM_FILE $SRCRPM_EXT` # sockperf-2.7-13.gitd8618862f05d.dirty 18 | FULL_VER=${APP_NAME_VER#$APP_NAME-} # 2.7-13.gitd8618862f05d.dirty 19 | VERSION=${FULL_VER%%-*} # 2.7 20 | 21 | TEMP_DIR=/tmp/for-deb-$APP_NAME_VER 22 | rm -rf $TEMP_DIR; mkdir $TEMP_DIR; cd $TEMP_DIR 23 | rpm2cpio $SRCRPM_FILE | cpio -i 2> /dev/null # extract *.src.rpm 24 | OLD_NAME=`basename $APP_NAME-*$TARBALL_EXT $TARBALL_EXT` 25 | 26 | ln -s $OLD_NAME$TARBALL_EXT ${APP_NAME}_${VERSION}.orig$TARBALL_EXT 27 | tar xf $OLD_NAME$TARBALL_EXT 28 | cd $OLD_NAME 29 | 30 | dpkg-buildpackage -us -uc # actual build of *.deb 31 | cd $BASE_DIR 32 | cp --verbose $TEMP_DIR/*.deb . 33 | rm -rf $TEMP_DIR 34 | -------------------------------------------------------------------------------- /build/build-rpm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | ################################################################# 4 | ######## create *.src.rpm based on specfile template ############ 5 | ################################################################# 6 | 7 | BASE_DIR=`pwd` 8 | script_dir=`dirname $(readlink -f $0)` 9 | cd $script_dir/.. 10 | 11 | source ./build/versioning.sh 12 | APP_NAME=sockperf 13 | MAINTAINER="Mellanox Technologies Ltd. " 14 | DATE=`date -R` 15 | 16 | GITHUB_REF=$APP_NAME-$GIT_REF 17 | FULL_VER=${VERSION}-${RELEASE} 18 | echo $FULL_VER > ./build/current-version 19 | echo $GIT_REF >> ./build/current-version 20 | 21 | APP_NAME_VER=$APP_NAME-$FULL_VER 22 | 23 | #DIRNAME=$GITHUB_REF # match Fedora original style 24 | DIRNAME=$APP_NAME_VER # better MOFED 25 | DIRNAME=$APP_NAME-$VERSION 26 | 27 | TEMP_DIR=/tmp/$DIRNAME 28 | rm -rf $TEMP_DIR; mkdir $TEMP_DIR 29 | cp -a * $TEMP_DIR/ # do not copy hidden files like .git 30 | cd $TEMP_DIR 31 | 32 | 33 | if [ $# -lt 1 ]; then 34 | RPM_DIR=`rpm --eval '%{_topdir}'` 35 | else 36 | RPM_DIR=$1 37 | fi 38 | 39 | mkdir -p --verbose $RPM_DIR/{BUILD,RPMS,SOURCES,SPECS,SRPMS,tmp} 40 | 41 | APP_SPEC=$RPM_DIR/SPECS/$APP_NAME_VER.spec 42 | sed -e s/__GIT_REF__/$GIT_REF/g -e s/__VERSION__/$VERSION/g -e s/__RELEASE__/$RELEASE/g ./build/$APP_NAME.spec.in > $APP_SPEC 43 | sed -i -e s/__VERSION__/$VERSION/g -e s/__RELEASE__/$RELEASE/g -e s/__APP_NAME__/$APP_NAME/g -e "s/__DATE__/$DATE/g" -e "s/__MAINTAINER__/$MAINTAINER/g" debian/* 2> /dev/null || true 44 | 45 | 46 | ./autogen.sh 47 | 48 | tar -zcf $RPM_DIR/SOURCES/$DIRNAME.tar.gz --exclude .git -C .. $DIRNAME 49 | env RPM_BUILD_NCPUS=${NPROC} rpmbuild -bs --define 'dist %{nil}' --define '_source_filedigest_algorithm md5' --define '_binary_filedigest_algorithm md5' --rmsource --rmspec --define "_topdir $RPM_DIR" $APP_SPEC 50 | cd $BASE_DIR 51 | rm -rf $TEMP_DIR 52 | 53 | # mv XXX.src.rpm from $RPM_DIR/SRPMS -> /.autodirect/mswg/release/sockperf/ and update ./latest.txt 54 | -------------------------------------------------------------------------------- /build/sockperf.spec.in: -------------------------------------------------------------------------------- 1 | %global version __VERSION__ 2 | %global git_ref __GIT_REF__ 3 | %global release __RELEASE__ 4 | %global full_ver %{version}-%{release} 5 | 6 | Name: sockperf 7 | Version: %{version} 8 | Release: %{release}%{?dist} 9 | Summary: Network benchmarking utility for testing latency and throughput 10 | Group: Applications/Internet 11 | License: BSD 12 | URL: https://github.com/mellanox/%{name} 13 | #Source0: https://github.com/mellanox/%{name}/archive/%{git_ref}.tar.gz#/%{name}-%{git_ref}.tar.gz 14 | Source0: %{name}-%{version}.tar.gz 15 | 16 | BuildRequires: doxygen 17 | # can't use _pkgdocdir neither _docdir since it is not the same even where it is defined 18 | %global _my_pkgdocdir /usr/share/doc/%{name} 19 | 20 | 21 | %description 22 | sockperf is a network benchmarking utility over socket API that was designed 23 | for testing performance (latency and throughput) of high-performance systems 24 | (it is also good for testing performance of regular networking systems as 25 | well). It covers most of the socket API calls and options. 26 | 27 | Specifically, in addition to the standard throughput tests, sockperf, does the 28 | following: 29 | 30 | * Measure latency of each discrete packet at sub-nanosecond resolution (using 31 | TSC register that counts CPU ticks with very low overhead). 32 | 33 | * Does the above for both ping-pong mode and for latency under load mode. This 34 | means that we measure latency of single packets even under load of millions 35 | Packets Per Second (without waiting for reply of packet before sending 36 | subsequent packet on time) 37 | 38 | * Enable spike analysis by providing histogram, with various percentiles of the 39 | packets' latencies (for example: median, min, max, 99% percentile, and more), 40 | (this is in addition to average and standard deviation). Also, sockperf 41 | provides full log with all packet's tx/rx times that can be further analyzed 42 | with external tools, such as MS-Excel or matplotlib - All this without 43 | affecting the benchmark itself. 44 | 45 | * Support MANY optional settings for good coverage of socket API and network 46 | configurations, while still keeping very low overhead in the fast path to 47 | allow cleanest results. 48 | 49 | %prep 50 | #%setup -q -n %{name}-%{git_ref} 51 | %setup -q -n %{name}-%{version} 52 | 53 | 54 | %build 55 | 56 | # Upstream wants and defaults to "-O3 --param inline-unit-growth=200". 57 | # The Fedora optflags would override the former, so let's put it back. 58 | # Avner wrote: 59 | # > I reached that in the past after fine tuning the performance of sockperf. 60 | # > We used sockperf for measuring latency of extremely fast networks. 61 | # > Sometimes at sub microsecond resolution. This parameter helps us keeping 62 | # > the entire fast path of the application as "one big function" with no 63 | # > calls to other functions because it helps the compiler to respect all our 64 | # > "inline" directive for other functions that we call (while still keeping 65 | # > the "one big function" at a reasonable size for good performance at run 66 | # > time). 67 | export CXXFLAGS='%{optflags} -O3' 68 | %configure --enable-doc 69 | # --enable-tool --enable-test 70 | make %{?_smp_mflags} 71 | 72 | %install 73 | make install DESTDIR="%{?buildroot}" 74 | 75 | %files 76 | %defattr(-,root,root,-) 77 | %{_bindir}/%{name} 78 | %{_mandir}/man3/%{name}.3.* 79 | %{_my_pkgdocdir} 80 | -------------------------------------------------------------------------------- /build/versioning.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | VERSION=`cat sockperf-version | tr -d '\n'` 4 | GIT_REF=`git rev-parse HEAD 2> /dev/null || echo "no.git"` 5 | x=`git describe --long --abbrev=12 --dirty 2> /dev/null || echo ""` 6 | if [ -n "$x" ]; then x=`echo $x | sed -e 's/-g/.git/' -e 's/-dirty/.dirty/' | sed s/.*-//`; else x="no.git"; fi 7 | RELEASE=$x 8 | #RELEASE=20 # TEMP !!! 9 | #GIT_REF=${VERSION}-${RELEASE} # TEMP !!! 10 | 11 | -------------------------------------------------------------------------------- /config/m4/arg-bool.m4: -------------------------------------------------------------------------------- 1 | dnl Kind of like AC_ARG_ENABLE, but enforces that the optional argument is 2 | dnl either "yes" or "no". Returns the result in a variable called have_NAME. 3 | dnl 4 | dnl SP_ARG_ENABLE_BOOL(NAME, HELP-STRING) 5 | 6 | AC_DEFUN([SP_ARG_ENABLE_BOOL], [ 7 | have_$1=no 8 | AC_ARG_ENABLE([$1], [$2], [ 9 | AS_IF([test "x$enableval" = "xno"], [have_$1=no], 10 | [test "x$enableval" = "xyes"], [have_$1=yes], 11 | [AC_MSG_ERROR([bad value $enableval for --enable-$1])])]) 12 | ]) 13 | -------------------------------------------------------------------------------- /config/m4/checkflags.m4: -------------------------------------------------------------------------------- 1 | dnl Check if compiler accepts FLAG in CXXFLAGS. If accepted, do 2 | dnl ACTION-IF-FLAG-WORKS. Otherwise do ACTION-IF-FLAG-DOES-NOT-WORK. 3 | dnl 4 | dnl SP_CHECK_CXXFLAG(FLAG, [ACTION-IF-FLAG-WORKS], [ACTION-IF-FLAG-DOES-NOT-WORK]) 5 | 6 | AC_DEFUN([SP_CHECK_CXXFLAG], [ 7 | AS_VAR_PUSHDEF([sp_cxxflag], [sockperf_cv_cxxflags_$1]) 8 | AC_CACHE_CHECK([whether $CXX supports $1 in CXXFLAGS], 9 | [sp_cxxflag], [ 10 | saved_cxxflags="$CXXFLAGS" 11 | CXXFLAGS="$1" 12 | AC_LINK_IFELSE([AC_LANG_PROGRAM()], 13 | [AS_VAR_SET([sp_cxxflag], [yes])], 14 | [AS_VAR_SET([sp_cxxflag], [no])]) 15 | CXXFLAGS="$saved_cxxflags"]) 16 | AS_VAR_IF([sp_cxxflag], [yes], [$2], [$3]) 17 | AS_VAR_POPDEF([sp_cxxflag]) 18 | ]) 19 | 20 | dnl Check if compiler accepts FLAG in CXXFLAGS. If accepted, append the flag 21 | dnl to environment variable ENV-VAR. Otherwise do ACTION-IF-FLAG-DOES-NOT-WORK. 22 | dnl 23 | dnl SP_CHECK_CXXFLAG_APPEND(ENV-VAR, FLAG, [ACTION-IF-FLAG-DOES-NOT-WORK]) 24 | 25 | AC_DEFUN([SP_CHECK_CXXFLAG_APPEND], 26 | [SP_CHECK_CXXFLAG([$2], [$1="${$1} $2"], [$3]) 27 | ]) 28 | 29 | dnl Check if compiler accepts FLAGS in CXXFLAGS. Append accepted flags to 30 | dnl environment variable ENV-VAR. Ignore rejected flags. 31 | dnl 32 | dnl SP_CHECK_CXXFLAGS_APPEND(ENV-VAR, FLAGS) 33 | 34 | AC_DEFUN([SP_CHECK_CXXFLAGS_APPEND], [ 35 | for flag in $2; do 36 | SP_CHECK_CXXFLAG_APPEND([$1], [$flag]) 37 | done]) 38 | -------------------------------------------------------------------------------- /config/m4/tls.m4: -------------------------------------------------------------------------------- 1 | # tls.m4 - Library to operate TLS 2 | # 3 | # Copyright (C) Mellanox Technologies Ltd. 2020-2024. ALL RIGHTS RESERVED. 4 | # See file LICENSE for terms. 5 | # 6 | 7 | ########################## 8 | # tls usage support 9 | # 10 | AC_DEFUN([TLS_CAPABILITY_SETUP], 11 | [ 12 | AC_ARG_WITH([tls], 13 | AS_HELP_STRING([--with-tls(=DIR)], 14 | [Search for tls headers and libraries in DIR (default NO)]), 15 | [], 16 | [with_tls=no] 17 | ) 18 | 19 | sockperf_cv_tls_lib=0 20 | sockperf_cv_tls_lib_str="None" 21 | 22 | AS_IF([test "x$with_tls" == xno], 23 | [], 24 | [ 25 | if test -z "$with_tls" || test "$with_tls" = "yes"; then 26 | with_tls=/usr 27 | fi 28 | 29 | # Find a name of tls library as openssl, gnutls etc 30 | if test ! -d "openssl"; then 31 | sockperf_cv_tls_lib=1 32 | sockperf_cv_tls_lib_str="openssl" 33 | 34 | sockperf_cv_tls_save_CPPFLAGS="$CPPFLAGS" 35 | sockperf_cv_tls_save_CXXFLAGS="$CXXFLAGS" 36 | sockperf_cv_tls_save_CFLAGS="$CFLAGS" 37 | sockperf_cv_tls_save_LDFLAGS="$LDFLAGS" 38 | sockperf_cv_tls_save_LIBS="$LIBS" 39 | 40 | sockperf_cv_tls_CPPFLAGS="-I$with_tls/include" 41 | sockperf_cv_tls_LIBS="-lssl -lcrypto" 42 | sockperf_cv_tls_LDFLAGS="-L$with_tls/lib -Wl,--rpath,$with_tls/lib" 43 | if test -d "$with_tls/lib64"; then 44 | sockperf_cv_tls_LDFLAGS="-L$with_tls/lib64 -Wl,--rpath,$with_tls/lib64" 45 | fi 46 | 47 | CPPFLAGS="$sockperf_cv_tls_CPPFLAGS $CPPFLAGS" 48 | CXXFLAGS="$sockperf_cv_dpcp_CXXFLAGS $CXXFLAGS" 49 | LDFLAGS="$sockperf_cv_dpcp_LDFLAGS $LDFLAGS" 50 | LIBS="$sockperf_cv_tls_LIBS $LIBS" 51 | 52 | AC_LANG_PUSH([C]) 53 | AC_CHECK_HEADER( 54 | [openssl/ssl.h], 55 | [AC_LINK_IFELSE([AC_LANG_PROGRAM( 56 | [[#include 57 | #include 58 | ]], 59 | [[SSL_library_init(); 60 | ERR_clear_error(); 61 | SSL_load_error_strings(); 62 | ]])], 63 | [], [sockperf_cv_tls_lib=0]) 64 | ]) 65 | AC_LANG_POP() 66 | 67 | CPPFLAGS="$sockperf_cv_tls_save_CPPFLAGS" 68 | CXXFLAGS="$sockperf_cv_tls_save_CXXFLAGS" 69 | CFLAGS="$sockperf_cv_tls_save_CFLAGS" 70 | LDFLAGS="$sockperf_cv_tls_save_LDFLAGS" 71 | LIBS="$sockperf_cv_tls_save_LIBS" 72 | fi 73 | ]) 74 | 75 | AC_MSG_CHECKING([for tls support]) 76 | if test "$sockperf_cv_tls_lib" -ne 0; then 77 | CPPFLAGS="$CPPFLAGS $sockperf_cv_tls_CPPFLAGS" 78 | LDFLAGS="$LDFLAGS $sockperf_cv_tls_LDFLAGS" 79 | LIBS="$LIBS $sockperf_cv_tls_LIBS" 80 | AC_DEFINE_UNQUOTED([DEFINED_TLS], [$sockperf_cv_tls_lib], [Using TLS]) 81 | AC_MSG_RESULT([$sockperf_cv_tls_lib_str]) 82 | else 83 | AC_MSG_RESULT([no]) 84 | fi 85 | ]) 86 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # Indicate that we require autoconf 2.59 or later. 2 | # 3 | AC_PREREQ(2.59) 4 | 5 | define([sockperf_version], esyscmd([sh -c "head -1 ./build/current-version | tr -d '\n'"])) 6 | AC_INIT([SOCKPERF], [sockperf_version], [http://github.com/mellanox/sockperf/issues]) 7 | 8 | AC_CONFIG_HEADERS([config.h]) 9 | AC_CONFIG_MACRO_DIR([config/m4]) 10 | AC_CONFIG_AUX_DIR([config/aux]) 11 | 12 | # Determine the host system 13 | AC_CANONICAL_TARGET 14 | 15 | TARGETDIR="unknown" 16 | case "$host" in 17 | 18 | i?86-*-*) TARGET=X86; TARGETDIR=x86;; 19 | ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;; 20 | powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;; 21 | arm*-*-linux*) TARGET=ARM; TARGETDIR=arm;; 22 | powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;; 23 | powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;; 24 | powerpc-*-aix* | rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; 25 | powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;; 26 | powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;; 27 | x86_64-*-*) TARGET=X86_64; TARGETDIR=x86;; 28 | amd64-*-freebsd*) TARGET=FREEBSD; TARGETDIR=x86;; 29 | i386-*-freebsd*) TARGET=FREEBSD; TARGETDIR=x86;; 30 | aarch64-*-*) TARGET=AARCH64; TARGETDIR=aarch64;; 31 | s390*-*-*) TARGET=S390; TARGETDIR=s390;; 32 | esac 33 | 34 | AC_SUBST(AM_RUNTESTFLAGS) 35 | AC_SUBST(AM_LTLDFLAGS) 36 | 37 | if test $TARGETDIR = unknown; then 38 | AC_MSG_ERROR(["it has not been ported to $host."]) 39 | fi 40 | 41 | AM_CONDITIONAL(X86, test x$TARGET = xX86) 42 | AM_CONDITIONAL(IA64, test x$TARGET = xIA64) 43 | AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC) 44 | AM_CONDITIONAL(ARM, test x$TARGET = xARM) 45 | AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX) 46 | AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN) 47 | AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD) 48 | AM_CONDITIONAL(FREEBSD, test x$TARGET = xFREEBSD) 49 | AM_CONDITIONAL(AARCH64, test x$TARGET = xAARCH64) 50 | AM_CONDITIONAL(S390, test x$TARGET = xS390) 51 | 52 | AC_SUBST(TARGET) 53 | AC_SUBST(TARGETDIR) 54 | 55 | ######### 56 | # Locate a compiler for the build machine. This compiler should 57 | # generate command-line programs that run on the build machine. 58 | # 59 | if test x"$cross_compiling" = xyes; then 60 | AC_MSG_NOTICE([Enable cross compiling on ${build_cpu} for ${host_cpu}]) 61 | #prefix=${prefix}/${host_cpu} 62 | fi 63 | 64 | AM_INIT_AUTOMAKE([foreign subdir-objects -Wall]) 65 | AM_MAINTAINER_MODE 66 | 67 | ##################################### 68 | # check for C++ preprocessor and compiler 69 | # 70 | : ${CXXFLAGS="-O3 -g"} 71 | AC_PROG_CXX 72 | AC_LANG(C++) 73 | AM_PROG_AR 74 | LT_INIT 75 | 76 | AX_CXX_COMPILE_STDCXX([11], [], [mandatory]) 77 | 78 | SP_CHECK_CXXFLAGS_APPEND([OUR_CXXFLAGS], [\ 79 | -Wall \ 80 | "--param inline-unit-growth=300"]) 81 | 82 | ########################################################################## 83 | # check VMA extra API 84 | # 85 | AC_ARG_ENABLE( 86 | [vma-api], 87 | AS_HELP_STRING([--enable-vma-api], 88 | [SOCKPERF: enable vma extra api support: 'yes', 'no' or library installation path (default=no)]), 89 | [have_vma_api=$enableval], 90 | [have_vma_api=no]) 91 | AS_IF([test "${have_vma_api}" != "no"], 92 | [ 93 | if test "$have_vma_api" = "yes" 94 | then 95 | have_vma_api=/usr 96 | fi 97 | CPPFLAGS="$CPPFLAGS -I$have_vma_api/include" 98 | 99 | AC_CHECK_HEADER([mellanox/vma_extra.h], 100 | [AC_DEFINE([USING_VMA_EXTRA_API],[1],[[Enable using VMA extra API]])], 101 | [AC_MSG_ERROR([vma_extra.h file not found at $have_vma_api/include])] 102 | [have_vma_api=no])]) 103 | AC_MSG_CHECKING( 104 | [for vma extra api]) 105 | AC_MSG_RESULT([${have_vma_api}]) 106 | 107 | ########################################################################## 108 | # check XLIO extra API 109 | # 110 | AC_ARG_ENABLE( 111 | [xlio-api], 112 | AS_HELP_STRING([--enable-xlio-api], 113 | [SOCKPERF: enable xlio extra api support: 'yes', 'no' or library installation path (default=no)]), 114 | [have_xlio_api=$enableval], 115 | [have_xlio_api=no]) 116 | AS_IF([test "${have_xlio_api}" != "no"], 117 | [ 118 | if test "$have_xlio_api" = "yes" 119 | then 120 | have_xlio_api=/usr 121 | fi 122 | CPPFLAGS="$CPPFLAGS -I$have_xlio_api/include" 123 | 124 | AC_CHECK_HEADER([mellanox/xlio_extra.h], 125 | [AC_DEFINE([USING_XLIO_EXTRA_API],[1],[[Enable using XLIO extra API]])], 126 | [AC_MSG_ERROR([xlio_extra.h file not found at $have_xlio_api/include])] 127 | [have_xlio_api=no])]) 128 | AC_MSG_CHECKING( 129 | [for xlio extra api]) 130 | AC_MSG_RESULT([${have_xlio_api}]) 131 | 132 | ########################## 133 | # Documentation 134 | # 135 | SP_ARG_ENABLE_BOOL( 136 | [doc], 137 | AS_HELP_STRING([--enable-doc], 138 | [SOCKPERF: create documentation with doxygen in html and unix-man (default=no)])) 139 | AS_IF([test "x$have_doc" = "xyes"], [ 140 | # Checks for doxygen 141 | AC_PATH_PROG(DOXYGEN, doxygen, ,$PATH:/usr/local/bin:/usr/bin) 142 | AS_IF([test -z "$DOXYGEN"], 143 | [AC_MSG_ERROR([Building of doc requested, but doxygen not found])])]) 144 | AM_CONDITIONAL(DOC, test "x$have_doc" = "xyes") 145 | 146 | 147 | ########################## 148 | # Enable tests 149 | # 150 | SP_ARG_ENABLE_BOOL( 151 | [test], 152 | AS_HELP_STRING([--enable-test], 153 | [SOCKPERF: compile tests (default=no)])) 154 | AM_CONDITIONAL(TEST, test "x$have_test" = "xyes") 155 | 156 | 157 | ########################## 158 | # Enable tools 159 | # 160 | SP_ARG_ENABLE_BOOL( 161 | [tool], 162 | AS_HELP_STRING([--enable-tool], 163 | [SOCKPERF: compile utilities (default=no)])) 164 | AM_CONDITIONAL(TOOL, test "x$have_tool" = "xyes") 165 | 166 | 167 | ########################## 168 | # Enable debug build 169 | # 170 | SP_ARG_ENABLE_BOOL( 171 | [debug], 172 | AS_HELP_STRING([--enable-debug], 173 | [SOCKPERF: turn on debugging (default=no)])) 174 | AS_IF([test "x$have_debug" = "xyes"], 175 | [AC_DEFINE([DEBUG], [], [Enable debugging])], 176 | [AC_DEFINE([NDEBUG], [], [Disable debugging])]) 177 | 178 | 179 | ########################## 180 | # Enable build 32bit 181 | # 182 | SP_ARG_ENABLE_BOOL( 183 | [build32], 184 | AS_HELP_STRING([--enable-build32], 185 | [SOCKPERF: force build 32bit (default=no)])) 186 | AS_IF([test "x$have_build32" = "xyes"], [ 187 | SP_CHECK_CXXFLAG_APPEND([OUR_CXXFLAGS], [-m32], 188 | [AC_MSG_ERROR([32bit build requested, but -m32 compiler flag does not work])])]) 189 | 190 | AC_SUBST([OUR_CXXFLAGS]) 191 | 192 | ########################## 193 | # TLS support 194 | # 195 | TLS_CAPABILITY_SETUP 196 | 197 | ##################################### 198 | # Checks for header files. 199 | # 200 | AC_CHECK_HEADERS( 201 | [arpa/inet.h fcntl.h netinet/in.h stdint.h stdlib.h \ 202 | string.h sys/ioctl.h sys/socket.h sys/time.h syslog.h \ 203 | termios.h unistd.h]) 204 | 205 | ##################################### 206 | # Checks for libraries. 207 | # 208 | AC_SEARCH_LIBS([clock_gettime], [rt], [], AC_MSG_ERROR([librt not found])) 209 | AC_SEARCH_LIBS([pthread_create], [pthread], [], AC_MSG_ERROR([libpthread not found])) 210 | AC_SEARCH_LIBS([backtrace], [execinfo], [], AC_MSG_ERROR([libexecinfo not found])) 211 | AC_SEARCH_LIBS([dlsym], [dl], [], AC_MSG_ERROR([libdl not found])) 212 | 213 | AC_CONFIG_FILES([ 214 | Makefile 215 | tools/Makefile 216 | tests/Makefile 217 | tests/gtest/Makefile 218 | doc/Doxyfile 219 | build/sockperf.spec 220 | ]) 221 | 222 | AC_OUTPUT 223 | 224 | AC_MSG_RESULT([ 225 | ${PACKAGE} ${VERSION} 226 | 227 | prefix: ${prefix} 228 | 229 | compiler: ${CXX} 230 | cppflags: ${CPPFLAGS} 231 | cxxflags: ${OUR_CXXFLAGS} ${CXXFLAGS} 232 | ldflags: ${LDFLAGS} 233 | 234 | doc: ${have_doc} 235 | test: ${have_test} 236 | tool: ${have_tool} 237 | vma_api: ${have_vma_api} 238 | xlio_api: ${have_xlio_api} 239 | debug: ${have_debug} 240 | ]) 241 | -------------------------------------------------------------------------------- /contrib/jenkins_tests/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eExl 2 | 3 | source $(dirname $0)/globals.sh 4 | 5 | echo "Checking for building with gcc ..." 6 | 7 | cd $WORKSPACE 8 | 9 | rm -rf ${build_dir} 10 | mkdir -p ${build_dir} 11 | cd ${build_dir} 12 | 13 | # Set symbolic links to default build and install 14 | ln -s "${build_dir}/0/install" "${install_dir}" 15 | 16 | build_list="\ 17 | default: \ 18 | debug:--enable-debug" 19 | 20 | build_tap=${WORKSPACE}/${prefix}/build.tap 21 | echo "1..$(echo $build_list | tr " " "\n" | wc -l)" > $build_tap 22 | 23 | test_id=0 24 | for build in $build_list; do 25 | IFS=':' read build_name build_option <<< "$build" 26 | mkdir -p ${build_dir}/${test_id} 27 | cd ${build_dir}/${test_id} 28 | test_exec='${WORKSPACE}/configure --prefix=${build_dir}/${test_id}/install $build_option $jenkins_test_custom_configure && make $make_opt install' 29 | do_check_result "$test_exec" "$test_id" "$build_name" "$build_tap" "${build_dir}/build-${test_id}" 30 | cd ${build_dir} 31 | test_id=$((test_id+1)) 32 | done 33 | 34 | 35 | echo "[${0##*/}]..................exit code = $rc" 36 | exit $rc 37 | -------------------------------------------------------------------------------- /contrib/jenkins_tests/compiler.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eExl 2 | 3 | source $(dirname $0)/globals.sh 4 | 5 | echo "Checking for compiler ..." 6 | 7 | cd $WORKSPACE 8 | 9 | rm -rf $compiler_dir 10 | mkdir -p $compiler_dir 11 | cd $compiler_dir 12 | 13 | compiler_list="clang:clang++:dev/clang-9.0.1 icc:icpc:intel/ics-18.0.4 icc:icpc:intel/ics-19.1.1 gcc:g++:dev/gcc-8.3.0 gcc:g++:dev/gcc-9.3.0 gcc:g++:dev/gcc-10.1.0" 14 | 15 | compiler_tap=${WORKSPACE}/${prefix}/compiler.tap 16 | echo "1..$(echo $compiler_list | tr " " "\n" | wc -l)" > $compiler_tap 17 | 18 | test_id=0 19 | for compiler in $compiler_list; do 20 | IFS=':' read cc cxx module <<< "$compiler" 21 | mkdir -p ${compiler_dir}/${test_id} 22 | cd ${compiler_dir}/${test_id} 23 | [ -z "$module" ] && test_name=$($cc --version | head -n 1) || test_name="$module" 24 | [ ! -z "$module" ] && do_module "$module" 25 | echo "======================================================" 26 | $cc --version 27 | echo 28 | test_exec='${WORKSPACE}/configure --prefix=$compiler_dir-$cc CC=$cc CXX=$cxx $jenkins_test_custom_configure && make $make_opt all' 29 | do_check_result "$test_exec" "$test_id" "$test_name" "$compiler_tap" "${compiler_dir}/compiler-${test_id}" 30 | [ ! -z "$module" ] && module unload "$module" 31 | cd ${compiler_dir} 32 | test_id=$((test_id+1)) 33 | done 34 | 35 | echo "[${0##*/}]..................exit code = $rc" 36 | exit $rc 37 | -------------------------------------------------------------------------------- /contrib/jenkins_tests/copyright-check-map.yaml: -------------------------------------------------------------------------------- 1 | general: 2 | exclude: 3 | - "\\.git.*" 4 | - "\\.ci.*" 5 | - "\\.dockers.*" 6 | - "build.*" 7 | - "contrib/jenkins_tests.*" 8 | - "contrib/valgrind.*" 9 | - "contrib/xlio-bench.*" 10 | - "contrib/.*\\.sh" 11 | - "debian.*" 12 | - "doc.*" 13 | - ".*\\.pdf" 14 | - ".*Makefile\\.am" 15 | - ".*CHANGES" 16 | - ".*LICENSE" 17 | - ".*authors" 18 | - ".*README" 19 | - ".*version" 20 | - ".*copying" 21 | - ".*news" 22 | - ".*\\.md" 23 | - ".*configure\\.ac" 24 | - ".*Jenkinsfile" 25 | - ".*\\.docx" 26 | - ".*\\.txt" 27 | - ".*\\.log" 28 | - ".*\\.cmake" 29 | - ".*\\.png" 30 | - ".*\\.conf" 31 | - ".*\\.awk" 32 | - ".*\\.pm" 33 | - ".*autogen\\.sh" 34 | - ".*\\.sln" 35 | - ".*\\.vcxproj" 36 | - ".*\\.vcxproj.filters" 37 | - ".*\\.props" 38 | - ".*avner-test-orig" 39 | - ".*\\.m4" 40 | 41 | dual_gpl_2_bsd_3: 42 | include: 43 | - ".*" 44 | exclude: 45 | - ".*tests/gtest/common/tap\\.h" 46 | - ".*tests/gtest/common/gtest\\.h" 47 | - ".*tests/gtest/common/gtest-all\\.cpp" 48 | - ".*tests/gtest/googletest/src/.*" 49 | - ".*tests/gtest/googletest/include/.*" 50 | -------------------------------------------------------------------------------- /contrib/jenkins_tests/copyrights.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xeEl 2 | 3 | source $(dirname $0)/globals.sh 4 | 5 | if [ -z "$WORKSPACE" ]; then 6 | echo "ERROR: WORKSPACE variable is empty" 7 | exit 1 8 | fi 9 | 10 | if [ ! -d "$WORKSPACE" ]; then 11 | echo "ERROR: $WORKSPACE does not exist" 12 | exit 1 13 | fi 14 | 15 | HEADER_CHECK_TOOL=/opt/nvidia/header_check.py 16 | if [ ! -f "${HEADER_CHECK_TOOL}" ]; then 17 | echo "ERROR: ${HEADER_CHECK_TOOL} doesn't exist!" 18 | exit 1 19 | fi 20 | 21 | cpp_files=' "extensions": [".c", ".cc", ".cpp", "c++", ".h", ".hpp", ".cs", ".inl", ".l", ".y"],' 22 | sed -i "s/.*\"extensions\": \[\"\.c\".*/$cpp_files/g" /opt/nvidia/ProjectConfig/header-types.json 23 | 24 | cat /opt/nvidia/ProjectConfig/header-types.json 25 | 26 | ${HEADER_CHECK_TOOL} \ 27 | --config ${WORKSPACE}/contrib/jenkins_tests/copyright-check-map.yaml \ 28 | --path ${WORKSPACE} \ 29 | --git-repo ${WORKSPACE} | tee copyrights.log 30 | exit_code=$? 31 | echo "exit_code=${exit_code}" 32 | # Correct error code is not returned by the script 33 | set +eE 34 | grep -rn ERROR copyrights.log 35 | exit_code=$? 36 | set -eE 37 | if [ ${exit_code} -eq 0 ]; then 38 | echo "Please refer to https://confluence.nvidia.com/pages/viewpage.action?pageId=788418816" 39 | ${HEADER_CHECK_TOOL} \ 40 | --config contrib/jenkins_tests/copyright-check-map.yaml \ 41 | --path ${WORKSPACE} \ 42 | --repair \ 43 | --git-repo ${WORKSPACE} | tee copyrights_repair.log 44 | # create list of modified files 45 | files=$(git status | grep 'modified:' | awk '{print $NF}' ) 46 | mkdir $WORKSPACE/repaired_files/ 47 | cp --parents $files $WORKSPACE/repaired_files/ 48 | cd $WORKSPACE/repaired_files/ 49 | tar -czf $WORKSPACE/copyright_repaired_files.tar.gz . 50 | exit 1 51 | fi 52 | -------------------------------------------------------------------------------- /contrib/jenkins_tests/cov.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xeEl 2 | 3 | source $(dirname $0)/globals.sh 4 | 5 | echo "Checking for coverity ..." 6 | 7 | do_module "tools/cov-2020.06" 8 | 9 | cd $WORKSPACE 10 | 11 | rm -rf $cov_dir 12 | mkdir -p $cov_dir 13 | cd $cov_dir 14 | 15 | cov_exclude_file_list="tests" 16 | 17 | cov_build_id="cov_build_${BUILD_NUMBER}" 18 | cov_build="${cov_dir}/$cov_build_id" 19 | 20 | set +eE 21 | 22 | eval "${WORKSPACE}/configure --prefix=${cov_dir}/install $jenkins_test_custom_configure > ${cov_dir}/cov.log 2>&1" 23 | make clean >> "${cov_dir}/cov.log" 2>&1 24 | sleep 1 25 | eval "cov-configure --config ${cov_dir}/coverity_config.xml --gcc >> ${cov_dir}/cov.log 2>&1" 26 | sleep 1 27 | eval "cov-build --config ${cov_dir}/coverity_config.xml --dir ${cov_build} make $make_opt >> ${cov_dir}/cov.log 2>&1" 28 | rc=$(($rc+$?)) 29 | 30 | for excl in $cov_exclude_file_list; do 31 | cov-manage-emit --config ${cov_dir}/coverity_config.xml --dir ${cov_build} --tu-pattern "file('$excl')" delete >> "${cov_dir}/cov.log" 2>&1 32 | sleep 1 33 | done 34 | 35 | # List of translated units 36 | eval "cov-manage-emit --config ${cov_dir}/coverity_config.xml --dir ${cov_build} list >> ${cov_dir}/cov.log 2>&1" 37 | sleep 1 38 | 39 | eval "cov-analyze --config ${cov_dir}/coverity_config.xml \ 40 | --all --aggressiveness-level low \ 41 | --enable-fnptr --fnptr-models --paths 20000 \ 42 | --disable-parse-warnings \ 43 | --dir ${cov_build}" 44 | rc=$(($rc+$?)) 45 | 46 | set -eE 47 | 48 | nerrors=$(cov-format-errors --dir ${cov_build} | awk '/Processing [0-9]+ errors?/ { print $2 }') 49 | rc=$(($rc+$nerrors)) 50 | 51 | index_html=$(cd $cov_build && find . -name index.html | cut -c 3-) 52 | cov_file="$cov_build/${index_html}" 53 | 54 | coverity_tap=${WORKSPACE}/${prefix}/coverity.tap 55 | 56 | echo 1..1 > $coverity_tap 57 | if [ $rc -gt 0 ]; then 58 | echo "not ok 1 Coverity Detected $nerrors failures at ${cov_file}" >> $coverity_tap 59 | do_err "coverity" "${cov_build}/output/summary.txt" 60 | else 61 | echo ok 1 Coverity found no issues >> $coverity_tap 62 | fi 63 | 64 | module unload "tools/cov-2020.06" 65 | 66 | do_archive "$( find ${cov_build}/output -type f -name "*.txt" -or -name "*.html" -or -name "*.xml" )" 67 | 68 | echo "[${0##*/}]..................exit code = $rc" 69 | exit $rc 70 | -------------------------------------------------------------------------------- /contrib/jenkins_tests/cppcheck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xeEl 2 | 3 | source $(dirname $0)/globals.sh 4 | 5 | echo "Checking for cppcheck ..." 6 | 7 | tool_app=cppcheck 8 | 9 | # This unit requires cppcheck so check for existence 10 | if [ $(command -v ${tool_app} >/dev/null 2>&1 || echo $?) ]; then 11 | set +e 12 | eval "timeout -s SIGKILL 20s https://github.com/danmar/cppcheck.git cppcheck " > /dev/null 2>&1 13 | if [ $? -eq 0 ]; then 14 | eval "cd cppcheck && checkout 2.1 " > /dev/null 2>&1 15 | if [ $? -eq 0 ]; then 16 | eval "make $make_opt FILESDIR=$PWD HAVE_RULES=yes " > /dev/null 2>&1 17 | if [ $? -eq 0 ]; then 18 | tool_app=$PWD/cppcheck 19 | fi 20 | fi 21 | cd .. 22 | fi 23 | set -e 24 | 25 | if [ $(command -v ${tool_app} >/dev/null 2>&1 || echo $?) ]; then 26 | echo "[SKIP] cppcheck tool does not exist" 27 | exit 1 28 | fi 29 | fi 30 | 31 | echo $(${tool_app} --version) 32 | 33 | cd $WORKSPACE 34 | 35 | rm -rf $cppcheck_dir 36 | mkdir -p $cppcheck_dir 37 | cd $cppcheck_dir 38 | 39 | ${WORKSPACE}/configure $jenkins_test_custom_configure > "${cppcheck_dir}/cppcheck.log" 2>&1 40 | 41 | set +eE 42 | eval "find ${WORKSPACE}/src -name '*.h' -o -name '*.cpp' -o -name '*.c' -o -name '*.hpp' -o -name '*.inl' | \ 43 | ${tool_app} --std=c99 --std=c++11 --language=c++ --force --enable=information \ 44 | -I${WORKSPACE}/src \ 45 | --inline-suppr --suppress=memleak:config_parser.y \ 46 | --template='{severity}: {id}: {file}:{line}: {message}' \ 47 | --file-list=- 2> ${cppcheck_dir}/cppcheck.err 1> ${cppcheck_dir}/cppcheck.log" 48 | rc=$(($rc+$?)) 49 | set -eE 50 | 51 | nerrors=$(cat ${cppcheck_dir}/cppcheck.err | grep error | wc -l) 52 | rc=$(($rc+$nerrors)) 53 | 54 | cppcheck_tap=${WORKSPACE}/${prefix}/cppcheck.tap 55 | 56 | echo 1..1 > $cppcheck_tap 57 | if [ $rc -gt 0 ]; then 58 | echo "not ok 1 cppcheck Detected $nerrors failures # ${cppcheck_dir}/cppcheck.err" >> $cppcheck_tap 59 | do_err "cppcheck" "${cppcheck_dir}/cppcheck.err" 60 | info="cppcheck found $nerrors errors" 61 | status="error" 62 | else 63 | echo ok 1 cppcheck found no issues >> $cppcheck_tap 64 | info="cppcheck found no issues" 65 | status="success" 66 | fi 67 | 68 | do_archive "${cppcheck_dir}/cppcheck.err" "${cppcheck_dir}/cppcheck.log" 69 | 70 | echo "[${0##*/}]..................exit code = $rc" 71 | exit $rc 72 | -------------------------------------------------------------------------------- /contrib/jenkins_tests/csbuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xeEl 2 | 3 | source $(dirname $0)/globals.sh 4 | 5 | echo "Checking for csbuild ..." 6 | 7 | # This unit requires csbuild so check for existence 8 | if [ $(command -v csbuild >/dev/null 2>&1 || echo $?) ]; then 9 | echo "[SKIP] csbuild tool does not exist" 10 | exit 0 11 | fi 12 | 13 | # There is a bug in gcc less than 4.5 14 | if [ $(echo `gcc -dumpversion | cut -f1-2 -d.` \< 4.5 | bc ) -eq 1 ]; then 15 | echo "[SKIP] csbuild tool can not launch on this gcc" 16 | exit 0 17 | fi 18 | 19 | cd $WORKSPACE 20 | 21 | rm -rf $csbuild_dir 22 | mkdir -p $csbuild_dir 23 | cd $csbuild_dir 24 | 25 | set +eE 26 | 27 | ${WORKSPACE}/configure --prefix=${csbuild_dir}/install $jenkins_test_custom_configure > "${csbuild_dir}/csbuild.log" 2>&1 28 | make clean 29 | 30 | eval "csbuild --cswrap-timeout=180 --no-clean -c \"make \" > \"${csbuild_dir}/csbuild.log\" 2>&1" 31 | rc=$(($rc+$?)) 32 | 33 | eval "csgrep --quiet --event 'error|warning' \ 34 | --path '^${WORKSPACE}' --strip-path-prefix '${WORKSPACE}' \ 35 | --remove-duplicates '${csbuild_dir}/csbuild.log' | \ 36 | csgrep --invert-match --path '^ksh-.*[0-9]+\.c$' | \ 37 | csgrep --invert-match --checker CLANG_WARNING --msg \"internal warning\" | \ 38 | csgrep --invert-match --checker COMPILER_WARNING --event \"warning\[-Woverloaded-virtual\]\" | \ 39 | csgrep --invert-match --checker COMPILER_WARNING --event \"warning\[-Wformat-nonliteral\]\" | \ 40 | csgrep --invert-match --checker CPPCHECK_WARNING --event 'preprocessorErrorDirective|syntaxError' | \ 41 | csgrep --mode=grep --invert-match --event 'internal warning' --prune-events=1 | \ 42 | cssort --key=path > ${csbuild_dir}/csbuild.err 2>&1 \ 43 | " 44 | eval "grep 'timed out' ${csbuild_dir}/csbuild.log >> ${csbuild_dir}/csbuild.err 2>&1" 45 | 46 | set -eE 47 | 48 | nerrors=$(cat ${csbuild_dir}/csbuild.err | grep 'Error:\|error:' | wc -l) 49 | rc=$(($rc+$nerrors)) 50 | 51 | csbuild_tap=${WORKSPACE}/${prefix}/csbuild.tap 52 | 53 | echo 1..1 > $csbuild_tap 54 | if [ $rc -gt 0 ]; then 55 | echo "not ok 1 csbuild Detected $nerrors failures # ${csbuild_dir}/csbuild.err" >> $csbuild_tap 56 | do_err "csbuild" "${csbuild_dir}/csbuild.err" 57 | info="csbuild found $nerrors errors" 58 | status="error" 59 | else 60 | echo ok 1 csbuild found no issues >> $csbuild_tap 61 | info="csbuild found no issues" 62 | status="success" 63 | fi 64 | 65 | do_archive "${csbuild_dir}/csbuild.err" "${csbuild_dir}/csbuild.log" 66 | 67 | echo "[${0##*/}]..................exit code = $rc" 68 | exit $rc 69 | -------------------------------------------------------------------------------- /contrib/jenkins_tests/gtest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eExl 2 | 3 | source $(dirname $0)/globals.sh 4 | 5 | echo "Checking for gtest ..." 6 | 7 | # Check dependencies 8 | if [ $(test -d ${install_dir} >/dev/null 2>&1 || echo $?) ]; then 9 | echo "[SKIP] Not found ${install_dir} : build should be done before this stage" 10 | exit 1 11 | fi 12 | 13 | cd $WORKSPACE 14 | 15 | rm -rf $gtest_dir 16 | mkdir -p $gtest_dir 17 | cd $gtest_dir 18 | 19 | gtest_app="$PWD/tests/gtest/gtest" 20 | gtest_lib=$install_dir/lib/${prj_lib} 21 | 22 | set +eE 23 | 24 | ${WORKSPACE}/configure --prefix=$install_dir --enable-test 25 | make -C tests/gtest 26 | rc=$(($rc+$?)) 27 | 28 | $timeout_exe env GTEST_TAP=2 $gtest_app --gtest_output=xml:${WORKSPACE}/${prefix}/test-basic.xml 29 | rc=$(($rc+$?)) 30 | 31 | set -eE 32 | 33 | for f in $(find $gtest_dir -name '*.tap') 34 | do 35 | cp $f ${WORKSPACE}/${prefix}/gtest-$(basename $f .tap).tap 36 | done 37 | 38 | echo "[${0##*/}]..................exit code = $rc" 39 | exit $rc 40 | -------------------------------------------------------------------------------- /contrib/jenkins_tests/rpm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eExl 2 | 3 | source $(dirname $0)/globals.sh 4 | 5 | echo "Checking for rpm ..." 6 | 7 | cd $WORKSPACE 8 | 9 | rm -rf $rpm_dir 10 | mkdir -p $rpm_dir 11 | cd $rpm_dir 12 | 13 | rpm_tap=${WORKSPACE}/${prefix}/rpm.tap 14 | 15 | cd ${build_dir}/0 16 | 17 | if [ -x /usr/bin/dpkg-buildpackage ]; then 18 | echo "Build on debian" 19 | set +e 20 | ${WORKSPACE}/build/build-rpm.sh "$rpm_dir" 2> "${rpm_dir}/rpm.err" 1> "${rpm_dir}/rpm.log" 21 | rc=$((rc + $?)) 22 | ${WORKSPACE}/build/build-rpm-to-deb.sh $(find $rpm_dir/SRPMS -maxdepth 1 -type f -name "sockperf*.src.rpm") 2> "${rpm_dir}/rpm-deb.err" 1> "${rpm_dir}/rpm-deb.log" 23 | rc=$((rc + $?)) 24 | do_archive "${rpm_dir}/*.err" "${rpm_dir}/*.log" 25 | set -e 26 | echo "1..1" > $rpm_tap 27 | if [ $rc -gt 0 ]; then 28 | echo "not ok 1 Debian package" >> $rpm_tap 29 | else 30 | echo ok 1 Debian package >> $rpm_tap 31 | fi 32 | else 33 | echo "Build rpm" 34 | set +e 35 | ${WORKSPACE}/build/build-rpm.sh "$rpm_dir" 2> "${rpm_dir}/rpm.err" 1> "${rpm_dir}/rpm.log" 36 | rc=$((rc + $?)) 37 | do_archive "${rpm_dir}/*.err" "${rpm_dir}/*.log" 38 | set -e 39 | echo "1..1" > $rpm_tap 40 | if [ $rc -gt 0 ]; then 41 | echo "not ok 1 rpm package" >> $rpm_tap 42 | else 43 | echo ok 1 rpm package >> $rpm_tap 44 | fi 45 | fi 46 | 47 | 48 | echo "[${0##*/}]..................exit code = $rc" 49 | exit $rc 50 | -------------------------------------------------------------------------------- /contrib/jenkins_tests/style.conf: -------------------------------------------------------------------------------- 1 | ## This config file is only relevant for clang-format version 9.0.0 2 | ## 3 | ## Examples of each format style can be found on the in the clang-format documentation 4 | ## See: https://clang.llvm.org/docs/ClangFormatStyleOptions.html for details of each option 5 | ## 6 | ## The clang-format binaries can be downloaded as part of the clang binary distributions 7 | ## from http://releases.llvm.org/download.html 8 | ## 9 | --- 10 | # C Language specifics 11 | Language: Cpp 12 | 13 | BasedOnStyle: WebKit 14 | AccessModifierOffset: -4 15 | 16 | # Align parameters on the open bracket 17 | # someLongFunction(argument1, 18 | # argument2); 19 | AlignAfterOpenBracket: Align 20 | 21 | # Align operands of binary and ternary expressions 22 | # int aaa = bbbbbbbbbbb + 23 | # cccccc; 24 | AlignOperands: false 25 | 26 | # Don't align trailing comments 27 | # int a; // Comment a 28 | # int b = 2; // Comment b 29 | AlignTrailingComments: false 30 | 31 | AlignConsecutiveMacros: true 32 | 33 | AllowAllArgumentsOnNextLine: false 34 | 35 | # By default don't allow putting parameters onto the next line 36 | # myFunction(foo, bar, baz); 37 | AllowAllParametersOfDeclarationOnNextLine: false 38 | 39 | # Don't allow short braced statements to be on a single line 40 | # if (a) not if (a) return; 41 | # return; 42 | AllowShortBlocksOnASingleLine: false 43 | 44 | AllowShortCaseLabelsOnASingleLine: false 45 | AllowShortFunctionsOnASingleLine: InlineOnly 46 | AllowShortIfStatementsOnASingleLine: false 47 | AllowShortLoopsOnASingleLine: false 48 | 49 | # By default don't add a line break after the return type of top-level functions 50 | # int foo(); 51 | AlwaysBreakAfterReturnType: None 52 | 53 | AlwaysBreakBeforeMultilineStrings: false 54 | AlwaysBreakTemplateDeclarations: false 55 | 56 | # Pack as many parameters or arguments onto the same line as possible 57 | # int myFunction(int aaaaaaaaaaaa, int bbbbbbbb, 58 | # int cccc); 59 | BinPackArguments: true 60 | BinPackParameters: true 61 | 62 | BreakBeforeBraces: Custom 63 | BraceWrapping: 64 | AfterClass: false 65 | AfterControlStatement: false 66 | AfterEnum: false 67 | AfterFunction: true 68 | AfterNamespace: false 69 | AfterStruct: false 70 | AfterUnion: false 71 | AfterExternBlock: false 72 | BeforeCatch: false 73 | BeforeElse: false 74 | IndentBraces: false 75 | SplitEmptyFunction: true 76 | SplitEmptyRecord: true 77 | SplitEmptyNamespace: true 78 | 79 | # Break after operators 80 | # int valuve = aaaaaaaaaaaaa + 81 | # bbbbbb - 82 | # ccccccccccc; 83 | BreakBeforeBinaryOperators: false 84 | BreakBeforeInheritanceComma: false 85 | BreakBeforeTernaryOperators: true 86 | BreakConstructorInitializersBeforeComma: true 87 | BreakConstructorInitializers: BeforeColon 88 | 89 | # Don't break string literals 90 | BreakStringLiterals: true 91 | 92 | ColumnLimit: 100 93 | CompactNamespaces: false 94 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 95 | ConstructorInitializerIndentWidth: 4 96 | ContinuationIndentWidth: 4 97 | 98 | # Insert a space after '{' and before '}' in struct initializers 99 | Cpp11BracedListStyle: true 100 | 101 | DerivePointerAlignment: false 102 | DisableFormat: false 103 | ExperimentalAutoDetectBinPacking: false 104 | FixNamespaceComments: true 105 | IncludeBlocks: Preserve 106 | IndentCaseLabels: false 107 | IndentWidth: 4 108 | IndentWrappedFunctionNames: false 109 | 110 | # The maximum number of consecutive empty lines to keep. 111 | MaxEmptyLinesToKeep: 1 112 | 113 | # The indentation used for namespaces. 114 | NamespaceIndentation: None 115 | 116 | # Penalties 117 | # This decides what order things should be done if a line is too long 118 | PenaltyBreakAssignment: 2 119 | PenaltyBreakBeforeFirstCallParameter: 1 120 | PenaltyBreakComment: 300 121 | PenaltyBreakFirstLessLess: 120 122 | PenaltyBreakString: 1000 123 | PenaltyExcessCharacter: 1000000 124 | PenaltyReturnTypeOnItsOwnLine: 200 125 | 126 | # Align pointer to the right 127 | # int *a; 128 | PointerAlignment: Right 129 | 130 | ReflowComments: true 131 | SortIncludes: false 132 | SortUsingDeclarations: true 133 | SpaceAfterTemplateKeyword: true 134 | 135 | # Insert spaces before and after assignment operators 136 | # int a = 5; not int a=5; 137 | # a += 42; a+=42; 138 | SpaceBeforeAssignmentOperators: true 139 | 140 | # Put a space before opening parentheses only after control statement keywords. 141 | # void f() { 142 | # if (true) { 143 | # f(); 144 | # } 145 | # } 146 | SpaceBeforeParens: ControlStatements 147 | 148 | # Don't insert spaces inside empty '()' 149 | SpaceInEmptyParentheses: false 150 | 151 | # The number of spaces before trailing line comments (// - comments). 152 | # This does not affect trailing block comments (/* - comments). 153 | SpacesBeforeTrailingComments: 1 154 | 155 | # The space to use for template argument lists. 156 | SpacesInAngles: false 157 | 158 | # Don't insert spaces inside container literals 159 | # var arr = [1, 2, 3]; not var arr = [ 1, 2, 3 ]; 160 | SpacesInContainerLiterals: false 161 | 162 | # Don't insert spaces in casts 163 | # x = (int32) y; not x = ( int32 ) y; 164 | SpacesInCStyleCastParentheses: false 165 | 166 | # Don't insert spaces after '(' or before ')' 167 | # f(arg); not f( arg ); 168 | SpacesInParentheses: false 169 | 170 | # Don't insert spaces after '[' or before ']' 171 | # int a[5]; not int a[ 5 ]; 172 | SpacesInSquareBrackets: false 173 | 174 | # Parse and format C++ constructs compatible with this standard. 175 | Standard: Cpp11 176 | 177 | TabWidth: 4 178 | UseTab: Never 179 | ... 180 | -------------------------------------------------------------------------------- /contrib/jenkins_tests/style.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xeEl 2 | 3 | source $(dirname $0)/globals.sh 4 | 5 | echo "Checking for codying style ..." 6 | 7 | do_module "dev/clang-9.0.1" 8 | 9 | cd $WORKSPACE 10 | 11 | rm -rf $style_dir 12 | mkdir -p $style_dir 13 | cd $style_dir 14 | 15 | test_app="clang-format" 16 | 17 | if [ $(command -v $test_app >/dev/null 2>&1 || echo $?) ]; then 18 | echo can not find $test_app 19 | exit 1 20 | fi 21 | 22 | style_tap=${WORKSPACE}/${prefix}/style_test.tap 23 | rm -rf $style_tap 24 | ln -sf $WORKSPACE/contrib/jenkins_tests/style.conf $WORKSPACE/.clang-format 25 | 26 | 27 | check_files=$(find $WORKSPACE/src/ -name '*.c' -o -name '*.cpp' -o -name '*.h') 28 | 29 | i=0 30 | nerrors=0 31 | 32 | for file in $check_files; do 33 | set +eE 34 | style_diff="${style_dir}/$(basename ${file}).diff" 35 | eval "env $test_app -style=file \ 36 | ${file} \ 37 | | diff -u ${file} - | sed -e '1s|-- |--- a/|' -e '2s|+++ -|+++ b/$file|' \ 38 | > ${style_diff} 2>&1" 39 | [ -s ${style_diff} ] 40 | ret=$((1-$?)) 41 | nerrors=$((nerrors+ret)) 42 | set -eE 43 | 44 | file=$(basename ${file}) 45 | if [ $ret -gt 0 ]; then 46 | i=$((i+1)) 47 | echo "not ok $i $file # See: ${file}.diff" >> $style_tap 48 | else 49 | rm -rf ${style_diff} 50 | fi 51 | done 52 | if [ $nerrors -eq 0 ]; then 53 | echo "1..1" > $style_tap 54 | echo "ok 1 all $(echo "$check_files" | wc -l) files" >> $style_tap 55 | else 56 | mv $style_tap ${style_tap}.backup 57 | echo "1..$(cat ${style_tap}.backup | wc -l)" > $style_tap 58 | cat ${style_tap}.backup >> $style_tap 59 | rm -rf ${style_tap}.backup 60 | fi 61 | rc=$(($rc+$nerrors)) 62 | 63 | module unload "dev/clang-9.0.1" 64 | 65 | do_archive "${style_dir}/*.diff" 66 | 67 | echo "[${0##*/}]..................exit code = $rc" 68 | exit $rc 69 | -------------------------------------------------------------------------------- /contrib/jenkins_tests/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eExl 2 | 3 | source $(dirname $0)/globals.sh 4 | 5 | echo "Checking for test ..." 6 | if [ $(test -d ${install_dir} >/dev/null 2>&1 || echo $?) ]; then 7 | echo "[SKIP] Not found ${install_dir} : build should be done before this stage" 8 | exit 1 9 | fi 10 | 11 | if [ $(command -v ibdev2netdev >/dev/null 2>&1 || echo $?) ]; then 12 | echo "[SKIP] ibdev2netdev tool does not exist" 13 | exit 0 14 | fi 15 | 16 | cd $WORKSPACE 17 | 18 | rm -rf $test_dir 19 | mkdir -p $test_dir 20 | cd $test_dir 21 | 22 | test_app="$install_dir/bin/sockperf" 23 | 24 | if [ $(command -v $test_app >/dev/null 2>&1 || echo $?) ]; then 25 | echo can not find $test_app 26 | exit 1 27 | fi 28 | 29 | ip=$(do_get_ip 'eth') 30 | if [ -n "$ip" ]; then 31 | test_ip_list="${test_ip_list} eth:$ip" 32 | fi 33 | ip=$(do_get_ip 'eth6') 34 | if [ -n "$ip" ]; then 35 | test_ip_list="${test_ip_list} eth6:$ip" 36 | fi 37 | 38 | if [ -z "$test_ip_list" ]; then 39 | echo "no IP addresses detected" 40 | rc=1 41 | fi 42 | 43 | test_list="tcp-pp tcp-tp tcp-ul udp-pp udp-tp udp-ul" 44 | nerrors=0 45 | 46 | for test_link in $test_ip_list; do 47 | for test in $test_list; do 48 | IFS=':' read test_in test_ip <<< "$test_link" 49 | test_name=${test_in}-${test} 50 | test_tap=${WORKSPACE}/${prefix}/test-${test_name}.tap 51 | 52 | $timeout_exe ${WORKSPACE}/tests/verifier/verifier.pl -a ${test_app} \ 53 | -t ${test} -s ${test_ip} -l ${test_dir}/${test_name}.log \ 54 | --progress=0 55 | 56 | # exclude multicast tests from final result 57 | # because they are not valid when server/client on the same node 58 | grep -e 'PASS' -e 'FAIL' ${test_dir}/${test_name}.dump | grep -v 'multicast' > ${test_dir}/${test_name}.tmp 59 | 60 | do_archive "${test_dir}/${test_name}.dump" "${test_dir}/${test_name}.log" 61 | 62 | echo "1..$(wc -l < ${test_dir}/${test_name}.tmp)" > $test_tap 63 | 64 | v1=1 65 | while read line; do 66 | if [[ $(echo $line | cut -f1 -d' ') =~ 'PASS' ]]; then 67 | v0='ok' 68 | v2=$(echo $line | sed 's/PASS //') 69 | else 70 | v0='not ok' 71 | v2=$(echo $line | sed 's/FAIL //') 72 | nerrors=$((nerrors+1)) 73 | fi 74 | 75 | echo -e "$v0 ${test_in}: $v2" >> $test_tap 76 | v1=$(($v1+1)) 77 | done < ${test_dir}/${test_name}.tmp 78 | rm -f ${test_dir}/${test_name}.tmp 79 | done 80 | done 81 | 82 | 83 | test_ip_list="local:/tmp/sockperf-test-$$" 84 | test_list="uds" 85 | 86 | for test_link in $test_ip_list; do 87 | for test in $test_list; do 88 | IFS=':' read test_in test_address <<< "$test_link" 89 | test_name=${test_in}-${test} 90 | test_tap=${WORKSPACE}/${prefix}/test-${test_name}.tap 91 | 92 | $timeout_exe ${WORKSPACE}/tests/verifier/verifier.pl -a ${test_app} \ 93 | -t ${test} -s ${test_address} -l ${test_dir}/${test_name}.log \ 94 | --progress=0 95 | 96 | do_archive "${test_dir}/${test_name}.dump" "${test_dir}/${test_name}.log" 97 | 98 | echo "1..$(wc -l < ${test_dir}/${test_name}.tmp)" > $test_tap 99 | 100 | v1=1 101 | while read line; do 102 | if [[ $(echo $line | cut -f1 -d' ') =~ 'PASS' ]]; then 103 | v0='ok' 104 | v2=$(echo $line | sed 's/PASS //') 105 | else 106 | v0='not ok' 107 | v2=$(echo $line | sed 's/FAIL //') 108 | nerrors=$((nerrors+1)) 109 | fi 110 | 111 | echo -e "$v0 ${test_in}: $v2" >> $test_tap 112 | v1=$(($v1+1)) 113 | done < ${test_dir}/${test_name}.tmp 114 | rm -f ${test_dir}/${test_name}.tmp 115 | 116 | done 117 | done 118 | 119 | rc=$(($rc+$nerrors)) 120 | 121 | echo "[${0##*/}]..................exit code = $rc" 122 | exit $rc 123 | -------------------------------------------------------------------------------- /contrib/test_jenkins.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -El 2 | # 3 | # Testing script for SOCKPERF, to run from Jenkins CI 4 | # 5 | # Copyright (C) Mellanox Technologies Ltd. 2011-2024. ALL RIGHTS RESERVED. 6 | # 7 | # See file LICENSE for terms. 8 | # 9 | # 10 | # Environment variables set by Jenkins CI: 11 | # - WORKSPACE : path to working directory 12 | # - BUILD_NUMBER : jenkins build number 13 | # - TARGET : target configuration 14 | # 15 | 16 | echo "======================================================" 17 | echo 18 | echo "# starting on host ---------> ${HOSTNAME} " 19 | echo "# arguments called with ----> ${@} " 20 | echo "# path to me ---------------> ${0} " 21 | echo "# parent path --------------> ${0%/*} " 22 | echo "# name ---------------------> ${0##*/} " 23 | echo 24 | 25 | PATH=${PATH}:/hpc/local/bin:/hpc/local/oss/vma/ 26 | MODULEPATH=${MODULEPATH}:/hpc/local/etc/modulefiles 27 | 28 | echo 29 | for f in autoconf automake libtool ; do $f --version | head -1 ; done 30 | echo 31 | 32 | rel_path=$(dirname $0) 33 | abs_path=$(readlink -f $rel_path) 34 | 35 | echo 36 | echo "# rel_path -----------------> ${rel_path} " 37 | echo "# abs_path -----------------> ${abs_path} " 38 | echo 39 | 40 | source ${abs_path}/jenkins_tests/globals.sh 41 | 42 | # Cleanup target folder 43 | # 44 | cd $WORKSPACE > /dev/null 2>&1 45 | 46 | if [ $BUILD_NUMBER -le 0 ]; then 47 | rm -rf ${WORKSPACE}/${prefix} > /dev/null 2>&1 48 | rm -rf autom4te.cache > /dev/null 2>&1 49 | fi 50 | 51 | echo 52 | echo "# WORKSPACE ----------------> ${WORKSPACE} " 53 | echo "# BUILD_NUMBER -------------> ${BUILD_NUMBER} " 54 | echo "# TARGET -------------------> ${TARGET} " 55 | echo 56 | 57 | # Values: none, fail, always 58 | # 59 | jenkins_opt_artifacts=${jenkins_opt_artifacts:="always"} 60 | 61 | # Values: 0..N test (max 100) 62 | # 63 | jenkins_opt_exit=${jenkins_opt_exit:="6"} 64 | 65 | # Test scenario list 66 | # 67 | jenkins_test_build=${jenkins_test_build:="no"} 68 | 69 | jenkins_test_compiler=${jenkins_test_compiler:="no"} 70 | jenkins_test_rpm=${jenkins_test_rpm:="no"} 71 | jenkins_test_copyrights=${jenkins_test_copyrights:="no"} 72 | jenkins_test_cov=${jenkins_test_cov:="no"} 73 | jenkins_test_cppcheck=${jenkins_test_cppcheck:="no"} 74 | jenkins_test_csbuild=${jenkins_test_csbuild:="no"} 75 | jenkins_test_run=${jenkins_test_run:="no"} 76 | jenkins_test_gtest=${jenkins_test_gtest:="no"} 77 | jenkins_test_style=${jenkins_test_style:="no"} 78 | 79 | 80 | 81 | echo 82 | for var in ${!jenkins_test_@}; do 83 | printf "%s%q\n" "$var=" "${!var}" 84 | done 85 | echo 86 | 87 | # check go/not go 88 | # 89 | do_check_env 90 | 91 | # set predefined configuration settings and extra options 92 | # that depend on environment 93 | # 94 | TARGET=${TARGET:=all} 95 | i=0 96 | if [ "$TARGET" == "all" -o "$TARGET" == "default" ]; then 97 | target_list[$i]="default: " 98 | i=$((i+1)) 99 | fi 100 | 101 | echo 102 | echo "======================================================" 103 | set -xe 104 | 105 | if [ ! -e configure ] && [ -e autogen.sh ]; then 106 | ./autogen.sh -s 107 | fi 108 | 109 | for target_v in "${target_list[@]}"; do 110 | ret=0 111 | IFS=':' read target_name target_option <<< "$target_v" 112 | 113 | export jenkins_test_artifacts="${WORKSPACE}/${prefix}/sockperf-${BUILD_NUMBER}-${HOSTNAME}-${target_name}" 114 | export jenkins_test_custom_configure="${jenkins_test_custom_configure} ${target_option}" 115 | export jenkins_target="${target_name}" 116 | set +x 117 | echo "======================================================" 118 | echo " Checking for [${jenkins_target}] target" 119 | echo " Checking for [${jenkins_test_custom_configure}] options" 120 | echo "======================================================" 121 | set -x 122 | 123 | # check building and exit immediately in case failure 124 | # 125 | if [ "$jenkins_test_build" = "yes" ]; then 126 | $WORKSPACE/contrib/jenkins_tests/build.sh 127 | ret=$? 128 | if [ $ret -gt 0 ]; then 129 | do_err "case: [build: ret=$ret]" 130 | fi 131 | rc=$((rc + $ret)) 132 | fi 133 | 134 | # check other units w/o forcing exiting 135 | # 136 | set +e 137 | if [ 1 -lt "$jenkins_opt_exit" -o "$rc" -eq 0 ]; then 138 | if [ "$jenkins_test_compiler" = "yes" ]; then 139 | $WORKSPACE/contrib/jenkins_tests/compiler.sh 140 | ret=$? 141 | if [ $ret -gt 0 ]; then 142 | do_err "case: [compiler: ret=$ret]" 143 | fi 144 | rc=$((rc + $ret)) 145 | fi 146 | fi 147 | if [ 2 -lt "$jenkins_opt_exit" -o "$rc" -eq 0 ]; then 148 | if [ "$jenkins_test_rpm" = "yes" ]; then 149 | $WORKSPACE/contrib/jenkins_tests/rpm.sh 150 | ret=$? 151 | if [ $ret -gt 0 ]; then 152 | do_err "case: [rpm: ret=$ret]" 153 | fi 154 | rc=$((rc + $ret)) 155 | fi 156 | fi 157 | if [ 3 -lt "$jenkins_opt_exit" -o "$rc" -eq 0 ]; then 158 | if [ "$jenkins_test_cov" = "yes" ]; then 159 | $WORKSPACE/contrib/jenkins_tests/cov.sh 160 | ret=$? 161 | if [ $ret -gt 0 ]; then 162 | do_err "case: [cov: ret=$ret]" 163 | fi 164 | rc=$((rc + $ret)) 165 | fi 166 | fi 167 | if [ 4 -lt "$jenkins_opt_exit" -o "$rc" -eq 0 ]; then 168 | if [ "$jenkins_test_cppcheck" = "yes" ]; then 169 | $WORKSPACE/contrib/jenkins_tests/cppcheck.sh 170 | ret=$? 171 | if [ $ret -gt 0 ]; then 172 | do_err "case: [cppcheck: ret=$ret]" 173 | fi 174 | rc=$((rc + $ret)) 175 | fi 176 | fi 177 | if [ 5 -lt "$jenkins_opt_exit" -o "$rc" -eq 0 ]; then 178 | if [ "$jenkins_test_csbuild" = "yes" ]; then 179 | $WORKSPACE/contrib/jenkins_tests/csbuild.sh 180 | ret=$? 181 | if [ $ret -gt 0 ]; then 182 | do_err "case: [csbuild: ret=$ret]" 183 | fi 184 | rc=$((rc + $ret)) 185 | fi 186 | fi 187 | if [ 6 -lt "$jenkins_opt_exit" -o "$rc" -eq 0 ]; then 188 | if [ "$jenkins_test_run" = "yes" ]; then 189 | $WORKSPACE/contrib/jenkins_tests/test.sh 190 | ret=$? 191 | if [ $ret -gt 0 ]; then 192 | do_err "case: [test: ret=$ret]" 193 | fi 194 | rc=$((rc + $ret)) 195 | fi 196 | fi 197 | if [ 7 -lt "$jenkins_opt_exit" -o "$rc" -eq 0 ]; then 198 | if [ "$jenkins_test_gtest" = "yes" ]; then 199 | $WORKSPACE/contrib/jenkins_tests/gtest.sh 200 | ret=$? 201 | if [ $ret -gt 0 ]; then 202 | do_err "case: [gtest: ret=$ret]" 203 | fi 204 | rc=$((rc + $ret)) 205 | fi 206 | fi 207 | if [ 8 -lt "$jenkins_opt_exit" -o "$rc" -eq 0 ]; then 208 | if [ "$jenkins_test_style" = "yes" ]; then 209 | $WORKSPACE/contrib/jenkins_tests/style.sh 210 | ret=$? 211 | if [ $ret -gt 0 ]; then 212 | do_err "case: [style: ret=$ret]" 213 | fi 214 | rc=$((rc + $ret)) 215 | fi 216 | fi 217 | if [ 9 -lt "$jenkins_opt_exit" -o "$rc" -eq 0 ]; then 218 | if [ "$jenkins_test_copyrights" = "yes" ]; then 219 | $WORKSPACE/contrib/jenkins_tests/copyrights.sh 220 | ret=$? 221 | if [ $ret -gt 0 ]; then 222 | do_err "case: [copyrights: ret=$ret]" 223 | fi 224 | rc=$((rc + $ret)) 225 | fi 226 | fi 227 | set -e 228 | 229 | if [ "$jenkins_opt_artifacts" == "always" ] || [ "$jenkins_opt_artifacts" == "fail" -a "$rc" -gt 0 ]; then 230 | 231 | # Archive all logs in single file 232 | do_archive "${WORKSPACE}/${prefix}/${target_name}/*.tap" 233 | 234 | set +x 235 | gzip -f "${jenkins_test_artifacts}.tar" 236 | echo "======================================================" 237 | echo "Jenkins result for [${target_name}] target: return $rc" 238 | echo "Artifacts: ${jenkins_test_artifacts}.tar.gz" 239 | echo "======================================================" 240 | set -x 241 | fi 242 | 243 | done 244 | 245 | rm -rf $WORKSPACE/config.cache 246 | 247 | echo "[${0##*/}]..................exit code = $rc" 248 | exit $rc 249 | -------------------------------------------------------------------------------- /copying: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2024 Mellanox Technologies Ltd. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 14 | * contributors may be used to endorse or promote products derived from this 15 | * software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 20 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 22 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 26 | * OF SUCH DAMAGE. 27 | * 28 | */ 29 | -------------------------------------------------------------------------------- /debian/README.Debian: -------------------------------------------------------------------------------- 1 | __APP_NAME__-__VERSION__ for Debian 2 | 3 | -- __MAINTAINER__ __DATE__ 4 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | __APP_NAME__ (__VERSION__-__RELEASE__) release; urgency=low 2 | 3 | * Initial Release. 4 | 5 | -- __MAINTAINER__ __DATE__ 6 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: __APP_NAME__ 2 | Section: unknown 3 | Priority: extra 4 | Maintainer: Mellanox Technologies Ltd. 5 | Build-Depends: debhelper (>= 8.0.0) 6 | Standards-Version: 3.9.5 7 | Homepage: http://www.mellanox.com 8 | 9 | Package: __APP_NAME__ 10 | Architecture: any 11 | Multi-Arch: foreign 12 | Depends: ${misc:Depends}, ${shlibs:Depends} 13 | Description: auto-generated package by debmake 14 | This Debian binary package was auto-generated by the 15 | debmake(1) command provided by the debmake package. 16 | . 17 | ===== This comes from the unmodified template file ===== 18 | . 19 | Please edit this template file (debian/control) and other package files 20 | (debian/*) to make them meet all the requirements of the Debian Policy 21 | before uploading this package to the Debian archive. 22 | . 23 | See 24 | * http://www.debian.org/doc/manuals/maint-guide/dreq.en.html#control 25 | * http://www.debian.org/doc/manuals/developers-reference/best-pkging-practices.html#bpp-debian-control 26 | . 27 | The synopsis description at the top should be about 60 characters and 28 | written as a phrase. No extra capital letters or a final period. No 29 | articles — "a", "an", or "the". 30 | . 31 | The package description for general-purpose applications should be 32 | written for a less technical user. This means that we should avoid 33 | jargon. GNOME or KDE is fine but GTK+ is probably not. 34 | . 35 | Use the canonical forms of words: 36 | * Use X Window System, X11, or X; not X Windows, X-Windows, or X Window. 37 | * Use GTK+, not GTK or gtk. 38 | * Use GNOME, not Gnome. 39 | * Use PostScript, not Postscript or postscript. 40 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: __APP_NAME__ 3 | Source: 4 | ### 5 | ### Uncomment the following 2 lines to enable uscan to exclude non-DFSG components 6 | ### Files-Excluded: command/non-dfsg.exe 7 | ### docs/source/javascripts/jquery-1.7.1.min.js 8 | ### 9 | ### This is a autogenerated template for debian/copyright. 10 | ### 11 | ### Edit this accordinng to the "Machine-readable debian/copyright file" as 12 | ### http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ . 13 | ### 14 | ### Generate updated license templates with the "debmake -cc" to STDOUT 15 | ### and merge them into debian/copyright as needed. 16 | ### 17 | ### Please avoid to pick license terms that are more restrictive than the 18 | ### packaged work, as it may make Debian's contributions unacceptable upstream. 19 | 20 | Copyright: 2011-2024 Mellanox Technologies, Ltd. 21 | License: __UNKNOWN__ 22 | Redistribution and use in source and binary forms, with or without modification, 23 | are permitted provided that the following conditions are met: 24 | . 25 | 1. Redistributions of source code must retain the above copyright notice, 26 | this list of conditions and the following disclaimer. 27 | 2. Redistributions in binary form must reproduce the above copyright notice, 28 | this list of conditions and the following disclaimer in the documentation 29 | and/or other materials provided with the distribution. 30 | 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 31 | contributors may be used to endorse or promote products derived from this 32 | software without specific prior written permission. 33 | . 34 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 35 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 36 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 37 | SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 38 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 39 | OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 40 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 41 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 42 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 43 | OF SUCH DAMAGE. 44 | . 45 | -------------------------------------------------------------------------------- /debian/patches/series: -------------------------------------------------------------------------------- 1 | ### The patch files of the -p1 format included in the debian/patches directory 2 | ### are applied to the upstream source in the order listed below. 3 | ### This is manually managed by users with dquilt (quilt(1) wrapper) etc. 4 | ### Also this may be updated by dpkg-source(1) when making a package. 5 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | ### See debhelper(7) (uncomment to enable) 3 | ### This is a autogenerated template for debian/rules. 4 | ### You must remove unused comment lines for the released package. 5 | ### 6 | ### Output every command that modifies files on the build system. 7 | #DH_VERBOSE = 1 8 | ### 9 | ### Define DEB_HOST_* and DEB_BUILD_* variables using 10 | ### dpkg-architecture(1) if they are used in this file. E.g.: 11 | ###DEB_HOST_MULTIARCH = $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) 12 | ###DEB_HOST_ARCH_OS = $(shell dpkg-architecture -qDEB_HOST_ARCH_OS) 13 | ### 14 | ### Copy some variable definitions from pkg-info.mk and vendor.mk 15 | ### under /usr/share/dpkg/ to here if they are useful. 16 | ### 17 | ### See FEATURE AREAS in dpkg-buildflags(1) 18 | #export DEB_BUILD_MAINT_OPTIONS = hardening=+all 19 | ### 20 | ### See ENVIRONMENT in dpkg-buildflags(1) 21 | ### Package maintainers to append CFLAGS 22 | #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic 23 | ### Package maintainers to append LDFLAGS 24 | #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed 25 | 26 | ### main packaging script based on dh7 syntax 27 | %: 28 | dh $@ 29 | 30 | ### Alternatively 31 | ### support for -Wl,--as-needed to ltmain.sh with autoreconf -f -i 32 | ###override_dh_autoreconf: 33 | ### dh_autoreconf --as-needed 34 | ### 35 | ### Set options for ./configure 36 | ###CONFIGURE_FLAGS = 37 | ###overrride_dh_configure: 38 | ### dh_configure -- $(CONFIGURE_FLAGS) 39 | ### 40 | ### Do not install libtool archive, python .pyc .pyo 41 | override_dh_install: 42 | dh_install --list-missing -X.la -X.pyc -X.pyo 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | 3 | -------------------------------------------------------------------------------- /debian/source/local-options: -------------------------------------------------------------------------------- 1 | ### Uncomment to active options. See dpkg-source(1) 2 | ###abort-on-upstream-changes 3 | ###unapply-patches 4 | -------------------------------------------------------------------------------- /news: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mellanox/sockperf/f12cc1b663385394a62d4438c8530955ac4083c0/news -------------------------------------------------------------------------------- /sockperf-version: -------------------------------------------------------------------------------- 1 | 3.10 2 | -------------------------------------------------------------------------------- /src/aopt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | /** 31 | * @file aopt.h 32 | * 33 | * @brief aOpt is tiny set of ANSI C library functions for parsing command line. 34 | * 35 | * @details This module is written in ANSI C89. Support short and long styles of 36 | * option. Automatic error messages can be turned on by _AOPT_CONF_TRACE==TRUE. 37 | * Easy initialization, simple set of operations and automatic help make 38 | * this library very friendly and flexible. 39 | * Example of option usage: 40 | * short style: -o123, -o 123, -o=123, -o 41 | * long style: --option 123, --option=123, --option 42 | * 43 | * @author Igor Ivanov 44 | * 45 | **/ 46 | #ifndef _AOPT_H_ 47 | #define _AOPT_H_ 48 | 49 | #ifdef __cplusplus 50 | extern "C" { 51 | #endif 52 | 53 | /** 54 | * @enum AOPT_TYPE 55 | * @brief Define option type. 56 | */ 57 | typedef enum { 58 | AOPT_NOARG = 0, /**< option does not have value */ 59 | AOPT_REPEAT = 1, /**< option can appear few times */ 60 | AOPT_ARG = 2, /**< option should have value */ 61 | AOPT_OPTARG = 4 /**< option can have value */ 62 | } AOPT_TYPE; 63 | 64 | /** 65 | * @def AOPT_MAX_NUMBER 66 | * @brief Maximum number of options 67 | */ 68 | #define AOPT_MAX_NUMBER 4 69 | 70 | /** 71 | * @struct _AOPT_DESC 72 | * @brief 73 | * Description of supported options. 74 | */ 75 | typedef struct _AOPT_DESC { 76 | int key; /**< unique identifier */ 77 | AOPT_TYPE flags; /**< option type */ 78 | const char shorts[AOPT_MAX_NUMBER]; /**< short name */ 79 | const char *const longs[AOPT_MAX_NUMBER]; /**< long name */ 80 | const char *note; /**< option description */ 81 | } AOPT_DESC; 82 | 83 | /** 84 | * @struct _AOPT_OBJECT 85 | * @brief 86 | * Option container. 87 | */ 88 | typedef struct _AOPT_OBJECT { 89 | int key; /**< unique identifier */ 90 | const char *arg; /**< option value */ 91 | } AOPT_OBJECT; 92 | 93 | /** 94 | * @def aopt_set_literal 95 | * @brief 96 | * Set option as literal. 97 | */ 98 | #define aopt_set_literal(...) \ 99 | { __VA_ARGS__, 0 } 100 | 101 | /** 102 | * @def aopt_set_string 103 | * @brief 104 | * Set option as string. 105 | */ 106 | #define aopt_set_string(...) \ 107 | { __VA_ARGS__, NULL } 108 | 109 | /** 110 | * aopt_init 111 | * 112 | * @brief 113 | * This function parses command line and creates object with options 114 | * basing options description. It returns count of correct tokens. 115 | * 116 | * @param[in,out] argc Argument count. 117 | * @param[in] argv Argument vector. 118 | * @param[in] desc Option description. 119 | * 120 | * @retval pointer to object - on success 121 | * @retval NULL - on failure 122 | ***************************************************************************/ 123 | const AOPT_OBJECT *aopt_init(int *argc, const char **argv, const AOPT_DESC *desc); 124 | 125 | /** 126 | * aopt_exit 127 | * 128 | * @brief 129 | * The function is used as a destructor. Releases memory allocated in 130 | * the corresponding call. Object can not be used later. 131 | * 132 | * @return @a none 133 | ***************************************************************************/ 134 | void aopt_exit(AOPT_OBJECT *aopt_obj); 135 | 136 | /** 137 | * aopt_check 138 | * 139 | * @brief 140 | * Returns number of appearance of the option in command line. 141 | * 142 | * @param[in] aopt_obj Object. 143 | * @param[in] key Option key. 144 | * 145 | * @retval (>0) - on success 146 | * @retval ( 0) - on failure 147 | ***************************************************************************/ 148 | int aopt_check(const AOPT_OBJECT *aopt_obj, int key); 149 | 150 | /** 151 | * aopt_value 152 | * 153 | * @brief 154 | * Returns option value by key. 155 | * 156 | * @param[in] aopt_obj Object. 157 | * @param[in] key Option key. 158 | * 159 | * @retval pointer to value - on success 160 | * @retval NULL - on failure 161 | ***************************************************************************/ 162 | const char *aopt_value(const AOPT_OBJECT *aopt_obj, int key); 163 | 164 | /** 165 | * aopt_get_desc 166 | * 167 | * @brief 168 | * Return AOPT Description struct of option selected via key. 169 | * 170 | * @param[in] desc Option description. 171 | * @param[in] key Option key. 172 | * 173 | * @retval pointer to description struct - on success 174 | * @retval NULL - on failure 175 | ***************************************************************************/ 176 | const AOPT_DESC *aopt_get_desc(const AOPT_DESC *aopt_desc, int key); 177 | 178 | /** 179 | * aopt_get_long_name 180 | * 181 | * @brief 182 | * Return long name of option description selected via key. 183 | * 184 | * @param[in] desc Option description. 185 | * @param[in] key Option key. 186 | * 187 | * @retval pointer to string - on success 188 | * @retval NULL - on failure 189 | ***************************************************************************/ 190 | const char *aopt_get_long_name(const AOPT_DESC *aopt_desc, int key); 191 | 192 | /** 193 | * aopt_help 194 | * 195 | * @brief 196 | * This function form help information basing options description and 197 | * return string with one. The string should be freed using the free() 198 | * function when you are done with it. NULL is returned if the it would 199 | * produce an empty string or if the string cannot be allocated. 200 | * 201 | * @param[in] desc Option description. 202 | * 203 | * @retval pointer to string - on success 204 | * @retval NULL - on failure 205 | ***************************************************************************/ 206 | const char *aopt_help(const AOPT_DESC *desc); 207 | 208 | /** 209 | * isNumeric 210 | * 211 | * @brief 212 | * This function checks if the arg is from numeric type. 213 | * 214 | * @param[in] arg char* 215 | * 216 | * @retval 1 if numeric, 0 otherwise. 217 | ***************************************************************************/ 218 | int isNumeric(const char *arg); 219 | 220 | #ifdef __cplusplus 221 | } 222 | #endif 223 | 224 | #endif /* _AOPT_H_ */ 225 | -------------------------------------------------------------------------------- /src/clock.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef CLOCK_H_ 31 | #define CLOCK_H_ 32 | 33 | /* 34 | * Parameters used to convert the time values: 35 | */ 36 | #define MSEC_PER_SEC 1000L 37 | #define USEC_PER_MSEC 1000L 38 | #define NSEC_PER_USEC 1000L 39 | #define NSEC_PER_MSEC 1000000L 40 | #define USEC_PER_SEC 1000000L 41 | #define NSEC_PER_SEC 1000000000L 42 | #define FSEC_PER_SEC 1000000000000000L 43 | 44 | /* 45 | * Convenience macros for operations on timevals 46 | */ 47 | #define TIMEVAL_INITIALIZER \ 48 | { 0, 0 } 49 | 50 | #define tv_to_sec(tvp) ((tvp)->tv_sec) 51 | #define tv_to_msec(tvp) \ 52 | ((int64_t((tvp)->tv_sec) * MSEC_PER_SEC) + (int64_t((tvp)->tv_usec) / USEC_PER_MSEC)) 53 | #define tv_to_usec(tvp) ((int64_t((tvp)->tv_sec) * USEC_PER_SEC) + (int64_t((tvp)->tv_usec))) 54 | #define tv_to_nsec(tvp) \ 55 | ((int64_t((tvp)->tv_sec) * NSEC_PER_SEC) + (int64_t((tvp)->tv_usec) * NSEC_PER_USEC)) 56 | 57 | #define tv_isset(tvp) timerisset(tvp) 58 | #define tv_clear(tvp) timerclear(tvp) 59 | 60 | #define tv_cmp(a, b, CMP) timercmp(a, b, CMP) 61 | #define tv_add(a, b, result) timeradd(a, b, result) 62 | #define tv_sub(a, b, result) timersub(a, b, result) 63 | 64 | /* Convenience macros for operations on timespecs */ 65 | #define TIMESPEC_INITIALIZER \ 66 | { 0, 0 } 67 | 68 | #define ts_to_sec(tsp) ((tsp)->tv_sec) 69 | #define ts_to_msec(tsp) \ 70 | ((int64_t((tsp)->tv_sec) * MSEC_PER_SEC) + (int64_t((tsp)->tv_nsec) / NSEC_PER_MSEC)) 71 | #define ts_to_usec(tsp) \ 72 | ((int64_t((tsp)->tv_sec) * USEC_PER_SEC) + (int64_t((tsp)->tv_nsec) / NSEC_PER_USEC)) 73 | #define ts_to_nsec(tsp) ((int64_t((tsp)->tv_sec) * NSEC_PER_SEC) + (int64_t((tsp)->tv_nsec))) 74 | 75 | #define ts_isset(tvp) ((tvp)->tv_sec || (tvp)->tv_nsec) 76 | #define ts_clear(tvp) ((tvp)->tv_sec = (tvp)->tv_nsec = 0) 77 | 78 | #define ts_cmp(a, b, CMP) \ 79 | (((a)->tv_sec == (b)->tv_sec) ? ((a)->tv_nsec CMP(b)->tv_nsec) : ((a)->tv_sec CMP(b)->tv_sec)) 80 | 81 | #define ts_add(a, b, result) \ 82 | do { \ 83 | (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ 84 | (result)->tv_nsec = (a)->tv_nsec + (b)->tv_nsec; \ 85 | if ((result)->tv_nsec >= NSEC_PER_SEC) { \ 86 | ++(result)->tv_sec; \ 87 | (result)->tv_nsec -= NSEC_PER_SEC; \ 88 | } \ 89 | } while (0) 90 | 91 | #define ts_sub(a, b, result) \ 92 | do { \ 93 | (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ 94 | (result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; \ 95 | if ((result)->tv_nsec < 0) { \ 96 | --(result)->tv_sec; \ 97 | (result)->tv_nsec += NSEC_PER_SEC; \ 98 | } \ 99 | } while (0) 100 | 101 | #endif /* CLOCK_H_ */ 102 | -------------------------------------------------------------------------------- /src/defs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | #include "defs.h" 31 | #include "message.h" 32 | #include "packet.h" 33 | 34 | /* Global variables */ 35 | bool g_b_exit = false; 36 | bool g_b_errorOccured = false; 37 | uint64_t g_receiveCount = 0; // TODO: should be one per server 38 | uint64_t g_skipCount = 0; // TODO: should be one per server 39 | 40 | unsigned long long g_cycle_wait_loop_counter = 0; 41 | TicksTime g_cycleStartTime; 42 | 43 | debug_level_t g_debug_level = LOG_LVL_INFO; 44 | 45 | #ifdef USING_EXTRA_API 46 | ZeroCopyData::ZeroCopyData() : m_pkt_buf(NULL), m_pkts(NULL) {} 47 | 48 | void ZeroCopyData::allocate() { m_pkt_buf = (unsigned char *)MALLOC(Message::getMaxSize()); } 49 | 50 | ZeroCopyData::~ZeroCopyData() { 51 | if (m_pkt_buf) FREE(m_pkt_buf); 52 | } 53 | 54 | zeroCopyMap g_zeroCopyData; 55 | #endif // USING_EXTRA_API 56 | 57 | uint32_t MPS_MAX = MPS_MAX_UL; // will be overwrite at runtime in case of ping-pong test 58 | PacketTimes *g_pPacketTimes = NULL; 59 | 60 | TicksTime g_lastTicks; 61 | 62 | int max_fds_num = 0; 63 | fds_data **g_fds_array = NULL; 64 | int MAX_PAYLOAD_SIZE = 65507; 65 | int IGMP_MAX_MEMBERSHIPS = IP_MAX_MEMBERSHIPS; 66 | 67 | #ifdef USING_VMA_EXTRA_API // VMA 68 | struct vma_api_t *g_vma_api; 69 | #else 70 | void *g_vma_api = nullptr; // Dummy variable 71 | #endif // USING_VMA_EXTRA_API 72 | 73 | #ifdef USING_XLIO_EXTRA_API // XLIO 74 | struct xlio_api_t *g_xlio_api; 75 | #else 76 | void *g_xlio_api = nullptr; // Dummy variable 77 | #endif // USING_XLIO_EXTRA_API 78 | 79 | const App *g_pApp = NULL; 80 | -------------------------------------------------------------------------------- /src/ip_address.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | #include "ip_address.h" 31 | #include "common.h" 32 | 33 | #ifdef __windows__ 34 | #include 35 | #else 36 | #include 37 | #include 38 | #include 39 | #endif 40 | 41 | IPAddress::IPAddress(const IPAddress &rhs) : m_family(rhs.m_family), m_addr6(rhs.m_addr6), m_addr_un(rhs.m_addr_un) 42 | { 43 | } 44 | 45 | IPAddress::IPAddress(const sockaddr *sa, socklen_t len) 46 | { 47 | if (len < sizeof(m_family)) { 48 | m_family = AF_UNSPEC; 49 | return; 50 | } 51 | m_family = sa->sa_family; 52 | switch (m_family) { 53 | case AF_INET: 54 | if (len >= sizeof(sockaddr_in)) { 55 | m_addr4 = reinterpret_cast(sa)->sin_addr; 56 | } else { 57 | m_family = AF_UNSPEC; 58 | } 59 | break; 60 | case AF_INET6: 61 | if (len >= sizeof(sockaddr_in6)) { 62 | m_addr6 = reinterpret_cast(sa)->sin6_addr; 63 | } else { 64 | m_family = AF_UNSPEC; 65 | } 66 | break; 67 | case AF_UNIX: 68 | if (len >= sizeof(sockaddr_un)) { 69 | m_addr_un = unix_sockaddr_to_string(reinterpret_cast(sa)); 70 | } else { 71 | m_family = AF_UNSPEC; 72 | } 73 | break; 74 | } 75 | } 76 | 77 | bool IPAddress::resolve(const char *str, IPAddress &out, std::string &err) 78 | { 79 | struct addrinfo hints; 80 | 81 | memset(&hints, 0, sizeof(hints)); 82 | // allow IPv4 or IPv6 83 | hints.ai_family = AF_UNSPEC; 84 | // return addresses only from configured address families 85 | hints.ai_flags = AI_ADDRCONFIG; 86 | // any protocol 87 | hints.ai_protocol = 0; 88 | // any socket type 89 | hints.ai_socktype = 0; 90 | 91 | struct addrinfo *result; 92 | int res = getaddrinfo(str, NULL, &hints, &result); 93 | if (res == 0) { 94 | out.m_family = AF_UNSPEC; 95 | for (const addrinfo *rp = result; rp != NULL; rp = rp->ai_next) { 96 | if (rp->ai_family == AF_INET6) { 97 | out.m_family = rp->ai_family; 98 | out.m_addr6 = reinterpret_cast(rp->ai_addr)->sin6_addr; 99 | } 100 | } 101 | if (out.m_family == AF_UNSPEC) { 102 | for (addrinfo *rp = result; rp != NULL; rp = rp->ai_next) { 103 | out.m_family = rp->ai_family; 104 | out.m_addr4 = reinterpret_cast(rp->ai_addr)->sin_addr; 105 | } 106 | } 107 | } else { 108 | err = os_get_error(res); 109 | } 110 | freeaddrinfo(result); 111 | 112 | return res == 0; 113 | } 114 | 115 | IPAddress IPAddress::zero() 116 | { 117 | IPAddress res; 118 | memset(&res.m_addr6, 0, sizeof(res.m_addr6)); 119 | return res; 120 | } 121 | 122 | bool IPAddress::is_specified() const 123 | { 124 | switch (m_family) { 125 | case AF_INET: 126 | return m_addr4.s_addr != INADDR_ANY; 127 | case AF_INET6: 128 | return !IN6_IS_ADDR_UNSPECIFIED(&m_addr6); 129 | } 130 | return false; 131 | } 132 | 133 | std::string IPAddress::toString() const 134 | { 135 | if (m_family == AF_UNSPEC) { 136 | return "(unspec)"; 137 | } 138 | char hbuf[INET6_ADDRSTRLEN]; 139 | const char *res = inet_ntop(m_family, &m_addr4, hbuf, INET6_ADDRSTRLEN); 140 | if (res) { 141 | return res; 142 | } else { 143 | return "(unknown)"; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/ip_address.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef IP_ADDRESS_H_ 31 | #define IP_ADDRESS_H_ 32 | 33 | #ifdef __windows__ 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | typedef unsigned short int sa_family_t; 41 | 42 | #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) 43 | #include 44 | #include 45 | #include /* definitions for UNIX domain sockets */ 46 | #include 47 | #endif // defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) 48 | 49 | #include "os_abstract.h" 50 | #include 51 | #include 52 | 53 | #include 54 | 55 | class IPAddress { 56 | private: 57 | sa_family_t m_family; 58 | union { 59 | in_addr m_addr4; 60 | in6_addr m_addr6; 61 | }; 62 | std::string m_addr_un; 63 | 64 | public: 65 | static bool resolve(const char *str, IPAddress &out, std::string &err); 66 | static IPAddress zero(); 67 | 68 | IPAddress(const IPAddress &rhs); 69 | IPAddress(const sockaddr *sa, socklen_t len); 70 | IPAddress() : m_family(AF_UNSPEC) 71 | { 72 | } 73 | 74 | inline sa_family_t family() const 75 | { 76 | return m_family; 77 | } 78 | 79 | inline const in_addr &addr4() const 80 | { 81 | return m_addr4; 82 | } 83 | 84 | inline const in6_addr &addr6() const 85 | { 86 | return m_addr6; 87 | } 88 | 89 | inline std::string addr_un() const 90 | { 91 | return m_addr_un; 92 | } 93 | 94 | bool is_specified() const; 95 | 96 | std::string toString() const; 97 | 98 | inline friend bool operator==(const IPAddress &key1, const IPAddress &key2) 99 | { 100 | if (key1.m_family == key2.m_family) { 101 | switch (key1.m_family) { 102 | case AF_UNSPEC: 103 | return true; 104 | case AF_INET: 105 | return key1.m_addr4.s_addr == key2.m_addr4.s_addr; 106 | case AF_INET6: 107 | return IN6_ARE_ADDR_EQUAL(&key1.m_addr6, &key2.m_addr6); 108 | case AF_UNIX: 109 | return key1.m_addr_un.compare(key2.m_addr_un) == 0; 110 | } 111 | } 112 | return false; 113 | } 114 | }; 115 | 116 | // The only types that TR1 has built-in hash/equal_to functions for, are scalar types, 117 | // std:: string, and std::wstring. For any other type, we need to write a 118 | // hash/equal_to functions, by ourself. 119 | namespace std { 120 | template <> struct hash : public std::unary_function { 121 | int operator()(IPAddress const &key) const 122 | { 123 | switch (key.family()) { 124 | case AF_INET: 125 | return key.addr4().s_addr & 0xFF; 126 | case AF_INET6: { 127 | const uint32_t *addr = reinterpret_cast(&key.addr6()); 128 | return addr[0] ^ addr[1] ^ addr[2] ^ addr[3]; 129 | } 130 | default: 131 | return 0; 132 | } 133 | } 134 | }; 135 | 136 | template <> 137 | struct equal_to : public std::binary_function { 139 | bool operator()(IPAddress const &key1, IPAddress const &key2) const { 140 | return key1 == key2; 141 | } 142 | }; 143 | 144 | } // namespace std 145 | 146 | #endif // IP_ADDRESS_H_ 147 | -------------------------------------------------------------------------------- /src/message.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | #include "message.h" 31 | 32 | #if !defined(__FreeBSD__) && !defined(__APPLE__) 33 | #include 34 | #endif // !defined(__FreeBSD__) && !defined(__APPLE__) 35 | 36 | #include 37 | #include "common.h" 38 | 39 | // static memebers initialization 40 | /*static*/ uint64_t Message::ms_maxSequenceNo; 41 | /*static*/ int Message::ms_maxSize; 42 | 43 | //------------------------------------------------------------------------------ 44 | class MemException : public std::exception { 45 | public: 46 | MemException(const char *file, int line, const char *handler, size_t size) throw(); 47 | virtual ~MemException() throw() {} 48 | virtual const char *what() const throw() { return m_what.c_str(); } 49 | 50 | private: 51 | std::string m_what; 52 | }; 53 | //------------------ 54 | MemException::MemException(const char *file, int line, const char *handler, size_t size) throw() { 55 | const size_t LEN = 256; 56 | char buf[LEN + 1]; 57 | snprintf(buf, LEN, "%s:%d: %s failed allocating %d bytes", file, line, handler, (int)size); 58 | buf[LEN] = '\0'; 59 | m_what = buf; 60 | } 61 | 62 | //------------------------------------------------------------------------------ 63 | /*static*/ void Message::initMaxSize(int size) { 64 | if (size < 0) 65 | throw std::out_of_range("size < 0"); 66 | else if (ms_maxSize) 67 | throw std::logic_error("MaxSize is already initialized"); 68 | else 69 | ms_maxSize = size; 70 | } 71 | 72 | //------------------------------------------------------------------------------ 73 | /*static*/ void Message::initMaxSeqNo(uint64_t seqno) { 74 | if (ms_maxSequenceNo) 75 | throw std::logic_error("MaxSeqNo is already initialized"); 76 | else 77 | ms_maxSequenceNo = seqno; 78 | } 79 | 80 | //------------------------------------------------------------------------------ 81 | Message::Message() { 82 | 83 | if (!ms_maxSize) throw std::logic_error("MaxSize was NOT initialized"); 84 | 85 | if (ms_maxSize < MsgHeader::EFFECTIVE_SIZE) 86 | throw std::out_of_range("maxSize < MsgHeader::EFFECTIVE_SIZE"); 87 | 88 | m_buf = MALLOC(ms_maxSize + 7); // extra +7 for enabling 8 alignment of m_sequence_number 89 | if (!m_buf) { 90 | throw MemException(__FILE__, __LINE__, "malloc", ms_maxSize); 91 | } 92 | 93 | setBuf(); 94 | 95 | for (int len = 0; len < ms_maxSize; len++) 96 | m_addr[len] = (uint8_t)rand(); 97 | memset((void *)m_header, 0, MsgHeader::EFFECTIVE_SIZE); 98 | 99 | /* 100 | log_msg("ms_maxSize=%d, m_buf=%p, alignment=%d, m_data=%p, m_header=%p", ms_maxSize, m_buf, 101 | alignment, m_data, m_header); 102 | log_msg("header addresses: m_sequence_number=%p", &m_header->m_sequence_number); 103 | */ 104 | } 105 | 106 | //------------------------------------------------------------------------------ 107 | Message::~Message() { 108 | if (m_buf) { 109 | FREE(m_buf); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/message.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef MESSAGE_H_ 31 | #define MESSAGE_H_ 32 | 33 | #include 34 | #include 35 | #include 36 | #include // for uint64_t 37 | #include "os_abstract.h" 38 | 39 | // Using pack() pragma set needed alignment 40 | #pragma pack(push, 2) 41 | class MsgHeader { 42 | friend class Message; 43 | 44 | public: 45 | MsgHeader(uint64_t _sequence_number = 0) : m_sequence_number(_sequence_number) {} 46 | ~MsgHeader() {} 47 | 48 | // uint32_t isClient() const {return m_isClient;} 49 | // void setClient() {m_isClient = 1;} 50 | // void setServer() {m_isClient = 0;} 51 | // uint32_t isPongRequest() const {return m_isPongRequest;} 52 | // void setPongRequest(bool on = true) {m_isPongRequest = on ? 1 : 0;} 53 | 54 | bool isClient() const { return (!!(m_flags_and_length.m_flags & MASK_CLIENT)); } 55 | void setClient() { m_flags_and_length.m_flags |= MASK_CLIENT; } 56 | void setServer() { m_flags_and_length.m_flags &= ~MASK_CLIENT; } 57 | 58 | bool isPongRequest() const { return (!!(m_flags_and_length.m_flags & MASK_PONG)); } 59 | void setPongRequest() { m_flags_and_length.m_flags |= MASK_PONG; } 60 | void resetPongRequest() { m_flags_and_length.m_flags &= ~MASK_PONG; } 61 | 62 | bool isWarmupMessage() const { return (!!(m_flags_and_length.m_flags & MASK_WARMUP_MSG)); } 63 | void setWarmupMessage() { m_flags_and_length.m_flags |= MASK_WARMUP_MSG; } 64 | void resetWarmupMessage() { m_flags_and_length.m_flags &= ~MASK_WARMUP_MSG; } 65 | 66 | void hton() { 67 | m_sequence_number = htonll(m_sequence_number); 68 | m_flags_and_length.m_flags = htons(m_flags_and_length.m_flags); 69 | m_flags_and_length.length = htonl(m_flags_and_length.length); 70 | } 71 | 72 | void ntoh() { 73 | m_sequence_number = ntohll(m_sequence_number); 74 | m_flags_and_length.m_flags = ntohs(m_flags_and_length.m_flags); 75 | m_flags_and_length.length = ntohl(m_flags_and_length.length); 76 | } 77 | // this is different than sizeof(MsgHeader) and safe only for the current implementation of the 78 | // class 79 | static const int EFFECTIVE_SIZE = (int)(sizeof(uint64_t) + sizeof(uint16_t) + sizeof(uint32_t)); 80 | // static const int EFFECTIVE_SIZE = 16; 81 | 82 | private: 83 | typedef struct { 84 | uint16_t m_flags; 85 | uint32_t length; 86 | } s_flags_and_length; 87 | // NOTE: m_sequence_number must be the 1st field, because we want EFFECTIVE_SIZE of header to be 88 | // 14 bytes 89 | // hence we need the padding (to 16 bytes) to be after last field and not between fields 90 | // pack() pragma can be added to set needed alignment 91 | uint64_t m_sequence_number; 92 | s_flags_and_length m_flags_and_length; 93 | 94 | static const uint32_t MASK_CLIENT = 1; 95 | static const uint32_t MASK_PONG = 2; 96 | static const uint32_t MASK_WARMUP_MSG = 4; 97 | /* 98 | uint32_t m_isClient:1; 99 | uint32_t m_isPongRequest:1; 100 | uint32_t m_reservedFlags:6; 101 | uint32_t m_reserved:24; 102 | */ 103 | }; 104 | #pragma pack(pop) 105 | 106 | class Message { 107 | private: 108 | // noncopyable 109 | Message(const Message &); 110 | Message &operator=(const Message &); 111 | public: 112 | Message(); 113 | ~Message(); 114 | 115 | static void initMaxSize(int size); 116 | static void initMaxSeqNo(uint64_t seqno); 117 | static size_t getMaxSize() { return ms_maxSize; } 118 | 119 | uint8_t *getBuf() const { return m_addr; } 120 | uint8_t *setBuf(uint8_t *addr = NULL) { 121 | 122 | /* set buffer as intrenal in case NULL is passed */ 123 | if (!addr) { 124 | int alignment = (8 - reinterpret_cast(m_buf)) % 8; 125 | addr = (uint8_t *)m_buf + alignment; // this will force m_sequence_number to be 8 126 | // aligned even on 32 bit arch 127 | } 128 | 129 | m_addr = addr; 130 | m_header = (MsgHeader *)m_addr; 131 | m_data = (uint8_t *)m_header + MsgHeader::EFFECTIVE_SIZE; 132 | 133 | if ((void *)m_addr != (void *)m_header) throw std::logic_error("address error"); 134 | 135 | return m_addr; 136 | } 137 | 138 | const MsgHeader *getHeader() const { return m_header; } 139 | MsgHeader *getHeader() { return m_header; } 140 | uint8_t *getData() const { return m_data; } 141 | 142 | uint16_t isClient() const { return m_header->isClient(); } 143 | void setClient() { m_header->setClient(); } 144 | void setServer() { m_header->setServer(); } 145 | 146 | uint16_t isPongRequest() const { return m_header->isPongRequest(); } 147 | 148 | uint64_t getSequenceCounter() const { 149 | assert((m_header->m_sequence_number <= ms_maxSequenceNo) && 150 | "exceeded message number limitation"); 151 | return m_header->m_sequence_number; 152 | } 153 | void setSequenceCounter(uint64_t _sequence) { 154 | assert((_sequence <= ms_maxSequenceNo) && "exceeded message number limitation"); 155 | m_header->m_sequence_number = _sequence; 156 | } 157 | void incSequenceCounter() { m_header->m_sequence_number++; } 158 | void decSequenceCounter() { m_header->m_sequence_number--; } 159 | 160 | uint16_t isWarmupMessage() const { return m_header->isWarmupMessage(); } 161 | void setWarmupMessage() { m_header->setWarmupMessage(); } 162 | void resetWarmupMessage() { m_header->resetWarmupMessage(); } 163 | 164 | void setHeaderToHost() { m_header->ntoh(); } 165 | void setHeaderToNetwork() { m_header->hton(); } 166 | 167 | uint16_t getFlags() const { return (m_header->m_flags_and_length.m_flags); } 168 | 169 | int getLength() const { 170 | // extract msg length from m_length and m_flags. 171 | return m_header->m_flags_and_length.length; 172 | } 173 | void setLength(uint32_t _length) { m_header->m_flags_and_length.length = _length; } 174 | 175 | bool isValidHeader() const 176 | { 177 | return (unsigned)getLength() <= (unsigned)ms_maxSize; 178 | } 179 | 180 | private: 181 | void *m_buf; 182 | 183 | uint8_t *m_addr; // points to 1st 8 aligned adrs inside m_buf 184 | MsgHeader *m_header; // points to header 185 | uint8_t *m_data; // points to data 186 | 187 | static uint64_t ms_maxSequenceNo; // maximum expected sequence number 188 | static int ms_maxSize; // use int (instead of size_t to save casting to 'int' in recvfrom) 189 | }; 190 | 191 | #endif /* MESSAGE_H_ */ 192 | -------------------------------------------------------------------------------- /src/packet.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include "defs.h" 32 | #include "packet.h" 33 | 34 | #include "common.h" 35 | 36 | PacketTimes::PacketTimes(uint64_t _maxSequenceNo, uint64_t _replyEvery, uint64_t _numServers) 37 | : m_maxSequenceNo(_maxSequenceNo), m_replyEvery(_replyEvery), 38 | m_blockSize(1 + _numServers) // 1 sent + N replies 39 | , 40 | m_pTimes(new TicksTime[(_maxSequenceNo / _replyEvery + 1) * 41 | m_blockSize]) //_maxSequenceNo/_replyEvery+1 is _numBlocks rounded up 42 | , 43 | m_pInternalUse(&m_pTimes[1]), m_pErrors(new ArrivalErrors[_numServers]) { 44 | /* 45 | log_msg("m_maxSequenceNo=%lu, m_replyEvery=%lu, m_blockSize=%lu, m_pTimes=%p[%lu], 46 | m_pInternalUse=%p, m_pErrors=%p[%lu]" 47 | 48 | , m_maxSequenceNo, m_replyEvery, m_blockSize, m_pTimes 49 | , (_maxSequenceNo / _replyEvery + 1) * m_blockSize 50 | , m_pInternalUse 51 | , m_pErrors, _numServers 52 | ); 53 | */ 54 | } 55 | 56 | PacketTimes::~PacketTimes() { 57 | delete[] m_pTimes; 58 | delete[] m_pErrors; 59 | } 60 | 61 | bool PacketTimes::verifyError(uint64_t _seqNo) { 62 | exit_with_err("_seqN > m_maxSequenceNo", SOCKPERF_ERR_FATAL); 63 | return false; 64 | } 65 | -------------------------------------------------------------------------------- /src/packet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef PACKETTIMES_H_ 31 | #define PACKETTIMES_H_ 32 | 33 | #include // for uint64_t 34 | #include "ticks.h" 35 | #include 36 | #include "common.h" 37 | 38 | class PacketTimes { 39 | public: 40 | PacketTimes(uint64_t _maxSequenceNo, uint64_t _replyEvery, uint64_t _numServers); 41 | ~PacketTimes(); 42 | 43 | bool verifyError(uint64_t _seqNo); 44 | 45 | uint64_t seq2index(uint64_t _seqNo) { 46 | return ((_seqNo <= m_maxSequenceNo) ? _seqNo / m_replyEvery * m_blockSize 47 | : verifyError(_seqNo)); 48 | } // index 0 is not used for real packets 49 | 50 | const TicksTime &getTxTime(uint64_t _seqNo) { return m_pTimes[seq2index(_seqNo)]; } 51 | const TicksTime *getRxTimeArray(uint64_t _seqNo) { return &m_pInternalUse[seq2index(_seqNo)]; } 52 | 53 | void clearTxTime(uint64_t _seqNo) { m_pTimes[seq2index(_seqNo)] = TicksTime::TICKS0; } 54 | void setTxTime(uint64_t _seqNo) { 55 | m_pTimes[seq2index(_seqNo)].setNow(); 56 | // log_msg(">>> %lu: tx=%.3lf", _seqNo, 57 | // (double)m_pTimes[seq2index(_seqNo)].debugToNsec()/1000/1000 );//TODO: remove 58 | } 59 | void setRxTime(uint64_t _seqNo, uint64_t _serverNo = 0) { 60 | setRxTime(_seqNo, TicksTime().setNow(), _serverNo); 61 | } 62 | void setRxTime(uint64_t _seqNo, const TicksTime &_time, uint64_t _serverNo = 0) { 63 | TicksTime *rxTimes = &m_pInternalUse[seq2index(_seqNo)]; 64 | if (rxTimes[_serverNo] == TicksTime::TICKS0) { 65 | rxTimes[_serverNo] = _time; 66 | ++g_receiveCount; 67 | // log_msg("<<< %lu: rx=%.3lf", _seqNo, (double)_time.debugToNsec()/1000/1000 );//TODO: 68 | // remove 69 | } else if (!g_b_exit) { 70 | incDupCount(_serverNo); /*log_err("dup-packket at _seqNo=%lu", _seqNo);*/ 71 | } 72 | } 73 | 74 | void incDupCount(uint64_t serverNo) { m_pErrors[serverNo].duplicates++; } 75 | void incOooCount(uint64_t serverNo) { m_pErrors[serverNo].ooo++; } 76 | void incDroppedCount(uint64_t serverNo) { m_pErrors[serverNo].dropped++; } 77 | 78 | size_t getDupCount(uint64_t serverNo) { return m_pErrors[serverNo].duplicates; } 79 | size_t getOooCount(uint64_t serverNo) { return m_pErrors[serverNo].ooo; } 80 | size_t getDroppedCount(uint64_t serverNo) { return m_pErrors[serverNo].dropped; } 81 | 82 | const uint64_t m_maxSequenceNo; 83 | const uint64_t m_replyEvery; 84 | const uint64_t m_blockSize; 85 | 86 | private: 87 | TicksTime *const m_pTimes; 88 | TicksTime *const m_pInternalUse; 89 | 90 | // prevent creation by compiler 91 | PacketTimes(const PacketTimes &); 92 | PacketTimes &operator=(const PacketTimes &); 93 | 94 | struct ArrivalErrors { 95 | size_t duplicates; 96 | size_t ooo; // out-of-order 97 | size_t dropped; 98 | ArrivalErrors() : duplicates(0), ooo(0), dropped(0) {} 99 | }; 100 | ArrivalErrors *const m_pErrors; // array with one line per server 101 | /* 102 | //------------------------------------------------------------------------------ 103 | void dumpFullLog(FILE * f) 104 | { 105 | if (!f) return; 106 | 107 | fprintf(f, "------------------------------\n"); 108 | const uint64_t NUM_SERVERS = m_blockSize -1; 109 | fprintf(f, "txTime"); 110 | for (uint64_t i = 0; i < NUM_SERVERS; i++) fprintf(f, ", rxTime%d", i); 111 | fprintf(f, "\n"); 112 | 113 | // 114 | 115 | for (uint64_t i = 0; i < m_maxSequenceNo; i++) { 116 | printf("%.9lf", debugToNsec()) 117 | double tx = (double)pFullLog[i][0].debugToNsec()/1000/1000/1000; 118 | double rx = (double)pFullLog[i][1].debugToNsec()/1000/1000/1000; 119 | fprintf(f, "%.9lf, %.9lf\n", tx, rx); 120 | } 121 | fprintf(f, "------------------------------\n"); 122 | } 123 | 124 | */ 125 | }; 126 | 127 | #endif /* PACKETTIMES_H_ */ 128 | -------------------------------------------------------------------------------- /src/playback.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include "defs.h" 35 | #include "playback.h" 36 | #include "ticks.h" 37 | 38 | // How to build unit test: g++ Playback.cpp Ticks.cpp -lrt -Wall -Dplayback_test=main -o playback 39 | 40 | using std::cout; 41 | 42 | typedef std::vector StringVector; 43 | 44 | void readFile(StringVector &sv, const char *filename) { 45 | std::string line; 46 | std::ifstream infile(filename, std::ios_base::in); 47 | if (infile.fail()) { 48 | log_msg("Can't open file: %s\n", filename); 49 | exit(SOCKPERF_ERR_NOT_EXIST); 50 | } 51 | int i = 0; 52 | 53 | while (infile.good() && getline(infile, line)) { 54 | sv.push_back(line); 55 | i++; 56 | } 57 | if (!infile.eof()) { 58 | log_msg("file: %s, error in line: #%d\n", filename, i + 1); 59 | exit(SOCKPERF_ERR_INCORRECT); 60 | } 61 | } 62 | 63 | void parsePlaybackData(PlaybackVector &pv, StringVector &sv) { 64 | PlaybackItem pi; 65 | 66 | double curr_time, prev_time = 0; 67 | TicksDuration duration; 68 | 69 | for (size_t i = 0; i < sv.size(); i++) { 70 | std::string s = sv[i]; 71 | if (!s.empty() && s[0] != '#') { 72 | // printf("[%lu]: %s\n", i+1, s.c_str()); 73 | if (2 == sscanf(s.c_str(), "%lf, %d", &curr_time, &pi.size)) { 74 | if (prev_time > curr_time) { 75 | printf("out-of-order timestamp at line #%lu\n", (long unsigned)i + 1); 76 | exit(SOCKPERF_ERR_INCORRECT); 77 | } 78 | pi.duration.setFromSeconds(curr_time - prev_time); 79 | if (!pi.isValid()) { 80 | printf("illegal time or size at line #%lu\n", (long unsigned)i + 1); 81 | exit(SOCKPERF_ERR_INCORRECT); 82 | } 83 | 84 | pv.push_back(pi); 85 | prev_time = curr_time; 86 | } else { 87 | cout << "can't read time & size, at line #" << i + 1 << '\n'; 88 | exit(1); 89 | } 90 | } 91 | } 92 | // printf("pv.size()=%d\n", (int)pv.size()); 93 | } 94 | 95 | void loadPlaybackData(PlaybackVector &pv, const char *filename) { 96 | StringVector sv; 97 | readFile(sv, filename); 98 | parsePlaybackData(pv, sv); 99 | sv.clear(); 100 | } 101 | 102 | void doPlayback(PlaybackVector &pv) { 103 | size_t size = pv.size(); 104 | for (size_t i = 0; i < size; i++) 105 | printf("item #%lu: duration=%" PRId64 ", size=%d\n", (long unsigned)i, 106 | pv[i].duration.toNsec(), pv[i].size); 107 | } 108 | 109 | // unit test 110 | int playback_test(int argc, char *argv[]) { 111 | if (argc < 2) { 112 | cout << argv[0] << ": Need a filename for a parameter.\n"; 113 | exit(1); 114 | } 115 | 116 | PlaybackVector pv; 117 | loadPlaybackData(pv, argv[1]); 118 | doPlayback(pv); 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /src/playback.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef PLAYBACK_H_ 31 | #define PLAYBACK_H_ 32 | 33 | #include 34 | #include "ticks.h" 35 | 36 | struct PlaybackItem { 37 | TicksDuration duration; 38 | int size; 39 | bool isValid() { return duration > TicksDuration::TICKS0 && size >= 14 && size <= 64000; } 40 | }; 41 | 42 | typedef std::vector PlaybackVector; 43 | 44 | // main interface to the module 45 | void loadPlaybackData(PlaybackVector &pv, const char *filename); 46 | 47 | #endif /* PLAYBACK_H__ */ 48 | -------------------------------------------------------------------------------- /src/port_descriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef PORT_DESCRIPTOR_H_ 31 | #define PORT_DESCRIPTOR_H_ 32 | 33 | #include 34 | 35 | #ifdef __windows__ 36 | 37 | typedef uint16_t in_port_t; 38 | 39 | #else 40 | 41 | #include /* internet address manipulation */ 42 | 43 | #endif // __windows__ 44 | 45 | typedef struct port_descriptor { 46 | int sock_type; /**< SOCK_STREAM (tcp), SOCK_DGRAM (udp), SOCK_RAW (ip) */ 47 | sa_family_t family; // AF_INET, AF_INET6 48 | in_port_t port; 49 | } port_type; 50 | 51 | // The only types that TR1 has built-in hash/equal_to functions for, are scalar types, 52 | // std:: string, and std::wstring. For any other type, we need to write a 53 | // hash/equal_to functions, by ourself. 54 | namespace std { 55 | 56 | template <> 57 | struct hash : public std::unary_function { 58 | int operator()(struct port_descriptor const &key) const { 59 | return key.sock_type ^ key.port ^ key.family; 60 | } 61 | }; 62 | 63 | template <> 64 | struct equal_to : public std::binary_function { 66 | bool operator()(struct port_descriptor const &key1, struct port_descriptor const &key2) const { 67 | return key1.sock_type == key2.sock_type 68 | && key1.family == key2.family 69 | && key1.port == key2.port; 70 | } 71 | }; 72 | 73 | } // namespace std 74 | 75 | #endif // PORT_DESCRIPTOR_H_ 76 | -------------------------------------------------------------------------------- /src/ticks_os.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | /** 31 | * @file ticks_os.h 32 | * 33 | * 34 | * @details: Base functions taken from ticks.h in favor of Windows compatibility, 35 | * using QueryPerformanceFrequency() and QueryPerformanceCounter() for max accuracy. 36 | * 37 | * 38 | * @author Meny Yossefi 39 | * 40 | **/ 41 | #ifndef _TICKS_OS_H_ 42 | #define _TICKS_OS_H_ 43 | 44 | #include /* clock_gettime()*/ 45 | #include 46 | #include // for int64_t 47 | #include // for qsort 48 | #include "clock.h" 49 | 50 | typedef int64_t ticks_t; 51 | 52 | #ifdef __windows__ 53 | 54 | #include 55 | #include 56 | 57 | #pragma warning(disable : 4290) // exception specification ignored except to indicate a function is 58 | // not __declspec(nothrow) 59 | #pragma warning(disable \ 60 | : 4996) // The compiler encountered a function that was marked with deprecated. 61 | 62 | #define usleep(x) Sleep(x / 1000) 63 | #define snprintf _snprintf 64 | 65 | #endif 66 | 67 | /** 68 | * RDTSC extensions 69 | */ 70 | #define TSCVAL_INITIALIZER (0) 71 | 72 | static const int64_t NSEC_IN_SEC = 1000 * 1000 * 1000; 73 | // Utility function 74 | inline ticks_t timespec2nsec(const struct timespec &_val) { 75 | return NSEC_IN_SEC * _val.tv_sec + _val.tv_nsec; 76 | } 77 | 78 | inline ticks_t os_gettimeoftsc() { 79 | #ifdef __windows__ 80 | LARGE_INTEGER lp; 81 | double PCFreq = 0.0; 82 | QueryPerformanceFrequency(&lp); 83 | PCFreq = (double(lp.QuadPart)) / (double)NSEC_IN_SEC; // NanoSec 84 | QueryPerformanceCounter(&lp); 85 | lp.QuadPart = (LONGLONG)((lp.QuadPart) / (PCFreq)); 86 | return (ticks_t)(lp.QuadPart); 87 | #else 88 | uint32_t upper_32, lower_32; 89 | 90 | #if defined(__powerpc64__) 91 | unsigned long long ret; 92 | asm volatile("mftb %0" : "=r"(ret) :); 93 | return (ticks_t)ret; 94 | #elif defined(__s390__) 95 | unsigned long long ret; 96 | asm volatile("stck %0" : "=Q"(ret) : : "cc"); 97 | return (ticks_t)ret; 98 | #elif defined(__aarch64__) 99 | uint64_t ret; 100 | asm volatile("isb" : : : "memory"); 101 | asm volatile("mrs %0, cntvct_el0" : "=r" (ret)); 102 | return ret; 103 | #elif defined(__arm__) 104 | // so the compiler will not complain. for 105 | // AArch32 compile, this inline is not used 106 | // since rdtsc is only supported in an optional timer extension 107 | upper_32 = lower_32 = 0; 108 | #else 109 | // ReaD Time Stamp Counter (RDTCS) 110 | __asm__ __volatile__("rdtsc" : "=a"(lower_32), "=d"(upper_32)); 111 | #endif 112 | // Return to user 113 | return (((ticks_t)upper_32) << 32) | lower_32; 114 | #endif 115 | } 116 | 117 | inline void os_ts_gettimeofclock(struct timespec *pts) { 118 | #ifdef __windows__ 119 | ticks_t val = os_gettimeoftsc(); // probably just NSEC_IN_SEC 120 | pts->tv_sec = val / NSEC_IN_SEC; 121 | pts->tv_nsec = val % NSEC_IN_SEC; 122 | #else 123 | 124 | if (clock_gettime(CLOCK_MONOTONIC, pts)) { 125 | throw("clock_gettime failed"); 126 | } 127 | #endif 128 | } 129 | 130 | inline ticks_t os_gettimeofclock() { 131 | struct timespec ts; 132 | os_ts_gettimeofclock(&ts); 133 | return timespec2nsec(ts); 134 | } 135 | 136 | #endif /*_TICKS_OS_H_*/ 137 | -------------------------------------------------------------------------------- /src/tls.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef _TLS_H_ 31 | #define _TLS_H_ 32 | 33 | #if defined(DEFINED_TLS) 34 | 35 | #define TLS_CHIPER_DEFAULT "AES128-GCM-SHA256" 36 | 37 | int tls_init(void); 38 | void tls_exit(void); 39 | void *tls_establish(int fd); 40 | int tls_write(void *handle, const void *buf, int num); 41 | int tls_read(void *handle, void *buf, int num); 42 | const char *tls_chipher(const char *name = NULL); 43 | 44 | #endif /* DEFINED_TLS == 1 */ 45 | 46 | #endif /*_TLS_H_*/ 47 | -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS := gtest 2 | EXTRA_DIST = gtest \ 3 | avner-analyze.awk \ 4 | avner-master-test.sh \ 5 | avner-test.sh \ 6 | avner-test-orig \ 7 | vma_multiplexers_test.sh \ 8 | vma_perf_envelope.sh 9 | -------------------------------------------------------------------------------- /tests/avner-analyze.awk: -------------------------------------------------------------------------------- 1 | #!/bin/awk -f 2 | 3 | # 4 | # This script will nicely analyze output file that was created using ./avner-test or ./avner-test2 5 | # 6 | 7 | /^[ \t]*#/ {print; next} # echo and skip comment line 8 | NF !=3 || $3+0 <= 0 {next} # Skip empty or text lines 9 | { # handle all other lines 10 | nsec = 1000 * $3 11 | sum[$1] += nsec 12 | num[$1] ++ 13 | sum_sqr[$1] += nsec * nsec 14 | } 15 | 16 | END { 17 | for (test in num) { 18 | avg[test] = sum[test] / num[test] 19 | std = (num[test] > 1) ? sqrt ( (sum_sqr[test] - num[test]*avg[test]*avg[test]) / (num[test] - 1) ) : 0 20 | printf "%s: %12s: avg=%.3fusec (std=%.3f, #Observations=%d)\n", FILENAME, test, avg[test]/1000, std/1000, num[test] 21 | } 22 | 23 | for (test in num) { 24 | if (prev) { 25 | printf "====> %s: delta_avg (%s_avg - %s_avg) = %.3fusec\n", FILENAME, prev, test, (avg[prev]-avg[test])/1000 26 | } 27 | else { 28 | printf "====> \n" 29 | } 30 | prev = test 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/avner-master-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 4 | # Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without modification, 8 | # are permitted provided that the following conditions are met: 9 | # 10 | # 1. Redistributions of source code must retain the above copyright notice, 11 | # this list of conditions and the following disclaimer. 12 | # 2. Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 16 | # contributors may be used to endorse or promote products derived from this 17 | # software without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 20 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 22 | # SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 24 | # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 | # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 28 | # OF SUCH DAMAGE. 29 | # 30 | 31 | if [ $# != 1 ] 32 | then 33 | echo "Usage: $0 " 34 | exit 1 35 | fi; 36 | IP=$1 37 | 38 | LOG_DIR=./log/`hostname` 39 | mkdir -p $LOG_DIR 40 | 41 | function clean_up { 42 | # Perform program exit housekeeping 43 | kill %1 %2 %3 %4 # kill any running child 44 | exit 45 | } 46 | 47 | trap clean_up SIGINT SIGTERM SIGHUP 48 | 49 | function run_test() 50 | { 51 | echo -e "\n# >> running test for $RUNTIME; LOG_FILE is: $LOG_DIR/$LOG_FILE\n" 52 | echo "# $MSG" | tee -a $LOG_DIR/$LOG_FILE 53 | ./avner-test.sh $IP | tee -a $LOG_DIR/$LOG_FILE & 54 | 55 | sleep $RUNTIME 56 | kill %1 57 | echo -e \\a #beep 58 | } 59 | 60 | #export VMA_PATH=/volt/avnerb/vma/libvma.so-4.5 61 | #export VMA_PATH=/volt/avnerb/vma/libvma.so-nosend-norecv 62 | #export VMA_PATH=/volt/avnerb/vma/libvma.so-nosocket 63 | #export VMA_PATH=/volt/avnerb/vma/libvma.so-norecv 64 | #export VMA_PATH=/volt/avnerb/vma/libvma.so-nosend 65 | #export VMA_PATH=/volt/avnerb/vma/libvma.so-nosend-norecv-nobind 66 | 67 | #export BASE_ARG="-c -t 4 -m 14" 68 | 69 | 70 | export VMA_RX_OFFLOAD=0 VMA_UC_OFFLOAD=1 71 | export BASE_ARG="-c -t 4 -m 14 --ping-pong --pps=max" 72 | export VMA_PATH=/volt/avnerb/vma/libvma.so-4.5 73 | RUNTIME=300s 74 | LOG_FILE=0.eth_server_ucoff-0.pingmax.rx0ff-0.ucoff-1.server-vma-custom-mc-reply-uc-client-vma4.5 75 | MSG="ETH Server-Command: VMA_IGMP=0 VMA_RX_OFFLOAD=1 VMA_UC_OFFLOAD=0 LD_PRELOAD=/volt/avnerb/vma/libvma.so-4.5 ./sockperf -s -i 226.8.8.8 --force_unicast_reply" 76 | #run_test 77 | 78 | export VMA_RX_OFFLOAD=1 VMA_UC_OFFLOAD=1 79 | export BASE_ARG="-c -t 4 -m 14 --ping-pong --pps=max" 80 | export VMA_PATH=/volt/avnerb/vma/libvma.so-4.5 81 | RUNTIME=300s 82 | LOG_FILE=1.eth_server_ucoff-0.pingmax.rx0ff-1.ucoff-1.server-vma-custom-mc-reply-uc-client-vma4.5 83 | MSG="ETH Server-Command: VMA_IGMP=0 VMA_RX_OFFLOAD=1 VMA_UC_OFFLOAD=0 LD_PRELOAD=/volt/avnerb/vma/libvma.so-4.5 ./sockperf -s -i 226.8.8.8 --force_unicast_reply" 84 | #run_test 85 | 86 | export VMA_RX_OFFLOAD=0 VMA_UC_OFFLOAD=1 87 | export BASE_ARG="-c -t 4 -m 14 --ping-pong --pps=max" 88 | export VMA_PATH=/volt/avnerb/vma/libvma.so-norecv 89 | RUNTIME=300s 90 | LOG_FILE=2.eth_server_ucoff-0.pingmax.rx0ff-0.ucoff-1.server-vma-custom-mc-reply-uc-client-vma-norecv 91 | MSG="ETH Server-Command: VMA_IGMP=0 VMA_RX_OFFLOAD=1 VMA_UC_OFFLOAD=0 LD_PRELOAD=/volt/avnerb/vma/libvma.so-4.5 ./sockperf -s -i 226.8.8.8 --force_unicast_reply" 92 | #run_test 93 | 94 | 95 | export VMA_RX_OFFLOAD=0 VMA_UC_OFFLOAD=1 96 | export BASE_ARG="-c -t 4 -m 14 --ping-pong --pps=max" 97 | export VMA_PATH=/volt/avnerb/vma/libvma.so-4.5 98 | RUNTIME=300s 99 | LOG_FILE=3.eth_server_ucoff-1.pingmax.rx0ff-0.ucoff-1.server-vma-custom-mc-reply-uc-client-vma4.5 100 | MSG="ETH Server-Command: VMA_IGMP=0 VMA_RX_OFFLOAD=1 VMA_UC_OFFLOAD=1 LD_PRELOAD=/volt/avnerb/vma/libvma.so-4.5 ./sockperf -s -i 226.8.8.8 --force_unicast_reply" 101 | run_test 102 | 103 | export VMA_RX_OFFLOAD=1 VMA_UC_OFFLOAD=1 104 | export BASE_ARG="-c -t 4 -m 14 --ping-pong --pps=max" 105 | export VMA_PATH=/volt/avnerb/vma/libvma.so-4.5 106 | RUNTIME=300s 107 | LOG_FILE=4.eth_server_ucoff-1.pingmax.rx0ff-1.ucoff-1.server-vma-custom-mc-reply-uc-client-vma4.5 108 | MSG="ETH Server-Command: VMA_IGMP=0 VMA_RX_OFFLOAD=1 VMA_UC_OFFLOAD=1 LD_PRELOAD=/volt/avnerb/vma/libvma.so-4.5 ./sockperf -s -i 226.8.8.8 --force_unicast_reply" 109 | run_test 110 | 111 | export VMA_RX_OFFLOAD=0 VMA_UC_OFFLOAD=1 112 | export BASE_ARG="-c -t 4 -m 14 --ping-pong --pps=max" 113 | export VMA_PATH=/volt/avnerb/vma/libvma.so-norecv 114 | RUNTIME=300s 115 | LOG_FILE=5.eth_server_ucoff-1.pingmax.rx0ff-0.ucoff-1.server-vma-custom-mc-reply-uc-client-vma-norecv 116 | MSG="ETH Server-Command: VMA_IGMP=0 VMA_RX_OFFLOAD=1 VMA_UC_OFFLOAD=1 LD_PRELOAD=/volt/avnerb/vma/libvma.so-4.5 ./sockperf -s -i 226.8.8.8 --force_unicast_reply" 117 | run_test 118 | 119 | -------------------------------------------------------------------------------- /tests/avner-test-orig: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #export VMA_IGMP=0 LD_PRELOAD=libvma.so 4 | 5 | #BASE_ARG="-c -t 10 -m 14 -i 224.99.200.8" 6 | BASE_ARG="-c -t 10 -m 14 -F e -f conf/conf25.inp" 7 | 8 | while true 9 | do 10 | CMD="udp_lat "; ARG=${BASE_ARG}5; sleep 1 11 | echo -n "$CMD : ";VMA_IGMP=0 LD_PRELOAD=libvma.so $CMD $ARG 2> /dev/null | grep "Summary: Latency is " | awk '{print $5}' 12 | 13 | #CMD="udp_lat "; ARG=${BASE_ARG}5; sleep 1 14 | #echo -n "$CMD : ";VMA_IGMP=0 LD_PRELOAD=libvma.so $CMD $ARG 2> /dev/null | grep "Summary: Latency is " | awk '{print $5}' 15 | 16 | CMD="./sockperf "; ARG="${BASE_ARG}4 --ping-pong"; sleep 1 17 | echo -n "$CMD : ";VMA_IGMP=0 LD_PRELOAD=libvma.so $CMD $ARG 2> /dev/null | grep "Summary: Latency is " | awk '{print $5}' 18 | 19 | #CMD="././sockperf"; ARG="${BASE_ARG}4 --reply-every=1"; sleep 1 20 | #echo -n "$CMD : ";VMA_IGMP=0 LD_PRELOAD=libvma.so $CMD $ARG 2> /dev/null | grep "Summary: Latency is " | awk '{print $5}' 21 | 22 | echo --- 23 | done 24 | -------------------------------------------------------------------------------- /tests/avner-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 4 | # Copyright (c) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without modification, 8 | # are permitted provided that the following conditions are met: 9 | # 10 | # 1. Redistributions of source code must retain the above copyright notice, 11 | # this list of conditions and the following disclaimer. 12 | # 2. Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 16 | # contributors may be used to endorse or promote products derived from this 17 | # software without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 20 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 22 | # SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 24 | # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 | # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 28 | # OF SUCH DAMAGE. 29 | # 30 | 31 | 32 | if [ $# != 1 ] 33 | then 34 | echo "Usage: $0 " 35 | exit 1 36 | fi; 37 | IP=$1 38 | 39 | function clean_up { 40 | # Perform program exit housekeeping 41 | kill %1 %2 %3 %4 # kill any running child 42 | exit 43 | } 44 | 45 | trap clean_up SIGINT SIGTERM SIGHUP 46 | 47 | echo \# FILTER = percentile 75 48 | #echo \# FILTER = Message Rate 49 | 50 | echo \# VMA_PATH = $VMA_PATH 51 | echo \# BASE_ARG = $BASE_ARG 52 | echo \# Server-IP = $IP 53 | 54 | export | awk '/VMA/ {print "#", $0}' 55 | 56 | while true 57 | do 58 | CMD="./sockperf "; ARG="${BASE_ARG} -i $IP"; 59 | sleep 1 60 | echo -n "OS : ";_D_PRELOAD=$VMA_PATH $CMD $ARG 2> /dev/null | awk '/dropped packets/ && $6+$11+$16 {printf("#%s\n#", $0) } /percentile 75/{print $6}' 61 | #echo -n "OS : ";_D_PRELOAD=$VMA_PATH $CMD $ARG 2> /dev/null | awk '/Message Rate/{print $6}' 62 | sleep 1 63 | echo -n "VMA : ";LD_PRELOAD=$VMA_PATH $CMD $ARG 2> /dev/null | awk '/dropped packets/ && $6+$11+$16 {printf("#%s\n#", $0) } /percentile 75/{print $6}' 64 | #echo -n "VMA : ";LD_PRELOAD=$VMA_PATH $CMD $ARG 2> /dev/null | awk '/Message Rate/{print $6}' 65 | 66 | echo --- 67 | done 68 | -------------------------------------------------------------------------------- /tests/gtest/Makefile.am: -------------------------------------------------------------------------------- 1 | noinst_PROGRAMS = gtest 2 | 3 | #CXXFLAGS = 4 | # google test shows some warnings that are suppressed 5 | AM_CXXFLAGS = \ 6 | -Wno-error=sign-compare \ 7 | -Wno-error=missing-field-initializers \ 8 | -g -O0 9 | 10 | AM_CPPFLAGS = \ 11 | -DGTEST_LANG_CXX11=0 \ 12 | -DGTEST_HAS_PTHREAD=1 \ 13 | -DGTEST_USE_OWN_TR1_TUPLE=0 \ 14 | -DGTEST_HAS_TR1_TUPLE=1 \ 15 | -DGTEST_ENV_HAS_STD_TUPLE_=0 \ 16 | -DGTEST_USES_SIMPLE_RE=0 \ 17 | -DPTHREADS \ 18 | \ 19 | -DGTEST_DONT_DEFINE_ASSERT_GT=0 \ 20 | -DGTEST_DONT_DEFINE_ASSERT_GE=0 \ 21 | -DGTEST_DONT_DEFINE_ASSERT_LT=0 \ 22 | -DGTEST_DONT_DEFINE_ASSERT_LE=0 \ 23 | -DGTEST_DONT_DEFINE_ASSERT_NE=0 \ 24 | -DGTEST_DONT_DEFINE_ASSERT_EQ=0 \ 25 | -DGTEST_DONT_DEFINE_SUCCEED=0 \ 26 | -DGTEST_DONT_DEFINE_FAIL=0 \ 27 | -DGTEST_DONT_DEFINE_TEST=0 \ 28 | \ 29 | -DGTEST_HAS_STD_WSTRING=0 \ 30 | -DGTEST_HAS_GLOBAL_STRING=0 \ 31 | \ 32 | -DGTEST_OS_WINDOWS=0 \ 33 | -DGTEST_OS_LINUX_ANDROID=0 \ 34 | -DGTEST_OS_CYGWIN=0 \ 35 | -DGTEST_OS_SOLARIS=0 \ 36 | -DGTEST_OS_SYMBIAN=0 \ 37 | -DGTEST_OS_WINDOWS_MOBILE=0 \ 38 | -DGTEST_OS_QNX=0 \ 39 | -DGTEST_OS_MAC=0 \ 40 | -DGTEST_OS_IOS=0 \ 41 | -DGTEST_OS_ZOS 42 | 43 | # lgtest 44 | noinst_LTLIBRARIES = libgtest.la 45 | 46 | libgtest_la_CPPFLAGS = \ 47 | -I$(top_srcdir)/tests/gtest/googletest \ 48 | -I$(top_srcdir)/tests/gtest/googletest/include \ 49 | $(AM_CPPFLAGS) 50 | 51 | libgtest_la_LDFLAGS = -pthread -static 52 | libgtest_la_CXXFLAGS = \ 53 | $(AM_CXXFLAGS) 54 | 55 | EXTRA_DIST = \ 56 | googletest/include \ 57 | googletest/src \ 58 | googletest/README.md \ 59 | googletest/LICENSE 60 | 61 | libgtest_la_SOURCES = \ 62 | googletest/src/gtest-all.cc \ 63 | googletest/src/gtest_main.cc 64 | 65 | # gtest 66 | gtest_LDADD = libgtest.la 67 | 68 | gtest_CPPFLAGS = \ 69 | -I$(top_srcdir)/ \ 70 | -I$(top_srcdir)/src \ 71 | -I$(top_srcdir)/tests/gtest/googletest/include \ 72 | $(AM_CPPFLAGS) 73 | 74 | gtest_LDFLAGS = -no-install 75 | gtest_CXXFLAGS = \ 76 | $(AM_CXXFLAGS) 77 | 78 | gtest_SOURCES = \ 79 | main.cpp \ 80 | \ 81 | message_parser_tests.cpp 82 | 83 | noinst_HEADERS = 84 | 85 | gtest_DEPENDENCIES = \ 86 | libgtest.la 87 | 88 | # This workaround allows to compile files located 89 | # at another directory. 90 | # This place resolve make distcheck issue 91 | nodist_gtest_SOURCES = \ 92 | defs.cpp \ 93 | message.cpp \ 94 | os_abstract.cpp 95 | 96 | CLEANFILES = \ 97 | defs.cpp \ 98 | message.cpp \ 99 | os_abstract.cpp 100 | 101 | defs.cpp: 102 | @echo "#include \"$(top_builddir)/src/$@\"" >$@ 103 | 104 | message.cpp: 105 | @echo "#include \"$(top_builddir)/src/$@\"" >$@ 106 | 107 | os_abstract.cpp: 108 | @echo "#include \"$(top_builddir)/src/$@\"" >$@ 109 | -------------------------------------------------------------------------------- /tests/gtest/common/tap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2011 Bruno P. Kinoshita 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | * 24 | * @author Bruno P. Kinoshita 25 | * @since 0.1 26 | */ 27 | 28 | #ifndef TAP_H_ 29 | #define TAP_H_ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | namespace tap { 39 | 40 | #ifdef GTEST_TAP_13_DIAGNOSTIC 41 | // based on http://stackoverflow.com/a/7724536/831180 42 | static std::string replace_all_copy( 43 | std::string const& original, 44 | std::string const& before, 45 | std::string const& after 46 | ) { 47 | using namespace std; 48 | 49 | if (before == after) return string(original); 50 | 51 | string retval; 52 | if (before.length() == after.length()) retval.reserve(original.size()); 53 | 54 | basic_string ::const_iterator end = original.end(); 55 | basic_string ::const_iterator current = original.begin(); 56 | basic_string ::const_iterator next = 57 | search(current, end, before.begin(), before.end()); 58 | 59 | while ( next != end ) { 60 | retval.append( current, next ); 61 | retval.append( after ); 62 | current = next + before.size(); 63 | next = search(current, end, before.begin(), before.end()); 64 | } 65 | retval.append( current, next ); 66 | return retval; 67 | } 68 | #endif 69 | 70 | class TestResult { 71 | 72 | private: 73 | int number; 74 | std::string status; 75 | std::string name; 76 | std::string comment; 77 | bool skip; 78 | 79 | public: 80 | std::string getComment() const { 81 | std::stringstream ss; 82 | if (this->skip) { 83 | ss << "# SKIP " << this->comment; 84 | } else if (!this->comment.empty()) { 85 | ss << "# " << this->comment; 86 | } 87 | return ss.str(); 88 | } 89 | 90 | const std::string& getName() const { 91 | return name; 92 | } 93 | 94 | int getNumber() const { 95 | return number; 96 | } 97 | 98 | const std::string& getStatus() const { 99 | return status; 100 | } 101 | 102 | bool getSkip() const { 103 | return skip; 104 | } 105 | 106 | void setComment(const std::string& value) { 107 | this->comment = value; 108 | } 109 | 110 | void setName(const std::string& value) { 111 | this->name = value; 112 | } 113 | 114 | void setNumber(int value) { 115 | this->number = value; 116 | } 117 | 118 | void setStatus(const std::string& value) { 119 | this->status = value; 120 | } 121 | 122 | void setSkip(bool value) { 123 | this->skip = value; 124 | } 125 | 126 | std::string toString() const { 127 | std::stringstream ss; 128 | ss << this->status << " " << this->number << " " << this->name; 129 | #ifdef GTEST_TAP_13_DIAGNOSTIC 130 | std::string comment_text = this->getComment(); 131 | if (!comment_text.empty()) { 132 | ss << std::endl 133 | << "# Diagnostic" << std::endl 134 | << " ---" << std::endl 135 | << " " << replace_all_copy(this->getComment(), "\n", "\n "); 136 | } 137 | #endif 138 | return ss.str(); 139 | } 140 | }; 141 | 142 | class TestSet { 143 | 144 | private: 145 | std::list testResults; 146 | 147 | public: 148 | const std::list& getTestResults() const { 149 | return testResults; 150 | } 151 | 152 | void addTestResult(TestResult& testResult) { 153 | testResult.setNumber((this->getNumberOfTests() + 1)); 154 | this->testResults.push_back(testResult); 155 | } 156 | 157 | int getNumberOfTests() const { 158 | return this->testResults.size(); 159 | } 160 | 161 | std::string toString() const { 162 | std::stringstream ss; 163 | ss << "1.." << this->getNumberOfTests() << std::endl; 164 | for (std::list::const_iterator ci = this->testResults.begin(); 165 | ci != this->testResults.end(); ++ci) { 166 | TestResult testResult = *ci; 167 | ss << testResult.toString() << std::endl; 168 | } 169 | return ss.str(); 170 | } 171 | }; 172 | 173 | class TapListener: public ::testing::EmptyTestEventListener { 174 | 175 | private: 176 | std::map testCaseTestResultMap; 177 | 178 | void addTapTestResult(const testing::TestInfo& testInfo) { 179 | tap::TestResult tapResult; 180 | tapResult.setName(testInfo.name()); 181 | tapResult.setSkip(!testInfo.should_run()); 182 | 183 | const testing::TestResult *testResult = testInfo.result(); 184 | int number = testResult->total_part_count(); 185 | tapResult.setNumber(number-1); 186 | if (testResult->HasFatalFailure()) { 187 | tapResult.setStatus("Bail out!"); 188 | } else if (testResult->Failed()) { 189 | tapResult.setStatus("not ok"); 190 | tapResult.setComment(testResult->GetTestPartResult(number-1).summary()); 191 | } else { 192 | tapResult.setStatus("ok"); 193 | } 194 | 195 | this->addNewOrUpdate(testInfo.test_case_name(), tapResult); 196 | } 197 | 198 | std::string getCommentOrDirective(const std::string& comment, bool skip) { 199 | std::stringstream commentText; 200 | 201 | if (skip) { 202 | commentText << " # SKIP " << comment; 203 | } else if (!comment.empty()) { 204 | commentText << " # " << comment; 205 | } 206 | 207 | return commentText.str(); 208 | } 209 | 210 | void addNewOrUpdate(const std::string& testCaseName, tap::TestResult testResult) { 211 | std::map::const_iterator ci = 212 | this->testCaseTestResultMap.find(testCaseName); 213 | if (ci != this->testCaseTestResultMap.end()) { 214 | tap::TestSet testSet = ci->second; 215 | testSet.addTestResult(testResult); 216 | this->testCaseTestResultMap[testCaseName] = testSet; 217 | } else { 218 | tap::TestSet testSet; 219 | testSet.addTestResult(testResult); 220 | this->testCaseTestResultMap[testCaseName] = testSet; 221 | } 222 | } 223 | 224 | public: 225 | virtual void OnTestEnd(const testing::TestInfo& testInfo) { 226 | //printf("%s %d - %s\n", testInfo.result()->Passed() ? "ok" : "not ok", this->testNumber, testInfo.name()); 227 | this->addTapTestResult(testInfo); 228 | } 229 | 230 | virtual void OnTestProgramEnd(const testing::UnitTest& unit_test) { 231 | //--- Write the count and the word. 232 | (void)unit_test; 233 | std::map::const_iterator ci; 234 | for (ci = this->testCaseTestResultMap.begin(); 235 | ci != this->testCaseTestResultMap.end(); ++ci) { 236 | const tap::TestSet& testSet = ci->second; 237 | #ifdef GTEST_TAP_PRINT_TO_STDOUT 238 | std::cout << "TAP version 13" << std::endl; 239 | std::cout << testSet.toString(); 240 | #else 241 | std::string ext = ".tap"; 242 | std::ofstream tapFile; 243 | tapFile.open((ci->first + ext).c_str()); 244 | tapFile << testSet.toString(); 245 | tapFile.close(); 246 | #endif 247 | } 248 | } 249 | }; 250 | 251 | } // namespace tap 252 | 253 | #endif // TAP_H_ 254 | -------------------------------------------------------------------------------- /tests/gtest/googletest/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2008, Google Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /tests/gtest/googletest/README.md: -------------------------------------------------------------------------------- 1 | # Google Test 2 | 3 | This directory contains minimum set of needed source code of Google Test release-1.7.0 4 | (see full package at https://github.com/google/googletest/releases/tag/release-1.7.0) 5 | with following back ported commits: 6 | 7 | 1. commit 15dde751ff5ea0f21f2a7182186be4564f30adc7 8 | Author: Arseny Aprelev 9 | Date: Mon Oct 1 16:47:09 2018 -0400 10 | 11 | Merge 2ce0685f76a4db403b7b2650433a584c150f2108 into 75e834700d19aa373b428c7c746f951737354c28 12 | 13 | Closes #1544 14 | With refinements and changes 15 | 16 | PiperOrigin-RevId: 215273083 17 | 18 | 2. commit 59f90a338bce2376b540ee239cf4e269bf6d68ad (HEAD) 19 | Author: durandal 20 | Date: Tue Oct 23 15:31:17 2018 -0400 21 | 22 | Googletest export 23 | 24 | Honor GTEST_SKIP() in SetUp(). 25 | 26 | PiperOrigin-RevId: 218387359 27 | -------------------------------------------------------------------------------- /tests/gtest/googletest/include/gtest/gtest-test-part.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | 33 | #ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 34 | #define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 35 | 36 | #include 37 | #include 38 | #include "gtest/internal/gtest-internal.h" 39 | #include "gtest/internal/gtest-string.h" 40 | 41 | namespace testing { 42 | 43 | // A copyable object representing the result of a test part (i.e. an 44 | // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). 45 | // 46 | // Don't inherit from TestPartResult as its destructor is not virtual. 47 | class GTEST_API_ TestPartResult { 48 | public: 49 | // The possible outcomes of a test part (i.e. an assertion or an 50 | // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). 51 | enum Type { 52 | kSuccess, // Succeeded. 53 | kNonFatalFailure, // Failed but the test can continue. 54 | kFatalFailure, // Failed and the test should be terminated. 55 | kSkip // Skipped. 56 | }; 57 | 58 | // C'tor. TestPartResult does NOT have a default constructor. 59 | // Always use this constructor (with parameters) to create a 60 | // TestPartResult object. 61 | TestPartResult(Type a_type, 62 | const char* a_file_name, 63 | int a_line_number, 64 | const char* a_message) 65 | : type_(a_type), 66 | file_name_(a_file_name == NULL ? "" : a_file_name), 67 | line_number_(a_line_number), 68 | summary_(ExtractSummary(a_message)), 69 | message_(a_message) { 70 | } 71 | 72 | // Gets the outcome of the test part. 73 | Type type() const { return type_; } 74 | 75 | // Gets the name of the source file where the test part took place, or 76 | // NULL if it's unknown. 77 | const char* file_name() const { 78 | return file_name_.empty() ? NULL : file_name_.c_str(); 79 | } 80 | 81 | // Gets the line in the source file where the test part took place, 82 | // or -1 if it's unknown. 83 | int line_number() const { return line_number_; } 84 | 85 | // Gets the summary of the failure message. 86 | const char* summary() const { return summary_.c_str(); } 87 | 88 | // Gets the message associated with the test part. 89 | const char* message() const { return message_.c_str(); } 90 | 91 | // Returns true iff the test part was skipped. 92 | bool skipped() const { return type_ == kSkip; } 93 | 94 | // Returns true iff the test part passed. 95 | bool passed() const { return type_ == kSuccess; } 96 | 97 | // Returns true iff the test part non-fatally failed. 98 | bool nonfatally_failed() const { return type_ == kNonFatalFailure; } 99 | 100 | // Returns true iff the test part fatally failed. 101 | bool fatally_failed() const { return type_ == kFatalFailure; } 102 | 103 | // Returns true iff the test part failed. 104 | bool failed() const { return fatally_failed() || nonfatally_failed(); } 105 | 106 | private: 107 | Type type_; 108 | 109 | // Gets the summary of the failure message by omitting the stack 110 | // trace in it. 111 | static std::string ExtractSummary(const char* message); 112 | 113 | // The name of the source file where the test part took place, or 114 | // "" if the source file is unknown. 115 | std::string file_name_; 116 | // The line in the source file where the test part took place, or -1 117 | // if the line number is unknown. 118 | int line_number_; 119 | std::string summary_; // The test failure summary. 120 | std::string message_; // The test failure message. 121 | }; 122 | 123 | // Prints a TestPartResult object. 124 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result); 125 | 126 | // An array of TestPartResult objects. 127 | // 128 | // Don't inherit from TestPartResultArray as its destructor is not 129 | // virtual. 130 | class GTEST_API_ TestPartResultArray { 131 | public: 132 | TestPartResultArray() {} 133 | 134 | // Appends the given TestPartResult to the array. 135 | void Append(const TestPartResult& result); 136 | 137 | // Returns the TestPartResult at the given index (0-based). 138 | const TestPartResult& GetTestPartResult(int index) const; 139 | 140 | // Returns the number of TestPartResult objects in the array. 141 | int size() const; 142 | 143 | private: 144 | std::vector array_; 145 | 146 | GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); 147 | }; 148 | 149 | // This interface knows how to report a test part result. 150 | class TestPartResultReporterInterface { 151 | public: 152 | virtual ~TestPartResultReporterInterface() {} 153 | 154 | virtual void ReportTestPartResult(const TestPartResult& result) = 0; 155 | }; 156 | 157 | namespace internal { 158 | 159 | // This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a 160 | // statement generates new fatal failures. To do so it registers itself as the 161 | // current test part result reporter. Besides checking if fatal failures were 162 | // reported, it only delegates the reporting to the former result reporter. 163 | // The original result reporter is restored in the destructor. 164 | // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 165 | class GTEST_API_ HasNewFatalFailureHelper 166 | : public TestPartResultReporterInterface { 167 | public: 168 | HasNewFatalFailureHelper(); 169 | virtual ~HasNewFatalFailureHelper(); 170 | virtual void ReportTestPartResult(const TestPartResult& result); 171 | bool has_new_fatal_failure() const { return has_new_fatal_failure_; } 172 | private: 173 | bool has_new_fatal_failure_; 174 | TestPartResultReporterInterface* original_reporter_; 175 | 176 | GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); 177 | }; 178 | 179 | } // namespace internal 180 | 181 | } // namespace testing 182 | 183 | #endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 184 | -------------------------------------------------------------------------------- /tests/gtest/googletest/include/gtest/gtest_prod.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | // 32 | // Google C++ Testing Framework definitions useful in production code. 33 | 34 | #ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 35 | #define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 36 | 37 | // When you need to test the private or protected members of a class, 38 | // use the FRIEND_TEST macro to declare your tests as friends of the 39 | // class. For example: 40 | // 41 | // class MyClass { 42 | // private: 43 | // void MyMethod(); 44 | // FRIEND_TEST(MyClassTest, MyMethod); 45 | // }; 46 | // 47 | // class MyClassTest : public testing::Test { 48 | // // ... 49 | // }; 50 | // 51 | // TEST_F(MyClassTest, MyMethod) { 52 | // // Can call MyClass::MyMethod() here. 53 | // } 54 | 55 | #define FRIEND_TEST(test_case_name, test_name)\ 56 | friend class test_case_name##_##test_name##_Test 57 | 58 | #endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 59 | -------------------------------------------------------------------------------- /tests/gtest/googletest/include/gtest/internal/gtest-string.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) 31 | // 32 | // The Google C++ Testing Framework (Google Test) 33 | // 34 | // This header file declares the String class and functions used internally by 35 | // Google Test. They are subject to change without notice. They should not used 36 | // by code external to Google Test. 37 | // 38 | // This header file is #included by . 39 | // It should not be #included by other files. 40 | 41 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 42 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 43 | 44 | #ifdef __BORLANDC__ 45 | // string.h is not guaranteed to provide strcpy on C++ Builder. 46 | # include 47 | #endif 48 | 49 | #include 50 | #include 51 | 52 | #include "gtest/internal/gtest-port.h" 53 | 54 | namespace testing { 55 | namespace internal { 56 | 57 | // String - an abstract class holding static string utilities. 58 | class GTEST_API_ String { 59 | public: 60 | // Static utility methods 61 | 62 | // Clones a 0-terminated C string, allocating memory using new. The 63 | // caller is responsible for deleting the return value using 64 | // delete[]. Returns the cloned string, or NULL if the input is 65 | // NULL. 66 | // 67 | // This is different from strdup() in string.h, which allocates 68 | // memory using malloc(). 69 | static const char* CloneCString(const char* c_str); 70 | 71 | #if GTEST_OS_WINDOWS_MOBILE 72 | // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be 73 | // able to pass strings to Win32 APIs on CE we need to convert them 74 | // to 'Unicode', UTF-16. 75 | 76 | // Creates a UTF-16 wide string from the given ANSI string, allocating 77 | // memory using new. The caller is responsible for deleting the return 78 | // value using delete[]. Returns the wide string, or NULL if the 79 | // input is NULL. 80 | // 81 | // The wide string is created using the ANSI codepage (CP_ACP) to 82 | // match the behaviour of the ANSI versions of Win32 calls and the 83 | // C runtime. 84 | static LPCWSTR AnsiToUtf16(const char* c_str); 85 | 86 | // Creates an ANSI string from the given wide string, allocating 87 | // memory using new. The caller is responsible for deleting the return 88 | // value using delete[]. Returns the ANSI string, or NULL if the 89 | // input is NULL. 90 | // 91 | // The returned string is created using the ANSI codepage (CP_ACP) to 92 | // match the behaviour of the ANSI versions of Win32 calls and the 93 | // C runtime. 94 | static const char* Utf16ToAnsi(LPCWSTR utf16_str); 95 | #endif 96 | 97 | // Compares two C strings. Returns true iff they have the same content. 98 | // 99 | // Unlike strcmp(), this function can handle NULL argument(s). A 100 | // NULL C string is considered different to any non-NULL C string, 101 | // including the empty string. 102 | static bool CStringEquals(const char* lhs, const char* rhs); 103 | 104 | // Converts a wide C string to a String using the UTF-8 encoding. 105 | // NULL will be converted to "(null)". If an error occurred during 106 | // the conversion, "(failed to convert from wide string)" is 107 | // returned. 108 | static std::string ShowWideCString(const wchar_t* wide_c_str); 109 | 110 | // Compares two wide C strings. Returns true iff they have the same 111 | // content. 112 | // 113 | // Unlike wcscmp(), this function can handle NULL argument(s). A 114 | // NULL C string is considered different to any non-NULL C string, 115 | // including the empty string. 116 | static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); 117 | 118 | // Compares two C strings, ignoring case. Returns true iff they 119 | // have the same content. 120 | // 121 | // Unlike strcasecmp(), this function can handle NULL argument(s). 122 | // A NULL C string is considered different to any non-NULL C string, 123 | // including the empty string. 124 | static bool CaseInsensitiveCStringEquals(const char* lhs, 125 | const char* rhs); 126 | 127 | // Compares two wide C strings, ignoring case. Returns true iff they 128 | // have the same content. 129 | // 130 | // Unlike wcscasecmp(), this function can handle NULL argument(s). 131 | // A NULL C string is considered different to any non-NULL wide C string, 132 | // including the empty string. 133 | // NB: The implementations on different platforms slightly differ. 134 | // On windows, this method uses _wcsicmp which compares according to LC_CTYPE 135 | // environment variable. On GNU platform this method uses wcscasecmp 136 | // which compares according to LC_CTYPE category of the current locale. 137 | // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the 138 | // current locale. 139 | static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, 140 | const wchar_t* rhs); 141 | 142 | // Returns true iff the given string ends with the given suffix, ignoring 143 | // case. Any string is considered to end with an empty suffix. 144 | static bool EndsWithCaseInsensitive( 145 | const std::string& str, const std::string& suffix); 146 | 147 | // Formats an int value as "%02d". 148 | static std::string FormatIntWidth2(int value); // "%02d" for width == 2 149 | 150 | // Formats an int value as "%X". 151 | static std::string FormatHexInt(int value); 152 | 153 | // Formats a byte as "%02X". 154 | static std::string FormatByte(unsigned char value); 155 | 156 | private: 157 | String(); // Not meant to be instantiated. 158 | }; // class String 159 | 160 | // Gets the content of the stringstream's buffer as an std::string. Each '\0' 161 | // character in the buffer is replaced with "\\0". 162 | GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); 163 | 164 | } // namespace internal 165 | } // namespace testing 166 | 167 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 168 | -------------------------------------------------------------------------------- /tests/gtest/googletest/src/gtest-all.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | // Google C++ Testing Framework (Google Test) 33 | // 34 | // Sometimes it's desirable to build Google Test by compiling a single file. 35 | // This file serves this purpose. 36 | 37 | // This line ensures that gtest.h can be compiled on its own, even 38 | // when it's fused. 39 | #include "gtest/gtest.h" 40 | 41 | // The following lines pull in the real gtest *.cc files. 42 | #include "src/gtest.cc" 43 | #include "src/gtest-death-test.cc" 44 | #include "src/gtest-filepath.cc" 45 | #include "src/gtest-port.cc" 46 | #include "src/gtest-printers.cc" 47 | #include "src/gtest-test-part.cc" 48 | #include "src/gtest-typed-test.cc" 49 | -------------------------------------------------------------------------------- /tests/gtest/googletest/src/gtest-test-part.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | // The Google C++ Testing Framework (Google Test) 33 | 34 | #include "gtest/gtest-test-part.h" 35 | 36 | // Indicates that this translation unit is part of Google Test's 37 | // implementation. It must come before gtest-internal-inl.h is 38 | // included, or there will be a compiler error. This trick is to 39 | // prevent a user from accidentally including gtest-internal-inl.h in 40 | // his code. 41 | #define GTEST_IMPLEMENTATION_ 1 42 | #include "src/gtest-internal-inl.h" 43 | #undef GTEST_IMPLEMENTATION_ 44 | 45 | namespace testing { 46 | 47 | using internal::GetUnitTestImpl; 48 | 49 | // Gets the summary of the failure message by omitting the stack trace 50 | // in it. 51 | std::string TestPartResult::ExtractSummary(const char* message) { 52 | const char* const stack_trace = strstr(message, internal::kStackTraceMarker); 53 | return stack_trace == NULL ? message : 54 | std::string(message, stack_trace); 55 | } 56 | 57 | // Prints a TestPartResult object. 58 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { 59 | return os << result.file_name() << ":" << result.line_number() << ": " 60 | << (result.type() == TestPartResult::kSuccess 61 | ? "Success" 62 | : result.type() == TestPartResult::kSkip 63 | ? "Skipped" 64 | : result.type() == TestPartResult::kFatalFailure 65 | ? "Fatal failure" 66 | : "Non-fatal failure") 67 | << ":\n" 68 | << result.message() << std::endl; 69 | } 70 | 71 | // Appends a TestPartResult to the array. 72 | void TestPartResultArray::Append(const TestPartResult& result) { 73 | array_.push_back(result); 74 | } 75 | 76 | // Returns the TestPartResult at the given index (0-based). 77 | const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { 78 | if (index < 0 || index >= size()) { 79 | printf("\nInvalid index (%d) into TestPartResultArray.\n", index); 80 | internal::posix::Abort(); 81 | } 82 | 83 | return array_[index]; 84 | } 85 | 86 | // Returns the number of TestPartResult objects in the array. 87 | int TestPartResultArray::size() const { 88 | return static_cast(array_.size()); 89 | } 90 | 91 | namespace internal { 92 | 93 | HasNewFatalFailureHelper::HasNewFatalFailureHelper() 94 | : has_new_fatal_failure_(false), 95 | original_reporter_(GetUnitTestImpl()-> 96 | GetTestPartResultReporterForCurrentThread()) { 97 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); 98 | } 99 | 100 | HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { 101 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( 102 | original_reporter_); 103 | } 104 | 105 | void HasNewFatalFailureHelper::ReportTestPartResult( 106 | const TestPartResult& result) { 107 | if (result.fatally_failed()) 108 | has_new_fatal_failure_ = true; 109 | original_reporter_->ReportTestPartResult(result); 110 | } 111 | 112 | } // namespace internal 113 | 114 | } // namespace testing 115 | -------------------------------------------------------------------------------- /tests/gtest/googletest/src/gtest-typed-test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008 Google Inc. 2 | // All Rights Reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | #include "gtest/gtest.h" 33 | #include "gtest/gtest-typed-test.h" 34 | 35 | namespace testing { 36 | namespace internal { 37 | 38 | #if GTEST_HAS_TYPED_TEST_P 39 | 40 | // Skips to the first non-space char in str. Returns an empty string if str 41 | // contains only whitespace characters. 42 | static const char* SkipSpaces(const char* str) { 43 | while (IsSpace(*str)) 44 | str++; 45 | return str; 46 | } 47 | 48 | // Verifies that registered_tests match the test names in 49 | // defined_test_names_; returns registered_tests if successful, or 50 | // aborts the program otherwise. 51 | const char* TypedTestCasePState::VerifyRegisteredTestNames( 52 | const char* file, int line, const char* registered_tests) { 53 | typedef ::std::set::const_iterator DefinedTestIter; 54 | registered_ = true; 55 | 56 | // Skip initial whitespace in registered_tests since some 57 | // preprocessors prefix stringizied literals with whitespace. 58 | registered_tests = SkipSpaces(registered_tests); 59 | 60 | Message errors; 61 | ::std::set tests; 62 | for (const char* names = registered_tests; names != NULL; 63 | names = SkipComma(names)) { 64 | const std::string name = GetPrefixUntilComma(names); 65 | if (tests.count(name) != 0) { 66 | errors << "Test " << name << " is listed more than once.\n"; 67 | continue; 68 | } 69 | 70 | bool found = false; 71 | for (DefinedTestIter it = defined_test_names_.begin(); 72 | it != defined_test_names_.end(); 73 | ++it) { 74 | if (name == *it) { 75 | found = true; 76 | break; 77 | } 78 | } 79 | 80 | if (found) { 81 | tests.insert(name); 82 | } else { 83 | errors << "No test named " << name 84 | << " can be found in this test case.\n"; 85 | } 86 | } 87 | 88 | for (DefinedTestIter it = defined_test_names_.begin(); 89 | it != defined_test_names_.end(); 90 | ++it) { 91 | if (tests.count(*it) == 0) { 92 | errors << "You forgot to list test " << *it << ".\n"; 93 | } 94 | } 95 | 96 | const std::string& errors_str = errors.GetString(); 97 | if (errors_str != "") { 98 | fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), 99 | errors_str.c_str()); 100 | fflush(stderr); 101 | posix::Abort(); 102 | } 103 | 104 | return registered_tests; 105 | } 106 | 107 | #endif // GTEST_HAS_TYPED_TEST_P 108 | 109 | } // namespace internal 110 | } // namespace testing 111 | -------------------------------------------------------------------------------- /tests/gtest/googletest/src/gtest_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #include 31 | 32 | #include "gtest/gtest.h" 33 | 34 | GTEST_API_ int main(int argc, char **argv) { 35 | printf("Running main() from gtest_main.cc\n"); 36 | testing::InitGoogleTest(&argc, argv); 37 | return RUN_ALL_TESTS(); 38 | } 39 | -------------------------------------------------------------------------------- /tests/gtest/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES 3 | * Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the Mellanox Technologies Ltd nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | */ 29 | 30 | #include "gtest/gtest.h" 31 | #include "common/tap.h" 32 | 33 | #include "defs.h" 34 | #include "message.h" 35 | 36 | GTEST_API_ int main(int argc, char **argv) 37 | { 38 | testing::InitGoogleTest(&argc, argv); 39 | Message::initMaxSize(MAX_PAYLOAD_SIZE); 40 | Message::initMaxSeqNo(65535); 41 | 42 | char *str = getenv("GTEST_TAP"); 43 | // Append TAP Listener 44 | if (str) { 45 | if (0 < strtol(str, NULL, 0)) { 46 | testing::TestEventListeners& listeners = testing::UnitTest::GetInstance()->listeners(); 47 | if (1 == strtol(str, NULL, 0)) { 48 | delete listeners.Release(listeners.default_result_printer()); 49 | } 50 | listeners.Append(new tap::TapListener()); 51 | } 52 | } 53 | 54 | return RUN_ALL_TESTS(); 55 | } 56 | -------------------------------------------------------------------------------- /tests/verifier/README: -------------------------------------------------------------------------------- 1 | VPERF VERIFIER version 0.01 2 | ================ 3 | 4 | The README is used to introduce the module and provide instructions on 5 | how to install the module, any machine dependencies it may have (for 6 | example C compilers and installed libraries) and any other information 7 | that should be provided before the module is installed. 8 | 9 | A README file is required for CPAN modules since CPAN extracts the 10 | README file from a module distribution so that people browsing the 11 | archive can use it get an idea of the modules uses. It is usually a 12 | good idea to provide version information here so that people can 13 | decide whether fixes for the module are worth downloading. 14 | 15 | INSTALLATION 16 | 17 | To install this module type the following: 18 | 19 | perl Makefile.PL 20 | make 21 | make test 22 | make install 23 | 24 | DEPENDENCIES 25 | 26 | This module requires these other modules and libraries: 27 | 28 | blah blah blah 29 | 30 | COPYRIGHT AND LICENCE 31 | 32 | Put the correct copyright and licence information here. 33 | 34 | Copyright (C) 2011 by Igor Ivanov 35 | 36 | This library is free software; you can redistribute it and/or modify 37 | it under the same terms as Perl itself, either Perl version 5.8.8 or, 38 | at your option, any later version of Perl 5 you may have available. 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/verifier/doc/Test Matrix.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mellanox/sockperf/f12cc1b663385394a62d4438c8530955ac4083c0/tests/verifier/doc/Test Matrix.xls -------------------------------------------------------------------------------- /tests/verifier/lib/TE/Common.pm: -------------------------------------------------------------------------------- 1 | ## 2 | # @file Common.pm 3 | # 4 | # @brief TE module to define common data. 5 | # 6 | # 7 | 8 | ## @class 9 | # Container for common data. 10 | package TE::Common; 11 | 12 | use strict; 13 | use warnings; 14 | use vars qw(@EXPORT); 15 | use base qw(Exporter); 16 | @EXPORT = qw 17 | ( 18 | get_error 19 | set_error 20 | TE_ERR_NONE 21 | TE_ERR_FATAL 22 | TE_ERR_CONNECT 23 | TE_ERR_LOGIN 24 | TE_ERR_PROMPT 25 | TE_ERR_PERL 26 | TE_ERR_TIMEOUT 27 | TE_ERR_BREAK 28 | TE_ERR_BAD_ARGUMENT 29 | TE_ERR_CUSTOM 30 | TE_ERR_UNKNOWN 31 | ); 32 | 33 | our $last_error = {code => 0, msg => ''}; 34 | our $alias = 'verifier_te'; 35 | 36 | use constant 37 | { 38 | TE_ERR_NONE => 0, 39 | TE_ERR_FATAL => 1, 40 | TE_ERR_CONNECT => 2, 41 | TE_ERR_LOGIN => 3, 42 | TE_ERR_PROMPT => 4, 43 | TE_ERR_PERL => 5, 44 | TE_ERR_TIMEOUT => 6, 45 | TE_ERR_BREAK => 7, 46 | TE_ERR_BAD_ARGUMENT => 8, 47 | TE_ERR_CUSTOM => 9, 48 | TE_ERR_UNKNOWN => 10, 49 | }; 50 | 51 | 52 | our $conf = 53 | { 54 | options => 55 | { 56 | 'tasks' => undef, 57 | 'username' => "root", 58 | 'password' => "password", 59 | 'targets' => undef, 60 | 'log' => undef, 61 | 'screen_log' => 1, 62 | 'format_log' => 0, 63 | 'silent' => 0, 64 | 'progress' => 1, 65 | 'out_level' => 2, 66 | 'log_level' => 3, 67 | 'email' => undef, 68 | }, 69 | common => 70 | { 71 | 'app' => 'vperf', 72 | 'app_path' => '', 73 | 'host' => 'localhost', 74 | 'host_ip' => undef, 75 | 'flog' => undef, 76 | 'fdump' => undef, 77 | }, 78 | current => 79 | { 80 | 'target' => 'localhost', 81 | }, 82 | }; 83 | 84 | 85 | sub get_error 86 | { 87 | return ( @_ ? $last_error->{msg} : $last_error->{code} ); 88 | } 89 | 90 | 91 | sub set_error 92 | { 93 | my ($code, $msg) = @_; 94 | 95 | if (!$msg) 96 | { 97 | $msg = '' if ($code == TE_ERR_NONE); 98 | $msg = 'fatal operation' if ($code == TE_ERR_FATAL); 99 | $msg = 'unknown remote host' if ($code == TE_ERR_CONNECT); 100 | $msg = 'login failed' if ($code == TE_ERR_LOGIN); 101 | $msg = 'timed-out waiting for command prompt' if ($code == TE_ERR_PROMPT); 102 | $msg = 'perl script error' if ($code == TE_ERR_PERL); 103 | $msg = 'pattern match timed-out' if ($code == TE_ERR_TIMEOUT); 104 | $msg = 'pattern match timed-out' if ($code == TE_ERR_BREAK); 105 | $msg = 'pattern match timed-out' if ($code == TE_ERR_BAD_ARGUMENT); 106 | $msg = 'custom error' if ($code == TE_ERR_CUSTOM); 107 | $msg = 'unknown error' if ($code >= TE_ERR_UNKNOWN); 108 | } 109 | $last_error->{code} = $code; 110 | $last_error->{msg} = $msg; 111 | } 112 | 113 | 114 | 1; 115 | -------------------------------------------------------------------------------- /tests/verifier/lib/TE/Progress.pm: -------------------------------------------------------------------------------- 1 | ## 2 | # @file Progress.pm 3 | # 4 | # @brief TE module for Progress object. 5 | # 6 | # 7 | 8 | ## @class 9 | # Container for Progress object. 10 | package TE::Progress; 11 | 12 | use strict; 13 | use warnings; 14 | 15 | # External modules 16 | 17 | # Own modules 18 | 19 | 20 | our $object = undef; 21 | 22 | sub init 23 | { 24 | # Set default values 25 | $object->{_fh} = \*STDERR, 26 | $object->{_counter} = 0; 27 | $object->{_icons} = ['-', '\\', '|', '/']; 28 | $object->{_line} = undef; 29 | $object->{_fields} = (); 30 | $object->{_width} = 80; 31 | } 32 | 33 | sub update 34 | { 35 | # Check if it is initialized 36 | return if (not defined($object)); 37 | 38 | my $status_line = undef; 39 | my ($node_field, $status_field) = @_; 40 | my $icon_field = $object->{_icons}->[$object->{_counter} % scalar(@{$object->{_icons}})]; 41 | 42 | $status_field = (defined($object->{_fields}->[2]) ? $object->{_fields}->[2] : '') if (not defined($status_field)); 43 | $status_field = $1 if ($status_field =~ /([^\n\r]+)/); 44 | $status_field = (defined($object->{_fields}->[2]) ? $object->{_fields}->[2] : '') if ($status_field =~ /^([\n\r]+)/); 45 | $status_field = (defined($object->{_fields}->[2]) ? $object->{_fields}->[2] : '') if ($status_field eq ''); 46 | 47 | $node_field = (defined($object->{_fields}->[1]) ? $object->{_fields}->[1] : '') if (not defined($node_field)); 48 | 49 | $status_line = sprintf("%s(%-1.1s)%s %s[%-30.30s]%s %s%-40.40s%s\r", 50 | ($^O =~ /Win/ ? "" : "\e[33m"), 51 | $icon_field, 52 | ($^O =~ /Win/ ? "" : "\e[0m"), 53 | ($^O =~ /Win/ ? "" : "\e[32m"), 54 | $node_field, 55 | ($^O =~ /Win/ ? "" : "\e[0m"), 56 | ($^O =~ /Win/ ? "" : "\e[0m"), 57 | $status_field, 58 | ($^O =~ /Win/ ? "" : "\e[0m")); 59 | 60 | $object->{_counter} ++; 61 | $object->{_line} = $status_line; 62 | $object->{_fields}->[0] = $icon_field; 63 | $object->{_fields}->[1] = $node_field; 64 | $object->{_fields}->[2] = $status_field; 65 | 66 | printf ${$object->{_fh}} ("%s\r", $status_line) if defined($status_line); 67 | } 68 | 69 | 70 | sub clean 71 | { 72 | # Check if it is initialized 73 | return if (not defined($object)); 74 | 75 | # Clean status line 76 | my $status_line = (" " x $object->{_width}) . ("\b" x $object->{_width}) if defined($object->{_line}); 77 | 78 | $object->{_line} = $status_line; 79 | 80 | printf ${$object->{_fh}} ("%s\r", $status_line) if defined($status_line); 81 | } 82 | 83 | 84 | sub end 85 | { 86 | # Check if it is initialized 87 | return if (not defined($object)); 88 | 89 | # Clean status line 90 | my $status_line = (" " x $object->{_width}) . ("\b" x $object->{_width}) if defined($object->{_line}); 91 | 92 | printf ${$object->{_fh}} ("%s\r", $status_line) if defined($status_line); 93 | 94 | $object = (); 95 | $object = undef; 96 | } 97 | 98 | 99 | 1; 100 | -------------------------------------------------------------------------------- /tests/verifier/lib/TE/VERSION.pm: -------------------------------------------------------------------------------- 1 | our ($VERSION) = "0.1."; -------------------------------------------------------------------------------- /tests/verifier/lib/TPB.pm: -------------------------------------------------------------------------------- 1 | ## 2 | # @file TPB.pm 3 | # 4 | # @brief Test Suite TCP playback. 5 | # 6 | # 7 | 8 | ## @class 9 | # Container for common data. 10 | package TPB; 11 | 12 | use strict; 13 | use warnings; 14 | 15 | 16 | # Own modules 17 | use TE::Common; 18 | use TE::Funclet; 19 | use TE::Utility; 20 | 21 | 22 | our $test_suite_tcp_pb = 23 | [ 24 | { 25 | name => 'tc1', 26 | note => '#1 - playback w/o arguments', 27 | pre_proc => \&te_def_pre_proc, 28 | server_proc => \&te_def_server_proc, 29 | server_arg => 'sr -i TARGET() --tcp', 30 | client_proc => \&te_def_client_proc, 31 | client_arg => 'pb -i TARGET() --tcp --data-file=PLAYBACK(1.000000:0.000005:12:1000)', 32 | result_proc => \&te_def_result_proc, 33 | result_arg => { 34 | server => { 35 | success => ['Test end', 'interrupted by', 'exit', 'Total 1000 messages received'], 36 | failure => ['Segmentation fault', 'Assertion', 'ERROR'] 37 | }, 38 | client => { 39 | success => ['Test ended', 'Summary: Latency is', 'SentMessages=1000'], 40 | failure => ['Segmentation fault', 'Assertion', 'ERROR', 'server down'] 41 | }, 42 | }, 43 | post_proc => \&te_def_post_proc, 44 | }, 45 | ]; 46 | 47 | 48 | 1; 49 | -------------------------------------------------------------------------------- /tests/verifier/lib/UPB.pm: -------------------------------------------------------------------------------- 1 | ## 2 | # @file UPB.pm 3 | # 4 | # @brief Test Suite UDP playback. 5 | # 6 | # 7 | 8 | ## @class 9 | # Container for common data. 10 | package UPB; 11 | 12 | use strict; 13 | use warnings; 14 | 15 | 16 | # Own modules 17 | use TE::Common; 18 | use TE::Funclet; 19 | use TE::Utility; 20 | 21 | 22 | our $test_suite_udp_pb = 23 | [ 24 | { 25 | name => 'tc1', 26 | note => '#1 - playback w/o arguments', 27 | pre_proc => \&te_def_pre_proc, 28 | server_proc => \&te_def_server_proc, 29 | server_arg => 'sr -i TARGET()', 30 | client_proc => \&te_def_client_proc, 31 | client_arg => 'pb -i TARGET() --data-file=PLAYBACK(1.000000:0.000005:12:1000)', 32 | result_proc => \&te_def_result_proc, 33 | result_arg => { 34 | server => { 35 | success => ['Test end', 'interrupted by', 'exit', 'Total 1000 messages received'], 36 | failure => ['Segmentation fault', 'Assertion', 'ERROR'] 37 | }, 38 | client => { 39 | success => ['Test ended', 'Summary: Latency is', 'SentMessages=1000'], 40 | failure => ['Segmentation fault', 'Assertion', 'ERROR', 'server down'] 41 | }, 42 | }, 43 | post_proc => \&te_def_post_proc, 44 | }, 45 | ]; 46 | 47 | 48 | 1; 49 | -------------------------------------------------------------------------------- /tools/Makefile.am: -------------------------------------------------------------------------------- 1 | tooldir = $(prefix)/sbin/sockperf/ 2 | 3 | sbin_SCRIPTS = \ 4 | filter.awk \ 5 | gen1.awk \ 6 | gen2.awk 7 | 8 | dist_sbin_SCRIPTS = \ 9 | filter.awk \ 10 | gen1.awk \ 11 | gen2.awk 12 | -------------------------------------------------------------------------------- /tools/filter.awk: -------------------------------------------------------------------------------- 1 | #!/bin/awk -f 2 | BEGIN { 3 | # this syntax will allow --assign var=val in command line 4 | if (!RANGE_START_USEC) RANGE_START_USEC = 20 5 | if (!RANGE_START_END) RANGE_END_USEC = 1000*1000*1000 6 | if (!DECIMAL_DIGITS) DECIMAL_DIGITS = 9 7 | dataStarted = 0 8 | } 9 | 10 | $2 == "txTime(sec)," {dataStarted = 1; print "txTime, usecLat"} 11 | { 12 | if (!dataStarted) print 13 | else { 14 | usecLat = 1000*1000*($3 - $2)/2 15 | if (RANGE_START_USEC <= usecLat && usecLat <= RANGE_END_USEC ) 16 | printf "%.*f, %.3f\n", DECIMAL_DIGITS, $2, usecLat 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tools/gen1.awk: -------------------------------------------------------------------------------- 1 | #!/bin/awk -f 2 | 3 | BEGIN { 4 | print "# ==== playback file for sockperf - generated by gen1.awk ====" 5 | 6 | PPS = 200*1000 7 | NUM_RECORDS = PPS # 30*1000 8 | 9 | runtime = NUM_RECORDS/PPS 10 | interval = 1/PPS 11 | baseTime = 1 12 | 13 | printf "#baseTime=%f; PPS=%d; runtime=%f; interval=%lf; NUM_RECORDS=%d\n", baseTime, PPS, runtime, interval, NUM_RECORDS 14 | 15 | deltaSize = 0 16 | minSize = 12 17 | maxSize = 50000 - minSize 18 | 19 | t = baseTime 20 | s = 0 21 | 22 | printf "# file contains %d records\n", NUM_RECORDS 23 | 24 | for (i = 0; i < NUM_RECORDS; i++) { 25 | t += interval 26 | s += deltaSize 27 | printf("%.9lf, %d\n", t, minSize+s%maxSize) 28 | } 29 | 30 | printf "#%d records were written successfuly\n", NUM_RECORDS 31 | } 32 | -------------------------------------------------------------------------------- /tools/gen2.awk: -------------------------------------------------------------------------------- 1 | #!/bin/awk -f 2 | # 3 | # this awk script generates playback files to be played with ./sockperf --playback command 4 | # the input for this script is file with lines of the format: 5 | # startTime; duration; startPPS; endPPS; msgSize 6 | # example for such a file is: 7 | # 1 2 100 100 12 8 | # 3 1 100 10 12 9 | # 4 10 10 100 12 10 | # 11 | BEGIN { 12 | print "# ==== playback file for sockperf - generated by gen2.awk ====" 13 | } 14 | 15 | # file start => echo all orig lines as block of comments 16 | FNR == 1 && FILENAME != "-" { 17 | print "#---> echoing the content of the given input file: " FILENAME 18 | system("sed 's/^/#> /' " FILENAME) 19 | print "#<--- end of input file: " FILENAME 20 | } 21 | 22 | {print "#> " $0} # echo orig line as comment line 23 | /^[ \t]*$/ {next} # skip empty line 24 | /^[ \t]*#/ {next} # skip comment line 25 | NF < 5 {error = 1; exit 1} # too few fields 26 | 27 | # this will be executed for any input line 28 | { 29 | runtime = 0; startTime = $1; duration = $2; startPPS=$3; endPPS=$4; msgSize=$5 30 | if (startTime < t) { error = 1; exit 2} # file is un-ordered 31 | if (duration <= 0 || startPPS <= 0 || endPPS <= 0 || msgSize < 14 || msgSize > 65000) { error = 1; exit 3} 32 | 33 | ppsGradient = (endPPS - startPPS) / duration 34 | #pps = startPPS 35 | #runtime += 1/pps 36 | 37 | printf ("#startTime=%f; duration=%f; startPPS=%f; endPPS=%f; msgSize=%d; ppsGradient=%f\n", startTime, duration, startPPS, endPPS, msgSize, ppsGradient) 38 | print("#txTime, msgSize") # print header 39 | while (runtime <= duration) { 40 | t = startTime + runtime 41 | printf("%.9lf, %d\n", t, msgSize) # actual printing of the record #TODO: 12 digits! 42 | pps = startPPS + ppsGradient * runtime 43 | runtime += 1/pps 44 | counter++ 45 | } 46 | } 47 | 48 | END { 49 | if (!error) 50 | printf "# ==== file generation completed successfuly with %d records ====\n", counter 51 | else 52 | printf " ====> error has occured during file generation [file=%s : line=%d] <====\n", FILENAME, FNR 53 | } 54 | 55 | -------------------------------------------------------------------------------- /win/README.txt: -------------------------------------------------------------------------------- 1 | Sockperf - Windows support 2 | ========================== 3 | 4 | Not supported features (Windows): 5 | - Poll/Epoll. 6 | - RDTSC - Unlike in Linux, there's only one option for time handling. 7 | It is done using QueryPerformanceFrequency() and QueryPerformanceCounter() methoods. 8 | - VMA integration. 9 | - Daemonizing Sockperf process. 10 | - Message flags: MSG_DONTWAIT, MSG_NOSIGNAL. 11 | 12 | 13 | Notes/TODO's: 14 | - Modify type 'int' to type 'SOCK'. 15 | - Add windows installer. 16 | - Split os_abstact to os_win and os_linux. 17 | - Add regular expression check for the feed file. 18 | - Add colors (drops, errors, etc.) 19 | --------------------------------------------------------------------------------