locust 2.32.4.dev16__tar.gz → 2.32.4.dev18__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/PKG-INFO +1 -1
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/_version.py +2 -2
- locust-2.32.4.dev16/locust/webui/dist/assets/index-RwtjIXkg.js → locust-2.32.4.dev18/locust/webui/dist/assets/index-BjM9pW6b.js +1 -1
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/webui/dist/auth.html +1 -1
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/webui/dist/index.html +1 -1
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/pyproject.toml +1 -1
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/LICENSE +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/README.md +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/__init__.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/__main__.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/argument_parser.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/clients.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/contrib/__init__.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/contrib/fasthttp.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/contrib/mongodb.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/contrib/postgres.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/debug.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/dispatch.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/env.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/event.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/exception.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/html.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/input_events.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/log.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/main.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/py.typed +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/rpc/__init__.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/rpc/protocol.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/rpc/zmqrpc.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/runners.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/shape.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/stats.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/user/__init__.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/user/inspectuser.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/user/sequential_taskset.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/user/task.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/user/users.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/user/wait_time.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/util/__init__.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/util/cache.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/util/date.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/util/deprecation.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/util/directory.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/util/exception_handler.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/util/load_locustfile.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/util/rounding.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/util/timespan.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/util/url.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/web.py +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/webui/dist/assets/favicon-dark.png +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/webui/dist/assets/favicon-light.png +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/locust/webui/dist/report.html +0 -0
- {locust-2.32.4.dev16 → locust-2.32.4.dev18}/poetry.lock +0 -0
@@ -14,7 +14,7 @@ __version_tuple__: VERSION_TUPLE
|
|
14
14
|
version_tuple: VERSION_TUPLE
|
15
15
|
|
16
16
|
|
17
|
-
__version__ = "2.32.4.
|
17
|
+
__version__ = "2.32.4.dev18"
|
18
18
|
version = __version__
|
19
|
-
__version_tuple__ = (2, 32, 4, "
|
19
|
+
__version_tuple__ = (2, 32, 4, "dev18")
|
20
20
|
version_tuple = __version_tuple__
|
@@ -218,4 +218,4 @@ PERFORMANCE OF THIS SOFTWARE.
|
|
218
218
|
<span style="color:${f};">
|
219
219
|
${d}: ${ARe({chartValueFormatter:i,value:h})}
|
220
220
|
</span>
|
221
|
-
`,""):"No data",borderWidth:0},xAxis:{type:"time",min:(e.time||[new Date().toISOString()])[0],startValue:(e.time||[])[0],axisLabel:{formatter:TRe}},grid:{left:60,right:40},yAxis:CRe({splitAxis:a,yAxisLabels:o}),series:N7({charts:e,lines:r,scatterplot:s}),color:n,toolbox:{right:10,feature:{dataZoom:{title:{zoom:"Zoom Select",back:"Zoom Reset"},yAxisIndex:!1},saveAsImage:{name:t.replace(/\s+/g,"_").toLowerCase()+"_"+new Date().getTime()/1e3,title:"Download as PNG",emphasis:{iconStyle:{textPosition:"left"}}}}}}),kRe=e=>({symbol:"none",label:{formatter:t=>`Run #${t.dataIndex+1}`,padding:[0,0,8,0]},data:(e.markers||[]).map(t=>({xAxis:t}))}),IRe=e=>t=>{const{batch:r}=t;if(!r)return;const[{start:n,startValue:i,end:a}]=r,o=n>0&&a<=100||i>0;e.setOption({dataZoom:[{type:"slider",show:o}]})};function PRe({charts:e,title:t,lines:r,colors:n,chartValueFormatter:i,splitAxis:a,yAxisLabels:o,scatterplot:s,shouldReplaceMergeLines:l=!1}){const[u,c]=$.useState(null),f=Ii(({theme:{isDarkMode:h}})=>h),d=$.useRef(null);return $.useEffect(()=>{if(!d.current)return;const h=p1e(d.current);h.setOption(MRe({charts:e,title:t,lines:r,colors:n,chartValueFormatter:i,splitAxis:a,yAxisLabels:o,scatterplot:s})),h.on("datazoom",IRe(h));const v=()=>h.resize();return window.addEventListener("resize",v),h.group="swarmCharts",v1e("swarmCharts"),c(h),()=>{g1e(h),window.removeEventListener("resize",v)}},[d]),$.useEffect(()=>{const h=r.every(({key:v})=>!!e[v]);u&&h&&u.setOption({series:r.map(({key:v,yAxisIndex:g,...y},x)=>({...y,data:e[v],...a?{yAxisIndex:g||x}:{},...x===0?{markLine:kRe(e)}:{}}))})},[e,u,r]),$.useEffect(()=>{if(u){const{textColor:h,axisColor:v,backgroundColor:g,splitLine:y}=f?KF.DARK:KF.LIGHT;u.setOption({backgroundColor:g,textStyle:{color:h},title:{textStyle:{color:h}},legend:{icon:"circle",inactiveColor:h,textStyle:{color:h}},tooltip:{backgroundColor:g,textStyle:{color:h}},xAxis:{axisLine:{lineStyle:{color:v}}},yAxis:{axisLine:{lineStyle:{color:v}},splitLine:{lineStyle:{color:y}}}})}},[u,f]),$.useEffect(()=>{u&&u.setOption({series:N7({charts:e,lines:r,scatterplot:s})},l?{replaceMerge:["series"]}:void 0)},[r]),z.jsx("div",{ref:d,style:{width:"100%",height:"300px"}})}function DRe(){const{data:e,refetch:t}=kde(),r=qo(nv.setUi),n=Ii(({swarm:a})=>a.state),i=n===bn.SPAWNING||n==bn.RUNNING;$.useEffect(()=>{e&&r({ratios:e})},[e]),Ov(t,5e3,{shouldRunInterval:i,immediate:!0})}const JF=2e3;function RRe(){const e=qo(pk.setSwarm),t=qo(nv.setUi),r=qo(nv.updateCharts),n=qo(nv.updateChartMarkers),i=Ii(({swarm:d})=>d),a=$.useRef(i.state),[o,s]=$.useState(!1),{data:l,refetch:u}=Mde(),c=i.state===bn.SPAWNING||i.state==bn.RUNNING,f=()=>{if(!l)return;const{currentResponseTimePercentiles:d,extendedStats:h,stats:v,errors:g,totalRps:y,totalFailPerSec:x,failRatio:S,workers:b,userCount:w,totalAvgResponseTime:T}=l,C=new Date().toISOString();o&&(s(!1),n(C));const M=Rp(y,2),k=Rp(x,2),I=Rp(S*100),R={...Object.entries(d).reduce((L,[O,N])=>({...L,[O]:[C,N||0]}),{}),currentRps:[C,M],currentFailPerSec:[C,k],totalAvgResponseTime:[C,Rp(T,2)],userCount:[C,w],time:C};t({extendedStats:h,stats:v,errors:g,totalRps:M,failRatio:I,workers:b,userCount:w}),r(R)};$.useEffect(()=>{l&&e({state:l.state})},[l&&l.state]),Ov(f,JF,{shouldRunInterval:!!l&&c}),Ov(u,JF,{shouldRunInterval:c}),$.useEffect(()=>{i.state===bn.RUNNING&&a.current===bn.STOPPED&&s(!0),a.current=i.state},[i.state,a])}function ERe(){const{data:e,refetch:t}=Ide(),r=qo(nv.setUi),n=Ii(({swarm:a})=>a.state),i=n===bn.SPAWNING||n==bn.RUNNING;$.useEffect(()=>{e&&r({exceptions:e.exceptions})},[e]),Ov(t,5e3,{shouldRunInterval:i,immediate:!0})}function LRe(){return ERe(),z.jsx(vhe,{})}const ORe=[{key:"occurrences",title:"# Failures"},{key:"method",title:"Method"},{key:"name",title:"Name"},{key:"error",title:"Message",markdown:!0}];function NRe({errors:e}){return z.jsx(Tg,{rows:e,structure:ORe})}const zRe=({ui:{errors:e}})=>({errors:e}),BRe=ki(zRe)(NRe),FRe=e=>e.includes("CRITICAL")?Ks[900]:e.includes("ERROR")?Ks[700]:e.includes("WARNING")?HX[900]:e.includes("DEBUG")?_u[700]:"text.primary";function z7({log:e}){return z.jsx(zt,{color:FRe(e),fontFamily:"monospace",variant:"body2",children:e})}function VRe({workerId:e,logs:t}){const[r,n]=$.useState(!1);$.useEffect(()=>{t.slice(localStorage[e]).some(Y6)&&n(!0)},[t]);const i=$.useCallback(()=>{n(!1),localStorage[e]=t.length},[]);return z.jsxs(OM,{children:[z.jsxs(zM,{expandIcon:z.jsx(ck,{}),onClick:i,children:[r&&z.jsx(J6,{color:"secondary","data-testid":"worker-notification"}),e]}),z.jsx(NM,{children:z.jsx(Al,{elevation:3,sx:{p:2},children:t.map((a,o)=>z.jsx(z7,{log:a},`worker-${e}-log-${o}`))})})]})}function $Re(){const{master:e,workers:t}=Ii(({logViewer:r})=>r);return z.jsxs(ir,{sx:{display:"flex",flexDirection:"column",rowGap:4},children:[z.jsxs(ir,{children:[z.jsx(zt,{sx:{mb:2},variant:"h5",children:"Master Logs"}),z.jsx(Al,{elevation:3,sx:{p:2,fontFamily:"monospace"},children:e.map((r,n)=>z.jsx(z7,{log:r},`master-log-${n}`))})]}),!z6(t)&&z.jsxs(ir,{children:[z.jsx(zt,{sx:{mb:2},variant:"h5",children:"Worker Logs"}),Object.entries(t).map(([r,n],i)=>z.jsx(VRe,{logs:n,workerId:r},`worker-log-${i}`))]})]})}function GRe({extendedCsvFiles:e,statsHistoryEnabled:t}){const r=Ii(({theme:{isDarkMode:n}})=>n);return z.jsxs(N$,{sx:{display:"flex",flexDirection:"column"},children:[z.jsx(nf,{children:z.jsx(an,{href:"/stats/requests/csv",children:"Download requests CSV"})}),t&&z.jsx(nf,{children:z.jsx(an,{href:"/stats/requests_full_history/csv",children:"Download full request statistics history CSV"})}),z.jsx(nf,{children:z.jsx(an,{href:"/stats/failures/csv",children:"Download failures CSV"})}),z.jsx(nf,{children:z.jsx(an,{href:"/exceptions/csv",children:"Download exceptions CSV"})}),z.jsx(nf,{children:z.jsx(an,{href:`/stats/report?theme=${r?po.DARK:po.LIGHT}`,target:"_blank",children:"Download Report"})}),e&&e.map(({href:n,title:i},a)=>z.jsx(nf,{children:z.jsx(an,{href:n,children:i})},`extended-csv-${a}`))]})}const HRe=({swarm:{extendedCsvFiles:e,statsHistoryEnabled:t}})=>({extendedCsvFiles:e,statsHistoryEnabled:t}),WRe=ki(HRe)(GRe);var Mp={},eV;function jRe(){if(eV)return Mp;eV=1;var e=Sc();Object.defineProperty(Mp,"__esModule",{value:!0}),Mp.default=void 0;var t=e(bc()),r=Tl(),n=(0,t.default)((0,r.jsx)("path",{d:"M14.67 5v14H9.33V5h5.34zm1 14H21V5h-5.33v14zm-7.34 0V5H3v14h5.33z"}),"ViewColumn");return Mp.default=n,Mp}var URe=jRe();const YRe=ia(URe);function qRe({structure:e,selectedColumns:t,addColumn:r,removeColumn:n}){const[i,a]=$.useState(null);return z.jsxs(R$,{direction:"row",justifyContent:"end",my:2,spacing:1,children:[z.jsx(bo,{onClick:o=>a(o.currentTarget),variant:"outlined",children:z.jsx(YRe,{})}),z.jsx(V$,{anchorEl:i,anchorOrigin:{vertical:"bottom",horizontal:"left"},onClose:()=>a(null),open:!!i,children:z.jsx(L$,{sx:{p:2},children:e.map(({key:o,title:s})=>z.jsx(E$,{control:z.jsx(Fae,{checked:t.includes(o),onChange:()=>{t.includes(o)?n(o):r(o)}}),label:s},o))})})]})}function XRe(e){const[t,r]=$.useState(e.map(o=>o.key));return{selectedColumns:t,addColumn:o=>{r([...t,o])},removeColumn:o=>{r(t.filter(s=>s!==o))},filteredStructure:(o=>o.filter(s=>t.includes(s.key)))(e)}}const ZRe=vo.percentilesToStatistics?vo.percentilesToStatistics.map(e=>({title:`${e*100}%ile (ms)`,key:`responseTimePercentile${e}`})):[],KRe=[{key:"method",title:"Type"},{key:"name",title:"Name"},{key:"numRequests",title:"# Requests"},{key:"numFailures",title:"# Fails"},{key:"medianResponseTime",title:"Median (ms)",round:2},...ZRe,{key:"avgResponseTime",title:"Average (ms)",round:2},{key:"minResponseTime",title:"Min (ms)"},{key:"maxResponseTime",title:"Max (ms)"},{key:"avgContentLength",title:"Average size (bytes)",round:2},{key:"currentRps",title:"Current RPS",round:2},{key:"currentFailPerSec",title:"Current Failures/s",round:2}];function QRe({stats:e,tableStructure:t=KRe}){const{selectedColumns:r,addColumn:n,removeColumn:i,filteredStructure:a}=XRe(t);return z.jsxs(z.Fragment,{children:[z.jsx(qRe,{addColumn:n,removeColumn:i,selectedColumns:r,structure:t}),z.jsx(Tg,{hasTotalRow:!0,rows:e,structure:a})]})}const JRe=({ui:{stats:e}})=>({stats:e}),eEe=ki(JRe)(QRe),tEe=vo.percentilesToChart?vo.percentilesToChart.map(e=>({name:`${e*100}th percentile`,key:`responseTimePercentile${e}`})):[],rEe=["#ff9f00","#9966CC","#8A2BE2","#8E4585","#E0B0FF","#C8A2C8","#E6E6FA"],nEe=[{title:"Total Requests per Second",lines:[{name:"RPS",key:"currentRps"},{name:"Failures/s",key:"currentFailPerSec"}],colors:["#00ca5a","#ff6d6d"]},{title:"Response Times (ms)",lines:tEe,colors:rEe},{title:"Number of Users",lines:[{name:"Number of Users",key:"userCount"}],colors:["#0099ff"]}];function iEe({charts:e}){return z.jsx("div",{children:nEe.map((t,r)=>z.jsx(PRe,{...t,charts:e},`swarm-chart-${r}`))})}const aEe=({ui:{charts:e}})=>({charts:e}),oEe=ki(aEe)(iEe);function sEe(e){return(e*100).toFixed(1)+"%"}function rM({classRatio:e}){return z.jsx("ul",{children:Object.entries(e).map(([t,{ratio:r,tasks:n}])=>z.jsxs("li",{children:[`${sEe(r)} ${t}`,n&&z.jsx(rM,{classRatio:n})]},`nested-ratio-${t}`))})}function lEe({ratios:{perClass:e,total:t}}){return!e&&!t?null:z.jsxs("div",{children:[e&&z.jsxs(z.Fragment,{children:[z.jsx("h3",{children:"Ratio Per Class"}),z.jsx(rM,{classRatio:e})]}),t&&z.jsxs(z.Fragment,{children:[z.jsx("h3",{children:"Total Ratio"}),z.jsx(rM,{classRatio:t})]})]})}const uEe=({ui:{ratios:e}})=>({ratios:e}),cEe=ki(uEe)(lEe);function fEe(){return DRe(),z.jsx(cEe,{})}const dEe=[{key:"id",title:"Worker"},{key:"state",title:"State"},{key:"userCount",title:"# users"},{key:"cpuUsage",title:"CPU usage"},{key:"memoryUsage",title:"Memory usage",formatter:GX}];function hEe({workers:e=[]}){return z.jsx(Tg,{defaultSortKey:"id",rows:e,structure:dEe})}const pEe=({ui:{workers:e}})=>({workers:e}),vEe=ki(pEe)(hEe),qs={stats:{component:eEe,key:"stats",title:"Statistics"},charts:{component:oEe,key:"charts",title:"Charts"},failures:{component:BRe,key:"failures",title:"Failures"},exceptions:{component:LRe,key:"exceptions",title:"Exceptions"},ratios:{component:fEe,key:"ratios",title:"Current Ratio"},reports:{component:WRe,key:"reports",title:"Download Data"},logs:{component:$Re,key:q6,title:"Logs"},workers:{component:vEe,key:"workers",title:"Workers",shouldDisplayTab:e=>e.swarm.isDistributed}},gEe=[qs.stats,qs.charts,qs.failures,qs.exceptions,qs.ratios,qs.reports,qs.logs,qs.workers];function mEe({hasNotification:e,title:t}){return z.jsxs(ir,{sx:{display:"flex",alignItems:"center"},children:[e&&z.jsx(J6,{color:"secondary"}),z.jsx("span",{children:t})]})}function yEe({currentTabIndexFromQuery:e,notification:t,setNotification:r,setUrl:n,tabs:i}){const[a,o]=$.useState(e),s=(l,u)=>{const c=i[u].key;t[c]&&r({[c]:!1}),She({tab:c}),n({query:{tab:c}}),o(u)};return $.useEffect(()=>{o(e)},[e]),z.jsxs(bg,{maxWidth:"xl",children:[z.jsx(ir,{sx:{mb:2},children:z.jsx(Woe,{onChange:s,value:a,children:i.map(({key:l,title:u},c)=>z.jsx(Wae,{label:z.jsx(mEe,{hasNotification:t[l],title:u})},`tab-${c}`))})}),i.map(({component:l=fhe},u)=>a===u&&z.jsx(l,{},`tabpabel-${u}`))]})}const xEe=(e,{tabs:t,extendedTabs:r})=>{const{notification:n,swarm:{extendedTabs:i},url:{query:a}}=e,s=(t||[...gEe,...r||i||[]]).filter(({shouldDisplayTab:u})=>!u||u&&u(e)),l=a&&a.tab?s.findIndex(({key:u})=>u===a.tab):0;return{notification:n,tabs:s,currentTabIndexFromQuery:l>-1?l:0}},SEe={setNotification:Z6.setNotification,setUrl:whe.setUrl},bEe=ki(xEe,SEe)(yEe);function _Ee({swarmState:e,tabs:t,extendedTabs:r}){RRe(),nhe();const n=N6();return z.jsxs(c$,{theme:n,children:[z.jsx(P$,{}),z.jsx(Xde,{children:e===bn.READY?z.jsx(vk,{}):z.jsx(bEe,{extendedTabs:r,tabs:t})})]})}const wEe=({swarm:{state:e}})=>({swarmState:e}),CEe=ki(wEe)(_Ee);function TEe(){if(ME){const e=yV({reducer:hx({theme:L6})});return z.jsx(TE,{store:e,children:z.jsx(yfe,{...ME})})}else return z.jsx(TE,{store:Ahe,children:z.jsx(CEe,{})})}function AEe({error:e}){return z.jsxs("div",{role:"alert",children:[z.jsx("p",{children:"Something went wrong"}),e.message&&z.jsx("pre",{style:{color:"red"},children:e.message}),"If the issue persists, please consider opening an"," ",z.jsx("a",{href:"https://github.com/locustio/locust/issues/new?assignees=&labels=bug&projects=&template=bug.yml",children:"issue"})]})}const MEe=zY.createRoot(document.getElementById("root"));MEe.render(z.jsx(FY,{fallbackRender:AEe,children:z.jsx(TEe,{})}));
|
221
|
+
`,""):"No data",borderWidth:0},xAxis:{type:"time",min:(e.time||[new Date().toISOString()])[0],startValue:(e.time||[])[0],axisLabel:{formatter:TRe}},grid:{left:60,right:40},yAxis:CRe({splitAxis:a,yAxisLabels:o}),series:N7({charts:e,lines:r,scatterplot:s}),color:n,toolbox:{right:10,feature:{dataZoom:{title:{zoom:"Zoom Select",back:"Zoom Reset"},yAxisIndex:!1},saveAsImage:{name:t.replace(/\s+/g,"_").toLowerCase()+"_"+new Date().getTime()/1e3,title:"Download as PNG",emphasis:{iconStyle:{textPosition:"left"}}}}}}),kRe=e=>({symbol:"none",label:{formatter:t=>`Run #${t.dataIndex+1}`,padding:[0,0,8,0]},data:(e.markers||[]).map(t=>({xAxis:t}))}),IRe=e=>t=>{const{batch:r}=t;if(!r)return;const[{start:n,startValue:i,end:a}]=r,o=n>0&&a<=100||i>0;e.setOption({dataZoom:[{type:"slider",show:o}]})};function PRe({charts:e,title:t,lines:r,colors:n,chartValueFormatter:i,splitAxis:a,yAxisLabels:o,scatterplot:s,shouldReplaceMergeLines:l=!1}){const[u,c]=$.useState(null),f=Ii(({theme:{isDarkMode:h}})=>h),d=$.useRef(null);return $.useEffect(()=>{if(!d.current)return;const h=p1e(d.current);h.setOption(MRe({charts:e,title:t,lines:r,colors:n,chartValueFormatter:i,splitAxis:a,yAxisLabels:o,scatterplot:s})),h.on("datazoom",IRe(h));const v=()=>h.resize();return window.addEventListener("resize",v),h.group="swarmCharts",v1e("swarmCharts"),c(h),()=>{g1e(h),window.removeEventListener("resize",v)}},[d]),$.useEffect(()=>{const h=r.every(({key:v})=>!!e[v]);u&&h&&u.setOption({series:r.map(({key:v,yAxisIndex:g,...y},x)=>({...y,data:e[v],...a?{yAxisIndex:g||x}:{},...x===0?{markLine:kRe(e)}:{}}))})},[e,u,r]),$.useEffect(()=>{if(u){const{textColor:h,axisColor:v,backgroundColor:g,splitLine:y}=f?KF.DARK:KF.LIGHT;u.setOption({backgroundColor:g,textStyle:{color:h},title:{textStyle:{color:h}},legend:{icon:"circle",inactiveColor:h,textStyle:{color:h}},tooltip:{backgroundColor:g,textStyle:{color:h}},xAxis:{axisLine:{lineStyle:{color:v}}},yAxis:{axisLine:{lineStyle:{color:v}},splitLine:{lineStyle:{color:y}}}})}},[u,f]),$.useEffect(()=>{u&&u.setOption({series:N7({charts:e,lines:r,scatterplot:s})},l?{replaceMerge:["series"]}:void 0)},[r]),z.jsx("div",{ref:d,style:{width:"100%",height:"300px"}})}function DRe(){const{data:e,refetch:t}=kde(),r=qo(nv.setUi),n=Ii(({swarm:a})=>a.state),i=n===bn.SPAWNING||n==bn.RUNNING;$.useEffect(()=>{e&&r({ratios:e})},[e]),Ov(t,5e3,{shouldRunInterval:i,immediate:!0})}const JF=2e3;function RRe(){const e=qo(pk.setSwarm),t=qo(nv.setUi),r=qo(nv.updateCharts),n=qo(nv.updateChartMarkers),i=Ii(({swarm:d})=>d),a=$.useRef(i.state),[o,s]=$.useState(!1),{data:l,refetch:u}=Mde(),c=i.state===bn.SPAWNING||i.state==bn.RUNNING,f=()=>{if(!l)return;const{currentResponseTimePercentiles:d,extendedStats:h,stats:v,errors:g,totalRps:y,totalFailPerSec:x,failRatio:S,workers:b,userCount:w,totalAvgResponseTime:T}=l,C=new Date().toISOString();o&&(s(!1),n(C));const M=Rp(y,2),k=Rp(x,2),I=Rp(S*100),R={...Object.entries(d).reduce((L,[O,N])=>({...L,[O]:[C,N||0]}),{}),currentRps:[C,M],currentFailPerSec:[C,k],totalAvgResponseTime:[C,Rp(T,2)],userCount:[C,w],time:C};t({extendedStats:h,stats:v,errors:g,totalRps:M,failRatio:I,workers:b,userCount:w}),r(R)};$.useEffect(()=>{l&&e({state:l.state})},[l&&l.state]),Ov(f,JF,{shouldRunInterval:!!l&&c}),Ov(u,JF,{shouldRunInterval:c}),$.useEffect(()=>{i.state===bn.RUNNING&&a.current===bn.STOPPED&&s(!0),a.current=i.state},[i.state,a])}function ERe(){const{data:e,refetch:t}=Ide(),r=qo(nv.setUi),n=Ii(({swarm:a})=>a.state),i=n===bn.SPAWNING||n==bn.RUNNING;$.useEffect(()=>{e&&r({exceptions:e.exceptions})},[e]),Ov(t,5e3,{shouldRunInterval:i,immediate:!0})}function LRe(){return ERe(),z.jsx(vhe,{})}const ORe=[{key:"occurrences",title:"# Failures"},{key:"method",title:"Method"},{key:"name",title:"Name"},{key:"error",title:"Message",markdown:!0}];function NRe({errors:e}){return z.jsx(Tg,{rows:e,structure:ORe})}const zRe=({ui:{errors:e}})=>({errors:e}),BRe=ki(zRe)(NRe),FRe=e=>e.includes("CRITICAL")?Ks[900]:e.includes("ERROR")?Ks[700]:e.includes("WARNING")?HX[900]:e.includes("DEBUG")?_u[700]:"text.primary";function z7({log:e}){return z.jsx(zt,{color:FRe(e),fontFamily:"monospace",variant:"body2",children:e})}function VRe({workerId:e,logs:t}){const[r,n]=$.useState(!1);$.useEffect(()=>{t.slice(localStorage[e]).some(Y6)&&n(!0)},[t]);const i=$.useCallback(()=>{n(!1),localStorage[e]=t.length},[]);return z.jsxs(OM,{children:[z.jsxs(zM,{expandIcon:z.jsx(ck,{}),onClick:i,children:[r&&z.jsx(J6,{color:"secondary","data-testid":"worker-notification"}),e]}),z.jsx(NM,{children:z.jsx(Al,{elevation:3,sx:{p:2},children:t.map((a,o)=>z.jsx(z7,{log:a},`worker-${e}-log-${o}`))})})]})}function $Re(){const{master:e,workers:t}=Ii(({logViewer:r})=>r);return z.jsxs(ir,{sx:{display:"flex",flexDirection:"column",rowGap:4},children:[z.jsxs(ir,{children:[z.jsx(zt,{sx:{mb:2},variant:"h5",children:"Master Logs"}),z.jsx(Al,{elevation:3,sx:{p:2,fontFamily:"monospace"},children:e.map((r,n)=>z.jsx(z7,{log:r},`master-log-${n}`))})]}),!z6(t)&&z.jsxs(ir,{children:[z.jsx(zt,{sx:{mb:2},variant:"h5",children:"Worker Logs"}),Object.entries(t).map(([r,n],i)=>z.jsx(VRe,{logs:n,workerId:r},`worker-log-${i}`))]})]})}function GRe({extendedCsvFiles:e,statsHistoryEnabled:t}){const r=Ii(({theme:{isDarkMode:n}})=>n);return z.jsxs(N$,{sx:{display:"flex",flexDirection:"column"},children:[z.jsx(nf,{children:z.jsx(an,{href:"./stats/requests/csv",children:"Download requests CSV"})}),t&&z.jsx(nf,{children:z.jsx(an,{href:"./stats/requests_full_history/csv",children:"Download full request statistics history CSV"})}),z.jsx(nf,{children:z.jsx(an,{href:"./stats/failures/csv",children:"Download failures CSV"})}),z.jsx(nf,{children:z.jsx(an,{href:"./exceptions/csv",children:"Download exceptions CSV"})}),z.jsx(nf,{children:z.jsx(an,{href:`./stats/report?theme=${r?po.DARK:po.LIGHT}`,target:"_blank",children:"Download Report"})}),e&&e.map(({href:n,title:i},a)=>z.jsx(nf,{children:z.jsx(an,{href:n,children:i})},`extended-csv-${a}`))]})}const HRe=({swarm:{extendedCsvFiles:e,statsHistoryEnabled:t}})=>({extendedCsvFiles:e,statsHistoryEnabled:t}),WRe=ki(HRe)(GRe);var Mp={},eV;function jRe(){if(eV)return Mp;eV=1;var e=Sc();Object.defineProperty(Mp,"__esModule",{value:!0}),Mp.default=void 0;var t=e(bc()),r=Tl(),n=(0,t.default)((0,r.jsx)("path",{d:"M14.67 5v14H9.33V5h5.34zm1 14H21V5h-5.33v14zm-7.34 0V5H3v14h5.33z"}),"ViewColumn");return Mp.default=n,Mp}var URe=jRe();const YRe=ia(URe);function qRe({structure:e,selectedColumns:t,addColumn:r,removeColumn:n}){const[i,a]=$.useState(null);return z.jsxs(R$,{direction:"row",justifyContent:"end",my:2,spacing:1,children:[z.jsx(bo,{onClick:o=>a(o.currentTarget),variant:"outlined",children:z.jsx(YRe,{})}),z.jsx(V$,{anchorEl:i,anchorOrigin:{vertical:"bottom",horizontal:"left"},onClose:()=>a(null),open:!!i,children:z.jsx(L$,{sx:{p:2},children:e.map(({key:o,title:s})=>z.jsx(E$,{control:z.jsx(Fae,{checked:t.includes(o),onChange:()=>{t.includes(o)?n(o):r(o)}}),label:s},o))})})]})}function XRe(e){const[t,r]=$.useState(e.map(o=>o.key));return{selectedColumns:t,addColumn:o=>{r([...t,o])},removeColumn:o=>{r(t.filter(s=>s!==o))},filteredStructure:(o=>o.filter(s=>t.includes(s.key)))(e)}}const ZRe=vo.percentilesToStatistics?vo.percentilesToStatistics.map(e=>({title:`${e*100}%ile (ms)`,key:`responseTimePercentile${e}`})):[],KRe=[{key:"method",title:"Type"},{key:"name",title:"Name"},{key:"numRequests",title:"# Requests"},{key:"numFailures",title:"# Fails"},{key:"medianResponseTime",title:"Median (ms)",round:2},...ZRe,{key:"avgResponseTime",title:"Average (ms)",round:2},{key:"minResponseTime",title:"Min (ms)"},{key:"maxResponseTime",title:"Max (ms)"},{key:"avgContentLength",title:"Average size (bytes)",round:2},{key:"currentRps",title:"Current RPS",round:2},{key:"currentFailPerSec",title:"Current Failures/s",round:2}];function QRe({stats:e,tableStructure:t=KRe}){const{selectedColumns:r,addColumn:n,removeColumn:i,filteredStructure:a}=XRe(t);return z.jsxs(z.Fragment,{children:[z.jsx(qRe,{addColumn:n,removeColumn:i,selectedColumns:r,structure:t}),z.jsx(Tg,{hasTotalRow:!0,rows:e,structure:a})]})}const JRe=({ui:{stats:e}})=>({stats:e}),eEe=ki(JRe)(QRe),tEe=vo.percentilesToChart?vo.percentilesToChart.map(e=>({name:`${e*100}th percentile`,key:`responseTimePercentile${e}`})):[],rEe=["#ff9f00","#9966CC","#8A2BE2","#8E4585","#E0B0FF","#C8A2C8","#E6E6FA"],nEe=[{title:"Total Requests per Second",lines:[{name:"RPS",key:"currentRps"},{name:"Failures/s",key:"currentFailPerSec"}],colors:["#00ca5a","#ff6d6d"]},{title:"Response Times (ms)",lines:tEe,colors:rEe},{title:"Number of Users",lines:[{name:"Number of Users",key:"userCount"}],colors:["#0099ff"]}];function iEe({charts:e}){return z.jsx("div",{children:nEe.map((t,r)=>z.jsx(PRe,{...t,charts:e},`swarm-chart-${r}`))})}const aEe=({ui:{charts:e}})=>({charts:e}),oEe=ki(aEe)(iEe);function sEe(e){return(e*100).toFixed(1)+"%"}function rM({classRatio:e}){return z.jsx("ul",{children:Object.entries(e).map(([t,{ratio:r,tasks:n}])=>z.jsxs("li",{children:[`${sEe(r)} ${t}`,n&&z.jsx(rM,{classRatio:n})]},`nested-ratio-${t}`))})}function lEe({ratios:{perClass:e,total:t}}){return!e&&!t?null:z.jsxs("div",{children:[e&&z.jsxs(z.Fragment,{children:[z.jsx("h3",{children:"Ratio Per Class"}),z.jsx(rM,{classRatio:e})]}),t&&z.jsxs(z.Fragment,{children:[z.jsx("h3",{children:"Total Ratio"}),z.jsx(rM,{classRatio:t})]})]})}const uEe=({ui:{ratios:e}})=>({ratios:e}),cEe=ki(uEe)(lEe);function fEe(){return DRe(),z.jsx(cEe,{})}const dEe=[{key:"id",title:"Worker"},{key:"state",title:"State"},{key:"userCount",title:"# users"},{key:"cpuUsage",title:"CPU usage"},{key:"memoryUsage",title:"Memory usage",formatter:GX}];function hEe({workers:e=[]}){return z.jsx(Tg,{defaultSortKey:"id",rows:e,structure:dEe})}const pEe=({ui:{workers:e}})=>({workers:e}),vEe=ki(pEe)(hEe),qs={stats:{component:eEe,key:"stats",title:"Statistics"},charts:{component:oEe,key:"charts",title:"Charts"},failures:{component:BRe,key:"failures",title:"Failures"},exceptions:{component:LRe,key:"exceptions",title:"Exceptions"},ratios:{component:fEe,key:"ratios",title:"Current Ratio"},reports:{component:WRe,key:"reports",title:"Download Data"},logs:{component:$Re,key:q6,title:"Logs"},workers:{component:vEe,key:"workers",title:"Workers",shouldDisplayTab:e=>e.swarm.isDistributed}},gEe=[qs.stats,qs.charts,qs.failures,qs.exceptions,qs.ratios,qs.reports,qs.logs,qs.workers];function mEe({hasNotification:e,title:t}){return z.jsxs(ir,{sx:{display:"flex",alignItems:"center"},children:[e&&z.jsx(J6,{color:"secondary"}),z.jsx("span",{children:t})]})}function yEe({currentTabIndexFromQuery:e,notification:t,setNotification:r,setUrl:n,tabs:i}){const[a,o]=$.useState(e),s=(l,u)=>{const c=i[u].key;t[c]&&r({[c]:!1}),She({tab:c}),n({query:{tab:c}}),o(u)};return $.useEffect(()=>{o(e)},[e]),z.jsxs(bg,{maxWidth:"xl",children:[z.jsx(ir,{sx:{mb:2},children:z.jsx(Woe,{onChange:s,value:a,children:i.map(({key:l,title:u},c)=>z.jsx(Wae,{label:z.jsx(mEe,{hasNotification:t[l],title:u})},`tab-${c}`))})}),i.map(({component:l=fhe},u)=>a===u&&z.jsx(l,{},`tabpabel-${u}`))]})}const xEe=(e,{tabs:t,extendedTabs:r})=>{const{notification:n,swarm:{extendedTabs:i},url:{query:a}}=e,s=(t||[...gEe,...r||i||[]]).filter(({shouldDisplayTab:u})=>!u||u&&u(e)),l=a&&a.tab?s.findIndex(({key:u})=>u===a.tab):0;return{notification:n,tabs:s,currentTabIndexFromQuery:l>-1?l:0}},SEe={setNotification:Z6.setNotification,setUrl:whe.setUrl},bEe=ki(xEe,SEe)(yEe);function _Ee({swarmState:e,tabs:t,extendedTabs:r}){RRe(),nhe();const n=N6();return z.jsxs(c$,{theme:n,children:[z.jsx(P$,{}),z.jsx(Xde,{children:e===bn.READY?z.jsx(vk,{}):z.jsx(bEe,{extendedTabs:r,tabs:t})})]})}const wEe=({swarm:{state:e}})=>({swarmState:e}),CEe=ki(wEe)(_Ee);function TEe(){if(ME){const e=yV({reducer:hx({theme:L6})});return z.jsx(TE,{store:e,children:z.jsx(yfe,{...ME})})}else return z.jsx(TE,{store:Ahe,children:z.jsx(CEe,{})})}function AEe({error:e}){return z.jsxs("div",{role:"alert",children:[z.jsx("p",{children:"Something went wrong"}),e.message&&z.jsx("pre",{style:{color:"red"},children:e.message}),"If the issue persists, please consider opening an"," ",z.jsx("a",{href:"https://github.com/locustio/locust/issues/new?assignees=&labels=bug&projects=&template=bug.yml",children:"issue"})]})}const MEe=zY.createRoot(document.getElementById("root"));MEe.render(z.jsx(FY,{fallbackRender:AEe,children:z.jsx(TEe,{})}));
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<meta name="theme-color" content="#000000" />
|
9
9
|
|
10
10
|
<title>Locust</title>
|
11
|
-
<script type="module" crossorigin src="./assets/index-
|
11
|
+
<script type="module" crossorigin src="./assets/index-BjM9pW6b.js"></script>
|
12
12
|
</head>
|
13
13
|
<body>
|
14
14
|
<div id="root"></div>
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<meta name="theme-color" content="#000000" />
|
9
9
|
|
10
10
|
<title>Locust</title>
|
11
|
-
<script type="module" crossorigin src="./assets/index-
|
11
|
+
<script type="module" crossorigin src="./assets/index-BjM9pW6b.js"></script>
|
12
12
|
</head>
|
13
13
|
<body>
|
14
14
|
<div id="root"></div>
|
@@ -5,7 +5,7 @@ build-backend = "poetry_dynamic_versioning.backend"
|
|
5
5
|
[tool.poetry]
|
6
6
|
name = "locust"
|
7
7
|
description = "Developer-friendly load testing framework"
|
8
|
-
version = "2.32.4.
|
8
|
+
version = "2.32.4.dev18"
|
9
9
|
license = "MIT"
|
10
10
|
readme = "README.md"
|
11
11
|
authors = ["Jonatan Heyman", "Lars Holmberg"]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|