diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..233ecc0 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +go-runner/testdata/raw_results/*.json filter=lfs diff=lfs merge=lfs -text diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 772dc93..2be77ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,54 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + submodules: true - uses: actions/setup-go@v5 + - uses: moonrepo/setup-rust@v1 + with: + components: rustfmt, clippy - uses: pre-commit/action@v3.0.1 with: extra_args: --all-files + + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + lfs: true + submodules: true + - uses: moonrepo/setup-rust@v1 + - run: | + cd go-runner + cargo test --all + + + compat-integration-test-walltime: + runs-on: codspeed-macro + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - uses: actions/setup-go@v5 + - uses: moonrepo/setup-rust@v1 + with: + cache-target: release + + - name: Run the benchmarks + uses: CodSpeedHQ/action@main + with: + working-directory: example + run: cargo r --manifest-path ../go-runner/Cargo.toml -- test -bench=. + + check: + runs-on: ubuntu-latest + if: always() + needs: + - lint + - tests + - compat-integration-test-walltime + steps: + - uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJson( needs ) }} diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..4f09419 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,24 @@ +[submodule "go-runner/testdata/projects/fzf"] + path = go-runner/testdata/projects/fzf + url = https://github.com/junegunn/fzf +[submodule "go-runner/testdata/projects/opentelemetry-go"] + path = go-runner/testdata/projects/opentelemetry-go + url = https://github.com/open-telemetry/opentelemetry-go +[submodule "go-runner/testdata/projects/golang-benchmarks"] + path = go-runner/testdata/projects/golang-benchmarks + url = https://github.com/SimonWaldherr/golang-benchmarks +[submodule "go-runner/testdata/projects/fuego"] + path = go-runner/testdata/projects/fuego + url = https://github.com/go-fuego/fuego +[submodule "go-runner/testdata/projects/hugo"] + path = go-runner/testdata/projects/hugo + url = https://github.com/gohugoio/hugo/ +[submodule "go-runner/testdata/projects/zerolog"] + path = go-runner/testdata/projects/zerolog + url = https://github.com/rs/zerolog +[submodule "go-runner/testdata/projects/zap"] + path = go-runner/testdata/projects/zap + url = https://github.com/uber-go/zap +[submodule "go-runner/testdata/projects/cli-runtime"] + path = go-runner/testdata/projects/cli-runtime + url = https://github.com/kubernetes/cli-runtime diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ee40a96..c940288 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,6 +6,7 @@ repos: - id: end-of-file-fixer - id: check-yaml - id: check-json + exclude: ^go-runner/testdata/ - id: check-merge-conflict - id: check-added-large-files @@ -14,3 +15,31 @@ repos: hooks: - id: go-mod-tidy - id: go-fmt + exclude: ^go-runner/src/builder/template\.go$ + + - repo: https://github.com/doublify/pre-commit-rust + rev: v1.0 + hooks: + - id: fmt + args: [--all, --] + files: ^go-runner/ + pass_filenames: false + additional_dependencies: [] + entry: bash -c 'cd go-runner && cargo fmt --all' + language: system + + - id: cargo-check + args: [--all-targets] + files: ^go-runner/ + pass_filenames: false + additional_dependencies: [] + entry: bash -c 'cd go-runner && cargo check --all-targets' + language: system + + - id: clippy + args: [--all-targets, --, -D, warnings] + files: ^go-runner/ + pass_filenames: false + additional_dependencies: [] + entry: bash -c 'cd go-runner && cargo clippy --all-targets -- -D warnings' + language: system diff --git a/go-runner/.gitignore b/go-runner/.gitignore new file mode 100644 index 0000000..52c0c07 --- /dev/null +++ b/go-runner/.gitignore @@ -0,0 +1,3 @@ +build-*/ +target/ +.codspeed diff --git a/go-runner/Cargo.lock b/go-runner/Cargo.lock new file mode 100644 index 0000000..e3f81e7 --- /dev/null +++ b/go-runner/Cargo.lock @@ -0,0 +1,1213 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "clap" +version = "4.5.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "windows-sys", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "env_filter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi", +] + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "go-runner" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "env_logger", + "glob", + "gosyn", + "handlebars", + "insta", + "itertools", + "log", + "rand", + "regex", + "rstest", + "serde", + "serde_json", + "statrs", + "tempfile", + "thiserror 2.0.12", +] + +[[package]] +name = "gosyn" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb37859fda6792e95231aef1c5838f4043ec0ee352d8313421e311c606df612" +dependencies = [ + "anyhow", + "strum", + "thiserror 1.0.69", + "unic-ucd-category", +] + +[[package]] +name = "handlebars" +version = "6.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759e2d5aea3287cb1190c8ec394f42866cb5bf74fcbf213f354e3c856ea26098" +dependencies = [ + "derive_builder", + "log", + "num-order", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror 2.0.12", +] + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "insta" +version = "1.43.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "154934ea70c58054b556dd430b99a98c2a7ff5309ac9891597e339b5c28f4371" +dependencies = [ + "console", + "once_cell", + "pest", + "pest_derive", + "serde", + "similar", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jiff" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "num-modular" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" + +[[package]] +name = "num-order" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" +dependencies = [ + "num-modular", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "pest" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" +dependencies = [ + "memchr", + "thiserror 2.0.12", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" +dependencies = [ + "pest", + "sha2", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + +[[package]] +name = "rstest" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5a3193c063baaa2a95a33f03035c8a72b83d97a54916055ba22d35ed3839d49" +dependencies = [ + "futures-timer", + "futures-util", + "rstest_macros", +] + +[[package]] +name = "rstest_macros" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c845311f0ff7951c5506121a9ad75aec44d083c31583b2ea5a30bcb0b0abba0" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn", + "unicode-ident", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.141" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + +[[package]] +name = "slab" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" + +[[package]] +name = "statrs" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a3fe7c28c6512e766b0874335db33c94ad7b8f9054228ae1c2abd47ce7d335e" +dependencies = [ + "approx", + "num-traits", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[package]] +name = "syn" +version = "2.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-ucd-category" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8d4591f5fcfe1bd4453baaf803c40e1b1e69ff8455c47620440b46efef91c0" +dependencies = [ + "matches", + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/go-runner/Cargo.toml b/go-runner/Cargo.toml new file mode 100644 index 0000000..3d04632 --- /dev/null +++ b/go-runner/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "go-runner" +version = "0.1.0" +edition = "2024" + +[dependencies] +anyhow = "1.0.98" +clap = { version = "4.5", features = ["derive"] } +env_logger = "0.11.8" +glob = "0.3.2" +gosyn = "0.2.9" +handlebars = "6.3.2" +itertools = "0.14.0" +log = "0.4.27" +rand = "0.9.2" +regex = "1.11.1" +serde = { version = "1.0.219", features = ["derive"] } +serde_json = "1.0.141" +statrs = { version = "0.18.0", default-features = false } +thiserror = "2.0.12" +tempfile = "3.14.0" + +[dev-dependencies] +insta = { version = "1.43.1", features = ["json", "redactions"] } +rstest = "0.26" diff --git a/go-runner/src/builder/discovery.rs b/go-runner/src/builder/discovery.rs new file mode 100644 index 0000000..dd1cacc --- /dev/null +++ b/go-runner/src/builder/discovery.rs @@ -0,0 +1,350 @@ +//! Finds all the benchmarks and packages in a given Go project. + +use std::{ + ops::Deref, + path::{Path, PathBuf}, + process::Command, +}; + +use crate::builder::verifier; +use crate::prelude::*; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct GoModule { + /// The module path (e.g., "local.dev/example-complex"). + #[serde(rename = "Path")] + pub path: String, + + /// The module directory (e.g., "/home/user/go/src/local.dev/example-complex"). + #[serde(rename = "Dir")] + pub dir: PathBuf, + + /// The module go.mod file (e.g., "/home/user/go/src/local.dev/example-complex/go.mod"). + #[serde(rename = "GoMod")] + pub go_mod: PathBuf, + + /// The module version (e.g., "v1.0.0"). + #[serde(rename = "GoVersion")] + pub version: String, + + /// Whether this is the main module. + #[serde(rename = "Main")] + pub main: bool, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct GoPackage { + /// The path to the package (e.g., "github.com/user/project/pkg/foo"). + #[serde(rename = "Dir")] + pub dir: PathBuf, + + /// The name of the package (e.g., "foo"). + #[serde(rename = "Name")] + pub name: String, + + /// TBA + /// "ImportPath": "local.dev/example-complex/internal/config [local.dev/example-complex/internal/config.test]", + #[serde(rename = "ImportPath")] + pub import_path: String, + + #[serde(rename = "TestGoFiles")] + pub test_go_files: Option>, + + #[serde(rename = "TestImports")] + pub test_imports: Option>, + + #[serde(rename = "CompiledGoFiles")] + pub compiled_go_files: Option>, + + #[serde(rename = "Module")] + pub module: GoModule, +} + +impl GoPackage { + pub fn from_go_list_output(output: &str) -> anyhow::Result> { + // Replace all \n, then find '}{' and replace with '},{' to convert the output into a valid JSON array + let output = output.replace("\n", ""); + let output = output.replace("}{", "},{"); + + serde_json::from_str(&format!("[{output}]")).context("Failed to parse Go list output") + } + + fn benchmarks(&self) -> anyhow::Result> { + let Some(test_go_files) = &self.test_go_files else { + bail!("No test files found for package: {}", self.name); + }; + + let mut benchmarks = Vec::new(); + for file in test_go_files { + assert!(file.ends_with("_test.go")); + + let file_path = self.dir.join(file); + let content = std::fs::read_to_string(&file_path) + .context(format!("Failed to read test file: {file_path:?}"))?; + + let file = match gosyn::parse_source(&content) { + Ok(ast) => ast, + Err(e) => { + warn!("Failed to parse Go file {file_path:?}: {e}"); + continue; + } + }; + + // We don't support files with benchmarks that also contains github.com/frankban/quicktest + if file + .imports + .iter() + .any(|import| import.path.value.contains("github.com/frankban/quicktest")) + { + warn!("Skipping file with quicktest import: {file_path:?}"); + continue; + } + + // We don't support testify yet + if file + .imports + .iter() + .any(|import| import.path.value.contains("github.com/stretchr/testify")) + { + warn!("Skipping file with testify import: {file_path:?}"); + continue; + } + + // We can't import packages that are declared as `main` + if file.pkg_name.name == "main" { + warn!("Skipping file with main package: {file_path:?}"); + continue; + } + + // First, collect all benchmark function names from this file + let mut found_benchmarks = Vec::new(); + for decl in &file.decl { + let gosyn::ast::Declaration::Function(func_decl) = decl else { + continue; + }; + + let func_name = &func_decl.name.name; + + // Check if function name starts with "Benchmark" + if !func_name.starts_with("Benchmark") { + continue; + } + + found_benchmarks.push(func_name.clone()); + } + + // Extract the actual package import path from the full import_path + // The import_path format is like "local.dev/example-complex/pkg/auth [local.dev/example-complex/pkg/auth.test]" + let package_import_path = self + .import_path + .split_whitespace() + .next() + .unwrap_or(&self.import_path) + .to_string(); + + // Remove the module dir parent from the file path + let root_relative_file_path = file_path.strip_prefix(&self.module.dir).context( + format!("Couldn't strip the module dir from file path: {file_path:?}"), + )?; + + let valid_benchmarks = + verifier::FuncVisitor::verify_source_code(&content, &found_benchmarks)?; + if valid_benchmarks.len() != found_benchmarks.len() { + warn!( + "Only {} out of {} are valid, skipping file", + valid_benchmarks.len(), + found_benchmarks.len() + ); + warn!("Valid benchmarks: {valid_benchmarks:?}"); + warn!( + "Invalid benchmarks: {:?}", + found_benchmarks + .iter() + .filter(|f| !valid_benchmarks.contains(f)) + .collect::>() + ); + + continue; + } + + for func in valid_benchmarks { + benchmarks.push(GoBenchmark::new( + package_import_path.clone(), + func, + root_relative_file_path.to_path_buf(), + )); + } + } + + Ok(benchmarks) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct GoBenchmark { + /// The name of the benchmark (e.g. `BenchmarkFoo`). + pub name: String, + + /// The path to the module (e.g. `github.com/user/foo`). + module_path: String, + + /// The import alias (e.g. `foo_test_49212941`). + import_alias: String, + + /// The name with the package (e.g. `foo_test.BenchmarkFoo`). + qualified_name: String, + + /// The file path relative to the module directory (e.g. `pkg/foo/foo_test.go`). + pub file_path: PathBuf, +} + +impl GoBenchmark { + pub fn new(package_import_path: String, name: String, file_path: PathBuf) -> Self { + #[cfg(test)] + let import_alias = { + use rand::{Rng, SeedableRng}; + let mut rng = rand::rngs::StdRng::seed_from_u64(42); + format!("{}_{}", name.to_lowercase(), rng.random::()) + }; + + #[cfg(not(test))] + let import_alias = format!("{}_{}", name.to_lowercase(), rand::random::()); + + let qualified_name = format!("{}.{}", import_alias, &name); + Self { + module_path: package_import_path, + import_alias, + name, + qualified_name, + file_path, + } + } +} + +/// Represents a package with its benchmarks. +#[derive(Debug, Clone, Serialize)] +pub struct BenchmarkPackage { + raw_package: GoPackage, + pub benchmarks: Vec, +} + +impl BenchmarkPackage { + fn new(package: GoPackage, benchmarks: Vec) -> Self { + Self { + raw_package: package, + benchmarks, + } + } + + pub fn from_project(go_project_path: &Path) -> anyhow::Result> { + let raw_packages = Self::run_go_list(go_project_path)?; + let has_test_files = + |files: &Vec| files.iter().any(|name| name.ends_with("_test.go")); + let has_test_imports = |imports: &Vec| { + imports.iter().any(|import| { + // import "testing" + import.contains("testing") + }) + }; + + let mut packages = Vec::new(); + for package in raw_packages { + // Skip packages without test files + let has_tests = package + .test_go_files + .as_ref() + .map(has_test_files) + .unwrap_or_default(); + if !has_tests { + debug!("Skipping package without test files: {}", package.name); + continue; + } + + // Skip packages without test imports + let has_test_imports = package + .test_imports + .as_ref() + .map(has_test_imports) + .unwrap_or_default(); + if !has_test_imports { + debug!("Skipping package without test imports: {}", package.name); + continue; + } + + // Only include test executables, since we want to generate them manually. + // Example format: `local.dev/example-complex [local.dev/example-complex.test]` + if !package.import_path.ends_with(".test]") { + debug!("Skipping package without test executable: {}", package.name); + continue; + } + + // Skip packages that don't have benchmarks + let benchmarks = match package.benchmarks() { + Ok(benchmarks) => benchmarks, + Err(e) => { + warn!( + "Failed to get benchmarks for package {}: {}", + package.name, e + ); + continue; + } + }; + if benchmarks.is_empty() { + debug!("Skipping package without benchmarks: {}", package.name); + continue; + } + + packages.push(BenchmarkPackage::new(package, benchmarks)); + } + + Ok(packages) + } + + fn run_go_list(go_project_path: &Path) -> anyhow::Result> { + // Execute 'go list -test -compiled -json ./...' to get package information + let output = Command::new("go") + .args(["list", "-test", "-compiled", "-json", "./..."]) + .current_dir(go_project_path) + .output()?; + + if !output.status.success() { + bail!( + "Failed to execute 'go list': {}", + String::from_utf8_lossy(&output.stderr) + ); + } + + // Wrap it in '[{output}]' and parse it with serde_json + let output_str = String::from_utf8(output.stdout)?; + trace!("Go list output: {output_str}"); + + GoPackage::from_go_list_output(&output_str) + } +} + +impl Deref for BenchmarkPackage { + type Target = GoPackage; + + fn deref(&self) -> &Self::Target { + &self.raw_package + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_discover_benchmarks() { + let packages = + BenchmarkPackage::from_project(Path::new("testdata/projects/golang-benchmarks")) + .unwrap(); + + insta::assert_json_snapshot!(packages, { + ".**[\"Dir\"]" => "[package_dir]", + ".**[\"Module\"][\"Dir\"]" => "[module_dir]", + ".**[\"Module\"][\"GoMod\"]" => "[go_mod_path]" + }); + } +} diff --git a/go-runner/src/builder/mod.rs b/go-runner/src/builder/mod.rs new file mode 100644 index 0000000..d18d78a --- /dev/null +++ b/go-runner/src/builder/mod.rs @@ -0,0 +1,7 @@ +pub mod discovery; +pub mod patcher; +pub mod runner; +pub mod templater; +pub mod verifier; + +pub use discovery::*; diff --git a/go-runner/src/builder/patcher.rs b/go-runner/src/builder/patcher.rs new file mode 100644 index 0000000..b03e604 --- /dev/null +++ b/go-runner/src/builder/patcher.rs @@ -0,0 +1,196 @@ +//! Patches the imports to use codspeed rather than the official "testing" package. + +use crate::prelude::*; +use std::fs; +use std::path::{Path, PathBuf}; +use std::process::Command; + +pub fn patch_imports>( + folder: P, + files_to_patch: Vec, +) -> anyhow::Result<()> { + let folder = folder.as_ref(); + debug!("Patching imports in folder: {folder:?}"); + + // 2. Find all imports that match "testing" and replace them with codspeed equivalent + let mut patched_files = 0; + for go_file in files_to_patch { + let content = + fs::read_to_string(&go_file).context(format!("Failed to read Go file: {go_file:?}"))?; + + let patched_content = patch_go_source(&content)?; + + if patched_content != content { + fs::write(&go_file, patched_content) + .context(format!("Failed to write patched Go file: {go_file:?}"))?; + + debug!("Patched imports in: {go_file:?}"); + patched_files += 1; + } + } + debug!("Patched {patched_files} files"); + + // 3. Update the go module to use the codspeed package + let mut cmd: Command = Command::new("go"); + cmd.arg("get") + .arg("github.com/CodSpeedHQ/codspeed-go@cod-1172-create-codspeed-go-repository-with-the-compat-layer") + // Bypass Go proxy cache to fetch directly from source - prevents issues with + // cached versions that may have incorrect module paths or outdated content + .env("GOPROXY", "direct") + .current_dir(folder); + + let output = cmd.output().context("Failed to execute 'go get' command")?; + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + bail!("Failed to install codspeed-go dependency: {}", stderr); + } + + debug!("Successfully installed codspeed-go dependency"); + + Ok(()) +} + +/// Internal function to apply import patterns to Go source code +pub fn patch_go_source(source: &str) -> anyhow::Result { + let parsed = gosyn::parse_source(source)?; + + let mut modified_content = source.to_string(); + if let Some(import) = parsed + .imports + .iter() + .find(|import| import.path.value == "\"testing\"") + { + let start_pos = import.path.pos; + let end_pos = start_pos + import.path.value.len(); + + let replacement = "testing \"github.com/CodSpeedHQ/codspeed-go/compat/testing\""; + modified_content.replace_range(start_pos..end_pos, replacement); + } + + Ok(modified_content) +} + +#[cfg(test)] +mod tests { + use super::*; + use insta::assert_snapshot; + use rstest::rstest; + + const SINGLE_IMPORT: &str = r#"package main + +import "testing" + +func TestExample(t *testing.T) { + // test code +} +"#; + + const MULTILINE_IMPORT: &str = r#"package main + +import ( + "fmt" + "testing" + "strings" +) + +func TestExample(t *testing.T) { + // test code +} +"#; + + const MULTILINE_IMPORT_WITH_TABS: &str = r#"package main + +import ( + "fmt" + "testing" + "strings" +) +"#; + + const IMPORT_WITH_COMMENTS: &str = r#"package main + +import ( + "fmt" + "testing" // for unit tests + "strings" +) +"#; + + const ALREADY_PATCHED_IMPORT: &str = r#"package main + +import testing "github.com/CodSpeedHQ/codspeed-go/compat/testing" + +func BenchmarkExample(b *testing.B) { + // benchmark code +} +"#; + + const MIXED_IMPORT_STYLES: &str = r#"package main + +import "testing" + +import ( + "fmt" + "something" +) +"#; + + const IMPORT_AT_END_OF_BLOCK: &str = r#"package main + +import ( + "fmt" + "strings" + "testing" +) +"#; + + const IMPORT_WITH_EXTRA_WHITESPACE: &str = r#"package main + +import ( + "fmt" + + "testing" + + "strings" +) +"#; + + const MULTILINE_IMPORT_WITH_TESTING_STRING: &str = r#"package main +import ( + "fmt" + "testing" +) + +func TestExample(t *testing.T) { + fmt.Println("testing") +} +"#; + + const IMPORT_WITH_TESTING_STRING: &str = r#"package main +import "testing" +import "fmt" + +func TestExample(t *testing.T) { + fmt.Println("testing") +} +"#; + + #[rstest] + #[case("single_import_replacement", SINGLE_IMPORT)] + #[case("multiline_import_replacement", MULTILINE_IMPORT)] + #[case("multiline_import_with_tabs", MULTILINE_IMPORT_WITH_TABS)] + #[case("import_with_comments", IMPORT_WITH_COMMENTS)] + #[case("already_patched_import", ALREADY_PATCHED_IMPORT)] + #[case("mixed_import_styles", MIXED_IMPORT_STYLES)] + #[case("import_at_end_of_block", IMPORT_AT_END_OF_BLOCK)] + #[case("import_with_extra_whitespace", IMPORT_WITH_EXTRA_WHITESPACE)] + #[case("import_with_testing_string", IMPORT_WITH_TESTING_STRING)] + #[case( + "multiline_import_with_testing_string", + MULTILINE_IMPORT_WITH_TESTING_STRING + )] + fn test_patch_go_source(#[case] test_name: &str, #[case] source: &str) { + let result = patch_go_source(source).unwrap(); + assert_snapshot!(test_name, result); + } +} diff --git a/go-runner/src/builder/runner.rs b/go-runner/src/builder/runner.rs new file mode 100644 index 0000000..20440e1 --- /dev/null +++ b/go-runner/src/builder/runner.rs @@ -0,0 +1,39 @@ +use crate::prelude::*; +use std::{path::Path, process::Command}; + +pub fn run>(runner_go_path: P, run_args: &[&str]) -> anyhow::Result<()> { + // Extract the directory containing runner.go to use as working directory + let runner_go_path = runner_go_path.as_ref(); + let file_dir = runner_go_path.parent().unwrap(); + let module_root = file_dir.parent().unwrap(); + let relative_path = runner_go_path.strip_prefix(module_root).unwrap(); + debug!( + "Building codspeed runner: {:?} (root = {:?})", + module_root.join(relative_path), + module_root + ); + + // Run go run -tags=codspeed {args} + let output = Command::new("go") + .arg("run") + .arg("-tags=codspeed") + .arg(relative_path) + .args(run_args) + .current_dir(module_root) + .stdout(std::process::Stdio::inherit()) + .stderr(std::process::Stdio::inherit()) + .output() + .context("Failed to execute go build command")?; + + if !output.status.success() { + let stdout = String::from_utf8_lossy(&output.stdout); + let stderr = String::from_utf8_lossy(&output.stderr); + + warn!("Command output: {stdout}"); + warn!("Command error output: {stderr}"); + + bail!("Failed to run benchmark. Exit status: {}", output.status); + } + + Ok(()) +} diff --git a/go-runner/src/builder/snapshots/go_runner__builder__discovery__tests__discover_benchmarks.snap b/go-runner/src/builder/snapshots/go_runner__builder__discovery__tests__discover_benchmarks.snap new file mode 100644 index 0000000..b8b6861 --- /dev/null +++ b/go-runner/src/builder/snapshots/go_runner__builder__discovery__tests__discover_benchmarks.snap @@ -0,0 +1,781 @@ +--- +source: src/builder/discovery.rs +expression: packages +--- +[ + { + "raw_package": { + "Dir": "[package_dir]", + "Name": "base64", + "ImportPath": "github.com/SimonWaldherr/golang-benchmarks/base64 [github.com/SimonWaldherr/golang-benchmarks/base64.test]", + "TestGoFiles": [ + "base64_test.go" + ], + "TestImports": [ + "encoding/base64", + "regexp", + "testing" + ], + "CompiledGoFiles": [ + "base64_test.go" + ], + "Module": { + "Path": "github.com/SimonWaldherr/golang-benchmarks", + "Dir": "[module_dir]", + "GoMod": "[go_mod_path]", + "GoVersion": "1.18", + "Main": true + } + }, + "benchmarks": [ + { + "name": "BenchmarkBase64decode", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/base64", + "import_alias": "benchmarkbase64decode_572990626", + "qualified_name": "benchmarkbase64decode_572990626.BenchmarkBase64decode", + "file_path": "base64/base64_test.go" + }, + { + "name": "BenchmarkBase64regex", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/base64", + "import_alias": "benchmarkbase64regex_572990626", + "qualified_name": "benchmarkbase64regex_572990626.BenchmarkBase64regex", + "file_path": "base64/base64_test.go" + } + ] + }, + { + "raw_package": { + "Dir": "[package_dir]", + "Name": "between", + "ImportPath": "github.com/SimonWaldherr/golang-benchmarks/between [github.com/SimonWaldherr/golang-benchmarks/between.test]", + "TestGoFiles": [ + "between_test.go" + ], + "TestImports": [ + "regexp", + "simonwaldherr.de/go/golibs/as", + "simonwaldherr.de/go/ranger", + "testing" + ], + "CompiledGoFiles": [ + "between_test.go" + ], + "Module": { + "Path": "github.com/SimonWaldherr/golang-benchmarks", + "Dir": "[module_dir]", + "GoMod": "[go_mod_path]", + "GoVersion": "1.18", + "Main": true + } + }, + "benchmarks": [ + { + "name": "BenchmarkNumberRegEx", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/between", + "import_alias": "benchmarknumberregex_572990626", + "qualified_name": "benchmarknumberregex_572990626.BenchmarkNumberRegEx", + "file_path": "between/between_test.go" + }, + { + "name": "BenchmarkFulltextRegEx", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/between", + "import_alias": "benchmarkfulltextregex_572990626", + "qualified_name": "benchmarkfulltextregex_572990626.BenchmarkFulltextRegEx", + "file_path": "between/between_test.go" + }, + { + "name": "BenchmarkNumberParse", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/between", + "import_alias": "benchmarknumberparse_572990626", + "qualified_name": "benchmarknumberparse_572990626.BenchmarkNumberParse", + "file_path": "between/between_test.go" + }, + { + "name": "BenchmarkFulltextParse", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/between", + "import_alias": "benchmarkfulltextparse_572990626", + "qualified_name": "benchmarkfulltextparse_572990626.BenchmarkFulltextParse", + "file_path": "between/between_test.go" + } + ] + }, + { + "raw_package": { + "Dir": "[package_dir]", + "Name": "trim", + "ImportPath": "github.com/SimonWaldherr/golang-benchmarks/caseinsensitivecompare [github.com/SimonWaldherr/golang-benchmarks/caseinsensitivecompare.test]", + "TestGoFiles": [ + "caseinsensitivecompare_test.go" + ], + "TestImports": [ + "strings", + "testing" + ], + "CompiledGoFiles": [ + "caseinsensitivecompare_test.go" + ], + "Module": { + "Path": "github.com/SimonWaldherr/golang-benchmarks", + "Dir": "[module_dir]", + "GoMod": "[go_mod_path]", + "GoVersion": "1.18", + "Main": true + } + }, + "benchmarks": [ + { + "name": "BenchmarkEqualFold", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/caseinsensitivecompare", + "import_alias": "benchmarkequalfold_572990626", + "qualified_name": "benchmarkequalfold_572990626.BenchmarkEqualFold", + "file_path": "caseinsensitivecompare/caseinsensitivecompare_test.go" + }, + { + "name": "BenchmarkToUpper", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/caseinsensitivecompare", + "import_alias": "benchmarktoupper_572990626", + "qualified_name": "benchmarktoupper_572990626.BenchmarkToUpper", + "file_path": "caseinsensitivecompare/caseinsensitivecompare_test.go" + }, + { + "name": "BenchmarkToLower", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/caseinsensitivecompare", + "import_alias": "benchmarktolower_572990626", + "qualified_name": "benchmarktolower_572990626.BenchmarkToLower", + "file_path": "caseinsensitivecompare/caseinsensitivecompare_test.go" + } + ] + }, + { + "raw_package": { + "Dir": "[package_dir]", + "Name": "concat", + "ImportPath": "github.com/SimonWaldherr/golang-benchmarks/concat [github.com/SimonWaldherr/golang-benchmarks/concat.test]", + "TestGoFiles": [ + "concat_test.go" + ], + "TestImports": [ + "bytes", + "strings", + "testing" + ], + "CompiledGoFiles": [ + "concat_test.go" + ], + "Module": { + "Path": "github.com/SimonWaldherr/golang-benchmarks", + "Dir": "[module_dir]", + "GoMod": "[go_mod_path]", + "GoVersion": "1.18", + "Main": true + } + }, + "benchmarks": [ + { + "name": "BenchmarkConcatString", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/concat", + "import_alias": "benchmarkconcatstring_572990626", + "qualified_name": "benchmarkconcatstring_572990626.BenchmarkConcatString", + "file_path": "concat/concat_test.go" + }, + { + "name": "BenchmarkConcatBuffer", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/concat", + "import_alias": "benchmarkconcatbuffer_572990626", + "qualified_name": "benchmarkconcatbuffer_572990626.BenchmarkConcatBuffer", + "file_path": "concat/concat_test.go" + }, + { + "name": "BenchmarkConcatBuilder", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/concat", + "import_alias": "benchmarkconcatbuilder_572990626", + "qualified_name": "benchmarkconcatbuilder_572990626.BenchmarkConcatBuilder", + "file_path": "concat/concat_test.go" + }, + { + "name": "BenchmarkConcat", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/concat", + "import_alias": "benchmarkconcat_572990626", + "qualified_name": "benchmarkconcat_572990626.BenchmarkConcat", + "file_path": "concat/concat_test.go" + } + ] + }, + { + "raw_package": { + "Dir": "[package_dir]", + "Name": "contains", + "ImportPath": "github.com/SimonWaldherr/golang-benchmarks/contains [github.com/SimonWaldherr/golang-benchmarks/contains.test]", + "TestGoFiles": [ + "contains_test.go" + ], + "TestImports": [ + "bytes", + "regexp", + "strings", + "testing" + ], + "CompiledGoFiles": [ + "contains_test.go" + ], + "Module": { + "Path": "github.com/SimonWaldherr/golang-benchmarks", + "Dir": "[module_dir]", + "GoMod": "[go_mod_path]", + "GoVersion": "1.18", + "Main": true + } + }, + "benchmarks": [ + { + "name": "BenchmarkContains", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/contains", + "import_alias": "benchmarkcontains_572990626", + "qualified_name": "benchmarkcontains_572990626.BenchmarkContains", + "file_path": "contains/contains_test.go" + }, + { + "name": "BenchmarkContainsNot", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/contains", + "import_alias": "benchmarkcontainsnot_572990626", + "qualified_name": "benchmarkcontainsnot_572990626.BenchmarkContainsNot", + "file_path": "contains/contains_test.go" + }, + { + "name": "BenchmarkContainsBytes", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/contains", + "import_alias": "benchmarkcontainsbytes_572990626", + "qualified_name": "benchmarkcontainsbytes_572990626.BenchmarkContainsBytes", + "file_path": "contains/contains_test.go" + }, + { + "name": "BenchmarkContainsBytesNot", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/contains", + "import_alias": "benchmarkcontainsbytesnot_572990626", + "qualified_name": "benchmarkcontainsbytesnot_572990626.BenchmarkContainsBytesNot", + "file_path": "contains/contains_test.go" + }, + { + "name": "BenchmarkCompileMatch", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/contains", + "import_alias": "benchmarkcompilematch_572990626", + "qualified_name": "benchmarkcompilematch_572990626.BenchmarkCompileMatch", + "file_path": "contains/contains_test.go" + }, + { + "name": "BenchmarkCompileMatchNot", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/contains", + "import_alias": "benchmarkcompilematchnot_572990626", + "qualified_name": "benchmarkcompilematchnot_572990626.BenchmarkCompileMatchNot", + "file_path": "contains/contains_test.go" + }, + { + "name": "BenchmarkMatch", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/contains", + "import_alias": "benchmarkmatch_572990626", + "qualified_name": "benchmarkmatch_572990626.BenchmarkMatch", + "file_path": "contains/contains_test.go" + }, + { + "name": "BenchmarkMatchNot", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/contains", + "import_alias": "benchmarkmatchnot_572990626", + "qualified_name": "benchmarkmatchnot_572990626.BenchmarkMatchNot", + "file_path": "contains/contains_test.go" + }, + { + "name": "BenchmarkContainsMethods", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/contains", + "import_alias": "benchmarkcontainsmethods_572990626", + "qualified_name": "benchmarkcontainsmethods_572990626.BenchmarkContainsMethods", + "file_path": "contains/contains_test.go" + } + ] + }, + { + "raw_package": { + "Dir": "[package_dir]", + "Name": "embed", + "ImportPath": "github.com/SimonWaldherr/golang-benchmarks/embed [github.com/SimonWaldherr/golang-benchmarks/embed.test]", + "TestGoFiles": [ + "embed_test.go" + ], + "TestImports": [ + "embed", + "io/ioutil", + "os", + "testing" + ], + "CompiledGoFiles": [ + "embed_test.go" + ], + "Module": { + "Path": "github.com/SimonWaldherr/golang-benchmarks", + "Dir": "[module_dir]", + "GoMod": "[go_mod_path]", + "GoVersion": "1.18", + "Main": true + } + }, + "benchmarks": [ + { + "name": "BenchmarkEmbed", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/embed", + "import_alias": "benchmarkembed_572990626", + "qualified_name": "benchmarkembed_572990626.BenchmarkEmbed", + "file_path": "embed/embed_test.go" + }, + { + "name": "BenchmarkReadFile", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/embed", + "import_alias": "benchmarkreadfile_572990626", + "qualified_name": "benchmarkreadfile_572990626.BenchmarkReadFile", + "file_path": "embed/embed_test.go" + }, + { + "name": "BenchmarkIoutilReadFile", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/embed", + "import_alias": "benchmarkioutilreadfile_572990626", + "qualified_name": "benchmarkioutilreadfile_572990626.BenchmarkIoutilReadFile", + "file_path": "embed/embed_test.go" + } + ] + }, + { + "raw_package": { + "Dir": "[package_dir]", + "Name": "foreach", + "ImportPath": "github.com/SimonWaldherr/golang-benchmarks/foreach [github.com/SimonWaldherr/golang-benchmarks/foreach.test]", + "TestGoFiles": [ + "foreach_test.go" + ], + "TestImports": [ + "testing" + ], + "CompiledGoFiles": [ + "foreach_test.go" + ], + "Module": { + "Path": "github.com/SimonWaldherr/golang-benchmarks", + "Dir": "[module_dir]", + "GoMod": "[go_mod_path]", + "GoVersion": "1.18", + "Main": true + } + }, + "benchmarks": [ + { + "name": "BenchmarkForMap", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/foreach", + "import_alias": "benchmarkformap_572990626", + "qualified_name": "benchmarkformap_572990626.BenchmarkForMap", + "file_path": "foreach/foreach_test.go" + }, + { + "name": "BenchmarkRangeMap", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/foreach", + "import_alias": "benchmarkrangemap_572990626", + "qualified_name": "benchmarkrangemap_572990626.BenchmarkRangeMap", + "file_path": "foreach/foreach_test.go" + }, + { + "name": "BenchmarkRangeSlice", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/foreach", + "import_alias": "benchmarkrangeslice_572990626", + "qualified_name": "benchmarkrangeslice_572990626.BenchmarkRangeSlice", + "file_path": "foreach/foreach_test.go" + }, + { + "name": "BenchmarkRangeSliceKey", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/foreach", + "import_alias": "benchmarkrangeslicekey_572990626", + "qualified_name": "benchmarkrangeslicekey_572990626.BenchmarkRangeSliceKey", + "file_path": "foreach/foreach_test.go" + } + ] + }, + { + "raw_package": { + "Dir": "[package_dir]", + "Name": "index", + "ImportPath": "github.com/SimonWaldherr/golang-benchmarks/index [github.com/SimonWaldherr/golang-benchmarks/index.test]", + "TestGoFiles": [ + "index_test.go" + ], + "TestImports": [ + "math/rand", + "strconv", + "testing" + ], + "CompiledGoFiles": [ + "index_test.go" + ], + "Module": { + "Path": "github.com/SimonWaldherr/golang-benchmarks", + "Dir": "[module_dir]", + "GoMod": "[go_mod_path]", + "GoVersion": "1.18", + "Main": true + } + }, + "benchmarks": [ + { + "name": "BenchmarkMapStringKeys", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/index", + "import_alias": "benchmarkmapstringkeys_572990626", + "qualified_name": "benchmarkmapstringkeys_572990626.BenchmarkMapStringKeys", + "file_path": "index/index_test.go" + }, + { + "name": "BenchmarkMapIntKeys", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/index", + "import_alias": "benchmarkmapintkeys_572990626", + "qualified_name": "benchmarkmapintkeys_572990626.BenchmarkMapIntKeys", + "file_path": "index/index_test.go" + }, + { + "name": "BenchmarkMapStringIndex", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/index", + "import_alias": "benchmarkmapstringindex_572990626", + "qualified_name": "benchmarkmapstringindex_572990626.BenchmarkMapStringIndex", + "file_path": "index/index_test.go" + }, + { + "name": "BenchmarkMapIntIndex", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/index", + "import_alias": "benchmarkmapintindex_572990626", + "qualified_name": "benchmarkmapintindex_572990626.BenchmarkMapIntIndex", + "file_path": "index/index_test.go" + } + ] + }, + { + "raw_package": { + "Dir": "[package_dir]", + "Name": "json", + "ImportPath": "github.com/SimonWaldherr/golang-benchmarks/json [github.com/SimonWaldherr/golang-benchmarks/json.test]", + "TestGoFiles": [ + "json_test.go" + ], + "TestImports": [ + "encoding/json", + "math", + "math/big", + "testing", + "time" + ], + "CompiledGoFiles": [ + "json_test.go" + ], + "Module": { + "Path": "github.com/SimonWaldherr/golang-benchmarks", + "Dir": "[module_dir]", + "GoMod": "[go_mod_path]", + "GoVersion": "1.18", + "Main": true + } + }, + "benchmarks": [ + { + "name": "BenchmarkJsonMarshal", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/json", + "import_alias": "benchmarkjsonmarshal_572990626", + "qualified_name": "benchmarkjsonmarshal_572990626.BenchmarkJsonMarshal", + "file_path": "json/json_test.go" + }, + { + "name": "BenchmarkJsonUnmarshal", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/json", + "import_alias": "benchmarkjsonunmarshal_572990626", + "qualified_name": "benchmarkjsonunmarshal_572990626.BenchmarkJsonUnmarshal", + "file_path": "json/json_test.go" + } + ] + }, + { + "raw_package": { + "Dir": "[package_dir]", + "Name": "math", + "ImportPath": "github.com/SimonWaldherr/golang-benchmarks/math [github.com/SimonWaldherr/golang-benchmarks/math.test]", + "TestGoFiles": [ + "math_test.go" + ], + "TestImports": [ + "sync", + "sync/atomic", + "testing" + ], + "CompiledGoFiles": [ + "math_test.go" + ], + "Module": { + "Path": "github.com/SimonWaldherr/golang-benchmarks", + "Dir": "[module_dir]", + "GoMod": "[go_mod_path]", + "GoVersion": "1.18", + "Main": true + } + }, + "benchmarks": [ + { + "name": "BenchmarkMathInt8", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/math", + "import_alias": "benchmarkmathint8_572990626", + "qualified_name": "benchmarkmathint8_572990626.BenchmarkMathInt8", + "file_path": "math/math_test.go" + }, + { + "name": "BenchmarkMathInt32", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/math", + "import_alias": "benchmarkmathint32_572990626", + "qualified_name": "benchmarkmathint32_572990626.BenchmarkMathInt32", + "file_path": "math/math_test.go" + }, + { + "name": "BenchmarkMathInt64", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/math", + "import_alias": "benchmarkmathint64_572990626", + "qualified_name": "benchmarkmathint64_572990626.BenchmarkMathInt64", + "file_path": "math/math_test.go" + }, + { + "name": "BenchmarkMathAtomicInt32", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/math", + "import_alias": "benchmarkmathatomicint32_572990626", + "qualified_name": "benchmarkmathatomicint32_572990626.BenchmarkMathAtomicInt32", + "file_path": "math/math_test.go" + }, + { + "name": "BenchmarkMathAtomicInt64", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/math", + "import_alias": "benchmarkmathatomicint64_572990626", + "qualified_name": "benchmarkmathatomicint64_572990626.BenchmarkMathAtomicInt64", + "file_path": "math/math_test.go" + }, + { + "name": "BenchmarkMathMutexInt", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/math", + "import_alias": "benchmarkmathmutexint_572990626", + "qualified_name": "benchmarkmathmutexint_572990626.BenchmarkMathMutexInt", + "file_path": "math/math_test.go" + }, + { + "name": "BenchmarkMathFloat32", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/math", + "import_alias": "benchmarkmathfloat32_572990626", + "qualified_name": "benchmarkmathfloat32_572990626.BenchmarkMathFloat32", + "file_path": "math/math_test.go" + }, + { + "name": "BenchmarkMathFloat64", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/math", + "import_alias": "benchmarkmathfloat64_572990626", + "qualified_name": "benchmarkmathfloat64_572990626.BenchmarkMathFloat64", + "file_path": "math/math_test.go" + } + ] + }, + { + "raw_package": { + "Dir": "[package_dir]", + "Name": "parse", + "ImportPath": "github.com/SimonWaldherr/golang-benchmarks/parse [github.com/SimonWaldherr/golang-benchmarks/parse.test]", + "TestGoFiles": [ + "parse_test.go" + ], + "TestImports": [ + "strconv", + "testing" + ], + "CompiledGoFiles": [ + "parse_test.go" + ], + "Module": { + "Path": "github.com/SimonWaldherr/golang-benchmarks", + "Dir": "[module_dir]", + "GoMod": "[go_mod_path]", + "GoVersion": "1.18", + "Main": true + } + }, + "benchmarks": [ + { + "name": "BenchmarkParseBool", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/parse", + "import_alias": "benchmarkparsebool_572990626", + "qualified_name": "benchmarkparsebool_572990626.BenchmarkParseBool", + "file_path": "parse/parse_test.go" + }, + { + "name": "BenchmarkParseInt", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/parse", + "import_alias": "benchmarkparseint_572990626", + "qualified_name": "benchmarkparseint_572990626.BenchmarkParseInt", + "file_path": "parse/parse_test.go" + }, + { + "name": "BenchmarkParseFloat", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/parse", + "import_alias": "benchmarkparsefloat_572990626", + "qualified_name": "benchmarkparsefloat_572990626.BenchmarkParseFloat", + "file_path": "parse/parse_test.go" + } + ] + }, + { + "raw_package": { + "Dir": "[package_dir]", + "Name": "random", + "ImportPath": "github.com/SimonWaldherr/golang-benchmarks/random [github.com/SimonWaldherr/golang-benchmarks/random.test]", + "TestGoFiles": [ + "random_test.go" + ], + "TestImports": [ + "crypto/rand", + "encoding/base64", + "math/big", + "math/rand", + "testing" + ], + "CompiledGoFiles": [ + "random_test.go" + ], + "Module": { + "Path": "github.com/SimonWaldherr/golang-benchmarks", + "Dir": "[module_dir]", + "GoMod": "[go_mod_path]", + "GoVersion": "1.18", + "Main": true + } + }, + "benchmarks": [ + { + "name": "BenchmarkMathRand", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/random", + "import_alias": "benchmarkmathrand_572990626", + "qualified_name": "benchmarkmathrand_572990626.BenchmarkMathRand", + "file_path": "random/random_test.go" + }, + { + "name": "BenchmarkCryptoRand", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/random", + "import_alias": "benchmarkcryptorand_572990626", + "qualified_name": "benchmarkcryptorand_572990626.BenchmarkCryptoRand", + "file_path": "random/random_test.go" + }, + { + "name": "BenchmarkCryptoRandString", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/random", + "import_alias": "benchmarkcryptorandstring_572990626", + "qualified_name": "benchmarkcryptorandstring_572990626.BenchmarkCryptoRandString", + "file_path": "random/random_test.go" + }, + { + "name": "BenchmarkCryptoRandBytes", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/random", + "import_alias": "benchmarkcryptorandbytes_572990626", + "qualified_name": "benchmarkcryptorandbytes_572990626.BenchmarkCryptoRandBytes", + "file_path": "random/random_test.go" + } + ] + }, + { + "raw_package": { + "Dir": "[package_dir]", + "Name": "regexp", + "ImportPath": "github.com/SimonWaldherr/golang-benchmarks/regexp [github.com/SimonWaldherr/golang-benchmarks/regexp.test]", + "TestGoFiles": [ + "regexp_test.go" + ], + "TestImports": [ + "regexp", + "simonwaldherr.de/go/golibs/regex", + "testing" + ], + "CompiledGoFiles": [ + "regexp_test.go" + ], + "Module": { + "Path": "github.com/SimonWaldherr/golang-benchmarks", + "Dir": "[module_dir]", + "GoMod": "[go_mod_path]", + "GoVersion": "1.18", + "Main": true + } + }, + "benchmarks": [ + { + "name": "BenchmarkMatchString", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/regexp", + "import_alias": "benchmarkmatchstring_572990626", + "qualified_name": "benchmarkmatchstring_572990626.BenchmarkMatchString", + "file_path": "regexp/regexp_test.go" + }, + { + "name": "BenchmarkMatchStringCompiled", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/regexp", + "import_alias": "benchmarkmatchstringcompiled_572990626", + "qualified_name": "benchmarkmatchstringcompiled_572990626.BenchmarkMatchStringCompiled", + "file_path": "regexp/regexp_test.go" + }, + { + "name": "BenchmarkMatchStringGolibs", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/regexp", + "import_alias": "benchmarkmatchstringgolibs_572990626", + "qualified_name": "benchmarkmatchstringgolibs_572990626.BenchmarkMatchStringGolibs", + "file_path": "regexp/regexp_test.go" + } + ] + }, + { + "raw_package": { + "Dir": "[package_dir]", + "Name": "template", + "ImportPath": "github.com/SimonWaldherr/golang-benchmarks/template [github.com/SimonWaldherr/golang-benchmarks/template.test]", + "TestGoFiles": [ + "template_test.go" + ], + "TestImports": [ + "bytes", + "html/template", + "regexp", + "testing", + "text/template" + ], + "CompiledGoFiles": [ + "template_test.go" + ], + "Module": { + "Path": "github.com/SimonWaldherr/golang-benchmarks", + "Dir": "[module_dir]", + "GoMod": "[go_mod_path]", + "GoVersion": "1.18", + "Main": true + } + }, + "benchmarks": [ + { + "name": "BenchmarkTextTemplate", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/template", + "import_alias": "benchmarktexttemplate_572990626", + "qualified_name": "benchmarktexttemplate_572990626.BenchmarkTextTemplate", + "file_path": "template/template_test.go" + }, + { + "name": "BenchmarkHTMLTemplate", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/template", + "import_alias": "benchmarkhtmltemplate_572990626", + "qualified_name": "benchmarkhtmltemplate_572990626.BenchmarkHTMLTemplate", + "file_path": "template/template_test.go" + }, + { + "name": "BenchmarkRegExp", + "module_path": "github.com/SimonWaldherr/golang-benchmarks/template", + "import_alias": "benchmarkregexp_572990626", + "qualified_name": "benchmarkregexp_572990626.BenchmarkRegExp", + "file_path": "template/template_test.go" + } + ] + } +] diff --git a/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__already_patched_import.snap b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__already_patched_import.snap new file mode 100644 index 0000000..eacf462 --- /dev/null +++ b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__already_patched_import.snap @@ -0,0 +1,11 @@ +--- +source: src/builder/patcher.rs +expression: result +--- +package main + +import testing "github.com/CodSpeedHQ/codspeed-go/compat/testing" + +func BenchmarkExample(b *testing.B) { + // benchmark code +} diff --git a/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__import_at_end_of_block.snap b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__import_at_end_of_block.snap new file mode 100644 index 0000000..69ebcbf --- /dev/null +++ b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__import_at_end_of_block.snap @@ -0,0 +1,11 @@ +--- +source: src/builder/patcher.rs +expression: result +--- +package main + +import ( + "fmt" + "strings" + testing "github.com/CodSpeedHQ/codspeed-go/compat/testing" +) diff --git a/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__import_with_comments.snap b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__import_with_comments.snap new file mode 100644 index 0000000..299ebe9 --- /dev/null +++ b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__import_with_comments.snap @@ -0,0 +1,11 @@ +--- +source: src/builder/patcher.rs +expression: result +--- +package main + +import ( + "fmt" + testing "github.com/CodSpeedHQ/codspeed-go/compat/testing" // for unit tests + "strings" +) diff --git a/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__import_with_extra_whitespace.snap b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__import_with_extra_whitespace.snap new file mode 100644 index 0000000..55bb32e --- /dev/null +++ b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__import_with_extra_whitespace.snap @@ -0,0 +1,13 @@ +--- +source: src/builder/patcher.rs +expression: result +--- +package main + +import ( + "fmt" + + testing "github.com/CodSpeedHQ/codspeed-go/compat/testing" + + "strings" +) diff --git a/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__import_with_testing_string.snap b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__import_with_testing_string.snap new file mode 100644 index 0000000..2c17e1d --- /dev/null +++ b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__import_with_testing_string.snap @@ -0,0 +1,11 @@ +--- +source: src/builder/patcher.rs +expression: result +--- +package main +import testing "github.com/CodSpeedHQ/codspeed-go/compat/testing" +import "fmt" + +func TestExample(t *testing.T) { + fmt.Println("testing") +} diff --git a/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__mixed_import_styles.snap b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__mixed_import_styles.snap new file mode 100644 index 0000000..f096b3d --- /dev/null +++ b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__mixed_import_styles.snap @@ -0,0 +1,12 @@ +--- +source: src/builder/patcher.rs +expression: result +--- +package main + +import testing "github.com/CodSpeedHQ/codspeed-go/compat/testing" + +import ( + "fmt" + "something" +) diff --git a/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__multiline_import_replacement.snap b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__multiline_import_replacement.snap new file mode 100644 index 0000000..f9abb1f --- /dev/null +++ b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__multiline_import_replacement.snap @@ -0,0 +1,15 @@ +--- +source: src/builder/patcher.rs +expression: result +--- +package main + +import ( + "fmt" + testing "github.com/CodSpeedHQ/codspeed-go/compat/testing" + "strings" +) + +func TestExample(t *testing.T) { + // test code +} diff --git a/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__multiline_import_with_tabs.snap b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__multiline_import_with_tabs.snap new file mode 100644 index 0000000..92ced0d --- /dev/null +++ b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__multiline_import_with_tabs.snap @@ -0,0 +1,11 @@ +--- +source: src/builder/patcher.rs +expression: result +--- +package main + +import ( + "fmt" + testing "github.com/CodSpeedHQ/codspeed-go/compat/testing" + "strings" +) diff --git a/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__multiline_import_with_testing_string.snap b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__multiline_import_with_testing_string.snap new file mode 100644 index 0000000..f92ec4c --- /dev/null +++ b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__multiline_import_with_testing_string.snap @@ -0,0 +1,13 @@ +--- +source: src/builder/patcher.rs +expression: result +--- +package main +import ( + "fmt" + testing "github.com/CodSpeedHQ/codspeed-go/compat/testing" +) + +func TestExample(t *testing.T) { + fmt.Println("testing") +} diff --git a/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__single_import_replacement.snap b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__single_import_replacement.snap new file mode 100644 index 0000000..619d862 --- /dev/null +++ b/go-runner/src/builder/snapshots/go_runner__builder__patcher__tests__single_import_replacement.snap @@ -0,0 +1,11 @@ +--- +source: src/builder/patcher.rs +expression: result +--- +package main + +import testing "github.com/CodSpeedHQ/codspeed-go/compat/testing" + +func TestExample(t *testing.T) { + // test code +} diff --git a/go-runner/src/builder/template.go b/go-runner/src/builder/template.go new file mode 100644 index 0000000..580b586 --- /dev/null +++ b/go-runner/src/builder/template.go @@ -0,0 +1,81 @@ +package main + +import ( + "io" + "time" + "reflect" + codspeed "github.com/CodSpeedHQ/codspeed-go/compat/testing" + codspeed_testing "github.com/CodSpeedHQ/codspeed-go/testing/testing" + + // Import parent package containing the benchmarks +{{#each benchmarks}} + {{import_alias}} "{{module_path}}" +{{/each}} +) + +type BenchmarkEntry struct { + Name string + Func func(b *codspeed.B) +} + +type corpusEntry = struct { + Parent string + Path string + Data []byte + Values []any + Generation int + IsSeed bool +} + +type simpleDeps struct{} + +func (d simpleDeps) ImportPath() string { return "" } +func (d simpleDeps) MatchString(pat, str string) (bool, error) { return true, nil } +func (d simpleDeps) SetPanicOnExit0(bool) {} +func (d simpleDeps) StartCPUProfile(io.Writer) error { return nil } +func (d simpleDeps) StopCPUProfile() {} +func (d simpleDeps) StartTestLog(io.Writer) {} +func (d simpleDeps) StopTestLog() error { return nil } +func (d simpleDeps) WriteProfileTo(string, io.Writer, int) error { return nil } + +func (d simpleDeps) CoordinateFuzzing( + fuzzTime time.Duration, + fuzzN int64, + minimizeTime time.Duration, + minimizeN int64, + parallel int, + corpus []corpusEntry, + types []reflect.Type, + corpusDir, + cacheDir string, +) error { + return nil +} +func (d simpleDeps) RunFuzzWorker(fn func(corpusEntry) error) error { + return nil +} +func (d simpleDeps) ReadCorpus(dir string, types []reflect.Type) ([]corpusEntry, error) { + return nil, nil +} +func (d simpleDeps) CheckCorpus(vals []any, types []reflect.Type) error { + return nil +} +func (d simpleDeps) ResetCoverage() {} +func (d simpleDeps) SnapshotCoverage() {} +func (d simpleDeps) InitRuntimeCoverage() (mode string, tearDown func(coverprofile string, gocoverdir string) (string, error), snapcov func() float64) { + return "", nil, nil +} + +func main() { + var tests = []codspeed_testing.InternalTest{} + var fuzzTargets = []codspeed_testing.InternalFuzzTarget{} + var examples = []codspeed_testing.InternalExample{} + var benchmarks = []codspeed_testing.InternalBenchmark{ +{{#each benchmarks}} + {"{{name}}", {{qualified_name}}}, +{{/each}} + } + + m := codspeed_testing.MainStart(simpleDeps{}, tests, benchmarks, fuzzTargets, examples) + m.Run() +} diff --git a/go-runner/src/builder/templater.rs b/go-runner/src/builder/templater.rs new file mode 100644 index 0000000..2ec8344 --- /dev/null +++ b/go-runner/src/builder/templater.rs @@ -0,0 +1,95 @@ +use std::fs; +use std::path::{Path, PathBuf}; + +use handlebars::Handlebars; +use serde::{Deserialize, Serialize}; +use tempfile::TempDir; + +use crate::builder::{BenchmarkPackage, GoBenchmark}; +use crate::utils; +use crate::{builder::patcher, prelude::*}; + +#[derive(Debug, Serialize, Deserialize)] +struct TemplateData { + benchmarks: Vec, + module_name: String, +} + +pub fn run(package: &BenchmarkPackage) -> anyhow::Result<(TempDir, PathBuf)> { + // 1. Copy the whole module to a build directory + let target_dir = TempDir::new()?; + std::fs::create_dir_all(&target_dir).context("Failed to create target directory")?; + utils::copy_dir_all(&package.module.dir, &target_dir)?; + + // Get files that need to be renamed first + let files = package + .test_go_files + .as_ref() + .ok_or_else(|| anyhow::anyhow!("No test files found for package: {}", package.name))?; + + // Calculate the relative path from module root to package directory + let package_dir = Path::new(&package.dir); + let module_dir = Path::new(&package.module.dir); + let relative_package_path = package_dir.strip_prefix(module_dir).context(format!( + "Package dir {:?} is not within module dir {:?}", + package.dir, package.module.dir + ))?; + debug!("Relative package path: {relative_package_path:?}"); + + // 2. Find benchmark files and patch their imports + let files_to_patch = package + .benchmarks + .iter() + .map(|bench| { + target_dir + .path() + // .join(relative_package_path) + .join(&bench.file_path) + }) + .collect::>(); + patcher::patch_imports(&target_dir, files_to_patch)?; + + // 3. Rename the _test.go files to _codspeed.go + for file in files { + let old_path = target_dir.path().join(relative_package_path).join(file); + let new_path = old_path.with_file_name( + old_path + .file_name() + .unwrap() + .to_string_lossy() + .replace("_test", "_codspeed"), + ); + + fs::rename(&old_path, &new_path) + .context(format!("Failed to rename {old_path:?} to {new_path:?}"))?; + } + + // 4. Generate the codspeed/runner.go file using the template + // + let mut handlebars = Handlebars::new(); + let template_content = include_str!("template.go"); + handlebars.register_template_string("main", template_content)?; + + // import + // { "", }, + let data = TemplateData { + benchmarks: package.benchmarks.clone(), + module_name: "codspeed_runner".into(), + }; + let rendered = handlebars.render("main", &data)?; + + let runner_path = target_dir + .path() + .join(relative_package_path) + .join("codspeed/runner.go"); + fs::create_dir_all( + target_dir + .path() + .join(relative_package_path) + .join("codspeed"), + ) + .context("Failed to create codspeed directory")?; + fs::write(&runner_path, rendered).context("Failed to write runner.go file")?; + + Ok((target_dir, runner_path)) +} diff --git a/go-runner/src/builder/verifier.rs b/go-runner/src/builder/verifier.rs new file mode 100644 index 0000000..d4553ba --- /dev/null +++ b/go-runner/src/builder/verifier.rs @@ -0,0 +1,208 @@ +use gosyn::ast::FuncDecl; + +use crate::prelude::*; + +pub struct FuncVisitor { + param_name: String, + func_decl: gosyn::ast::FuncDecl, +} + +impl FuncVisitor { + pub fn verify_source_code(source: &str, benchmarks: &[String]) -> anyhow::Result> { + let file = gosyn::parse_source(source)?; + Self::verify_file(&file, benchmarks) + } + + pub fn verify_file( + file: &gosyn::ast::File, + benchmarks: &[String], + ) -> anyhow::Result> { + let mut valid_benchmarks = Vec::new(); + for decl in &file.decl { + let gosyn::ast::Declaration::Function(func_decl) = decl else { + continue; + }; + let func_name = &func_decl.name.name; + if !benchmarks.contains(func_name) { + continue; + } + + if FuncVisitor::new(func_decl.clone())?.is_valid().is_err() { + continue; + }; + + valid_benchmarks.push(func_name.clone()); + } + + Ok(valid_benchmarks) + } + + pub fn new(func: FuncDecl) -> anyhow::Result { + let param_name = Self::find_testing_b_param_name(&func)?; + + Ok(Self { + param_name, + func_decl: func, + }) + } + + fn find_testing_b_param_name(func_decl: &gosyn::ast::FuncDecl) -> Result { + let params = &func_decl.typ.params; + for param in ¶ms.list { + let type_expr = ¶m.typ; + + let gosyn::ast::Expression::TypePointer(pointer_type) = type_expr else { + continue; + }; + let gosyn::ast::Expression::Selector(selector) = pointer_type.typ.as_ref() else { + continue; + }; + + let gosyn::ast::Expression::Ident(pkg) = selector.x.as_ref() else { + continue; + }; + + // We need a testing.B parameter + if pkg.name != "testing" || selector.sel.name != "B" { + continue; + } + + if let Some(first_name) = param.name.first() { + return Ok(first_name.name.clone()); + } + } + + bail!("Benchmark function does not have *testing.B parameter"); + } + + pub fn is_valid(&self) -> anyhow::Result<()> { + let Some(body) = &self.func_decl.body else { + return Ok(()); + }; + + self.is_valid_block(body) + } + + fn is_valid_block(&self, block: &gosyn::ast::BlockStmt) -> anyhow::Result<()> { + for stmt in &block.list { + self.is_valid_stmt(stmt)?; + } + Ok(()) + } + + fn is_valid_stmt(&self, stmt: &gosyn::ast::Statement) -> anyhow::Result<()> { + match stmt { + gosyn::ast::Statement::Expr(expr_stmt) => self.is_valid_expr(&expr_stmt.expr), + gosyn::ast::Statement::Assign(assign_stmt) => { + for expr in &assign_stmt.right { + self.is_valid_expr(expr)?; + } + Ok(()) + } + gosyn::ast::Statement::If(if_stmt) => { + self.is_valid_expr(&if_stmt.cond)?; + self.is_valid_block(&if_stmt.body)?; + if let Some(else_stmt) = &if_stmt.else_ { + self.is_valid_stmt(else_stmt)?; + } + Ok(()) + } + gosyn::ast::Statement::For(for_stmt) => { + if let Some(condition) = &for_stmt.cond { + self.is_valid_stmt(condition)?; + } + if let Some(init) = &for_stmt.init { + self.is_valid_stmt(init)?; + } + if let Some(post) = &for_stmt.post { + self.is_valid_stmt(post)?; + } + self.is_valid_block(&for_stmt.body) + } + gosyn::ast::Statement::Block(block_stmt) => self.is_valid_block(block_stmt), + _ => Ok(()), + } + } + + fn is_valid_expr(&self, expr: &gosyn::ast::Expression) -> anyhow::Result<()> { + match expr { + gosyn::ast::Expression::Call(call_expr) => { + if let gosyn::ast::Expression::Selector(_) = call_expr.func.as_ref() { + for arg in &call_expr.args { + if self.uses_testing_ident(arg) { + bail!( + "testing.B parameter '{}' passed as argument to method call", + self.param_name + ); + } + } + } else { + for arg in &call_expr.args { + if self.uses_testing_ident(arg) { + bail!( + "testing.B parameter '{}' passed as argument to function call", + self.param_name + ); + } + } + } + + for arg in &call_expr.args { + self.is_valid_expr(arg)?; + } + } + gosyn::ast::Expression::Operation(operation) => { + self.is_valid_expr(&operation.x)?; + if let Some(y) = &operation.y { + self.is_valid_expr(y)?; + } + } + _ => {} + } + Ok(()) + } + + fn uses_testing_ident(&self, expr: &gosyn::ast::Expression) -> bool { + if let gosyn::ast::Expression::Ident(ident) = expr { + ident.name == self.param_name + } else { + false + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_valid_benchmark() { + let source = include_str!("../../testdata/verifier/valid_benchmark.go"); + FuncVisitor::verify_source_code(source, &["BenchmarkValid".into()]).unwrap(); + } + + #[test] + fn test_invalid_benchmark_function_call() { + let source = include_str!("../../testdata/verifier/invalid_benchmark_function_call.go"); + FuncVisitor::verify_source_code(source, &["BenchmarkInvalid".into()]).unwrap(); + } + + #[test] + fn test_valid_benchmark_method_calls() { + let source = include_str!("../../testdata/verifier/valid_benchmark_methods.go"); + FuncVisitor::verify_source_code(source, &["BenchmarkValidMethods".into()]).unwrap(); + } + + #[test] + fn test_multiple_benchmarks_mixed_validity() { + let source = include_str!("../../testdata/verifier/mixed_validity_benchmarks.go"); + let valid_benches = FuncVisitor::verify_source_code( + source, + &["BenchmarkValid".into(), "BenchmarkInvalid".into()], + ) + .unwrap(); + + assert_eq!(valid_benches.len(), 1); + assert!(valid_benches.contains(&"BenchmarkValid".to_string())); + } +} diff --git a/go-runner/src/cli.rs b/go-runner/src/cli.rs new file mode 100644 index 0000000..8b6d93d --- /dev/null +++ b/go-runner/src/cli.rs @@ -0,0 +1,153 @@ +#[derive(Debug)] +pub enum CliExit { + Help, + Version, + MissingArgument, + UnknownFlag, +} + +#[derive(Debug)] +pub struct Cli { + /// Run only benchmarks matching regexp + pub bench: String, +} + +impl Cli { + pub fn parse() -> Self { + match Self::parse_args(std::env::args().skip(1)) { + Ok(cli) => cli, + Err(CliExit::Help) => std::process::exit(0), + Err(CliExit::Version) => std::process::exit(0), + Err(CliExit::MissingArgument) => std::process::exit(2), + Err(CliExit::UnknownFlag) => std::process::exit(1), + } + } + + fn parse_args(mut args: impl Iterator) -> Result { + let mut bench = ".".to_string(); + + // We currently only support the `test` subcommand. + let cmd = args.next(); + assert!( + cmd == Some("test".to_string()), + "Expected 'test' as the first argument, got {cmd:?}", + ); + + while let Some(arg) = args.next() { + match arg.as_str() { + "-h" | "--help" => { + println!( + "\ +The Codspeed Go Benchmark Runner + +USAGE: + go-runner test [OPTIONS] + +OPTIONS: + -bench Run only benchmarks matching regexp (defaults to '.') + -h, --help Print help information + -V, --version Print version information" + ); + return Err(CliExit::Help); + } + "-V" | "--version" => { + println!("{}", env!("CARGO_PKG_VERSION")); + return Err(CliExit::Version); + } + "-bench" => { + bench = args.next().ok_or_else(|| { + eprintln!("error: `-bench` requires a pattern"); + CliExit::MissingArgument + })?; + } + s if s.starts_with("-bench=") => { + bench = s.split_once('=').unwrap().1.to_string(); + } + + s if s.starts_with('-') => { + eprintln!("Unknown flag: {s}"); + return Err(CliExit::UnknownFlag); + } + + _ => { + eprintln!( + "warning: package arguments are not currently supported, ignoring '{arg}'" + ); + // Consume and ignore all remaining arguments + for remaining_arg in args { + eprintln!( + "warning: package arguments are not currently supported, ignoring '{remaining_arg}'" + ); + } + break; + } + } + } + Ok(Self { bench }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn str_to_iter(cmd: &str) -> Result { + let args: Vec = if cmd.trim().is_empty() { + Vec::new() + } else { + cmd.split_whitespace() + .map(|s| s.to_string()) + .skip(1) + .collect() + }; + Cli::parse_args(args.into_iter()) + } + + #[test] + fn test_cli_parse_defaults() { + let cli = str_to_iter("go-runner test").unwrap(); + assert_eq!(cli.bench, "."); + } + + #[test] + fn test_cli_parse_with_bench_flag() { + let cli = str_to_iter("go-runner test -bench Test").unwrap(); + assert_eq!(cli.bench, "Test"); + + let cli = str_to_iter("go-runner test -bench=BenchmarkFoo").unwrap(); + assert_eq!(cli.bench, "BenchmarkFoo"); + } + + #[test] + fn test_cli_parse_ignores_packages() { + let cli = str_to_iter("go-runner test package1 package2").unwrap(); + assert_eq!(cli.bench, "."); + } + + #[test] + fn test_cli_parse_help_flag() { + let result = str_to_iter("go-runner test -h"); + assert!(matches!(result, Err(CliExit::Help))); + + let result = str_to_iter("go-runner test --help"); + assert!(matches!(result, Err(CliExit::Help))); + } + + #[test] + fn test_cli_parse_version_flag() { + let result = str_to_iter("go-runner test -V"); + assert!(matches!(result, Err(CliExit::Version))); + + let result = str_to_iter("go-runner test --version"); + assert!(matches!(result, Err(CliExit::Version))); + } + + #[test] + fn test_cli_parse_invalid() { + let result = str_to_iter("go-runner test -bench"); + assert!(matches!(result, Err(CliExit::MissingArgument))); + + let result = str_to_iter("go-runner test -unknown"); + assert!(matches!(result, Err(CliExit::UnknownFlag))); + } +} diff --git a/go-runner/src/integration_tests.rs b/go-runner/src/integration_tests.rs new file mode 100644 index 0000000..678bd3b --- /dev/null +++ b/go-runner/src/integration_tests.rs @@ -0,0 +1,89 @@ +use itertools::Itertools; +use rstest::rstest; +use std::path::{Path, PathBuf}; +use std::sync::Mutex; +use tempfile::TempDir; + +use crate::results::walltime_results::WalltimeResults; + +fn setup_test_project(project_name: &str) -> anyhow::Result { + let project_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("testdata/projects") + .join(project_name); + println!("Project path: {project_path:?}"); + + let temp_dir = TempDir::new()?; + crate::utils::copy_dir_all(&project_path, &temp_dir)?; + + Ok(temp_dir) +} + +fn assert_results_snapshots(profile_dir: &Path, project_name: &str) { + let glob_pattern = profile_dir.join("results"); + if !glob_pattern.exists() { + eprintln!("No results found for project: {project_name}"); + return; + } + + let files = std::fs::read_dir(&glob_pattern) + .expect("Failed to read results directory") + .filter_map(Result::ok) + .map(|entry| entry.path()) + .map(|path| { + let file = std::fs::File::open(&path).unwrap(); + serde_json::from_reader::<_, WalltimeResults>(file).unwrap() + }) + // Ensure we have the correct order for multiple test executables + .sorted_by_cached_key(|r| { + r.benchmarks + .iter() + .map(|b| b.metadata.name.clone()) + .sorted() + .join(";") + }) + .collect::>(); + + for (i, mut content) in files.into_iter().enumerate() { + content + .benchmarks + .sort_by_cached_key(|b| b.metadata.name.clone()); + + let _guard = { + let mut settings = insta::Settings::clone_current(); + settings.set_snapshot_suffix(format!("{project_name}_{i}")); + settings.bind_to_scope() + }; + + insta::assert_json_snapshot!(content, { + ".creator.pid" => "[pid]", + ".benchmarks[].stats" => "[stats]", + }); + } +} + +#[rstest] +// // #[case::caddy("caddy")] +#[case::fzf("fzf")] +#[case::opentelemetry_go("opentelemetry-go")] +#[case::golang_benchmarks("golang-benchmarks")] +#[case::zerolog("zerolog")] +#[case::zap("zap")] +#[case::hugo("hugo")] +// Currently not producing results: +#[case::fuego("fuego")] +#[case::cli_runtime("cli-runtime")] +fn test_build_and_run(#[case] project_name: &str) { + let temp_dir = setup_test_project(project_name).unwrap(); + + // Mutex to prevent concurrent tests from interfering with CODSPEED_PROFILE_FOLDER env var + static ENV_MUTEX: Mutex<()> = Mutex::new(()); + let _env_guard = ENV_MUTEX.lock().unwrap_or_else(|e| e.into_inner()); + + let profile_dir = temp_dir.path().join("profile"); + unsafe { std::env::set_var("CODSPEED_PROFILE_FOLDER", &profile_dir) }; + if let Err(error) = crate::run_benchmarks(temp_dir.path(), ".") { + panic!("Benchmarks couldn't run: {error}"); + } + + assert_results_snapshots(&profile_dir, project_name); +} diff --git a/go-runner/src/lib.rs b/go-runner/src/lib.rs new file mode 100644 index 0000000..870c55c --- /dev/null +++ b/go-runner/src/lib.rs @@ -0,0 +1,103 @@ +use crate::{builder::BenchmarkPackage, prelude::*}; +use std::{ + collections::HashMap, + path::{Path, PathBuf}, +}; + +mod builder; +pub mod cli; +pub mod prelude; +mod results; +pub(crate) mod utils; + +#[cfg(test)] +mod integration_tests; + +/// Builds and runs the specified Go project benchmarks, writing results to the .codspeed folder. +pub fn run_benchmarks(project_dir: &Path, bench: &str) -> anyhow::Result<()> { + let profile_dir = std::env::var("CODSPEED_PROFILE_FOLDER") + .context("CODSPEED_PROFILE_FOLDER env var not set")?; + std::fs::remove_dir_all(&profile_dir).ok(); + + // 1. Build phase - Benchmark and package discovery + let packages = BenchmarkPackage::from_project(project_dir)?; + info!("Discovered {} packages", packages.len()); + + let mut bench_name_to_path = HashMap::new(); + for package in &packages { + for benchmark in &package.benchmarks { + bench_name_to_path.insert(benchmark.name.clone(), benchmark.file_path.clone()); + } + } + + let total_benchmarks: usize = packages.iter().map(|p| p.benchmarks.len()).sum(); + info!("Total benchmarks discovered: {total_benchmarks}"); + for (name, path) in &bench_name_to_path { + info!("Found {name:30} in {path:?}"); + } + + // 2. Generate codspeed runners and execute them + for package in &packages { + info!("Generating custom runner for package: {}", package.name); + let (_target_dir, runner_path) = builder::templater::run(package)?; + + let args = [ + "-test.bench", + bench, + // Use a single iteration in tests to speed up execution, otherwise use 5 seconds + "-test.benchtime", + if cfg!(test) || std::env::var("CODSPEED_ENV").is_err() { + "1x" + } else { + "5s" + }, + ]; + + info!("Running benchmarks for package: {}", package.name); + builder::runner::run(&runner_path, &args)?; + } + + // 3. Collect the results + collect_walltime_results(bench_name_to_path)?; + + Ok(()) +} + +// TODO: This should be merged with codspeed-rust/codspeed/walltime_results.rs +fn collect_walltime_results(bench_name_to_path: HashMap) -> anyhow::Result<()> { + let profile_dir = std::env::var("CODSPEED_PROFILE_FOLDER") + .context("CODSPEED_PROFILE_FOLDER env var not set")?; + let profile_dir = PathBuf::from(&profile_dir); + let raw_results = results::raw_result::RawResult::parse_folder(&profile_dir)?; + info!("Parsed {} raw results", raw_results.len()); + + let mut benchmarks_by_pid: HashMap> = + HashMap::new(); + for raw in raw_results { + let file_path = bench_name_to_path + .get(&raw.benchmark_name) + .map(|p| p.to_string_lossy().to_string()); + benchmarks_by_pid + .entry(raw.pid) + .or_default() + .push(raw.into_walltime_benchmark(file_path)); + } + + for (pid, walltime_benchmarks) in benchmarks_by_pid { + let creator = results::walltime_results::Creator { + name: "codspeed-go".into(), + version: env!("CARGO_PKG_VERSION").into(), + pid, + }; + let results_dir = profile_dir.join("results"); + std::fs::create_dir_all(&results_dir)?; + + let results_file = results_dir.join(format!("{pid}.json")); + let walltime_results = + results::walltime_results::WalltimeResults::new(walltime_benchmarks, creator)?; + std::fs::write(&results_file, serde_json::to_string(&walltime_results)?)?; + info!("Results written to {results_file:?}"); + } + + Ok(()) +} diff --git a/go-runner/src/main.rs b/go-runner/src/main.rs new file mode 100644 index 0000000..c4cc17d --- /dev/null +++ b/go-runner/src/main.rs @@ -0,0 +1,15 @@ +use go_runner::cli::Cli; +use std::path::Path; + +fn main() -> anyhow::Result<()> { + env_logger::builder() + .parse_env("CODSPEED_LOG") + .filter_module("handlebars", log::LevelFilter::Off) + .format_timestamp(None) + .init(); + + let cli = Cli::parse(); + go_runner::run_benchmarks(Path::new("."), &cli.bench)?; + + Ok(()) +} diff --git a/go-runner/src/prelude.rs b/go-runner/src/prelude.rs new file mode 100644 index 0000000..3a28356 --- /dev/null +++ b/go-runner/src/prelude.rs @@ -0,0 +1,2 @@ +pub use anyhow::{Context, Result, bail}; +pub use log::{debug, error, info, trace, warn}; diff --git a/go-runner/src/results/mod.rs b/go-runner/src/results/mod.rs new file mode 100644 index 0000000..992b095 --- /dev/null +++ b/go-runner/src/results/mod.rs @@ -0,0 +1,2 @@ +pub mod raw_result; +pub mod walltime_results; diff --git a/go-runner/src/results/raw_result.rs b/go-runner/src/results/raw_result.rs new file mode 100644 index 0000000..4f58ed4 --- /dev/null +++ b/go-runner/src/results/raw_result.rs @@ -0,0 +1,91 @@ +use std::path::Path; + +use serde::{Deserialize, Serialize}; + +use crate::results::walltime_results::WalltimeBenchmark; + +// WARN: Keep in sync with Golang "testing" fork (benchmark.go) +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct RawResult { + pub benchmark_name: String, + pub pid: u32, + pub codspeed_time_per_round_ns: Vec, + + #[serde(default)] + pub codspeed_iters_per_round: Vec, +} + +impl RawResult { + pub fn parse(content: &str) -> anyhow::Result { + serde_json::from_str(content) + .map_err(|e| anyhow::anyhow!("Failed to parse raw result: {}", e)) + } + + pub fn parse_folder>(folder: P) -> anyhow::Result> { + let glob_pattern = folder.as_ref().join("raw_results").join("*.json"); + Ok(glob::glob(&glob_pattern.to_string_lossy())? + .filter_map(Result::ok) + .filter_map(|path| { + let content = std::fs::read_to_string(&path).ok()?; + Self::parse(&content).ok() + }) + .collect()) + } + + pub fn into_walltime_benchmark(self, file_path: Option) -> WalltimeBenchmark { + let name = self.benchmark_name; + + let file = file_path.as_deref().unwrap_or("unknown"); + let uri = format!("{file}::{name}"); + + let times_per_round_ns = self + .codspeed_time_per_round_ns + .iter() + .map(|t| *t as u128) + .collect::>(); + let iters_per_round = if self.codspeed_iters_per_round.is_empty() { + vec![1; times_per_round_ns.len()] + } else { + self.codspeed_iters_per_round + .iter() + .map(|i| *i as u128) + .collect() + }; + + WalltimeBenchmark::from_runtime_data(name, uri, iters_per_round, times_per_round_ns, None) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_raw_result_deserialization() { + let json_data = include_str!("../../testdata/raw_results/BenchmarkFibonacci20-16.json"); + let result: RawResult = serde_json::from_str(json_data).unwrap(); + + assert_eq!(result.benchmark_name, "BenchmarkFibonacci20-16"); + assert_eq!(result.pid, 777767); + assert_eq!(result.codspeed_time_per_round_ns.len(), 3); + assert_eq!(result.codspeed_iters_per_round.len(), 0); // Default: 1 per round + } + + #[test] + fn test_into_walltime_benchmark_with_file_path() { + let raw_result = RawResult { + benchmark_name: "BenchmarkFibonacci20-16".to_string(), + pid: 777767, + codspeed_time_per_round_ns: vec![1000, 2000, 3000], + codspeed_iters_per_round: vec![], + }; + + // Test with file path - should not panic and create successfully + let _walltime_bench = raw_result + .clone() + .into_walltime_benchmark(Some("pkg/foo/fib_test.go".to_string())); + + // Test without file path (should default to TODO) - should not panic and create successfully + let _walltime_bench_no_path = raw_result.into_walltime_benchmark(None); + } +} diff --git a/go-runner/src/results/walltime_results.rs b/go-runner/src/results/walltime_results.rs new file mode 100644 index 0000000..65d659a --- /dev/null +++ b/go-runner/src/results/walltime_results.rs @@ -0,0 +1,213 @@ +// NOTE: This file was taken from `codspeed-rust` and modified a bit to fit this project. + +use anyhow::Result; + +use serde::{Deserialize, Serialize}; +use statrs::statistics::{Data, Distribution, Max, Min, OrderStatistics}; + +const IQR_OUTLIER_FACTOR: f64 = 1.5; +const STDEV_OUTLIER_FACTOR: f64 = 3.0; + +#[derive(Debug, Serialize, Deserialize)] +pub struct BenchmarkMetadata { + pub name: String, + pub uri: String, +} + +#[derive(Debug, Serialize, Deserialize)] +struct BenchmarkStats { + min_ns: f64, + max_ns: f64, + mean_ns: f64, + stdev_ns: f64, + + q1_ns: f64, + median_ns: f64, + q3_ns: f64, + + rounds: u64, + total_time: f64, + iqr_outlier_rounds: u64, + stdev_outlier_rounds: u64, + iter_per_round: u64, + warmup_iters: u64, +} + +#[derive(Debug, Serialize, Deserialize, Default)] +struct BenchmarkConfig { + warmup_time_ns: Option, + min_round_time_ns: Option, + max_time_ns: Option, + max_rounds: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct WalltimeBenchmark { + #[serde(flatten)] + pub metadata: BenchmarkMetadata, + + config: BenchmarkConfig, + stats: BenchmarkStats, +} + +impl WalltimeBenchmark { + pub fn from_runtime_data( + name: String, + uri: String, + iters_per_round: Vec, + times_per_round_ns: Vec, + max_time_ns: Option, + ) -> Self { + let total_time = times_per_round_ns.iter().sum::() as f64 / 1_000_000_000.0; + let time_per_iteration_per_round_ns: Vec<_> = times_per_round_ns + .into_iter() + .zip(&iters_per_round) + .map(|(time_per_round, iter_per_round)| time_per_round / iter_per_round) + .map(|t| t as f64) + .collect::>(); + + let mut data = Data::new(time_per_iteration_per_round_ns); + let rounds = data.len() as u64; + + let mean_ns = data.mean().unwrap(); + + let stdev_ns = if data.len() < 2 { + // std_dev() returns f64::NAN if data has less than two entries, so we have to + // manually handle this case. + 0.0 + } else { + data.std_dev().unwrap() + }; + + let q1_ns = data.quantile(0.25); + let median_ns = data.median(); + let q3_ns = data.quantile(0.75); + + let iqr_ns = q3_ns - q1_ns; + let iqr_outlier_rounds = data + .iter() + .filter(|&&t| { + t < q1_ns - IQR_OUTLIER_FACTOR * iqr_ns || t > q3_ns + IQR_OUTLIER_FACTOR * iqr_ns + }) + .count() as u64; + + let stdev_outlier_rounds = data + .iter() + .filter(|&&t| { + t < mean_ns - STDEV_OUTLIER_FACTOR * stdev_ns + || t > mean_ns + STDEV_OUTLIER_FACTOR * stdev_ns + }) + .count() as u64; + + let min_ns = data.min(); + let max_ns = data.max(); + + // TODO(COD-1056): We currently only support single iteration count per round + let iter_per_round = + (iters_per_round.iter().sum::() / iters_per_round.len() as u128) as u64; + let warmup_iters = 0; // FIXME: add warmup detection + + let stats = BenchmarkStats { + min_ns, + max_ns, + mean_ns, + stdev_ns, + q1_ns, + median_ns, + q3_ns, + rounds, + total_time, + iqr_outlier_rounds, + stdev_outlier_rounds, + iter_per_round, + warmup_iters, + }; + + WalltimeBenchmark { + metadata: BenchmarkMetadata { name, uri }, + config: BenchmarkConfig { + max_time_ns: max_time_ns.map(|t| t as f64), + ..Default::default() + }, + stats, + } + } +} + +#[derive(Debug, Serialize, Deserialize)] +struct Instrument { + #[serde(rename = "type")] + type_: String, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Creator { + pub name: String, + pub version: String, + pub pid: u32, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct WalltimeResults { + creator: Creator, + instrument: Instrument, + pub benchmarks: Vec, +} + +impl WalltimeResults { + pub fn new(benchmarks: Vec, creator: Creator) -> Result { + Ok(WalltimeResults { + instrument: Instrument { + type_: "walltime".to_string(), + }, + creator, + benchmarks, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const NAME: &str = "benchmark"; + const URI: &str = "test::benchmark"; + + #[test] + fn test_parse_single_benchmark() { + let benchmark = WalltimeBenchmark::from_runtime_data( + NAME.to_string(), + URI.to_string(), + vec![1], + vec![42], + None, + ); + assert_eq!(benchmark.stats.stdev_ns, 0.); + assert_eq!(benchmark.stats.min_ns, 42.); + assert_eq!(benchmark.stats.max_ns, 42.); + assert_eq!(benchmark.stats.mean_ns, 42.); + } + + #[test] + fn test_parse_bench_with_variable_iterations() { + let iters_per_round = vec![1, 2, 3, 4, 5, 6]; + let total_rounds = iters_per_round.iter().sum::() as f64; + + let benchmark = WalltimeBenchmark::from_runtime_data( + NAME.to_string(), + URI.to_string(), + iters_per_round, + vec![42, 42 * 2, 42 * 3, 42 * 4, 42 * 5, 42 * 6], + None, + ); + + assert_eq!(benchmark.stats.stdev_ns, 0.); + assert_eq!(benchmark.stats.min_ns, 42.); + assert_eq!(benchmark.stats.max_ns, 42.); + assert_eq!(benchmark.stats.mean_ns, 42.); + assert_eq!( + benchmark.stats.total_time, + 42. * total_rounds / 1_000_000_000.0 + ); + } +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@fzf_0.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@fzf_0.snap new file mode 100644 index 0000000..7e104de --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@fzf_0.snap @@ -0,0 +1,49 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkExtractColor", + "uri": "src/ansi_test.go::BenchmarkExtractColor", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkNextAnsiEscapeSequence", + "uri": "src/ansi_test.go::BenchmarkNextAnsiEscapeSequence", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkNextAnsiEscapeSequence_Regex", + "uri": "src/ansi_test.go::BenchmarkNextAnsiEscapeSequence_Regex", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_0.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_0.snap new file mode 100644 index 0000000..6070451 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_0.snap @@ -0,0 +1,38 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkBase64decode", + "uri": "base64/base64_test.go::BenchmarkBase64decode", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkBase64regex", + "uri": "base64/base64_test.go::BenchmarkBase64regex", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_1.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_1.snap new file mode 100644 index 0000000..7d32047 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_1.snap @@ -0,0 +1,148 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkCompileMatch", + "uri": "contains/contains_test.go::BenchmarkCompileMatch", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkCompileMatchNot", + "uri": "contains/contains_test.go::BenchmarkCompileMatchNot", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContains", + "uri": "contains/contains_test.go::BenchmarkContains", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContainsBytes", + "uri": "contains/contains_test.go::BenchmarkContainsBytes", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContainsBytesNot", + "uri": "contains/contains_test.go::BenchmarkContainsBytesNot", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContainsMethods::Bytes.Contains", + "uri": "unknown::BenchmarkContainsMethods::Bytes.Contains", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContainsMethods::RegexMatch", + "uri": "unknown::BenchmarkContainsMethods::RegexMatch", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContainsMethods::RegexMatchString", + "uri": "unknown::BenchmarkContainsMethods::RegexMatchString", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContainsMethods::Strings.Contains", + "uri": "unknown::BenchmarkContainsMethods::Strings.Contains", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContainsNot", + "uri": "contains/contains_test.go::BenchmarkContainsNot", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMatch", + "uri": "contains/contains_test.go::BenchmarkMatch", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMatchNot", + "uri": "contains/contains_test.go::BenchmarkMatchNot", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_10.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_10.snap new file mode 100644 index 0000000..9d80202 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_10.snap @@ -0,0 +1,60 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkMapIntIndex", + "uri": "index/index_test.go::BenchmarkMapIntIndex", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMapIntKeys", + "uri": "index/index_test.go::BenchmarkMapIntKeys", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMapStringIndex", + "uri": "index/index_test.go::BenchmarkMapStringIndex", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMapStringKeys", + "uri": "index/index_test.go::BenchmarkMapStringKeys", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_11.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_11.snap new file mode 100644 index 0000000..28a81cd --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_11.snap @@ -0,0 +1,49 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkMatchString", + "uri": "regexp/regexp_test.go::BenchmarkMatchString", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMatchStringCompiled", + "uri": "regexp/regexp_test.go::BenchmarkMatchStringCompiled", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMatchStringGolibs", + "uri": "regexp/regexp_test.go::BenchmarkMatchStringGolibs", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_12.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_12.snap new file mode 100644 index 0000000..46859fc --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_12.snap @@ -0,0 +1,104 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkMathAtomicInt32", + "uri": "math/math_test.go::BenchmarkMathAtomicInt32", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMathAtomicInt64", + "uri": "math/math_test.go::BenchmarkMathAtomicInt64", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMathFloat32", + "uri": "math/math_test.go::BenchmarkMathFloat32", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMathFloat64", + "uri": "math/math_test.go::BenchmarkMathFloat64", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMathInt32", + "uri": "math/math_test.go::BenchmarkMathInt32", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMathInt64", + "uri": "math/math_test.go::BenchmarkMathInt64", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMathInt8", + "uri": "math/math_test.go::BenchmarkMathInt8", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMathMutexInt", + "uri": "math/math_test.go::BenchmarkMathMutexInt", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_13.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_13.snap new file mode 100644 index 0000000..c559533 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_13.snap @@ -0,0 +1,49 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkParseBool", + "uri": "parse/parse_test.go::BenchmarkParseBool", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkParseFloat", + "uri": "parse/parse_test.go::BenchmarkParseFloat", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkParseInt", + "uri": "parse/parse_test.go::BenchmarkParseInt", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_14.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_14.snap new file mode 100644 index 0000000..9a03384 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_14.snap @@ -0,0 +1,27 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkSHA256Parallel", + "uri": "hash/hash_test.go::BenchmarkSHA256Parallel", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_2.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_2.snap new file mode 100644 index 0000000..06b1610 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_2.snap @@ -0,0 +1,82 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkConcat::Buffer", + "uri": "unknown::BenchmarkConcat::Buffer", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkConcat::Builder", + "uri": "unknown::BenchmarkConcat::Builder", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkConcat::String", + "uri": "unknown::BenchmarkConcat::String", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkConcatBuffer", + "uri": "concat/concat_test.go::BenchmarkConcatBuffer", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkConcatBuilder", + "uri": "concat/concat_test.go::BenchmarkConcatBuilder", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkConcatString", + "uri": "concat/concat_test.go::BenchmarkConcatString", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_3.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_3.snap new file mode 100644 index 0000000..95d7bf9 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_3.snap @@ -0,0 +1,60 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkCryptoRand", + "uri": "random/random_test.go::BenchmarkCryptoRand", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkCryptoRandBytes", + "uri": "random/random_test.go::BenchmarkCryptoRandBytes", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkCryptoRandString", + "uri": "random/random_test.go::BenchmarkCryptoRandString", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkMathRand", + "uri": "random/random_test.go::BenchmarkMathRand", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_4.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_4.snap new file mode 100644 index 0000000..79fcb07 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_4.snap @@ -0,0 +1,49 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkEmbed", + "uri": "embed/embed_test.go::BenchmarkEmbed", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkIoutilReadFile", + "uri": "embed/embed_test.go::BenchmarkIoutilReadFile", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkReadFile", + "uri": "embed/embed_test.go::BenchmarkReadFile", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_5.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_5.snap new file mode 100644 index 0000000..a5e409d --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_5.snap @@ -0,0 +1,49 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkEqualFold", + "uri": "caseinsensitivecompare/caseinsensitivecompare_test.go::BenchmarkEqualFold", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkToLower", + "uri": "caseinsensitivecompare/caseinsensitivecompare_test.go::BenchmarkToLower", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkToUpper", + "uri": "caseinsensitivecompare/caseinsensitivecompare_test.go::BenchmarkToUpper", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_6.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_6.snap new file mode 100644 index 0000000..1306c7f --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_6.snap @@ -0,0 +1,60 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkForMap", + "uri": "foreach/foreach_test.go::BenchmarkForMap", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkRangeMap", + "uri": "foreach/foreach_test.go::BenchmarkRangeMap", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkRangeSlice", + "uri": "foreach/foreach_test.go::BenchmarkRangeSlice", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkRangeSliceKey", + "uri": "foreach/foreach_test.go::BenchmarkRangeSliceKey", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_7.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_7.snap new file mode 100644 index 0000000..1abf1d6 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_7.snap @@ -0,0 +1,60 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkFulltextParse", + "uri": "between/between_test.go::BenchmarkFulltextParse", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkFulltextRegEx", + "uri": "between/between_test.go::BenchmarkFulltextRegEx", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkNumberParse", + "uri": "between/between_test.go::BenchmarkNumberParse", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkNumberRegEx", + "uri": "between/between_test.go::BenchmarkNumberRegEx", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_8.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_8.snap new file mode 100644 index 0000000..17b5ca3 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_8.snap @@ -0,0 +1,49 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkHTMLTemplate", + "uri": "template/template_test.go::BenchmarkHTMLTemplate", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkRegExp", + "uri": "template/template_test.go::BenchmarkRegExp", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkTextTemplate", + "uri": "template/template_test.go::BenchmarkTextTemplate", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_9.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_9.snap new file mode 100644 index 0000000..df75966 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@golang-benchmarks_9.snap @@ -0,0 +1,38 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkJsonMarshal", + "uri": "json/json_test.go::BenchmarkJsonMarshal", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkJsonUnmarshal", + "uri": "json/json_test.go::BenchmarkJsonUnmarshal", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_0.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_0.snap new file mode 100644 index 0000000..2cf767d --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_0.snap @@ -0,0 +1,60 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkAbsURL", + "uri": "transform/urlreplacers/absurlreplacer_test.go::BenchmarkAbsURL", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAbsURLSrcset", + "uri": "transform/urlreplacers/absurlreplacer_test.go::BenchmarkAbsURLSrcset", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkXMLAbsURL", + "uri": "transform/urlreplacers/absurlreplacer_test.go::BenchmarkXMLAbsURL", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkXMLAbsURLSrcset", + "uri": "transform/urlreplacers/absurlreplacer_test.go::BenchmarkXMLAbsURLSrcset", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_1.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_1.snap new file mode 100644 index 0000000..f4c0532 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_1.snap @@ -0,0 +1,313 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkCSSEscaper", + "uri": "tpl/internal/go_templates/htmltemplate/css_test.go::BenchmarkCSSEscaper", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkCSSEscaperNoSpecials", + "uri": "tpl/internal/go_templates/htmltemplate/css_test.go::BenchmarkCSSEscaperNoSpecials", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkCSSValueFilter", + "uri": "tpl/internal/go_templates/htmltemplate/css_test.go::BenchmarkCSSValueFilter", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkCSSValueFilterOk", + "uri": "tpl/internal/go_templates/htmltemplate/css_test.go::BenchmarkCSSValueFilterOk", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkDecodeCSS", + "uri": "tpl/internal/go_templates/htmltemplate/css_test.go::BenchmarkDecodeCSS", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkDecodeCSSNoSpecials", + "uri": "tpl/internal/go_templates/htmltemplate/css_test.go::BenchmarkDecodeCSSNoSpecials", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkEscapedExecute", + "uri": "tpl/internal/go_templates/htmltemplate/escape_test.go::BenchmarkEscapedExecute", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkHTMLNospaceEscaper", + "uri": "tpl/internal/go_templates/htmltemplate/html_test.go::BenchmarkHTMLNospaceEscaper", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkHTMLNospaceEscaperNoSpecials", + "uri": "tpl/internal/go_templates/htmltemplate/html_test.go::BenchmarkHTMLNospaceEscaperNoSpecials", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkJSRegexpEscaper", + "uri": "tpl/internal/go_templates/htmltemplate/js_test.go::BenchmarkJSRegexpEscaper", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkJSRegexpEscaperNoSpecials", + "uri": "tpl/internal/go_templates/htmltemplate/js_test.go::BenchmarkJSRegexpEscaperNoSpecials", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkJSStrEscaper", + "uri": "tpl/internal/go_templates/htmltemplate/js_test.go::BenchmarkJSStrEscaper", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkJSStrEscaperNoSpecials", + "uri": "tpl/internal/go_templates/htmltemplate/js_test.go::BenchmarkJSStrEscaperNoSpecials", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkJSValEscaperWithNum", + "uri": "tpl/internal/go_templates/htmltemplate/js_test.go::BenchmarkJSValEscaperWithNum", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkJSValEscaperWithObj", + "uri": "tpl/internal/go_templates/htmltemplate/js_test.go::BenchmarkJSValEscaperWithObj", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkJSValEscaperWithObjNoSpecials", + "uri": "tpl/internal/go_templates/htmltemplate/js_test.go::BenchmarkJSValEscaperWithObjNoSpecials", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkJSValEscaperWithStr", + "uri": "tpl/internal/go_templates/htmltemplate/js_test.go::BenchmarkJSValEscaperWithStr", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkJSValEscaperWithStrNoSpecials", + "uri": "tpl/internal/go_templates/htmltemplate/js_test.go::BenchmarkJSValEscaperWithStrNoSpecials", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkSrcsetFilter", + "uri": "tpl/internal/go_templates/htmltemplate/url_test.go::BenchmarkSrcsetFilter", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkSrcsetFilterNoSpecials", + "uri": "tpl/internal/go_templates/htmltemplate/url_test.go::BenchmarkSrcsetFilterNoSpecials", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkStripTags", + "uri": "tpl/internal/go_templates/htmltemplate/html_test.go::BenchmarkStripTags", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkStripTagsNoSpecials", + "uri": "tpl/internal/go_templates/htmltemplate/html_test.go::BenchmarkStripTagsNoSpecials", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkTemplateSpecialTags", + "uri": "tpl/internal/go_templates/htmltemplate/transition_test.go::BenchmarkTemplateSpecialTags", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkURLEscaper", + "uri": "tpl/internal/go_templates/htmltemplate/url_test.go::BenchmarkURLEscaper", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkURLEscaperNoSpecials", + "uri": "tpl/internal/go_templates/htmltemplate/url_test.go::BenchmarkURLEscaperNoSpecials", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkURLNormalizer", + "uri": "tpl/internal/go_templates/htmltemplate/url_test.go::BenchmarkURLNormalizer", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkURLNormalizerNoSpecials", + "uri": "tpl/internal/go_templates/htmltemplate/url_test.go::BenchmarkURLNormalizerNoSpecials", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_2.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_2.snap new file mode 100644 index 0000000..86f8b70 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_2.snap @@ -0,0 +1,27 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkHash", + "uri": "hugolib/pagesfromdata/pagesfromgotmpl_test.go::BenchmarkHash", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_3.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_3.snap new file mode 100644 index 0000000..c6fad2e --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_3.snap @@ -0,0 +1,49 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkListString", + "uri": "tpl/internal/go_templates/texttemplate/parse/parse_test.go::BenchmarkListString", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkParseLarge", + "uri": "tpl/internal/go_templates/texttemplate/parse/parse_test.go::BenchmarkParseLarge", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkVariableString", + "uri": "tpl/internal/go_templates/texttemplate/parse/parse_test.go::BenchmarkVariableString", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_4.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_4.snap new file mode 100644 index 0000000..370b0ba --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_4.snap @@ -0,0 +1,27 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkLoad", + "uri": "config/allconfig/load_test.go::BenchmarkLoad", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_5.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_5.snap new file mode 100644 index 0000000..838ccf2 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_5.snap @@ -0,0 +1,71 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkSortMap", + "uri": "tpl/collections/sort_test.go::BenchmarkSortMap", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkWhereMap", + "uri": "tpl/collections/where_test.go::BenchmarkWhereMap", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkWhereOps::eq", + "uri": "unknown::BenchmarkWhereOps::eq", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkWhereOps::like", + "uri": "unknown::BenchmarkWhereOps::like", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkWhereOps::ne", + "uri": "unknown::BenchmarkWhereOps::ne", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_6.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_6.snap new file mode 100644 index 0000000..70fa336 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@hugo_6.snap @@ -0,0 +1,38 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkTruncate::Plain_text", + "uri": "unknown::BenchmarkTruncate::Plain_text", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkTruncate::With_link", + "uri": "unknown::BenchmarkTruncate::With_link", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@opentelemetry-go_0.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@opentelemetry-go_0.snap new file mode 100644 index 0000000..a89f2c3 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@opentelemetry-go_0.snap @@ -0,0 +1,71 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkAsFloat64Slice", + "uri": "attribute/internal/attribute_test.go::BenchmarkAsFloat64Slice", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkBoolSliceValue", + "uri": "attribute/internal/attribute_test.go::BenchmarkBoolSliceValue", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkFloat64SliceValue", + "uri": "attribute/internal/attribute_test.go::BenchmarkFloat64SliceValue", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkInt64SliceValue", + "uri": "attribute/internal/attribute_test.go::BenchmarkInt64SliceValue", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkStringSliceValue", + "uri": "attribute/internal/attribute_test.go::BenchmarkStringSliceValue", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zap_0.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zap_0.snap new file mode 100644 index 0000000..baa63cd --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zap_0.snap @@ -0,0 +1,181 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "Benchmark100Fields", + "uri": "logger_bench_test.go::Benchmark100Fields", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAddCallerAndStacktrace", + "uri": "logger_bench_test.go::BenchmarkAddCallerAndStacktrace", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAddCallerHook", + "uri": "logger_bench_test.go::BenchmarkAddCallerHook", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAny::string::field-only::any", + "uri": "unknown::BenchmarkAny::string::field-only::any", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAny::string::field-only::typed", + "uri": "unknown::BenchmarkAny::string::field-only::typed", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAny::string::log-go::any", + "uri": "unknown::BenchmarkAny::string::log-go::any", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAny::string::log-go::typed", + "uri": "unknown::BenchmarkAny::string::log-go::typed", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAny::string::log::any", + "uri": "unknown::BenchmarkAny::string::log::any", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAny::string::log::typed", + "uri": "unknown::BenchmarkAny::string::log::typed", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAny::stringer::field-only::any", + "uri": "unknown::BenchmarkAny::stringer::field-only::any", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAny::stringer::field-only::typed", + "uri": "unknown::BenchmarkAny::stringer::field-only::typed", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAny::stringer::log-go::any", + "uri": "unknown::BenchmarkAny::stringer::log-go::any", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAny::stringer::log-go::typed", + "uri": "unknown::BenchmarkAny::stringer::log-go::typed", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAny::stringer::log::any", + "uri": "unknown::BenchmarkAny::stringer::log::any", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAny::stringer::log::typed", + "uri": "unknown::BenchmarkAny::stringer::log::typed", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_0.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_0.snap new file mode 100644 index 0000000..42d871e --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_0.snap @@ -0,0 +1,192 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkAppendBytes::EncodingFirst", + "uri": "unknown::BenchmarkAppendBytes::EncodingFirst", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendBytes::EncodingLast", + "uri": "unknown::BenchmarkAppendBytes::EncodingLast", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendBytes::EncodingMiddle", + "uri": "unknown::BenchmarkAppendBytes::EncodingMiddle", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendBytes::MultiBytesFirst", + "uri": "unknown::BenchmarkAppendBytes::MultiBytesFirst", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendBytes::MultiBytesLast", + "uri": "unknown::BenchmarkAppendBytes::MultiBytesLast", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendBytes::MultiBytesMiddle", + "uri": "unknown::BenchmarkAppendBytes::MultiBytesMiddle", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendBytes::NoEncoding", + "uri": "unknown::BenchmarkAppendBytes::NoEncoding", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendString::EncodingFirst", + "uri": "unknown::BenchmarkAppendString::EncodingFirst", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendString::EncodingLast", + "uri": "unknown::BenchmarkAppendString::EncodingLast", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendString::EncodingMiddle", + "uri": "unknown::BenchmarkAppendString::EncodingMiddle", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendString::MultiBytesFirst", + "uri": "unknown::BenchmarkAppendString::MultiBytesFirst", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendString::MultiBytesLast", + "uri": "unknown::BenchmarkAppendString::MultiBytesLast", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendString::MultiBytesMiddle", + "uri": "unknown::BenchmarkAppendString::MultiBytesMiddle", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendString::NoEncoding", + "uri": "unknown::BenchmarkAppendString::NoEncoding", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkEncoder_AppendFloat32", + "uri": "internal/json/types_test.go::BenchmarkEncoder_AppendFloat32", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkEncoder_AppendFloat64", + "uri": "internal/json/types_test.go::BenchmarkEncoder_AppendFloat64", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_1.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_1.snap new file mode 100644 index 0000000..8458fad --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_1.snap @@ -0,0 +1,247 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkAppendFloat::Float32", + "uri": "unknown::BenchmarkAppendFloat::Float32", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendFloat::Float64", + "uri": "unknown::BenchmarkAppendFloat::Float64", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendInt::int-Negative", + "uri": "unknown::BenchmarkAppendInt::int-Negative", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendInt::int-Positive", + "uri": "unknown::BenchmarkAppendInt::int-Positive", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendInt::int16", + "uri": "unknown::BenchmarkAppendInt::int16", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendInt::int32", + "uri": "unknown::BenchmarkAppendInt::int32", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendInt::int64", + "uri": "unknown::BenchmarkAppendInt::int64", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendInt::int8", + "uri": "unknown::BenchmarkAppendInt::int8", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendInt::uint16", + "uri": "unknown::BenchmarkAppendInt::uint16", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendInt::uint32", + "uri": "unknown::BenchmarkAppendInt::uint32", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendInt::uint64", + "uri": "unknown::BenchmarkAppendInt::uint64", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendInt::uint8", + "uri": "unknown::BenchmarkAppendInt::uint8", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendString::EncodingFirst", + "uri": "unknown::BenchmarkAppendString::EncodingFirst", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendString::EncodingLast", + "uri": "unknown::BenchmarkAppendString::EncodingLast", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendString::EncodingMiddle", + "uri": "unknown::BenchmarkAppendString::EncodingMiddle", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendString::MultiBytesFirst", + "uri": "unknown::BenchmarkAppendString::MultiBytesFirst", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendString::MultiBytesLast", + "uri": "unknown::BenchmarkAppendString::MultiBytesLast", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendString::MultiBytesMiddle", + "uri": "unknown::BenchmarkAppendString::MultiBytesMiddle", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendString::NoEncoding", + "uri": "unknown::BenchmarkAppendString::NoEncoding", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendTime::Float", + "uri": "unknown::BenchmarkAppendTime::Float", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkAppendTime::Integer", + "uri": "unknown::BenchmarkAppendTime::Integer", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_2.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_2.snap new file mode 100644 index 0000000..71191ba --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_2.snap @@ -0,0 +1,676 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkContextAppend", + "uri": "benchmark_test.go::BenchmarkContextAppend", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Bool", + "uri": "unknown::BenchmarkContextFieldType::Bool", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Bools", + "uri": "unknown::BenchmarkContextFieldType::Bools", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Ctx", + "uri": "unknown::BenchmarkContextFieldType::Ctx", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Dur", + "uri": "unknown::BenchmarkContextFieldType::Dur", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Durs", + "uri": "unknown::BenchmarkContextFieldType::Durs", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Err", + "uri": "unknown::BenchmarkContextFieldType::Err", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Errs", + "uri": "unknown::BenchmarkContextFieldType::Errs", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Float", + "uri": "unknown::BenchmarkContextFieldType::Float", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Floats", + "uri": "unknown::BenchmarkContextFieldType::Floats", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Int", + "uri": "unknown::BenchmarkContextFieldType::Int", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Interface", + "uri": "unknown::BenchmarkContextFieldType::Interface", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Interface(Object)", + "uri": "unknown::BenchmarkContextFieldType::Interface(Object)", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Interface(Objects)", + "uri": "unknown::BenchmarkContextFieldType::Interface(Objects)", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Interfaces", + "uri": "unknown::BenchmarkContextFieldType::Interfaces", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Ints", + "uri": "unknown::BenchmarkContextFieldType::Ints", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Object", + "uri": "unknown::BenchmarkContextFieldType::Object", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Str", + "uri": "unknown::BenchmarkContextFieldType::Str", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Stringer", + "uri": "unknown::BenchmarkContextFieldType::Stringer", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Strs", + "uri": "unknown::BenchmarkContextFieldType::Strs", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Time", + "uri": "unknown::BenchmarkContextFieldType::Time", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Times", + "uri": "unknown::BenchmarkContextFieldType::Times", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFieldType::Timestamp", + "uri": "unknown::BenchmarkContextFieldType::Timestamp", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkContextFields", + "uri": "benchmark_test.go::BenchmarkContextFields", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkDisabled", + "uri": "benchmark_test.go::BenchmarkDisabled", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkHooks::Nop/Multi", + "uri": "unknown::BenchmarkHooks::Nop/Multi", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkHooks::Nop/Single", + "uri": "unknown::BenchmarkHooks::Nop/Single", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkHooks::Simple", + "uri": "unknown::BenchmarkHooks::Simple", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkInfo", + "uri": "benchmark_test.go::BenchmarkInfo", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogArrayObject", + "uri": "benchmark_test.go::BenchmarkLogArrayObject", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogEmpty", + "uri": "benchmark_test.go::BenchmarkLogEmpty", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Bool", + "uri": "unknown::BenchmarkLogFieldType::Bool", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Bools", + "uri": "unknown::BenchmarkLogFieldType::Bools", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Ctx", + "uri": "unknown::BenchmarkLogFieldType::Ctx", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Dur", + "uri": "unknown::BenchmarkLogFieldType::Dur", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Durs", + "uri": "unknown::BenchmarkLogFieldType::Durs", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Err", + "uri": "unknown::BenchmarkLogFieldType::Err", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Errs", + "uri": "unknown::BenchmarkLogFieldType::Errs", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Float", + "uri": "unknown::BenchmarkLogFieldType::Float", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Floats", + "uri": "unknown::BenchmarkLogFieldType::Floats", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Int", + "uri": "unknown::BenchmarkLogFieldType::Int", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Interface", + "uri": "unknown::BenchmarkLogFieldType::Interface", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Interface(Object)", + "uri": "unknown::BenchmarkLogFieldType::Interface(Object)", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Interface(Objects)", + "uri": "unknown::BenchmarkLogFieldType::Interface(Objects)", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Interfaces", + "uri": "unknown::BenchmarkLogFieldType::Interfaces", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Ints", + "uri": "unknown::BenchmarkLogFieldType::Ints", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Object", + "uri": "unknown::BenchmarkLogFieldType::Object", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Str", + "uri": "unknown::BenchmarkLogFieldType::Str", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Strs", + "uri": "unknown::BenchmarkLogFieldType::Strs", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Time", + "uri": "unknown::BenchmarkLogFieldType::Time", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFieldType::Times", + "uri": "unknown::BenchmarkLogFieldType::Times", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkLogFields", + "uri": "benchmark_test.go::BenchmarkLogFields", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkSamplers::BasicSampler_0", + "uri": "unknown::BenchmarkSamplers::BasicSampler_0", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkSamplers::BasicSampler_1", + "uri": "unknown::BenchmarkSamplers::BasicSampler_1", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkSamplers::BasicSampler_5", + "uri": "unknown::BenchmarkSamplers::BasicSampler_5", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkSamplers::BurstSampler", + "uri": "unknown::BenchmarkSamplers::BurstSampler", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkSamplers::BurstSamplerNext", + "uri": "unknown::BenchmarkSamplers::BurstSamplerNext", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkSamplers::BurstSampler_0", + "uri": "unknown::BenchmarkSamplers::BurstSampler_0", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkSamplers::RandomSampler", + "uri": "unknown::BenchmarkSamplers::RandomSampler", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkSamplers::RandomSampler_0", + "uri": "unknown::BenchmarkSamplers::RandomSampler_0", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_3.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_3.snap new file mode 100644 index 0000000..034160d --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_3.snap @@ -0,0 +1,71 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkDataRace", + "uri": "hlog/hlog_test.go::BenchmarkDataRace", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkHandlers::Combined", + "uri": "unknown::BenchmarkHandlers::Combined", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkHandlers::CombinedDisabled", + "uri": "unknown::BenchmarkHandlers::CombinedDisabled", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkHandlers::Single", + "uri": "unknown::BenchmarkHandlers::Single", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + }, + { + "name": "BenchmarkHandlers::SingleDisabled", + "uri": "unknown::BenchmarkHandlers::SingleDisabled", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_4.snap b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_4.snap new file mode 100644 index 0000000..d3bb354 --- /dev/null +++ b/go-runner/src/snapshots/go_runner__integration_tests__assert_results_snapshots@zerolog_4.snap @@ -0,0 +1,27 @@ +--- +source: src/integration_tests.rs +expression: content +--- +{ + "creator": { + "name": "codspeed-go", + "version": "0.1.0", + "pid": "[pid]" + }, + "instrument": { + "type": "walltime" + }, + "benchmarks": [ + { + "name": "BenchmarkLogStack", + "uri": "pkgerrors/stacktrace_test.go::BenchmarkLogStack", + "config": { + "warmup_time_ns": null, + "min_round_time_ns": null, + "max_time_ns": null, + "max_rounds": null + }, + "stats": "[stats]" + } + ] +} diff --git a/go-runner/src/utils.rs b/go-runner/src/utils.rs new file mode 100644 index 0000000..c721cb1 --- /dev/null +++ b/go-runner/src/utils.rs @@ -0,0 +1,20 @@ +use std::path::Path; +use std::{fs, io}; + +pub fn copy_dir_all(src: impl AsRef, dst: impl AsRef) -> io::Result<()> { + fs::create_dir_all(&dst)?; + for entry in fs::read_dir(src)? { + let entry = entry?; + let ty = entry.file_type()?; + if ty.is_dir() { + if entry.file_name() == ".git" { + continue; + } + + copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?; + } else { + fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?; + } + } + Ok(()) +} diff --git a/go-runner/testdata/raw_results/0e63aecf81ebd4160bcb4533a480bc22.json b/go-runner/testdata/raw_results/0e63aecf81ebd4160bcb4533a480bc22.json new file mode 100644 index 0000000..112df13 --- /dev/null +++ b/go-runner/testdata/raw_results/0e63aecf81ebd4160bcb4533a480bc22.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dba7ab22e54cc974ee80bbf58aa5d50de1799470a2857ee2c10b3c88e60b55e9 +size 2015506 diff --git a/go-runner/testdata/raw_results/48abb733eb9fdf397328218686e21d47.json b/go-runner/testdata/raw_results/48abb733eb9fdf397328218686e21d47.json new file mode 100644 index 0000000..1f561d8 --- /dev/null +++ b/go-runner/testdata/raw_results/48abb733eb9fdf397328218686e21d47.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:617f462b9bc2d0abd24b24cf5b4263f0b24cdccccce789412c17699225a250fb +size 2742 diff --git a/go-runner/testdata/raw_results/7896771b6a9f0dfc37fb71e73be031cf.json b/go-runner/testdata/raw_results/7896771b6a9f0dfc37fb71e73be031cf.json new file mode 100644 index 0000000..8c3f1ce --- /dev/null +++ b/go-runner/testdata/raw_results/7896771b6a9f0dfc37fb71e73be031cf.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5015d4050c40fed4a158543c0c7fa31131ddea3761cde8b18a526052e296ccb2 +size 2545 diff --git a/go-runner/testdata/raw_results/BenchmarkFibonacci20-16.json b/go-runner/testdata/raw_results/BenchmarkFibonacci20-16.json new file mode 100644 index 0000000..b82b243 --- /dev/null +++ b/go-runner/testdata/raw_results/BenchmarkFibonacci20-16.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdb1aed6aa0000edad504612cc395bf7227a40a7601a799922ba6ac372c7b3b6 +size 119 diff --git a/go-runner/testdata/results/2595579.json b/go-runner/testdata/results/2595579.json new file mode 100644 index 0000000..6f39fb0 --- /dev/null +++ b/go-runner/testdata/results/2595579.json @@ -0,0 +1 @@ +{"creator":{"name":"go-runner","version":"0.1.0","pid":2595579},"instrument":{"type":"walltime"},"benchmarks":[{"name":"BenchmarkFibonacci20_Loop-16","uri":"BenchmarkFibonacci20_Loop-16","config":{"warmup_time_ns":null,"min_round_time_ns":null,"max_time_ns":null,"max_rounds":null},"stats":{"min_ns":24947.0,"max_ns":189175.0,"mean_ns":39919.68694047691,"stdev_ns":10899.225438059466,"q1_ns":32576.0,"median_ns":34493.0,"q3_ns":48574.0,"rounds":183192,"total_time":7.31296729,"iqr_outlier_rounds":1123,"stdev_outlier_rounds":1121,"iter_per_round":1,"warmup_iters":0}},{"name":"BenchmarkFibonacci10-16","uri":"BenchmarkFibonacci10-16","config":{"warmup_time_ns":null,"min_round_time_ns":null,"max_time_ns":null,"max_rounds":null},"stats":{"min_ns":234.0,"max_ns":467.0,"mean_ns":302.90000000000003,"stdev_ns":59.250793797691564,"q1_ns":266.4166666666667,"median_ns":285.5,"q3_ns":305.0,"rounds":100,"total_time":4.055220472,"iqr_outlier_rounds":13,"stdev_outlier_rounds":0,"iter_per_round":133650,"warmup_iters":0}},{"name":"BenchmarkFibonacci20_bN-16","uri":"BenchmarkFibonacci20_bN-16","config":{"warmup_time_ns":null,"min_round_time_ns":null,"max_time_ns":null,"max_rounds":null},"stats":{"min_ns":31416.0,"max_ns":83362.0,"mean_ns":43033.13000000001,"stdev_ns":10024.231931236032,"q1_ns":36419.25,"median_ns":39109.5,"q3_ns":47590.08333333333,"rounds":100,"total_time":4.522840037,"iqr_outlier_rounds":3,"stdev_outlier_rounds":2,"iter_per_round":1051,"warmup_iters":0}}]} diff --git a/go-runner/testdata/verifier/invalid_benchmark_function_call.go b/go-runner/testdata/verifier/invalid_benchmark_function_call.go new file mode 100644 index 0000000..66bb9e8 --- /dev/null +++ b/go-runner/testdata/verifier/invalid_benchmark_function_call.go @@ -0,0 +1,14 @@ +package main + +import "testing" + +func helper(b *testing.B) { + // This function receives testing.B as parameter +} + +func BenchmarkInvalid(b *testing.B) { + helper(b) // This is invalid - passing testing.B to another function + for i := 0; i < b.N; i++ { + // Some work + } +} diff --git a/go-runner/testdata/verifier/mixed_validity_benchmarks.go b/go-runner/testdata/verifier/mixed_validity_benchmarks.go new file mode 100644 index 0000000..acbcae1 --- /dev/null +++ b/go-runner/testdata/verifier/mixed_validity_benchmarks.go @@ -0,0 +1,20 @@ +package main + +import "testing" + +func helper(b *testing.B) { + // Helper function +} + +func BenchmarkValid(b *testing.B) { + for i := 0; i < b.N; i++ { + // Some work + } +} + +func BenchmarkInvalid(b *testing.B) { + helper(b) // Invalid + for i := 0; i < b.N; i++ { + // Some work + } +} diff --git a/go-runner/testdata/verifier/valid_benchmark.go b/go-runner/testdata/verifier/valid_benchmark.go new file mode 100644 index 0000000..c08bf6a --- /dev/null +++ b/go-runner/testdata/verifier/valid_benchmark.go @@ -0,0 +1,10 @@ +package main + +import "testing" + +func BenchmarkValid(b *testing.B) { + for i := 0; i < b.N; i++ { + // Some work + } + b.ReportAllocs() +} diff --git a/go-runner/testdata/verifier/valid_benchmark_methods.go b/go-runner/testdata/verifier/valid_benchmark_methods.go new file mode 100644 index 0000000..ff2557a --- /dev/null +++ b/go-runner/testdata/verifier/valid_benchmark_methods.go @@ -0,0 +1,13 @@ +package main + +import "testing" + +func BenchmarkValidMethods(b *testing.B) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + // Some work + } + b.StopTimer() + b.ReportAllocs() + b.StartTimer() +}