From 81ff7824768fdab32af801551fdd75cd9b32bd63 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Fri, 23 May 2025 15:40:31 +0900 Subject: [PATCH 01/32] go.mod --- projects/mongodb-benchmarking | 2 +- tools/go.mod | 17 +++++++++++------ tools/go.sum | 34 ++++++++++++++++------------------ 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/projects/mongodb-benchmarking b/projects/mongodb-benchmarking index c63459ddd..1516aa4d2 160000 --- a/projects/mongodb-benchmarking +++ b/projects/mongodb-benchmarking @@ -1 +1 @@ -Subproject commit c63459ddd39f61680d2898921abf36fff176f372 +Subproject commit 1516aa4d2ca9d4d1a3db5d0751f2524b8f09bd67 diff --git a/tools/go.mod b/tools/go.mod index afa3283b9..0ae751e32 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -5,6 +5,7 @@ go 1.24.1 toolchain go1.24.2 tool ( + benchmarking github.com/go-task/task/v3/cmd/task github.com/pingcap/go-ycsb/cmd/go-ycsb github.com/quasilyte/go-consistent @@ -17,7 +18,10 @@ tool ( mvdan.cc/gofumpt ) +replace benchmarking => github.com/idealo/mongodb-benchmarking v1.5.4 + require ( + benchmarking v0.0.0-00010101000000-000000000000 // indirect cloud.google.com/go v0.110.2 // indirect cloud.google.com/go/compute/metadata v0.3.0 // indirect cloud.google.com/go/iam v0.13.0 // indirect @@ -117,7 +121,7 @@ require ( github.com/joho/godotenv v1.5.1 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/kisielk/gotool v1.0.0 // indirect - github.com/klauspost/compress v1.13.6 // indirect + github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/lib/pq v1.10.9 // indirect github.com/magiconair/properties v1.8.0 // indirect @@ -130,7 +134,7 @@ require ( github.com/minio/minio-go v6.0.14+incompatible // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect - github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect + github.com/montanaflynn/stats v0.7.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c // indirect @@ -146,6 +150,7 @@ require ( github.com/prometheus/procfs v0.6.0 // indirect github.com/quasilyte/go-consistent v0.6.1 // indirect github.com/radovskyb/watcher v1.0.7 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect github.com/sajari/fuzzy v1.0.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect @@ -161,15 +166,15 @@ require ( github.com/twmb/murmur3 v1.1.3 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect - github.com/xdg-go/scram v1.1.1 // indirect - github.com/xdg-go/stringprep v1.0.3 // indirect - github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect + github.com/xdg-go/scram v1.1.2 // indirect + github.com/xdg-go/stringprep v1.0.4 // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da // indirect github.com/zeebo/xxh3 v1.0.2 // indirect go.etcd.io/etcd/api/v3 v3.5.2 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.2 // indirect go.etcd.io/etcd/client/v3 v3.5.2 // indirect - go.mongodb.org/mongo-driver v1.11.3 // indirect + go.mongodb.org/mongo-driver v1.17.3 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.7.0 // indirect diff --git a/tools/go.sum b/tools/go.sum index 716bf778b..bf066c3f4 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -283,7 +283,6 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -296,7 +295,6 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -334,6 +332,8 @@ github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMW github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/idealo/mongodb-benchmarking v1.5.4 h1:eNX5X+4U4Z2iHPSHPtnW1Uscv0a1U0/XaM1cL67jqcs= +github.com/idealo/mongodb-benchmarking v1.5.4/go.mod h1:ATLTc5hW3KT73tYvf/sEusNAsrIG/RWJ+R9vpv+6xRQ= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -361,8 +361,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -404,8 +404,8 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= +github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -479,6 +479,8 @@ github.com/quasilyte/go-consistent v0.6.1 h1:zfOZAzADcpxp9QXOmMspDTHEzoCJ5EpiTR+ github.com/quasilyte/go-consistent v0.6.1/go.mod h1:zo8fhUCPO6L+/vP78haKSsCKGCnlICdhKVW9CiQ5KcU= github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE= github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -526,7 +528,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -535,9 +536,6 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tikv/client-go/v2 v2.0.1-0.20220720064224-aa9ded37d17d h1:xllx8pkveVLcnAkWIa+cRpCVckbJF7LHS+9pURqp0Ig= github.com/tikv/client-go/v2 v2.0.1-0.20220720064224-aa9ded37d17d/go.mod h1:UmDQEoeHXza8RSHBXVFERpxH54VBOf8yKZVphyel3l4= github.com/tikv/pd/client v0.0.0-20220307081149-841fa61e9710 h1:jxgmKOscXSjaFEKQGRyY5qOpK8hLqxs2irb/uDJMtwk= @@ -550,14 +548,14 @@ github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E= -github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs= -github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -577,8 +575,8 @@ go.etcd.io/etcd/client/pkg/v3 v3.5.2 h1:4hzqQ6hIb3blLyQ8usCU4h3NghkqcsohEQ3o3Vet go.etcd.io/etcd/client/pkg/v3 v3.5.2/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v3 v3.5.2 h1:WdnejrUtQC4nCxK0/dLTMqKOB+U5TP/2Ya0BJL+1otA= go.etcd.io/etcd/client/v3 v3.5.2/go.mod h1:kOOaWFFgHygyT0WlSmL8TJiXmMysO/nNUlEsSsN6W4o= -go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= -go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= +go.mongodb.org/mongo-driver v1.17.3 h1:TQyXhnsWfWtgAhMtOgtYHMTkZIfBTpMTsMnd9ZBeHxQ= +go.mongodb.org/mongo-driver v1.17.3/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= From 8f28c00619bdad02316112bc8333dfc98d4c71f7 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Fri, 23 May 2025 17:23:35 +0900 Subject: [PATCH 02/32] add as replacement file directive --- tools/go.mod | 6 +++--- tools/go.sum | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/go.mod b/tools/go.mod index 0ae751e32..e7bb0c3de 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -5,8 +5,8 @@ go 1.24.1 toolchain go1.24.2 tool ( - benchmarking github.com/go-task/task/v3/cmd/task + github.com/idealo/mongodb-benchmarking github.com/pingcap/go-ycsb/cmd/go-ycsb github.com/quasilyte/go-consistent golang.org/x/perf/cmd/benchstat @@ -18,10 +18,9 @@ tool ( mvdan.cc/gofumpt ) -replace benchmarking => github.com/idealo/mongodb-benchmarking v1.5.4 +replace github.com/idealo/mongodb-benchmarking v1.5.4 => ../projects/mongodb-benchmarking require ( - benchmarking v0.0.0-00010101000000-000000000000 // indirect cloud.google.com/go v0.110.2 // indirect cloud.google.com/go/compute/metadata v0.3.0 // indirect cloud.google.com/go/iam v0.13.0 // indirect @@ -115,6 +114,7 @@ require ( github.com/googleapis/gax-go/v2 v2.11.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 // indirect github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect + github.com/idealo/mongodb-benchmarking v1.5.4 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect diff --git a/tools/go.sum b/tools/go.sum index bf066c3f4..7a2a53f7e 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -332,8 +332,6 @@ github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMW github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= -github.com/idealo/mongodb-benchmarking v1.5.4 h1:eNX5X+4U4Z2iHPSHPtnW1Uscv0a1U0/XaM1cL67jqcs= -github.com/idealo/mongodb-benchmarking v1.5.4/go.mod h1:ATLTc5hW3KT73tYvf/sEusNAsrIG/RWJ+R9vpv+6xRQ= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= From a9f26bb9c5bc4d1b5e371ccbe937aad7083c9981 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Fri, 23 May 2025 17:54:22 +0900 Subject: [PATCH 03/32] mongobench package --- internal/config/runner.go | 10 +++ internal/runner/mongobench/mongobench.go | 108 +++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 internal/runner/mongobench/mongobench.go diff --git a/internal/config/runner.go b/internal/config/runner.go index ce6b497d4..9492ef966 100644 --- a/internal/config/runner.go +++ b/internal/config/runner.go @@ -58,6 +58,15 @@ type RunnerParamsGoTest struct { Args []string } +// RunnerParamsMongoBench represents `mongobench` runner parameters. +type RunnerParamsMongoBench struct { + Dir string + Args []string +} + +// runnerParams implements [RunnerParams] interface. +func (rp *RunnerParamsMongoBench) runnerParams() {} + // runnerParams implements [RunnerParams] interface. func (rp *RunnerParamsGoTest) runnerParams() {} @@ -74,5 +83,6 @@ func (rp *RunnerParamsYCSB) runnerParams() {} var ( _ RunnerParams = (*RunnerParamsCommand)(nil) _ RunnerParams = (*RunnerParamsGoTest)(nil) + _ RunnerParams = (*RunnerParamsMongoBench)(nil) _ RunnerParams = (*RunnerParamsYCSB)(nil) ) diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go new file mode 100644 index 000000000..f8ad818a3 --- /dev/null +++ b/internal/runner/mongobench/mongobench.go @@ -0,0 +1,108 @@ +// Copyright 2021 FerretDB Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package mongobench provides `mongobench` runner. +package mongobench + +import ( + "context" + "errors" + "io" + "log/slog" + "os" + "os/exec" + "path/filepath" + "strings" + + "github.com/FerretDB/dance/internal/config" + "github.com/FerretDB/dance/internal/runner" +) + +// mongoBench represents `mongoBench` runner. +type mongoBench struct { + p *config.RunnerParamsMongoBench + l *slog.Logger +} + +// New creates a new `mongoBench` runner with given parameters. +func New(params *config.RunnerParamsMongoBench, l *slog.Logger) (runner.Runner, error) { + return &mongoBench{ + p: params, + l: l, + }, nil +} + +// parseOutput parses mongo-bench output. +func parseOutput(r io.Reader) (map[string]map[string]float64, error) { + var res map[string]map[string]float64 + + return res, errors.New("unimplemented") +} + +// run runs given command in the given directory and returns parsed results. +func run(ctx context.Context, args []string, dir string) (map[string]config.TestResult, error) { + cmd := exec.CommandContext(ctx, args[0], args[1:]...) + cmd.Dir = dir + cmd.Stderr = os.Stderr + + pipe, err := cmd.StdoutPipe() + if err != nil { + return nil, err + } + + defer pipe.Close() + + if err = cmd.Start(); err != nil { + return nil, err + } + + ms, err := parseOutput(io.TeeReader(pipe, os.Stdout)) + if err != nil { + _ = cmd.Process.Kill() + return nil, err + } + + if err = cmd.Wait(); err != nil { + return nil, err + } + + res := make(map[string]config.TestResult) + for t, m := range ms { + res[t] = config.TestResult{ + Status: config.Pass, + Measurements: m, + } + } + + return res, nil +} + +// Run implements [runner.Runner] interface. +func (y *mongoBench) Run(ctx context.Context) (map[string]config.TestResult, error) { + bin := filepath.Join("..", "bin", "mongodb-benchmarking") + if _, err := os.Stat(bin); err != nil { + return nil, err + } + + bin, err := filepath.Abs(bin) + if err != nil { + return nil, err + } + + args := append([]string{bin}, y.p.Args...) + + y.l.InfoContext(ctx, "Run", slog.String("cmd", strings.Join(args, " "))) + + return run(ctx, args, y.p.Dir) +} From 395c882ae0a071651b14ac4ba0b27ca6f9b732b9 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Mon, 26 May 2025 13:05:40 +0900 Subject: [PATCH 04/32] parsing --- internal/runner/mongobench/mongobench.go | 132 ++++++++++++++++++++++- projects/mongobench-runall.yml | 24 +++++ 2 files changed, 151 insertions(+), 5 deletions(-) create mode 100644 projects/mongobench-runall.yml diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go index f8ad818a3..a0b1fa648 100644 --- a/internal/runner/mongobench/mongobench.go +++ b/internal/runner/mongobench/mongobench.go @@ -16,14 +16,19 @@ package mongobench import ( + "bufio" "context" + "encoding/csv" "errors" + "fmt" "io" "log/slog" "os" "os/exec" "path/filepath" + "strconv" "strings" + "time" "github.com/FerretDB/dance/internal/config" "github.com/FerretDB/dance/internal/runner" @@ -43,11 +48,102 @@ func New(params *config.RunnerParamsMongoBench, l *slog.Logger) (runner.Runner, }, nil } -// parseOutput parses mongo-bench output. -func parseOutput(r io.Reader) (map[string]map[string]float64, error) { - var res map[string]map[string]float64 +// parseFilenames parses the file names that store benchmark results. +// Each operation is stored in different files such as `benchmark_results_insert.csv`, +// `benchmark_results_update.csv`, `benchmark_results_delete.csv` and `benchmark_results_upsert.csv`. +func parseFilenames(r io.Reader) ([]string, error) { + var files []string - return res, errors.New("unimplemented") + scanner := bufio.NewScanner(r) + for scanner.Scan() { + line := scanner.Text() + + if !strings.HasPrefix(line, "Benchmarking completed. Results saved to ") { + continue + } + + // `Benchmarking completed. Results saved to benchmark_results_delete.csv` + file := strings.TrimSpace(strings.TrimPrefix(line, "Benchmarking completed. Results saved to ")) + files = append(files, file) + } + + if err := scanner.Err(); err != nil { + return nil, err + } + + if len(files) == 0 { + return nil, errors.New("no benchmark results found") + } + + return files, nil +} + +// parseMeasurements reads the mongo-bench results from the reader. +func parseMeasurements(op string, r io.Reader) (map[string]map[string]float64, error) { + res := make(map[string]map[string]float64) + + reader := csv.NewReader(r) + + for { + record, err := reader.Read() + if err == io.EOF { + break + } + + if err != nil { + return nil, err + } + + i, err := strconv.ParseInt(record[0], 10, 64) + if err != nil { + return nil, err + } + + t := time.Unix(i, 0) + + count, err := strconv.ParseInt(record[1], 10, 64) + if err != nil { + return nil, err + } + + mean, err := strconv.ParseFloat(record[1], 64) + if err != nil { + return nil, err + } + + m1Rate, err := strconv.ParseFloat(record[2], 64) + if err != nil { + return nil, err + } + + m5Rate, err := strconv.ParseFloat(record[3], 64) + if err != nil { + return nil, err + } + + m15Rate, err := strconv.ParseFloat(record[4], 64) + if err != nil { + return nil, err + } + + meanRate, err := strconv.ParseFloat(record[5], 64) + if err != nil { + return nil, err + } + + // FIXME each record is measuring from each second during the benchmark, not a single measurement of an operation + res[fmt.Sprintf("%s%s", op, t.Format(time.DateTime))] = map[string]float64{ + "t": float64(t.Second()), // timestamp (epoch seconds) + "count": float64(count), // total document count + "mean": mean, // mean operation rate in docs/sec + "m1_rate": m1Rate, // moving average rates over 1 minute + "m5_rate": m5Rate, // moving average rates over 5 minutes + "m15_rate": m15Rate, // moving average rates over 15 minutes + "mean_rate": meanRate, // cumulative mean rate + } + } + + return res, nil } // run runs given command in the given directory and returns parsed results. @@ -67,7 +163,7 @@ func run(ctx context.Context, args []string, dir string) (map[string]config.Test return nil, err } - ms, err := parseOutput(io.TeeReader(pipe, os.Stdout)) + fileNames, err := parseFilenames(io.TeeReader(pipe, os.Stdout)) if err != nil { _ = cmd.Process.Kill() return nil, err @@ -77,6 +173,32 @@ func run(ctx context.Context, args []string, dir string) (map[string]config.Test return nil, err } + ms := make(map[string]map[string]float64) + + for _, fileName := range fileNames { + relPath := filepath.Join("..", fileName) + + var f *os.File + + if f, err = os.Open(relPath); err != nil { + return nil, err + } + + defer f.Close() + + op := strings.TrimSuffix(strings.TrimPrefix(fileName, "benchmark_results_"), ".csv") + + var m map[string]map[string]float64 + + if m, err = parseMeasurements(op, bufio.NewReader(f)); err != nil { + return nil, err + } + + for k, v := range m { + ms[k] = v + } + } + res := make(map[string]config.TestResult) for t, m := range ms { res[t] = config.TestResult{ diff --git a/projects/mongobench-runall.yml b/projects/mongobench-runall.yml new file mode 100644 index 000000000..d345ae8af --- /dev/null +++ b/projects/mongobench-runall.yml @@ -0,0 +1,24 @@ +--- +# Run all tests +runner: mongobench +params: + dir: mongodb-benchmarking + args: + - -threads 10 -docs 100000 -uri {{.MONGODB_URI}} --runAll + +results: + mongodb: + stats: + pass: 3 + + ferretdb-postgresql: + stats: + pass: 3 + + ferretdb2: + stats: + pass: 3 + + ferretdb-dev: + stats: + pass: 3 From dfde50beec60e53c719d90a20668c1a08e35d30e Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Mon, 26 May 2025 16:38:16 +0900 Subject: [PATCH 05/32] file is not valid csv --- internal/runner/mongobench/mongobench.go | 70 ++++++----- internal/runner/mongobench/mongobench_test.go | 109 ++++++++++++++++++ 2 files changed, 147 insertions(+), 32 deletions(-) create mode 100644 internal/runner/mongobench/mongobench_test.go diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go index a0b1fa648..22a79ef3a 100644 --- a/internal/runner/mongobench/mongobench.go +++ b/internal/runner/mongobench/mongobench.go @@ -18,7 +18,6 @@ package mongobench import ( "bufio" "context" - "encoding/csv" "errors" "fmt" "io" @@ -48,11 +47,11 @@ func New(params *config.RunnerParamsMongoBench, l *slog.Logger) (runner.Runner, }, nil } -// parseFilenames parses the file names that store benchmark results. +// parseFileNames parses the file names that store benchmark results. // Each operation is stored in different files such as `benchmark_results_insert.csv`, // `benchmark_results_update.csv`, `benchmark_results_delete.csv` and `benchmark_results_upsert.csv`. -func parseFilenames(r io.Reader) ([]string, error) { - var files []string +func parseFileNames(r io.Reader) ([]string, error) { + var fileNames []string scanner := bufio.NewScanner(r) for scanner.Scan() { @@ -62,30 +61,40 @@ func parseFilenames(r io.Reader) ([]string, error) { continue } - // `Benchmarking completed. Results saved to benchmark_results_delete.csv` - file := strings.TrimSpace(strings.TrimPrefix(line, "Benchmarking completed. Results saved to ")) - files = append(files, file) + // parse file name from the line such as `Benchmarking completed. Results saved to benchmark_results_delete.csv` + fileName := strings.TrimSpace(strings.TrimPrefix(line, "Benchmarking completed. Results saved to ")) + fileNames = append(fileNames, fileName) } if err := scanner.Err(); err != nil { return nil, err } - if len(files) == 0 { - return nil, errors.New("no benchmark results found") + if len(fileNames) == 0 { + return nil, errors.New("no benchmark result files found") } - return files, nil + return fileNames, nil } // parseMeasurements reads the mongo-bench results from the reader. -func parseMeasurements(op string, r io.Reader) (map[string]map[string]float64, error) { +func parseMeasurements(op string, r *bufio.Reader) (map[string]map[string]float64, error) { res := make(map[string]map[string]float64) - reader := csv.NewReader(r) + // cannot use [csv.NewReader] because the file does not contain valid CSV, + // it contains 7 header fields while record lines contain 6 fields, + // so we parse it manually and assume last field `mean_rate` is missing + // + //t,count,mean,m1_rate,m5_rate,m15_rate,mean_rate + //1748240899,13524,13522.216068,756.800000,756.800000,756.800000 + + // ignore header + if _, _, err := r.ReadLine(); err != nil { + return nil, err + } for { - record, err := reader.Read() + line, _, err := r.ReadLine() if err == io.EOF { break } @@ -94,6 +103,8 @@ func parseMeasurements(op string, r io.Reader) (map[string]map[string]float64, e return nil, err } + record := strings.Split(string(line), ",") + i, err := strconv.ParseInt(record[0], 10, 64) if err != nil { return nil, err @@ -106,40 +117,35 @@ func parseMeasurements(op string, r io.Reader) (map[string]map[string]float64, e return nil, err } - mean, err := strconv.ParseFloat(record[1], 64) - if err != nil { - return nil, err - } - - m1Rate, err := strconv.ParseFloat(record[2], 64) + mean, err := strconv.ParseFloat(record[2], 64) if err != nil { return nil, err } - m5Rate, err := strconv.ParseFloat(record[3], 64) + m1Rate, err := strconv.ParseFloat(record[3], 64) if err != nil { return nil, err } - m15Rate, err := strconv.ParseFloat(record[4], 64) + m5Rate, err := strconv.ParseFloat(record[4], 64) if err != nil { return nil, err } - meanRate, err := strconv.ParseFloat(record[5], 64) + m15Rate, err := strconv.ParseFloat(record[5], 64) if err != nil { return nil, err } - // FIXME each record is measuring from each second during the benchmark, not a single measurement of an operation - res[fmt.Sprintf("%s%s", op, t.Format(time.DateTime))] = map[string]float64{ - "t": float64(t.Second()), // timestamp (epoch seconds) - "count": float64(count), // total document count - "mean": mean, // mean operation rate in docs/sec - "m1_rate": m1Rate, // moving average rates over 1 minute - "m5_rate": m5Rate, // moving average rates over 5 minutes - "m15_rate": m15Rate, // moving average rates over 15 minutes - "mean_rate": meanRate, // cumulative mean rate + // FIXME each record is a measurement produced each second during the benchmark is running, + // not a single measurement of an operation + res[fmt.Sprintf("%s_%d", op, t.Unix())] = map[string]float64{ + "t": float64(t.Unix()), // timestamp (epoch seconds) + "count": float64(count), // total document count + "mean": mean, // mean operation rate in docs/sec + "m1_rate": m1Rate, // moving average rates over 1 minute + "m5_rate": m5Rate, // moving average rates over 5 minutes + "m15_rate": m15Rate, // moving average rates over 15 minutes } } @@ -163,7 +169,7 @@ func run(ctx context.Context, args []string, dir string) (map[string]config.Test return nil, err } - fileNames, err := parseFilenames(io.TeeReader(pipe, os.Stdout)) + fileNames, err := parseFileNames(io.TeeReader(pipe, os.Stdout)) if err != nil { _ = cmd.Process.Kill() return nil, err diff --git a/internal/runner/mongobench/mongobench_test.go b/internal/runner/mongobench/mongobench_test.go new file mode 100644 index 000000000..257fe2acf --- /dev/null +++ b/internal/runner/mongobench/mongobench_test.go @@ -0,0 +1,109 @@ +// Copyright 2021 FerretDB Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mongobench + +import ( + "bufio" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestParseFileNames(t *testing.T) { + t.Parallel() + + //nolint:lll // verbatim output + output := strings.NewReader(` + +2025/05/26 11:27:41 Collection dropped. Starting new rate test... +2025/05/26 11:27:42 Timestamp: 1748226462, Document Count: 19776, Mean Rate: 19773.41 docs/sec, m1_rate: 0.00, m5_rate: 0.00, m15_rate: 0.00 +Benchmarking completed. Results saved to benchmark_results_insert.csv +2025/05/26 11:27:42 Starting update test... +2025/05/26 11:27:43 Timestamp: 1748226463, Document Count: 17893, Mean Rate: 17888.70 docs/sec, m1_rate: 0.00, m5_rate: 0.00, m15_rate: 0.00 +Benchmarking completed. Results saved to benchmark_results_update.csv +2025/05/26 11:27:43 Starting delete test... +Benchmarking completed. Results saved to benchmark_results_delete.csv +2025/05/26 11:27:44 Collection dropped. Starting new rate test... +2025/05/26 11:27:45 Timestamp: 1748226465, Document Count: 16680, Mean Rate: 16677.66 docs/sec, m1_rate: 0.00, m5_rate: 0.00, m15_rate: 0.00 +Benchmarking completed. Results saved to benchmark_results_upsert.csv +`) + + actual, err := parseFileNames(output) + require.NoError(t, err) + + expected := []string{ + "benchmark_results_insert.csv", + "benchmark_results_update.csv", + "benchmark_results_delete.csv", + "benchmark_results_upsert.csv", + } + + assert.Equal(t, expected, actual) +} + +func TestParseMeasurements(t *testing.T) { + t.Parallel() + + //nolint:lll // verbatim results + results := strings.NewReader( + `t,count,mean,m1_rate,m5_rate,m15_rate,mean_rate +1748240899,13524,13522.216068,756.800000,756.800000,756.800000 +1748240900,21505,10748.078321,756.800000,756.800000,756.800000 +1748240901,27081,9027.363746,756.800000,756.800000,756.800000 +1748240902,30000,8288.694528,756.800000,756.800000,756.800000`, + ) + + actual, err := parseMeasurements("upsert", bufio.NewReader(results)) + require.NoError(t, err) + + expected := map[string]map[string]float64{ + "upsert_1748240899": { + "t": 1748240899, + "count": 13524, + "mean": 13522.216068, + "m1_rate": 756.800000, + "m5_rate": 756.800000, + "m15_rate": 756.800000, + }, + "upsert_1748240900": { + "t": 1748240900, + "count": 21505, + "mean": 10748.078321, + "m1_rate": 756.800000, + "m5_rate": 756.800000, + "m15_rate": 756.800000, + }, + "upsert_1748240901": { + "t": 1748240901, + "count": 27081, + "mean": 9027.363746, + "m1_rate": 756.800000, + "m5_rate": 756.800000, + "m15_rate": 756.800000, + }, + "upsert_1748240902": { + "t": 1748240902, + "count": 30000, + "mean": 8288.694528, + "m1_rate": 756.800000, + "m5_rate": 756.800000, + "m15_rate": 756.800000, + }, + } + + assert.Equal(t, expected, actual) +} From 3234b1ea0b7ad7d2fbd91db9b18b20cf002f364c Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Mon, 26 May 2025 16:42:44 +0900 Subject: [PATCH 06/32] comment and example --- internal/runner/mongobench/mongobench.go | 4 ++-- internal/runner/mongobench/mongobench_test.go | 17 ++++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go index 22a79ef3a..4aed6e1a9 100644 --- a/internal/runner/mongobench/mongobench.go +++ b/internal/runner/mongobench/mongobench.go @@ -81,9 +81,9 @@ func parseFileNames(r io.Reader) ([]string, error) { func parseMeasurements(op string, r *bufio.Reader) (map[string]map[string]float64, error) { res := make(map[string]map[string]float64) - // cannot use [csv.NewReader] because the file does not contain valid CSV, + // Cannot use [csv.NewReader] because the file does not contain valid CSV, // it contains 7 header fields while record lines contain 6 fields, - // so we parse it manually and assume last field `mean_rate` is missing + // so we parse it manually and assume the last field `mean_rate` is missing. // //t,count,mean,m1_rate,m5_rate,m15_rate,mean_rate //1748240899,13524,13522.216068,756.800000,756.800000,756.800000 diff --git a/internal/runner/mongobench/mongobench_test.go b/internal/runner/mongobench/mongobench_test.go index 257fe2acf..8164ba6c0 100644 --- a/internal/runner/mongobench/mongobench_test.go +++ b/internal/runner/mongobench/mongobench_test.go @@ -29,16 +29,19 @@ func TestParseFileNames(t *testing.T) { //nolint:lll // verbatim output output := strings.NewReader(` -2025/05/26 11:27:41 Collection dropped. Starting new rate test... -2025/05/26 11:27:42 Timestamp: 1748226462, Document Count: 19776, Mean Rate: 19773.41 docs/sec, m1_rate: 0.00, m5_rate: 0.00, m15_rate: 0.00 +2025/05/26 15:28:13 Collection dropped. Starting new rate test... +2025/05/26 15:28:14 Timestamp: 1748240894, Document Count: 20138, Mean Rate: 20134.59 docs/sec, m1_rate: 0.00, m5_rate: 0.00, m15_rate: 0.00 Benchmarking completed. Results saved to benchmark_results_insert.csv -2025/05/26 11:27:42 Starting update test... -2025/05/26 11:27:43 Timestamp: 1748226463, Document Count: 17893, Mean Rate: 17888.70 docs/sec, m1_rate: 0.00, m5_rate: 0.00, m15_rate: 0.00 +2025/05/26 15:28:15 Starting update test... +2025/05/26 15:28:16 Timestamp: 1748240896, Document Count: 18717, Mean Rate: 18716.72 docs/sec, m1_rate: 0.00, m5_rate: 0.00, m15_rate: 0.00 Benchmarking completed. Results saved to benchmark_results_update.csv -2025/05/26 11:27:43 Starting delete test... +2025/05/26 15:28:16 Starting delete test... +2025/05/26 15:28:17 Timestamp: 1748240897, Document Count: 20690, Mean Rate: 20689.05 docs/sec, m1_rate: 0.00, m5_rate: 0.00, m15_rate: 0.00 Benchmarking completed. Results saved to benchmark_results_delete.csv -2025/05/26 11:27:44 Collection dropped. Starting new rate test... -2025/05/26 11:27:45 Timestamp: 1748226465, Document Count: 16680, Mean Rate: 16677.66 docs/sec, m1_rate: 0.00, m5_rate: 0.00, m15_rate: 0.00 +2025/05/26 15:28:18 Collection dropped. Starting new rate test... +2025/05/26 15:28:19 Timestamp: 1748240899, Document Count: 13524, Mean Rate: 13522.22 docs/sec, m1_rate: 756.80, m5_rate: 756.80, m15_rate: 756.80 +2025/05/26 15:28:20 Timestamp: 1748240900, Document Count: 21505, Mean Rate: 10748.08 docs/sec, m1_rate: 756.80, m5_rate: 756.80, m15_rate: 756.80 +2025/05/26 15:28:21 Timestamp: 1748240901, Document Count: 27081, Mean Rate: 9027.36 docs/sec, m1_rate: 756.80, m5_rate: 756.80, m15_rate: 756.80 Benchmarking completed. Results saved to benchmark_results_upsert.csv `) From 9e07c18734a4679f9b60faa06e55735e525bf24a Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Mon, 26 May 2025 16:44:14 +0900 Subject: [PATCH 07/32] gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 5e8b49efd..7dff9cebf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ /dumps/mongodump_tests/ /vendor/ cover.txt + +# mongodb-benchmarking +benchmark_results_*.csv From 3d9f81e1de518f7d980ad603cee9551a98d54267 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Mon, 26 May 2025 16:54:32 +0900 Subject: [PATCH 08/32] lint --- internal/runner/mongobench/mongobench.go | 32 ++++++++++++++---------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go index 4aed6e1a9..85af8e49b 100644 --- a/internal/runner/mongobench/mongobench.go +++ b/internal/runner/mongobench/mongobench.go @@ -152,6 +152,24 @@ func parseMeasurements(op string, r *bufio.Reader) (map[string]map[string]float6 return res, nil } +// readMeasurements reads the measurements from the file with given name. +func readMeasurements(fileName string) (map[string]map[string]float64, error) { + relPath := filepath.Join("..", fileName) + + f, err := os.Open(relPath) + if err != nil { + return nil, err + } + + defer func() { + err = f.Close() + }() + + op := strings.TrimSuffix(strings.TrimPrefix(fileName, "benchmark_results_"), ".csv") + + return parseMeasurements(op, bufio.NewReader(f)) +} + // run runs given command in the given directory and returns parsed results. func run(ctx context.Context, args []string, dir string) (map[string]config.TestResult, error) { cmd := exec.CommandContext(ctx, args[0], args[1:]...) @@ -182,21 +200,9 @@ func run(ctx context.Context, args []string, dir string) (map[string]config.Test ms := make(map[string]map[string]float64) for _, fileName := range fileNames { - relPath := filepath.Join("..", fileName) - - var f *os.File - - if f, err = os.Open(relPath); err != nil { - return nil, err - } - - defer f.Close() - - op := strings.TrimSuffix(strings.TrimPrefix(fileName, "benchmark_results_"), ".csv") - var m map[string]map[string]float64 - if m, err = parseMeasurements(op, bufio.NewReader(f)); err != nil { + if m, err = readMeasurements(fileName); err != nil { return nil, err } From 779d88507005c986e821d9ebe6d1094a0061c3b5 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Mon, 26 May 2025 17:21:37 +0900 Subject: [PATCH 09/32] make it run --- cmd/dance/main.go | 3 +++ internal/config/runner.go | 9 ++++++--- internal/configload/configload.go | 2 ++ internal/configload/runner.go | 14 ++++++++++++++ internal/runner/mongobench/mongobench.go | 13 ++++--------- projects/mongobench-runall.yml | 8 +++++++- 6 files changed, 36 insertions(+), 13 deletions(-) diff --git a/cmd/dance/main.go b/cmd/dance/main.go index 867898113..6f3f055b6 100644 --- a/cmd/dance/main.go +++ b/cmd/dance/main.go @@ -41,6 +41,7 @@ import ( "github.com/FerretDB/dance/internal/runner" "github.com/FerretDB/dance/internal/runner/command" "github.com/FerretDB/dance/internal/runner/gotest" + "github.com/FerretDB/dance/internal/runner/mongobench" "github.com/FerretDB/dance/internal/runner/ycsb" ) @@ -200,6 +201,8 @@ func main() { runner, err = command.New(c.Params.(*config.RunnerParamsCommand), rl, cli.Verbose) case config.RunnerTypeGoTest: runner, err = gotest.New(c.Params.(*config.RunnerParamsGoTest), rl, cli.Verbose) + case config.RunnerTypeMongoBench: + runner, err = mongobench.New(c.Params.(*config.RunnerParamsMongoBench), rl) case config.RunnerTypeYCSB: runner, err = ycsb.New(c.Params.(*config.RunnerParamsYCSB), rl) default: diff --git a/internal/config/runner.go b/internal/config/runner.go index 9492ef966..070518ca4 100644 --- a/internal/config/runner.go +++ b/internal/config/runner.go @@ -24,6 +24,9 @@ const ( // RunnerTypeGoTest indicates a Go test runner. RunnerTypeGoTest RunnerType = "gotest" + // RunnerTypeMongoBench indicates a MongoDB benchmark test runner. + RunnerTypeMongoBench RunnerType = "mongobench" + // RunnerTypeYCSB indicates a YCSB test runner. RunnerTypeYCSB RunnerType = "ycsb" ) @@ -58,6 +61,9 @@ type RunnerParamsGoTest struct { Args []string } +// runnerParams implements [RunnerParams] interface. +func (rp *RunnerParamsGoTest) runnerParams() {} + // RunnerParamsMongoBench represents `mongobench` runner parameters. type RunnerParamsMongoBench struct { Dir string @@ -67,9 +73,6 @@ type RunnerParamsMongoBench struct { // runnerParams implements [RunnerParams] interface. func (rp *RunnerParamsMongoBench) runnerParams() {} -// runnerParams implements [RunnerParams] interface. -func (rp *RunnerParamsGoTest) runnerParams() {} - // RunnerParamsYCSB represents `ycsb` runner parameters. type RunnerParamsYCSB struct { Dir string diff --git a/internal/configload/configload.go b/internal/configload/configload.go index 3437a7cc4..a0a808e27 100644 --- a/internal/configload/configload.go +++ b/internal/configload/configload.go @@ -172,6 +172,8 @@ func loadContent(content, db string) (*config.Config, error) { p = &runnerParamsCommand{} case config.RunnerTypeGoTest: p = &runnerParamsGoTest{} + case config.RunnerTypeMongoBench: + p = &runnerParamsMongoBench{} case config.RunnerTypeYCSB: p = &runnerParamsYCSB{} default: diff --git a/internal/configload/runner.go b/internal/configload/runner.go index 84f1753aa..147d427f8 100644 --- a/internal/configload/runner.go +++ b/internal/configload/runner.go @@ -74,6 +74,20 @@ func (rp *runnerParamsGoTest) convert() (config.RunnerParams, error) { }, nil } +// runnerParamsMongoBench represents `mongobench` runner parameters in the project configuration YAML file. +type runnerParamsMongoBench struct { + Dir string `yaml:"dir"` + Args []string `yaml:"args"` +} + +// convert implements [runnerParams] interface. +func (rp *runnerParamsMongoBench) convert() (config.RunnerParams, error) { + return &config.RunnerParamsMongoBench{ + Dir: rp.Dir, + Args: rp.Args, + }, nil +} + // runnerParamsYCSB represents `ycsb` runner parameters in the project configuration YAML file. type runnerParamsYCSB struct { Dir string `yaml:"dir"` diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go index 85af8e49b..c555baadc 100644 --- a/internal/runner/mongobench/mongobench.go +++ b/internal/runner/mongobench/mongobench.go @@ -81,14 +81,9 @@ func parseFileNames(r io.Reader) ([]string, error) { func parseMeasurements(op string, r *bufio.Reader) (map[string]map[string]float64, error) { res := make(map[string]map[string]float64) - // Cannot use [csv.NewReader] because the file does not contain valid CSV, + // cannot use [csv.NewReader] because the file does not contain valid CSV, // it contains 7 header fields while record lines contain 6 fields, - // so we parse it manually and assume the last field `mean_rate` is missing. - // - //t,count,mean,m1_rate,m5_rate,m15_rate,mean_rate - //1748240899,13524,13522.216068,756.800000,756.800000,756.800000 - - // ignore header + // so we parse it manually and assume the last field `mean_rate` is missing if _, _, err := r.ReadLine(); err != nil { return nil, err } @@ -137,8 +132,8 @@ func parseMeasurements(op string, r *bufio.Reader) (map[string]map[string]float6 return nil, err } - // FIXME each record is a measurement produced each second during the benchmark is running, - // not a single measurement of an operation + // FIXME each record is a measurement produced each second while the benchmark is running, + // instead of a single measurement of an operation res[fmt.Sprintf("%s_%d", op, t.Unix())] = map[string]float64{ "t": float64(t.Unix()), // timestamp (epoch seconds) "count": float64(count), // total document count diff --git a/projects/mongobench-runall.yml b/projects/mongobench-runall.yml index d345ae8af..59d853f41 100644 --- a/projects/mongobench-runall.yml +++ b/projects/mongobench-runall.yml @@ -4,7 +4,13 @@ runner: mongobench params: dir: mongodb-benchmarking args: - - -threads 10 -docs 100000 -uri {{.MONGODB_URI}} --runAll + - -threads + - 10 + - -docs + - 100000 + - -uri + - {{.MONGODB_URI}} + - --runAll results: mongodb: From 3e72a3f102c803fcb677b094b84636de6758f3c0 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 10:44:20 +0900 Subject: [PATCH 10/32] allow pushing array of results --- internal/config/results.go | 7 +- internal/pusher/pusher.go | 2 +- internal/runner/mongobench/mongobench.go | 88 ++++++++++++------- internal/runner/mongobench/mongobench_test.go | 1 - internal/runner/ycsb/ycsb.go | 42 +++++---- projects/mongobench-runall.yml | 8 +- 6 files changed, 90 insertions(+), 58 deletions(-) diff --git a/internal/config/results.go b/internal/config/results.go index 2c27f8cc8..646b55e47 100644 --- a/internal/config/results.go +++ b/internal/config/results.go @@ -22,13 +22,18 @@ import ( "golang.org/x/exp/maps" ) +// Measurements is the actual measurements from a single test. +type Measurements interface { + Values() any +} + // TestResult represents the actual outcome of a single test. // //nolint:vet // for readability type TestResult struct { Status Status Output string - Measurements map[string]float64 + Measurements Measurements } // IndentedOutput returns the output of a test result with indented lines. diff --git a/internal/pusher/pusher.go b/internal/pusher/pusher.go index 3d83dcbfd..ca3a36fc3 100644 --- a/internal/pusher/pusher.go +++ b/internal/pusher/pusher.go @@ -131,7 +131,7 @@ func (c *Client) Push(ctx context.Context, config, database string, res map[stri for t, tr := range res { t = strings.ReplaceAll(t, ".", "_") // to make it compatible with FerretDB v1 - passed = append(passed, bson.E{t, bson.D{{"m", tr.Measurements}}}) + passed = append(passed, bson.E{t, bson.D{{"m", tr.Measurements.Values()}}}) } doc := bson.D{ diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go index c555baadc..7887a0cc8 100644 --- a/internal/runner/mongobench/mongobench.go +++ b/internal/runner/mongobench/mongobench.go @@ -19,7 +19,6 @@ import ( "bufio" "context" "errors" - "fmt" "io" "log/slog" "os" @@ -27,12 +26,36 @@ import ( "path/filepath" "strconv" "strings" - "time" "github.com/FerretDB/dance/internal/config" "github.com/FerretDB/dance/internal/runner" ) +// benchmark is numerical results of a benchmark operation. +// +// mongodb-benchmarking test produces measurements each second while the benchmark is running, +// and each index of the slices corresponds to a measurement from each second. +type benchmark struct { + ts []int64 // timestamp (epoch seconds) + counts []int64 // total document count + meanRates []float64 // mean operation rate in docs/sec + m1Rates []float64 // moving average rates over 1 minute + m5Rates []float64 // moving average rates over 5 minutes + m15Rates []float64 // moving average rates over 15 minutes +} + +// Values implements [config.Measurements] interface. +func (m *benchmark) Values() any { + return map[string]any{ + "ts": m.ts, + "counts": m.counts, + "mean_rates": m.meanRates, + "m1_rates": m.m1Rates, + "m5_rates": m.m5Rates, + "m15_rates": m.m15Rates, + } +} + // mongoBench represents `mongoBench` runner. type mongoBench struct { p *config.RunnerParamsMongoBench @@ -78,9 +101,7 @@ func parseFileNames(r io.Reader) ([]string, error) { } // parseMeasurements reads the mongo-bench results from the reader. -func parseMeasurements(op string, r *bufio.Reader) (map[string]map[string]float64, error) { - res := make(map[string]map[string]float64) - +func parseMeasurements(r *bufio.Reader) (*benchmark, error) { // cannot use [csv.NewReader] because the file does not contain valid CSV, // it contains 7 header fields while record lines contain 6 fields, // so we parse it manually and assume the last field `mean_rate` is missing @@ -88,9 +109,12 @@ func parseMeasurements(op string, r *bufio.Reader) (map[string]map[string]float6 return nil, err } + var ts, counts []int64 + var meanRates, m1Rates, m5Rates, m15Rates []float64 + for { line, _, err := r.ReadLine() - if err == io.EOF { + if errors.Is(err, io.EOF) { break } @@ -100,13 +124,11 @@ func parseMeasurements(op string, r *bufio.Reader) (map[string]map[string]float6 record := strings.Split(string(line), ",") - i, err := strconv.ParseInt(record[0], 10, 64) + t, err := strconv.ParseInt(record[0], 10, 64) if err != nil { return nil, err } - t := time.Unix(i, 0) - count, err := strconv.ParseInt(record[1], 10, 64) if err != nil { return nil, err @@ -132,23 +154,26 @@ func parseMeasurements(op string, r *bufio.Reader) (map[string]map[string]float6 return nil, err } - // FIXME each record is a measurement produced each second while the benchmark is running, - // instead of a single measurement of an operation - res[fmt.Sprintf("%s_%d", op, t.Unix())] = map[string]float64{ - "t": float64(t.Unix()), // timestamp (epoch seconds) - "count": float64(count), // total document count - "mean": mean, // mean operation rate in docs/sec - "m1_rate": m1Rate, // moving average rates over 1 minute - "m5_rate": m5Rate, // moving average rates over 5 minutes - "m15_rate": m15Rate, // moving average rates over 15 minutes - } + ts = append(ts, t) + counts = append(counts, count) + meanRates = append(meanRates, mean) + m1Rates = append(m1Rates, m1Rate) + m5Rates = append(m5Rates, m5Rate) + m15Rates = append(m15Rates, m15Rate) } - return res, nil + return &benchmark{ + ts: ts, + counts: counts, + meanRates: meanRates, + m1Rates: m1Rates, + m5Rates: m5Rates, + m15Rates: m15Rates, + }, nil } // readMeasurements reads the measurements from the file with given name. -func readMeasurements(fileName string) (map[string]map[string]float64, error) { +func readMeasurements(fileName string) (*benchmark, error) { relPath := filepath.Join("..", fileName) f, err := os.Open(relPath) @@ -160,9 +185,7 @@ func readMeasurements(fileName string) (map[string]map[string]float64, error) { err = f.Close() }() - op := strings.TrimSuffix(strings.TrimPrefix(fileName, "benchmark_results_"), ".csv") - - return parseMeasurements(op, bufio.NewReader(f)) + return parseMeasurements(bufio.NewReader(f)) } // run runs given command in the given directory and returns parsed results. @@ -192,23 +215,17 @@ func run(ctx context.Context, args []string, dir string) (map[string]config.Test return nil, err } - ms := make(map[string]map[string]float64) + res := make(map[string]config.TestResult) for _, fileName := range fileNames { - var m map[string]map[string]float64 + var m *benchmark if m, err = readMeasurements(fileName); err != nil { return nil, err } - for k, v := range m { - ms[k] = v - } - } - - res := make(map[string]config.TestResult) - for t, m := range ms { - res[t] = config.TestResult{ + op := strings.TrimSuffix(strings.TrimPrefix(fileName, "benchmark_results_"), ".csv") + res[op] = config.TestResult{ Status: config.Pass, Measurements: m, } @@ -235,3 +252,6 @@ func (y *mongoBench) Run(ctx context.Context) (map[string]config.TestResult, err return run(ctx, args, y.p.Dir) } + +// check inferface +var _ config.Measurements = (*benchmark)(nil) diff --git a/internal/runner/mongobench/mongobench_test.go b/internal/runner/mongobench/mongobench_test.go index 8164ba6c0..1d20cf0cc 100644 --- a/internal/runner/mongobench/mongobench_test.go +++ b/internal/runner/mongobench/mongobench_test.go @@ -61,7 +61,6 @@ Benchmarking completed. Results saved to benchmark_results_upsert.csv func TestParseMeasurements(t *testing.T) { t.Parallel() - //nolint:lll // verbatim results results := strings.NewReader( `t,count,mean,m1_rate,m5_rate,m15_rate,mean_rate 1748240899,13524,13522.216068,756.800000,756.800000,756.800000 diff --git a/internal/runner/ycsb/ycsb.go b/internal/runner/ycsb/ycsb.go index d7cb1179e..3d95d1d14 100644 --- a/internal/runner/ycsb/ycsb.go +++ b/internal/runner/ycsb/ycsb.go @@ -49,6 +49,24 @@ type measurement struct { Perc9999Us float64 `json:"99.99th(us),string"` } +// Values implements [config.Measurements] interface. +func (m *measurement) Values() any { + return map[string]float64{ + "takes": m.TakesS, + "count": float64(m.Count), + "ops": m.OPS, + "avg": (time.Duration(m.AvgUs) * time.Microsecond).Seconds(), + "min": (time.Duration(m.MinUs) * time.Microsecond).Seconds(), + "max": (time.Duration(m.MaxUs) * time.Microsecond).Seconds(), + "perc50": (time.Duration(m.Perc50Us) * time.Microsecond).Seconds(), + "perc90": (time.Duration(m.Perc90Us) * time.Microsecond).Seconds(), + "perc95": (time.Duration(m.Perc95Us) * time.Microsecond).Seconds(), + "perc99": (time.Duration(m.Perc99Us) * time.Microsecond).Seconds(), + "perc999": (time.Duration(m.Perc999Us) * time.Microsecond).Seconds(), + "perc9999": (time.Duration(m.Perc9999Us) * time.Microsecond).Seconds(), + } +} + // ycsb represents `ycsb` runner. type ycsb struct { p *config.RunnerParamsYCSB @@ -64,8 +82,8 @@ func New(params *config.RunnerParamsYCSB, l *slog.Logger) (runner.Runner, error) } // parseOutput parses go-ycsb JSON output. -func parseOutput(r io.Reader) (map[string]map[string]float64, error) { - var res map[string]map[string]float64 +func parseOutput(r io.Reader) (map[string]*measurement, error) { + var res map[string]*measurement scanner := bufio.NewScanner(r) for scanner.Scan() { @@ -84,22 +102,9 @@ func parseOutput(r io.Reader) (map[string]map[string]float64, error) { return nil, err } - res = make(map[string]map[string]float64) + res = make(map[string]*measurement) for _, m := range ms { - res[strings.ToLower(m.Operation)] = map[string]float64{ - "takes": m.TakesS, - "count": float64(m.Count), - "ops": m.OPS, - "avg": (time.Duration(m.AvgUs) * time.Microsecond).Seconds(), - "min": (time.Duration(m.MinUs) * time.Microsecond).Seconds(), - "max": (time.Duration(m.MaxUs) * time.Microsecond).Seconds(), - "perc50": (time.Duration(m.Perc50Us) * time.Microsecond).Seconds(), - "perc90": (time.Duration(m.Perc90Us) * time.Microsecond).Seconds(), - "perc95": (time.Duration(m.Perc95Us) * time.Microsecond).Seconds(), - "perc99": (time.Duration(m.Perc99Us) * time.Microsecond).Seconds(), - "perc999": (time.Duration(m.Perc999Us) * time.Microsecond).Seconds(), - "perc9999": (time.Duration(m.Perc9999Us) * time.Microsecond).Seconds(), - } + res[strings.ToLower(m.Operation)] = &m } } @@ -178,3 +183,6 @@ func (y *ycsb) Run(ctx context.Context) (map[string]config.TestResult, error) { return run(ctx, args, y.p.Dir) } + +// check interface +var _ config.Measurements = (*measurement)(nil) diff --git a/projects/mongobench-runall.yml b/projects/mongobench-runall.yml index 59d853f41..82234025f 100644 --- a/projects/mongobench-runall.yml +++ b/projects/mongobench-runall.yml @@ -15,16 +15,16 @@ params: results: mongodb: stats: - pass: 3 + pass: 4 ferretdb-postgresql: stats: - pass: 3 + pass: 4 ferretdb2: stats: - pass: 3 + pass: 4 ferretdb-dev: stats: - pass: 3 + pass: 4 From 580b57b076b0a900dd2324a6274138a2841dae35 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 10:55:24 +0900 Subject: [PATCH 11/32] allow flexibility to the way measurements are pushed --- internal/pusher/pusher.go | 2 +- internal/runner/ycsb/ycsb.go | 42 +++++++++++++++++++++--------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/internal/pusher/pusher.go b/internal/pusher/pusher.go index 3d83dcbfd..ca3a36fc3 100644 --- a/internal/pusher/pusher.go +++ b/internal/pusher/pusher.go @@ -131,7 +131,7 @@ func (c *Client) Push(ctx context.Context, config, database string, res map[stri for t, tr := range res { t = strings.ReplaceAll(t, ".", "_") // to make it compatible with FerretDB v1 - passed = append(passed, bson.E{t, bson.D{{"m", tr.Measurements}}}) + passed = append(passed, bson.E{t, bson.D{{"m", tr.Measurements.Values()}}}) } doc := bson.D{ diff --git a/internal/runner/ycsb/ycsb.go b/internal/runner/ycsb/ycsb.go index d7cb1179e..3d95d1d14 100644 --- a/internal/runner/ycsb/ycsb.go +++ b/internal/runner/ycsb/ycsb.go @@ -49,6 +49,24 @@ type measurement struct { Perc9999Us float64 `json:"99.99th(us),string"` } +// Values implements [config.Measurements] interface. +func (m *measurement) Values() any { + return map[string]float64{ + "takes": m.TakesS, + "count": float64(m.Count), + "ops": m.OPS, + "avg": (time.Duration(m.AvgUs) * time.Microsecond).Seconds(), + "min": (time.Duration(m.MinUs) * time.Microsecond).Seconds(), + "max": (time.Duration(m.MaxUs) * time.Microsecond).Seconds(), + "perc50": (time.Duration(m.Perc50Us) * time.Microsecond).Seconds(), + "perc90": (time.Duration(m.Perc90Us) * time.Microsecond).Seconds(), + "perc95": (time.Duration(m.Perc95Us) * time.Microsecond).Seconds(), + "perc99": (time.Duration(m.Perc99Us) * time.Microsecond).Seconds(), + "perc999": (time.Duration(m.Perc999Us) * time.Microsecond).Seconds(), + "perc9999": (time.Duration(m.Perc9999Us) * time.Microsecond).Seconds(), + } +} + // ycsb represents `ycsb` runner. type ycsb struct { p *config.RunnerParamsYCSB @@ -64,8 +82,8 @@ func New(params *config.RunnerParamsYCSB, l *slog.Logger) (runner.Runner, error) } // parseOutput parses go-ycsb JSON output. -func parseOutput(r io.Reader) (map[string]map[string]float64, error) { - var res map[string]map[string]float64 +func parseOutput(r io.Reader) (map[string]*measurement, error) { + var res map[string]*measurement scanner := bufio.NewScanner(r) for scanner.Scan() { @@ -84,22 +102,9 @@ func parseOutput(r io.Reader) (map[string]map[string]float64, error) { return nil, err } - res = make(map[string]map[string]float64) + res = make(map[string]*measurement) for _, m := range ms { - res[strings.ToLower(m.Operation)] = map[string]float64{ - "takes": m.TakesS, - "count": float64(m.Count), - "ops": m.OPS, - "avg": (time.Duration(m.AvgUs) * time.Microsecond).Seconds(), - "min": (time.Duration(m.MinUs) * time.Microsecond).Seconds(), - "max": (time.Duration(m.MaxUs) * time.Microsecond).Seconds(), - "perc50": (time.Duration(m.Perc50Us) * time.Microsecond).Seconds(), - "perc90": (time.Duration(m.Perc90Us) * time.Microsecond).Seconds(), - "perc95": (time.Duration(m.Perc95Us) * time.Microsecond).Seconds(), - "perc99": (time.Duration(m.Perc99Us) * time.Microsecond).Seconds(), - "perc999": (time.Duration(m.Perc999Us) * time.Microsecond).Seconds(), - "perc9999": (time.Duration(m.Perc9999Us) * time.Microsecond).Seconds(), - } + res[strings.ToLower(m.Operation)] = &m } } @@ -178,3 +183,6 @@ func (y *ycsb) Run(ctx context.Context) (map[string]config.TestResult, error) { return run(ctx, args, y.p.Dir) } + +// check interface +var _ config.Measurements = (*measurement)(nil) From da524444d6b5fde48c51839d1f69f1a4458e1890 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 11:05:20 +0900 Subject: [PATCH 12/32] config --- internal/config/results.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/config/results.go b/internal/config/results.go index 2c27f8cc8..646b55e47 100644 --- a/internal/config/results.go +++ b/internal/config/results.go @@ -22,13 +22,18 @@ import ( "golang.org/x/exp/maps" ) +// Measurements is the actual measurements from a single test. +type Measurements interface { + Values() any +} + // TestResult represents the actual outcome of a single test. // //nolint:vet // for readability type TestResult struct { Status Status Output string - Measurements map[string]float64 + Measurements Measurements } // IndentedOutput returns the output of a test result with indented lines. From ec091fbe7dc0d6abc1a6f31135c552c26c441324 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 11:06:41 +0900 Subject: [PATCH 13/32] lint --- internal/pusher/pusher.go | 2 +- internal/runner/ycsb/ycsb.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/pusher/pusher.go b/internal/pusher/pusher.go index ca3a36fc3..6c344b05d 100644 --- a/internal/pusher/pusher.go +++ b/internal/pusher/pusher.go @@ -131,7 +131,7 @@ func (c *Client) Push(ctx context.Context, config, database string, res map[stri for t, tr := range res { t = strings.ReplaceAll(t, ".", "_") // to make it compatible with FerretDB v1 - passed = append(passed, bson.E{t, bson.D{{"m", tr.Measurements.Values()}}}) + passed = append(passed, bson.E{Key: t, Value: bson.D{{"m", tr.Measurements.Values()}}}) } doc := bson.D{ diff --git a/internal/runner/ycsb/ycsb.go b/internal/runner/ycsb/ycsb.go index 3d95d1d14..d0258bbf9 100644 --- a/internal/runner/ycsb/ycsb.go +++ b/internal/runner/ycsb/ycsb.go @@ -184,5 +184,5 @@ func (y *ycsb) Run(ctx context.Context) (map[string]config.TestResult, error) { return run(ctx, args, y.p.Dir) } -// check interface +// check interface. var _ config.Measurements = (*measurement)(nil) From 777922e45daf11578089d66b6fa49588be851d77 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 11:16:03 +0900 Subject: [PATCH 14/32] check nil --- internal/pusher/pusher.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/pusher/pusher.go b/internal/pusher/pusher.go index 6c344b05d..fe566db7e 100644 --- a/internal/pusher/pusher.go +++ b/internal/pusher/pusher.go @@ -131,7 +131,13 @@ func (c *Client) Push(ctx context.Context, config, database string, res map[stri for t, tr := range res { t = strings.ReplaceAll(t, ".", "_") // to make it compatible with FerretDB v1 - passed = append(passed, bson.E{Key: t, Value: bson.D{{"m", tr.Measurements.Values()}}}) + + var measurements any + if tr.Measurements != nil { + measurements = tr.Measurements.Values() + } + + passed = append(passed, bson.E{Key: t, Value: bson.D{{"m", measurements}}}) } doc := bson.D{ From 20986fd52f8f101f07515ec811a64b7c98beefdc Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 11:24:11 +0900 Subject: [PATCH 15/32] test --- internal/runner/ycsb/ycsb_test.go | 89 ++++++++++++++++--------------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/internal/runner/ycsb/ycsb_test.go b/internal/runner/ycsb/ycsb_test.go index c140452c9..bae3502f8 100644 --- a/internal/runner/ycsb/ycsb_test.go +++ b/internal/runner/ycsb/ycsb_test.go @@ -53,50 +53,51 @@ Run finished, takes 14.676689042s actual, err := parseOutput(output) require.NoError(t, err) - expected := map[string]map[string]float64{ - "read": { - "takes": 14.7, - "count": 25030, - "ops": 1705.6, - "avg": 0.000293, - "min": 0.000175, - "max": 0.002407, - "perc50": 0.000288, - "perc90": 0.000331, - "perc95": 0.000353, - "perc99": 0.000427, - "perc999": 0.000757, - "perc9999": 0.001312, - }, - "update": { - "takes": 14.7, - "count": 24970, - "ops": 1701.4, - "avg": 0.000288, - "min": 0.000171, - "max": 0.002261, - "perc50": 0.000282, - "perc90": 0.000324, - "perc95": 0.000345, - "perc99": 0.000411, - "perc999": 0.000786, - "perc9999": 0.002151, - }, - "total": { - "takes": 14.7, - "count": 50000, - "ops": 3406.9, - "avg": 0.000291, - "min": 0.000171, - "max": 0.002407, - "perc50": 0.000285, - "perc90": 0.000328, - "perc95": 0.000349, - "perc99": 0.000421, - "perc999": 0.000777, - "perc9999": 0.001913, - }, + expectedRead := map[string]float64{ + "takes": 14.7, + "count": 25030, + "ops": 1705.6, + "avg": 0.000293, + "min": 0.000175, + "max": 0.002407, + "perc50": 0.000288, + "perc90": 0.000331, + "perc95": 0.000353, + "perc99": 0.000427, + "perc999": 0.000757, + "perc9999": 0.001312, } + assert.Equal(t, expectedRead, actual["read"].Values()) - assert.Equal(t, expected, actual) + expectedUpdate := map[string]float64{ + "takes": 14.7, + "count": 24970, + "ops": 1701.4, + "avg": 0.000288, + "min": 0.000171, + "max": 0.002261, + "perc50": 0.000282, + "perc90": 0.000324, + "perc95": 0.000345, + "perc99": 0.000411, + "perc999": 0.000786, + "perc9999": 0.002151, + } + assert.Equal(t, expectedUpdate, actual["update"].Values()) + + expectedTotal := map[string]float64{ + "takes": 14.7, + "count": 50000, + "ops": 3406.9, + "avg": 0.000291, + "min": 0.000171, + "max": 0.002407, + "perc50": 0.000285, + "perc90": 0.000328, + "perc95": 0.000349, + "perc99": 0.000421, + "perc999": 0.000777, + "perc9999": 0.001913, + } + assert.Equal(t, expectedTotal, actual["total"].Values()) } From 8639d2df80e3626282093b0a75aa70086a906f1a Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 14:19:29 +0900 Subject: [PATCH 16/32] workaround --- .github/workflows/go.yml | 3 +++ tools/go.mod | 2 ++ 2 files changed, 5 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index b8bf372c6..6240a018f 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -38,6 +38,8 @@ jobs: # TODO https://github.com/FerretDB/github-actions/issues/211 - name: Checkout code uses: actions/checkout@v4 + with: + submodules: true # for using `mongodb-benchmarking` submodule, see tools/go.mod - name: Setup Go uses: FerretDB/github-actions/setup-go@main @@ -87,6 +89,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 # for `golangci-lint run --new` to work + submodules: true # for using `mongodb-benchmarking` submodule, see tools/go.mod - name: Setup Go uses: FerretDB/github-actions/setup-go@main diff --git a/tools/go.mod b/tools/go.mod index e7bb0c3de..5eb87bdc2 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -18,6 +18,8 @@ tool ( mvdan.cc/gofumpt ) +// use local submodule path to prevent the error +// `module declares its path as: benchmarking but was required as: github.com/idealo/mongodb-benchmarking` replace github.com/idealo/mongodb-benchmarking v1.5.4 => ../projects/mongodb-benchmarking require ( From 4a81d993d49a3cfd6345fa4c2f7ddf2dcb2cd7ec Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 14:24:07 +0900 Subject: [PATCH 17/32] comment --- internal/runner/mongobench/mongobench.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go index 7887a0cc8..84c1d6051 100644 --- a/internal/runner/mongobench/mongobench.go +++ b/internal/runner/mongobench/mongobench.go @@ -62,7 +62,7 @@ type mongoBench struct { l *slog.Logger } -// New creates a new `mongoBench` runner with given parameters. +// New creates a new runner with given parameters. func New(params *config.RunnerParamsMongoBench, l *slog.Logger) (runner.Runner, error) { return &mongoBench{ p: params, @@ -172,7 +172,7 @@ func parseMeasurements(r *bufio.Reader) (*benchmark, error) { }, nil } -// readMeasurements reads the measurements from the file with given name. +// readMeasurements reads the measurements from the file with the given name. func readMeasurements(fileName string) (*benchmark, error) { relPath := filepath.Join("..", fileName) From 001b791a64ea2f4ee1231d3dbe63eea62e41a1f2 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 14:29:54 +0900 Subject: [PATCH 18/32] use fork --- .gitmodules | 2 +- tools/go.mod | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitmodules b/.gitmodules index 02d34f122..f722489dc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -39,5 +39,5 @@ branch = devel [submodule "mongodb-benchmarking"] path = projects/mongodb-benchmarking - url = https://github.com/idealo/mongodb-benchmarking.git + url = https://github.com/FerretDB/mongodb-benchmarking.git branch = main diff --git a/tools/go.mod b/tools/go.mod index 5eb87bdc2..17116ef43 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -5,8 +5,8 @@ go 1.24.1 toolchain go1.24.2 tool ( + github.com/FerretDB/mongodb-benchmarking github.com/go-task/task/v3/cmd/task - github.com/idealo/mongodb-benchmarking github.com/pingcap/go-ycsb/cmd/go-ycsb github.com/quasilyte/go-consistent golang.org/x/perf/cmd/benchstat @@ -19,8 +19,8 @@ tool ( ) // use local submodule path to prevent the error -// `module declares its path as: benchmarking but was required as: github.com/idealo/mongodb-benchmarking` -replace github.com/idealo/mongodb-benchmarking v1.5.4 => ../projects/mongodb-benchmarking +// `module declares its path as: benchmarking but was required as: github.com/FerretDB/mongodb-benchmarking` +replace github.com/FerretDB/mongodb-benchmarking v1.5.4 => ../projects/mongodb-benchmarking require ( cloud.google.com/go v0.110.2 // indirect @@ -30,6 +30,7 @@ require ( cloud.google.com/go/spanner v1.45.0 // indirect dario.cat/mergo v1.0.0 // indirect github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7 // indirect + github.com/FerretDB/mongodb-benchmarking v1.5.4 // indirect github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect github.com/Ladicle/tabwriter v1.0.0 // indirect github.com/Masterminds/semver/v3 v3.3.1 // indirect @@ -116,7 +117,6 @@ require ( github.com/googleapis/gax-go/v2 v2.11.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 // indirect github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect - github.com/idealo/mongodb-benchmarking v1.5.4 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect From 57b8e4e03360c7c521f05c6bc5bc328fee0d73d3 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 14:36:19 +0900 Subject: [PATCH 19/32] lint --- internal/runner/mongobench/mongobench.go | 6 +-- internal/runner/mongobench/mongobench_test.go | 43 ++++--------------- 2 files changed, 11 insertions(+), 38 deletions(-) diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go index 84c1d6051..cf3933f85 100644 --- a/internal/runner/mongobench/mongobench.go +++ b/internal/runner/mongobench/mongobench.go @@ -31,9 +31,9 @@ import ( "github.com/FerretDB/dance/internal/runner" ) -// benchmark is numerical results of a benchmark operation. +// benchmark contains numerical results of a benchmark operation. // -// mongodb-benchmarking test produces measurements each second while the benchmark is running, +// The mongodb-benchmarking test produces measurements each second while the benchmark is running, // and each index of the slices corresponds to a measurement from each second. type benchmark struct { ts []int64 // timestamp (epoch seconds) @@ -253,5 +253,5 @@ func (y *mongoBench) Run(ctx context.Context) (map[string]config.TestResult, err return run(ctx, args, y.p.Dir) } -// check inferface +// check interface. var _ config.Measurements = (*benchmark)(nil) diff --git a/internal/runner/mongobench/mongobench_test.go b/internal/runner/mongobench/mongobench_test.go index 1d20cf0cc..c10fdd4c1 100644 --- a/internal/runner/mongobench/mongobench_test.go +++ b/internal/runner/mongobench/mongobench_test.go @@ -69,43 +69,16 @@ func TestParseMeasurements(t *testing.T) { 1748240902,30000,8288.694528,756.800000,756.800000,756.800000`, ) - actual, err := parseMeasurements("upsert", bufio.NewReader(results)) + actual, err := parseMeasurements(bufio.NewReader(results)) require.NoError(t, err) - expected := map[string]map[string]float64{ - "upsert_1748240899": { - "t": 1748240899, - "count": 13524, - "mean": 13522.216068, - "m1_rate": 756.800000, - "m5_rate": 756.800000, - "m15_rate": 756.800000, - }, - "upsert_1748240900": { - "t": 1748240900, - "count": 21505, - "mean": 10748.078321, - "m1_rate": 756.800000, - "m5_rate": 756.800000, - "m15_rate": 756.800000, - }, - "upsert_1748240901": { - "t": 1748240901, - "count": 27081, - "mean": 9027.363746, - "m1_rate": 756.800000, - "m5_rate": 756.800000, - "m15_rate": 756.800000, - }, - "upsert_1748240902": { - "t": 1748240902, - "count": 30000, - "mean": 8288.694528, - "m1_rate": 756.800000, - "m5_rate": 756.800000, - "m15_rate": 756.800000, - }, + expected := &benchmark{ + ts: []int64{1748240899, 1748240900, 1748240901, 1748240902}, + counts: []int64{13524, 21505, 27081, 30000}, + meanRates: []float64{13522.216068, 10748.078321, 9027.363746, 8288.694528}, + m1Rates: []float64{756.800000, 756.800000, 756.800000, 756.800000}, + m5Rates: []float64{756.800000, 756.800000, 756.800000, 756.800000}, + m15Rates: []float64{756.800000, 756.800000, 756.800000, 756.800000}, } - assert.Equal(t, expected, actual) } From 24e15967eb0c83a4f86bce1d99abf2682012310b Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 14:44:24 +0900 Subject: [PATCH 20/32] tooling --- .github/workflows/go.yml | 3 +++ .gitmodules | 2 +- projects/mongodb-benchmarking | 2 +- tools/go.mod | 19 +++++++++++++------ tools/go.sum | 32 ++++++++++++++------------------ 5 files changed, 32 insertions(+), 26 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index b8bf372c6..6240a018f 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -38,6 +38,8 @@ jobs: # TODO https://github.com/FerretDB/github-actions/issues/211 - name: Checkout code uses: actions/checkout@v4 + with: + submodules: true # for using `mongodb-benchmarking` submodule, see tools/go.mod - name: Setup Go uses: FerretDB/github-actions/setup-go@main @@ -87,6 +89,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 # for `golangci-lint run --new` to work + submodules: true # for using `mongodb-benchmarking` submodule, see tools/go.mod - name: Setup Go uses: FerretDB/github-actions/setup-go@main diff --git a/.gitmodules b/.gitmodules index 02d34f122..f722489dc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -39,5 +39,5 @@ branch = devel [submodule "mongodb-benchmarking"] path = projects/mongodb-benchmarking - url = https://github.com/idealo/mongodb-benchmarking.git + url = https://github.com/FerretDB/mongodb-benchmarking.git branch = main diff --git a/projects/mongodb-benchmarking b/projects/mongodb-benchmarking index c63459ddd..1516aa4d2 160000 --- a/projects/mongodb-benchmarking +++ b/projects/mongodb-benchmarking @@ -1 +1 @@ -Subproject commit c63459ddd39f61680d2898921abf36fff176f372 +Subproject commit 1516aa4d2ca9d4d1a3db5d0751f2524b8f09bd67 diff --git a/tools/go.mod b/tools/go.mod index afa3283b9..17116ef43 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -5,6 +5,7 @@ go 1.24.1 toolchain go1.24.2 tool ( + github.com/FerretDB/mongodb-benchmarking github.com/go-task/task/v3/cmd/task github.com/pingcap/go-ycsb/cmd/go-ycsb github.com/quasilyte/go-consistent @@ -17,6 +18,10 @@ tool ( mvdan.cc/gofumpt ) +// use local submodule path to prevent the error +// `module declares its path as: benchmarking but was required as: github.com/FerretDB/mongodb-benchmarking` +replace github.com/FerretDB/mongodb-benchmarking v1.5.4 => ../projects/mongodb-benchmarking + require ( cloud.google.com/go v0.110.2 // indirect cloud.google.com/go/compute/metadata v0.3.0 // indirect @@ -25,6 +30,7 @@ require ( cloud.google.com/go/spanner v1.45.0 // indirect dario.cat/mergo v1.0.0 // indirect github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7 // indirect + github.com/FerretDB/mongodb-benchmarking v1.5.4 // indirect github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect github.com/Ladicle/tabwriter v1.0.0 // indirect github.com/Masterminds/semver/v3 v3.3.1 // indirect @@ -117,7 +123,7 @@ require ( github.com/joho/godotenv v1.5.1 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/kisielk/gotool v1.0.0 // indirect - github.com/klauspost/compress v1.13.6 // indirect + github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/lib/pq v1.10.9 // indirect github.com/magiconair/properties v1.8.0 // indirect @@ -130,7 +136,7 @@ require ( github.com/minio/minio-go v6.0.14+incompatible // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect - github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect + github.com/montanaflynn/stats v0.7.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pingcap/errors v0.11.5-0.20211224045212-9687c2b0f87c // indirect @@ -146,6 +152,7 @@ require ( github.com/prometheus/procfs v0.6.0 // indirect github.com/quasilyte/go-consistent v0.6.1 // indirect github.com/radovskyb/watcher v1.0.7 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect github.com/sajari/fuzzy v1.0.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect @@ -161,15 +168,15 @@ require ( github.com/twmb/murmur3 v1.1.3 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect - github.com/xdg-go/scram v1.1.1 // indirect - github.com/xdg-go/stringprep v1.0.3 // indirect - github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect + github.com/xdg-go/scram v1.1.2 // indirect + github.com/xdg-go/stringprep v1.0.4 // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da // indirect github.com/zeebo/xxh3 v1.0.2 // indirect go.etcd.io/etcd/api/v3 v3.5.2 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.2 // indirect go.etcd.io/etcd/client/v3 v3.5.2 // indirect - go.mongodb.org/mongo-driver v1.11.3 // indirect + go.mongodb.org/mongo-driver v1.17.3 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.7.0 // indirect diff --git a/tools/go.sum b/tools/go.sum index 716bf778b..7a2a53f7e 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -283,7 +283,6 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -296,7 +295,6 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -361,8 +359,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -404,8 +402,8 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= +github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -479,6 +477,8 @@ github.com/quasilyte/go-consistent v0.6.1 h1:zfOZAzADcpxp9QXOmMspDTHEzoCJ5EpiTR+ github.com/quasilyte/go-consistent v0.6.1/go.mod h1:zo8fhUCPO6L+/vP78haKSsCKGCnlICdhKVW9CiQ5KcU= github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE= github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -526,7 +526,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -535,9 +534,6 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tikv/client-go/v2 v2.0.1-0.20220720064224-aa9ded37d17d h1:xllx8pkveVLcnAkWIa+cRpCVckbJF7LHS+9pURqp0Ig= github.com/tikv/client-go/v2 v2.0.1-0.20220720064224-aa9ded37d17d/go.mod h1:UmDQEoeHXza8RSHBXVFERpxH54VBOf8yKZVphyel3l4= github.com/tikv/pd/client v0.0.0-20220307081149-841fa61e9710 h1:jxgmKOscXSjaFEKQGRyY5qOpK8hLqxs2irb/uDJMtwk= @@ -550,14 +546,14 @@ github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E= -github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs= -github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -577,8 +573,8 @@ go.etcd.io/etcd/client/pkg/v3 v3.5.2 h1:4hzqQ6hIb3blLyQ8usCU4h3NghkqcsohEQ3o3Vet go.etcd.io/etcd/client/pkg/v3 v3.5.2/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v3 v3.5.2 h1:WdnejrUtQC4nCxK0/dLTMqKOB+U5TP/2Ya0BJL+1otA= go.etcd.io/etcd/client/v3 v3.5.2/go.mod h1:kOOaWFFgHygyT0WlSmL8TJiXmMysO/nNUlEsSsN6W4o= -go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= -go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= +go.mongodb.org/mongo-driver v1.17.3 h1:TQyXhnsWfWtgAhMtOgtYHMTkZIfBTpMTsMnd9ZBeHxQ= +go.mongodb.org/mongo-driver v1.17.3/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= From afe5c7e1ddb60a06df69ce7b35ea0e157e9e86b3 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 14:50:31 +0900 Subject: [PATCH 21/32] interface check --- internal/configload/runner.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/configload/runner.go b/internal/configload/runner.go index 147d427f8..65a3a8d8e 100644 --- a/internal/configload/runner.go +++ b/internal/configload/runner.go @@ -106,5 +106,6 @@ func (rp *runnerParamsYCSB) convert() (config.RunnerParams, error) { var ( _ runnerParams = (*runnerParamsCommand)(nil) _ runnerParams = (*runnerParamsGoTest)(nil) + _ runnerParams = (*runnerParamsMongoBench)(nil) _ runnerParams = (*runnerParamsYCSB)(nil) ) From b738d6cbd3787dd2bc23af1dc0dac81d515bd65b Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 15:06:13 +0900 Subject: [PATCH 22/32] run in CI --- .github/workflows/dance.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/dance.yml b/.github/workflows/dance.yml index 396042220..4cb6170c9 100644 --- a/.github/workflows/dance.yml +++ b/.github/workflows/dance.yml @@ -52,6 +52,8 @@ jobs: - { config: mongo-tools } - { config: mongo-core-test, verbose: true } # verbose to view test output on CI + - { config: mongobench-runall } + - { config: ycsb-workloada } - { config: ycsb-workloada2 } - { config: ycsb-workloadb } From 221fbe1fb9f56bebad70b141945e7237d7e094c1 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 15:21:05 +0900 Subject: [PATCH 23/32] no ferretdb v1 --- projects/mongobench-runall.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/projects/mongobench-runall.yml b/projects/mongobench-runall.yml index 82234025f..17125f689 100644 --- a/projects/mongobench-runall.yml +++ b/projects/mongobench-runall.yml @@ -17,10 +17,6 @@ results: stats: pass: 4 - ferretdb-postgresql: - stats: - pass: 4 - ferretdb2: stats: pass: 4 From 029d36c494994261567cdd5c6771600d0cf10720 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 15:39:43 +0900 Subject: [PATCH 24/32] file path --- .gitignore | 3 --- internal/runner/mongobench/mongobench.go | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 7dff9cebf..5e8b49efd 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,3 @@ /dumps/mongodump_tests/ /vendor/ cover.txt - -# mongodb-benchmarking -benchmark_results_*.csv diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go index cf3933f85..8b1ccc797 100644 --- a/internal/runner/mongobench/mongobench.go +++ b/internal/runner/mongobench/mongobench.go @@ -174,7 +174,7 @@ func parseMeasurements(r *bufio.Reader) (*benchmark, error) { // readMeasurements reads the measurements from the file with the given name. func readMeasurements(fileName string) (*benchmark, error) { - relPath := filepath.Join("..", fileName) + relPath := filepath.Join("..", "projects", "mongodb-benchmarking", fileName) f, err := os.Open(relPath) if err != nil { From 1c26d6f2387586ac33c28d1d15b62499df2fe760 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Tue, 27 May 2025 15:57:49 +0900 Subject: [PATCH 25/32] fix --- projects/mongobench-runall.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/mongobench-runall.yml b/projects/mongobench-runall.yml index 17125f689..9b2fe2291 100644 --- a/projects/mongobench-runall.yml +++ b/projects/mongobench-runall.yml @@ -21,6 +21,6 @@ results: stats: pass: 4 - ferretdb-dev: + ferretdb2-dev: stats: pass: 4 From 1b5a43d1ccbc91a549069bd75de80bf7cef65b1f Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Wed, 28 May 2025 10:06:51 +0900 Subject: [PATCH 26/32] Update internal/runner/mongobench/mongobench.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- internal/runner/mongobench/mongobench.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go index 8b1ccc797..8654185b4 100644 --- a/internal/runner/mongobench/mongobench.go +++ b/internal/runner/mongobench/mongobench.go @@ -124,6 +124,9 @@ func parseMeasurements(r *bufio.Reader) (*benchmark, error) { record := strings.Split(string(line), ",") + if len(record) < 6 { + return nil, errors.New("malformed line: insufficient fields") + } t, err := strconv.ParseInt(record[0], 10, 64) if err != nil { return nil, err From 5715b6e18c682f83bc38820f489c29368137a7ad Mon Sep 17 00:00:00 2001 From: Alexey Palazhchenko Date: Thu, 29 May 2025 08:00:49 +0400 Subject: [PATCH 27/32] Do not use git submodule --- .gitmodules | 4 ---- go.mod | 2 +- projects/mongodb-benchmarking | 1 - tools/go.mod | 10 ++++------ tools/go.sum | 2 ++ tools/golangci/go.mod | 2 +- 6 files changed, 8 insertions(+), 13 deletions(-) delete mode 160000 projects/mongodb-benchmarking diff --git a/.gitmodules b/.gitmodules index f722489dc..64864467e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -37,7 +37,3 @@ path = projects/meteor url = https://github.com/meteor/meteor.git branch = devel -[submodule "mongodb-benchmarking"] - path = projects/mongodb-benchmarking - url = https://github.com/FerretDB/mongodb-benchmarking.git - branch = main diff --git a/go.mod b/go.mod index b7961ee7b..603fab0fe 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/FerretDB/dance go 1.24 -toolchain go1.24.2 +toolchain go1.24.3 require ( github.com/alecthomas/kong v1.10.0 diff --git a/projects/mongodb-benchmarking b/projects/mongodb-benchmarking deleted file mode 160000 index 1516aa4d2..000000000 --- a/projects/mongodb-benchmarking +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1516aa4d2ca9d4d1a3db5d0751f2524b8f09bd67 diff --git a/tools/go.mod b/tools/go.mod index 17116ef43..be8fa602a 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -2,11 +2,11 @@ module github.com/FerretDB/dance/tools go 1.24.1 -toolchain go1.24.2 +toolchain go1.24.3 tool ( - github.com/FerretDB/mongodb-benchmarking github.com/go-task/task/v3/cmd/task + github.com/idealo/mongodb-benchmarking github.com/pingcap/go-ycsb/cmd/go-ycsb github.com/quasilyte/go-consistent golang.org/x/perf/cmd/benchstat @@ -18,9 +18,7 @@ tool ( mvdan.cc/gofumpt ) -// use local submodule path to prevent the error -// `module declares its path as: benchmarking but was required as: github.com/FerretDB/mongodb-benchmarking` -replace github.com/FerretDB/mongodb-benchmarking v1.5.4 => ../projects/mongodb-benchmarking +replace github.com/idealo/mongodb-benchmarking => github.com/FerretDB/mongodb-benchmarking v0.0.0-20250529035102-a8e5993d9712 require ( cloud.google.com/go v0.110.2 // indirect @@ -30,7 +28,6 @@ require ( cloud.google.com/go/spanner v1.45.0 // indirect dario.cat/mergo v1.0.0 // indirect github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7 // indirect - github.com/FerretDB/mongodb-benchmarking v1.5.4 // indirect github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect github.com/Ladicle/tabwriter v1.0.0 // indirect github.com/Masterminds/semver/v3 v3.3.1 // indirect @@ -117,6 +114,7 @@ require ( github.com/googleapis/gax-go/v2 v2.11.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 // indirect github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect + github.com/idealo/mongodb-benchmarking v0.0.0-00010101000000-000000000000 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect diff --git a/tools/go.sum b/tools/go.sum index 7a2a53f7e..042aa2b63 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -18,6 +18,8 @@ github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOv github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/FerretDB/mongodb-benchmarking v0.0.0-20250529035102-a8e5993d9712 h1:2xQz9v3WhApK8HrwCUeVEZY9MelRKHAlh38CnIgKnxs= +github.com/FerretDB/mongodb-benchmarking v0.0.0-20250529035102-a8e5993d9712/go.mod h1:c7pDrPPjH2d5M2c3gZk3n+m4h5LTW72Ufw/kUpTUzlQ= github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Ladicle/tabwriter v1.0.0 h1:DZQqPvMumBDwVNElso13afjYLNp0Z7pHqHnu0r4t9Dg= diff --git a/tools/golangci/go.mod b/tools/golangci/go.mod index 26a1eb1f6..6384a9374 100644 --- a/tools/golangci/go.mod +++ b/tools/golangci/go.mod @@ -4,7 +4,7 @@ module github.com/FerretDB/dance/tools/golangci go 1.24 -toolchain go1.24.2 +toolchain go1.24.3 tool github.com/golangci/golangci-lint/cmd/golangci-lint From 32ebf5dadb2315b0728888d252af502ba54f1c4d Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Thu, 29 May 2025 13:39:08 +0900 Subject: [PATCH 28/32] undo workflow changes --- .github/workflows/go.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 6240a018f..b8bf372c6 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -38,8 +38,6 @@ jobs: # TODO https://github.com/FerretDB/github-actions/issues/211 - name: Checkout code uses: actions/checkout@v4 - with: - submodules: true # for using `mongodb-benchmarking` submodule, see tools/go.mod - name: Setup Go uses: FerretDB/github-actions/setup-go@main @@ -89,7 +87,6 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 # for `golangci-lint run --new` to work - submodules: true # for using `mongodb-benchmarking` submodule, see tools/go.mod - name: Setup Go uses: FerretDB/github-actions/setup-go@main From f489f0e5a7b22a328ef4302ab53bd7a62c9ab8a2 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Thu, 29 May 2025 13:57:08 +0900 Subject: [PATCH 29/32] update --- .gitignore | 3 +++ internal/runner/mongobench/mongobench.go | 2 +- projects/mongobench-runall.yml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 5e8b49efd..577181686 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ /dumps/mongodump_tests/ /vendor/ cover.txt + +# mongodb-benchmarking +projects/benchmark_results_*.csv diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go index 8b1ccc797..f126192b3 100644 --- a/internal/runner/mongobench/mongobench.go +++ b/internal/runner/mongobench/mongobench.go @@ -174,7 +174,7 @@ func parseMeasurements(r *bufio.Reader) (*benchmark, error) { // readMeasurements reads the measurements from the file with the given name. func readMeasurements(fileName string) (*benchmark, error) { - relPath := filepath.Join("..", "projects", "mongodb-benchmarking", fileName) + relPath := filepath.Join("..", "projects", fileName) f, err := os.Open(relPath) if err != nil { diff --git a/projects/mongobench-runall.yml b/projects/mongobench-runall.yml index 9b2fe2291..d25b59f46 100644 --- a/projects/mongobench-runall.yml +++ b/projects/mongobench-runall.yml @@ -2,7 +2,7 @@ # Run all tests runner: mongobench params: - dir: mongodb-benchmarking + dir: . args: - -threads - 10 From 0e52d402b1526525f4606bb7f4620f79ec4012f1 Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Thu, 29 May 2025 14:59:05 +0900 Subject: [PATCH 30/32] report last resutl --- internal/config/results.go | 7 +- internal/pusher/pusher.go | 8 +- internal/runner/mongobench/mongobench.go | 148 ++++++------------ internal/runner/mongobench/mongobench_test.go | 33 ++-- internal/runner/ycsb/ycsb.go | 42 ++--- internal/runner/ycsb/ycsb_test.go | 89 ++++++----- 6 files changed, 132 insertions(+), 195 deletions(-) diff --git a/internal/config/results.go b/internal/config/results.go index ac08c8857..1c1fe40c3 100644 --- a/internal/config/results.go +++ b/internal/config/results.go @@ -21,18 +21,13 @@ import ( "strings" ) -// Measurements is the actual measurements from a single test. -type Measurements interface { - Values() any -} - // TestResult represents the actual outcome of a single test. // //nolint:vet // for readability type TestResult struct { Status Status Output string - Measurements Measurements + Measurements map[string]float64 } // IndentedOutput returns the output of a test result with indented lines. diff --git a/internal/pusher/pusher.go b/internal/pusher/pusher.go index fe566db7e..3d83dcbfd 100644 --- a/internal/pusher/pusher.go +++ b/internal/pusher/pusher.go @@ -131,13 +131,7 @@ func (c *Client) Push(ctx context.Context, config, database string, res map[stri for t, tr := range res { t = strings.ReplaceAll(t, ".", "_") // to make it compatible with FerretDB v1 - - var measurements any - if tr.Measurements != nil { - measurements = tr.Measurements.Values() - } - - passed = append(passed, bson.E{Key: t, Value: bson.D{{"m", measurements}}}) + passed = append(passed, bson.E{t, bson.D{{"m", tr.Measurements}}}) } doc := bson.D{ diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go index 1ec1de966..7bca4def6 100644 --- a/internal/runner/mongobench/mongobench.go +++ b/internal/runner/mongobench/mongobench.go @@ -31,31 +31,6 @@ import ( "github.com/FerretDB/dance/internal/runner" ) -// benchmark contains numerical results of a benchmark operation. -// -// The mongodb-benchmarking test produces measurements each second while the benchmark is running, -// and each index of the slices corresponds to a measurement from each second. -type benchmark struct { - ts []int64 // timestamp (epoch seconds) - counts []int64 // total document count - meanRates []float64 // mean operation rate in docs/sec - m1Rates []float64 // moving average rates over 1 minute - m5Rates []float64 // moving average rates over 5 minutes - m15Rates []float64 // moving average rates over 15 minutes -} - -// Values implements [config.Measurements] interface. -func (m *benchmark) Values() any { - return map[string]any{ - "ts": m.ts, - "counts": m.counts, - "mean_rates": m.meanRates, - "m1_rates": m.m1Rates, - "m5_rates": m.m5Rates, - "m15_rates": m.m15Rates, - } -} - // mongoBench represents `mongoBench` runner. type mongoBench struct { p *config.RunnerParamsMongoBench @@ -100,95 +75,73 @@ func parseFileNames(r io.Reader) ([]string, error) { return fileNames, nil } -// parseMeasurements reads the mongo-bench results from the reader. -func parseMeasurements(r *bufio.Reader) (*benchmark, error) { - // cannot use [csv.NewReader] because the file does not contain valid CSV, - // it contains 7 header fields while record lines contain 6 fields, - // so we parse it manually and assume the last field `mean_rate` is missing - if _, _, err := r.ReadLine(); err != nil { +// parseMeasurements reads the file and gets the last measurement and parses them. +func parseMeasurements(filepath string) (map[string]float64, error) { + f, err := os.Open(filepath) + if err != nil { return nil, err } - var ts, counts []int64 - var meanRates, m1Rates, m5Rates, m15Rates []float64 - - for { - line, _, err := r.ReadLine() - if errors.Is(err, io.EOF) { - break - } - - if err != nil { - return nil, err - } - - record := strings.Split(string(line), ",") + defer func() { + err = f.Close() + }() - if len(record) < 6 { - return nil, errors.New("malformed line: insufficient fields") - } - t, err := strconv.ParseInt(record[0], 10, 64) - if err != nil { - return nil, err - } + // cannot use [csv.NewReader] because the file does not contain valid CSV, + // it contains 7 header fields while record lines contain 6 fields, + // so we parse it manually and assume the last field `mean_rate` is missing + s := bufio.NewScanner(f) - count, err := strconv.ParseInt(record[1], 10, 64) - if err != nil { - return nil, err - } + var lastLine string - mean, err := strconv.ParseFloat(record[2], 64) - if err != nil { - return nil, err - } + for s.Scan() { + line := s.Text() - m1Rate, err := strconv.ParseFloat(record[3], 64) - if err != nil { - return nil, err + if strings.TrimSpace(line) != "" { + lastLine = line } + } - m5Rate, err := strconv.ParseFloat(record[4], 64) - if err != nil { - return nil, err - } + if err = s.Err(); err != nil { + return nil, err + } - m15Rate, err := strconv.ParseFloat(record[5], 64) - if err != nil { - return nil, err - } + record := strings.Split(lastLine, ",") + if len(record) < 6 { + return nil, errors.New("insufficient fields") + } - ts = append(ts, t) - counts = append(counts, count) - meanRates = append(meanRates, mean) - m1Rates = append(m1Rates, m1Rate) - m5Rates = append(m5Rates, m5Rate) - m15Rates = append(m15Rates, m15Rate) + count, err := strconv.ParseFloat(record[1], 64) + if err != nil { + return nil, err } - return &benchmark{ - ts: ts, - counts: counts, - meanRates: meanRates, - m1Rates: m1Rates, - m5Rates: m5Rates, - m15Rates: m15Rates, - }, nil -} + mean, err := strconv.ParseFloat(record[2], 64) + if err != nil { + return nil, err + } -// readMeasurements reads the measurements from the file with the given name. -func readMeasurements(fileName string) (*benchmark, error) { - relPath := filepath.Join("..", "projects", fileName) + m1Rate, err := strconv.ParseFloat(record[3], 64) + if err != nil { + return nil, err + } - f, err := os.Open(relPath) + m5Rate, err := strconv.ParseFloat(record[4], 64) if err != nil { return nil, err } - defer func() { - err = f.Close() - }() + m15Rate, err := strconv.ParseFloat(record[5], 64) + if err != nil { + return nil, err + } - return parseMeasurements(bufio.NewReader(f)) + return map[string]float64{ + "count": count, + "mean": mean, + "m1_rate": m1Rate, + "m5_rate": m5Rate, + "m15_rate": m15Rate, + }, nil } // run runs given command in the given directory and returns parsed results. @@ -221,9 +174,9 @@ func run(ctx context.Context, args []string, dir string) (map[string]config.Test res := make(map[string]config.TestResult) for _, fileName := range fileNames { - var m *benchmark + var m map[string]float64 - if m, err = readMeasurements(fileName); err != nil { + if m, err = parseMeasurements(filepath.Join("..", "projects", fileName)); err != nil { return nil, err } @@ -255,6 +208,3 @@ func (y *mongoBench) Run(ctx context.Context) (map[string]config.TestResult, err return run(ctx, args, y.p.Dir) } - -// check interface. -var _ config.Measurements = (*benchmark)(nil) diff --git a/internal/runner/mongobench/mongobench_test.go b/internal/runner/mongobench/mongobench_test.go index c10fdd4c1..379e8c265 100644 --- a/internal/runner/mongobench/mongobench_test.go +++ b/internal/runner/mongobench/mongobench_test.go @@ -15,7 +15,7 @@ package mongobench import ( - "bufio" + "os" "strings" "testing" @@ -61,24 +61,31 @@ Benchmarking completed. Results saved to benchmark_results_upsert.csv func TestParseMeasurements(t *testing.T) { t.Parallel() - results := strings.NewReader( - `t,count,mean,m1_rate,m5_rate,m15_rate,mean_rate + results := `t,count,mean,m1_rate,m5_rate,m15_rate,mean_rate 1748240899,13524,13522.216068,756.800000,756.800000,756.800000 1748240900,21505,10748.078321,756.800000,756.800000,756.800000 1748240901,27081,9027.363746,756.800000,756.800000,756.800000 -1748240902,30000,8288.694528,756.800000,756.800000,756.800000`, - ) +1748240902,30000,8288.694528,756.800000,756.800000,756.800000 +` + f, err := os.CreateTemp(t.TempDir(), "benchmark_results_delete") + require.NoError(t, err) + + t.Cleanup(func() { + assert.NoError(t, f.Close()) + }) + + _, err = f.Write([]byte(results)) + require.NoError(t, err) - actual, err := parseMeasurements(bufio.NewReader(results)) + actual, err := parseMeasurements(f.Name()) require.NoError(t, err) - expected := &benchmark{ - ts: []int64{1748240899, 1748240900, 1748240901, 1748240902}, - counts: []int64{13524, 21505, 27081, 30000}, - meanRates: []float64{13522.216068, 10748.078321, 9027.363746, 8288.694528}, - m1Rates: []float64{756.800000, 756.800000, 756.800000, 756.800000}, - m5Rates: []float64{756.800000, 756.800000, 756.800000, 756.800000}, - m15Rates: []float64{756.800000, 756.800000, 756.800000, 756.800000}, + expected := map[string]float64{ + "count": 30000, + "mean": 8288.694528, + "m1_rate": 756.800000, + "m5_rate": 756.800000, + "m15_rate": 756.800000, } assert.Equal(t, expected, actual) } diff --git a/internal/runner/ycsb/ycsb.go b/internal/runner/ycsb/ycsb.go index d0258bbf9..d7cb1179e 100644 --- a/internal/runner/ycsb/ycsb.go +++ b/internal/runner/ycsb/ycsb.go @@ -49,24 +49,6 @@ type measurement struct { Perc9999Us float64 `json:"99.99th(us),string"` } -// Values implements [config.Measurements] interface. -func (m *measurement) Values() any { - return map[string]float64{ - "takes": m.TakesS, - "count": float64(m.Count), - "ops": m.OPS, - "avg": (time.Duration(m.AvgUs) * time.Microsecond).Seconds(), - "min": (time.Duration(m.MinUs) * time.Microsecond).Seconds(), - "max": (time.Duration(m.MaxUs) * time.Microsecond).Seconds(), - "perc50": (time.Duration(m.Perc50Us) * time.Microsecond).Seconds(), - "perc90": (time.Duration(m.Perc90Us) * time.Microsecond).Seconds(), - "perc95": (time.Duration(m.Perc95Us) * time.Microsecond).Seconds(), - "perc99": (time.Duration(m.Perc99Us) * time.Microsecond).Seconds(), - "perc999": (time.Duration(m.Perc999Us) * time.Microsecond).Seconds(), - "perc9999": (time.Duration(m.Perc9999Us) * time.Microsecond).Seconds(), - } -} - // ycsb represents `ycsb` runner. type ycsb struct { p *config.RunnerParamsYCSB @@ -82,8 +64,8 @@ func New(params *config.RunnerParamsYCSB, l *slog.Logger) (runner.Runner, error) } // parseOutput parses go-ycsb JSON output. -func parseOutput(r io.Reader) (map[string]*measurement, error) { - var res map[string]*measurement +func parseOutput(r io.Reader) (map[string]map[string]float64, error) { + var res map[string]map[string]float64 scanner := bufio.NewScanner(r) for scanner.Scan() { @@ -102,9 +84,22 @@ func parseOutput(r io.Reader) (map[string]*measurement, error) { return nil, err } - res = make(map[string]*measurement) + res = make(map[string]map[string]float64) for _, m := range ms { - res[strings.ToLower(m.Operation)] = &m + res[strings.ToLower(m.Operation)] = map[string]float64{ + "takes": m.TakesS, + "count": float64(m.Count), + "ops": m.OPS, + "avg": (time.Duration(m.AvgUs) * time.Microsecond).Seconds(), + "min": (time.Duration(m.MinUs) * time.Microsecond).Seconds(), + "max": (time.Duration(m.MaxUs) * time.Microsecond).Seconds(), + "perc50": (time.Duration(m.Perc50Us) * time.Microsecond).Seconds(), + "perc90": (time.Duration(m.Perc90Us) * time.Microsecond).Seconds(), + "perc95": (time.Duration(m.Perc95Us) * time.Microsecond).Seconds(), + "perc99": (time.Duration(m.Perc99Us) * time.Microsecond).Seconds(), + "perc999": (time.Duration(m.Perc999Us) * time.Microsecond).Seconds(), + "perc9999": (time.Duration(m.Perc9999Us) * time.Microsecond).Seconds(), + } } } @@ -183,6 +178,3 @@ func (y *ycsb) Run(ctx context.Context) (map[string]config.TestResult, error) { return run(ctx, args, y.p.Dir) } - -// check interface. -var _ config.Measurements = (*measurement)(nil) diff --git a/internal/runner/ycsb/ycsb_test.go b/internal/runner/ycsb/ycsb_test.go index bae3502f8..c140452c9 100644 --- a/internal/runner/ycsb/ycsb_test.go +++ b/internal/runner/ycsb/ycsb_test.go @@ -53,51 +53,50 @@ Run finished, takes 14.676689042s actual, err := parseOutput(output) require.NoError(t, err) - expectedRead := map[string]float64{ - "takes": 14.7, - "count": 25030, - "ops": 1705.6, - "avg": 0.000293, - "min": 0.000175, - "max": 0.002407, - "perc50": 0.000288, - "perc90": 0.000331, - "perc95": 0.000353, - "perc99": 0.000427, - "perc999": 0.000757, - "perc9999": 0.001312, + expected := map[string]map[string]float64{ + "read": { + "takes": 14.7, + "count": 25030, + "ops": 1705.6, + "avg": 0.000293, + "min": 0.000175, + "max": 0.002407, + "perc50": 0.000288, + "perc90": 0.000331, + "perc95": 0.000353, + "perc99": 0.000427, + "perc999": 0.000757, + "perc9999": 0.001312, + }, + "update": { + "takes": 14.7, + "count": 24970, + "ops": 1701.4, + "avg": 0.000288, + "min": 0.000171, + "max": 0.002261, + "perc50": 0.000282, + "perc90": 0.000324, + "perc95": 0.000345, + "perc99": 0.000411, + "perc999": 0.000786, + "perc9999": 0.002151, + }, + "total": { + "takes": 14.7, + "count": 50000, + "ops": 3406.9, + "avg": 0.000291, + "min": 0.000171, + "max": 0.002407, + "perc50": 0.000285, + "perc90": 0.000328, + "perc95": 0.000349, + "perc99": 0.000421, + "perc999": 0.000777, + "perc9999": 0.001913, + }, } - assert.Equal(t, expectedRead, actual["read"].Values()) - expectedUpdate := map[string]float64{ - "takes": 14.7, - "count": 24970, - "ops": 1701.4, - "avg": 0.000288, - "min": 0.000171, - "max": 0.002261, - "perc50": 0.000282, - "perc90": 0.000324, - "perc95": 0.000345, - "perc99": 0.000411, - "perc999": 0.000786, - "perc9999": 0.002151, - } - assert.Equal(t, expectedUpdate, actual["update"].Values()) - - expectedTotal := map[string]float64{ - "takes": 14.7, - "count": 50000, - "ops": 3406.9, - "avg": 0.000291, - "min": 0.000171, - "max": 0.002407, - "perc50": 0.000285, - "perc90": 0.000328, - "perc95": 0.000349, - "perc99": 0.000421, - "perc999": 0.000777, - "perc9999": 0.001913, - } - assert.Equal(t, expectedTotal, actual["total"].Values()) + assert.Equal(t, expected, actual) } From 561d8bd3a05fc5b57da9b6ed7ce942ad4a390cbe Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Thu, 29 May 2025 15:08:40 +0900 Subject: [PATCH 31/32] comment --- internal/runner/mongobench/mongobench.go | 16 +++++++++------- internal/runner/mongobench/mongobench_test.go | 4 ++-- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go index 7bca4def6..541284edb 100644 --- a/internal/runner/mongobench/mongobench.go +++ b/internal/runner/mongobench/mongobench.go @@ -75,8 +75,10 @@ func parseFileNames(r io.Reader) ([]string, error) { return fileNames, nil } -// parseMeasurements reads the file and gets the last measurement and parses them. -func parseMeasurements(filepath string) (map[string]float64, error) { +// readResult reads the file and gets the last measurement and parses it. +// The file contains measurements taken each second while the benchmark was running, +// the last measurement is parsed and returned. +func readResult(filepath string) (map[string]float64, error) { f, err := os.Open(filepath) if err != nil { return nil, err @@ -176,7 +178,7 @@ func run(ctx context.Context, args []string, dir string) (map[string]config.Test for _, fileName := range fileNames { var m map[string]float64 - if m, err = parseMeasurements(filepath.Join("..", "projects", fileName)); err != nil { + if m, err = readResult(filepath.Join("..", "projects", fileName)); err != nil { return nil, err } @@ -191,7 +193,7 @@ func run(ctx context.Context, args []string, dir string) (map[string]config.Test } // Run implements [runner.Runner] interface. -func (y *mongoBench) Run(ctx context.Context) (map[string]config.TestResult, error) { +func (m *mongoBench) Run(ctx context.Context) (map[string]config.TestResult, error) { bin := filepath.Join("..", "bin", "mongodb-benchmarking") if _, err := os.Stat(bin); err != nil { return nil, err @@ -202,9 +204,9 @@ func (y *mongoBench) Run(ctx context.Context) (map[string]config.TestResult, err return nil, err } - args := append([]string{bin}, y.p.Args...) + args := append([]string{bin}, m.p.Args...) - y.l.InfoContext(ctx, "Run", slog.String("cmd", strings.Join(args, " "))) + m.l.InfoContext(ctx, "Run", slog.String("cmd", strings.Join(args, " "))) - return run(ctx, args, y.p.Dir) + return run(ctx, args, m.p.Dir) } diff --git a/internal/runner/mongobench/mongobench_test.go b/internal/runner/mongobench/mongobench_test.go index 379e8c265..ad81cd367 100644 --- a/internal/runner/mongobench/mongobench_test.go +++ b/internal/runner/mongobench/mongobench_test.go @@ -58,7 +58,7 @@ Benchmarking completed. Results saved to benchmark_results_upsert.csv assert.Equal(t, expected, actual) } -func TestParseMeasurements(t *testing.T) { +func TestReadResult(t *testing.T) { t.Parallel() results := `t,count,mean,m1_rate,m5_rate,m15_rate,mean_rate @@ -77,7 +77,7 @@ func TestParseMeasurements(t *testing.T) { _, err = f.Write([]byte(results)) require.NoError(t, err) - actual, err := parseMeasurements(f.Name()) + actual, err := readResult(f.Name()) require.NoError(t, err) expected := map[string]float64{ From 303fd37a245123b6ef92988a59ffdab2bcccf01c Mon Sep 17 00:00:00 2001 From: Chi Fujii Date: Fri, 30 May 2025 10:47:59 +0900 Subject: [PATCH 32/32] copilot --- internal/runner/mongobench/mongobench.go | 50 +++++++++++++----------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/internal/runner/mongobench/mongobench.go b/internal/runner/mongobench/mongobench.go index 541284edb..54d4de910 100644 --- a/internal/runner/mongobench/mongobench.go +++ b/internal/runner/mongobench/mongobench.go @@ -78,14 +78,17 @@ func parseFileNames(r io.Reader) ([]string, error) { // readResult reads the file and gets the last measurement and parses it. // The file contains measurements taken each second while the benchmark was running, // the last measurement is parsed and returned. -func readResult(filepath string) (map[string]float64, error) { - f, err := os.Open(filepath) - if err != nil { - return nil, err +func readResult(filePath string) (result map[string]float64, err error) { + var f *os.File + + if f, err = os.Open(filePath); err != nil { + return } defer func() { - err = f.Close() + if e := f.Close(); e != nil && err == nil { + err = e + } }() // cannot use [csv.NewReader] because the file does not contain valid CSV, @@ -104,7 +107,7 @@ func readResult(filepath string) (map[string]float64, error) { } if err = s.Err(); err != nil { - return nil, err + return } record := strings.Split(lastLine, ",") @@ -112,38 +115,37 @@ func readResult(filepath string) (map[string]float64, error) { return nil, errors.New("insufficient fields") } - count, err := strconv.ParseFloat(record[1], 64) - if err != nil { - return nil, err + var count, mean, m1Rate, m5Rate, m15Rate float64 + + if count, err = strconv.ParseFloat(record[1], 64); err != nil { + return } - mean, err := strconv.ParseFloat(record[2], 64) - if err != nil { - return nil, err + if mean, err = strconv.ParseFloat(record[2], 64); err != nil { + return } - m1Rate, err := strconv.ParseFloat(record[3], 64) - if err != nil { - return nil, err + if m1Rate, err = strconv.ParseFloat(record[3], 64); err != nil { + return } - m5Rate, err := strconv.ParseFloat(record[4], 64) - if err != nil { - return nil, err + if m5Rate, err = strconv.ParseFloat(record[4], 64); err != nil { + return } - m15Rate, err := strconv.ParseFloat(record[5], 64) - if err != nil { - return nil, err + if m15Rate, err = strconv.ParseFloat(record[5], 64); err != nil { + return } - return map[string]float64{ + result = map[string]float64{ "count": count, "mean": mean, "m1_rate": m1Rate, "m5_rate": m5Rate, "m15_rate": m15Rate, - }, nil + } + + return } // run runs given command in the given directory and returns parsed results. @@ -166,6 +168,8 @@ func run(ctx context.Context, args []string, dir string) (map[string]config.Test fileNames, err := parseFileNames(io.TeeReader(pipe, os.Stdout)) if err != nil { _ = cmd.Process.Kill() + _ = cmd.Wait() + return nil, err }