Repository navigation
Goose 0.19.0
Summary
Goose 0.19 adds a live web dashboard that shows a load test while it runs and can steer it, and ships a rebuilt Goose Book that documents every option, report and Controller against what Goose actually prints. Writing that Book turned up dozens of defects in metrics, Controllers and option parsing, and 0.19 fixes them, so several numbers and refusals differ from 0.18.
Highlights
- Live dashboard:
--dashboardserves a browser view of a running load test, with graphs, request, scenario and transaction tables, a response time heatmap and coordinated omission figures;--dashboard-controladds start, stop and ramp controls. Live Dashboard - Thresholds:
--thresholdrules such asp95<500mspass or fail a run, and a failed rule makesexecute()return an error so the process exits nonzero. Thresholds - One folder per run: output flags given without a path write into a folder for the run, with notes, gzipped output for a
.gzname, and a report you can save from the dashboard. Output Files - Baselines and finer timing:
--baseline-filecompares a run with an earlier JSON report, times are kept in microseconds, and whole run figures that an audit found wrong are fixed. Metrics - New command line: Goose parses options with
clap, with a short-hand a long--helpthat explains each option's default and interactions, and--hatch-rateand--startup-timeare now--increase-rateand--increase-time, with new--decrease-rateand--decrease-time. Common Options - More to test: PDF reports, GraphQL requests, and load tests of TCP and other protocols that are not HTTP. Examples
Behavior and API changes
Every change a 0.18 load test may meet. The Book's Upgrading From 0.18 page walks through the ones most load tests need.
Options and the command line
--hatch-rate(-r) is now--increase-rateand--startup-time(-s) is now--increase-time;GooseDefault::HatchRateandStartupTimeare nowIncreaseRateandIncreaseTime, theGooseConfigurationfields are renamed to match, andutil::get_hatch_rate()is nowutil::parse_rate(). #687--iterationsis refused with--decrease-rateor--decrease-time. #781--no-autostartis refused when no Controller could bind its port and dashboard control is off. #778- A time span takes only
h,mands, in either case; values 0.18 misread, such as15minsor2h3min, are refused, andutil::parse_timespanreturnsNonefor them. #778 - Test plan steps take
h,mandsin either case. #779 --pdf-print-htmlcounts as a report for--notesand--no-granular-report, and is refused with--no-metrics. #778--scenariosaccepts_, soname_1selects a second scenario registered asname. #778--throttle-requests 0no longer refusesrpsthresholds. #778GooseConfigurationis parsed byclap:parse_args_defaultandparse_args_default_or_exitare inherent methods, so dropuse gumdrop::Options;, andparse(),try_parse()andtry_parse_from()work too. #760- Many
GooseConfigurationfields, among themhost,run_time,iterations, the log paths and the Controller hosts and ports, are nowOption,Nonewhen not given. #760 - The
helpfield is gone;parse_args_defaultreturnsGooseError::InvalidOptionfor-hand--help, and its errors never echo the rest of the command line. #760 pdf_scaleandpdf_timeoutareOption<f64>andOption<u64>, andGooseDefault::PdfScalesets the scale in code. #760- Help is split into a short
-hand a long--help, regrouped by task, printed to stdout and wrapped to the terminal. #760 - An option value that begins with a hyphen goes after
=, as in--goose-log=-run.log; a negative number is still read as a value. #760 - An output flag followed by another option is read as given without a path, so
--goose-log --quietwritesgoose.loginto the run's folder. #768 --dashboard-port 0binds a free port and reports it. #760--increase-rate,--decrease-rateand theirGooseDefaults are refused below one user a day. #752- A test plan with no users or too many to count, and a time span or step too large, is an error instead of a panic, including from
set_default(GooseDefault::TestPlan, ..). #752 --scenariosmatches names exactly instead of as substrings, and*is a wildcard. #655--accept-invalid-certsworks with every TLS backend; it was ignored unless therustls-tlsfeature was on. The default TLS backend is now rustls. #669
Metrics and reports
- With
--co-mitigation, the Aggregated# reqsis actual plus synthetic requests. #778 - Coordinated omission counts, and the errors and transaction errors tables, start again at the metrics reset after ramp up. #778, #779
- A run started by a Controller after another counts its requests from zero. #778
- The reports' Aggregated scenario Iterations matches the console: every run divided by every user. #778
- A scenario counts every user that ran it, not only those that completed an iteration. #778
- Averages with no measured times are 0, not NaN (
nullin JSON). #778 - Report averages are exact, so the JSON report carries them with more digits. #744
- The JSON report keeps its timing data in microseconds in
times_us, withminimum_time_us,maximum_time_usandtotal_time_us, in place of the millisecondtimes; minimums, maximums and percentiles stay whole milliseconds, and a 0.18.1 report still loads as a baseline. #767 - The telnet
metrics-jsonand WebSocketmetricsreplies carry the same microsecond timing data. #767 GooseRequestMetricTimingData'stimes,minimum_time,maximum_timeandtotal_timeare now_usfields in microseconds, withminimum_time_ms(),maximum_time_ms(),average_ms()andpercentile_us()to read them. #767TransactionMetricAggregateandScenarioMetricAggregatekeep their times inrun_times. #767StatusCodeTimingSummaryandStatusCodeBreakdowntimes are_usfields in microseconds. #767GooseRequestMetricgainsresponse_time_fraction_us, andTransactionMetricandScenarioMetricgainrun_time_fraction_us, so struct literals must set them. #767GooseMetric::Allholds its scenario in aBox. #767GooseMetricsgainstransaction_errors, andGooseMetricandGooseLoggain transaction error variants, so an exhaustivematchneeds new arms. #776- With the heatmap on, a run that writes a report keeps per second response time histograms, and a user's metrics batch may be sent early. #763
report.jsonand the Controller'smetrics-jsoninclude the test plan history. #768- A report or log named
.gzis written gzipped. #768 --report-filereports are written even with--no-print-metrics, and--no-granular-reportworks with--dashboard. #768- Metrics printed when a
--no-autostartrun returns to Idle respect--no-print-metrics. #768 - The HTML report's active users graph shows the increase ramp after the default metrics reset. #690
- The
metrics::deltaandmetrics::nullablemodules are private, soDeltaValue,Value,ApplyBaselineandNullableFloatare no longer public. #660
Thresholds and the killswitch
execute()returnsGooseError::ThresholdsFailedafter the reports are written when a threshold fails, so amainusing?exits nonzero. #773GooseMetricsgainsthresholds, and the newgoose::thresholdmodule holdsThresholdandThresholdResult. #773GooseConfigurationgainsthreshold,no_threshold_abortandthreshold_abort_delay, andGooseDefaultthe matching variants. #773- The killswitch keeps its first reason and is cleared when a run starts, and
reset_killswitch()is public. #768
Output folders
GooseConfigurationgainsoutput_dir,compress,notes,report_graph_dataandrender_report, andGooseDefaultthe matching variants. #768config::RUN_FOLDERis public and marks an output flag given without a path. #768- An autostarted
--dashboardrun that ends on its own with a client connected stays up until Quit, Ctrl-C orshutdown. #768
Controllers
- The WebSocket Controller is off by default;
--websocketturns it on. #782 - The telnet and WebSocket Controllers listen on
127.0.0.1by default instead of0.0.0.0, and warn when listening off loopback. #782 - A set dashboard auth token shows as
(set)in a Controller'sconfigand in{:?}ofGooseConfigurationorGooseUser. #782 usersrefuses 0 and anything above 100000. #729userson a running ramp keeps its run time and ramp down, and is refused while a test plan runs; a rate or time is refused while a test plan is configured. #761runtimeon a running ramp changes the current run;runtime 0holds until stopped. #762- A decrease rate on a running ramp takes effect at once. #761
- The command line's rules between options also apply to Controller commands, and out of range hosts, rates, times and test plans are refused. #761
increaserateanddecreaseratemust be at least one user a day; 0 and absurd values are refused. #752test-planmust start 1 to 100000 users and is refused while stopping and in Shutdown. #752- Refusals say what the value must be or why a Start was refused, instead of generic replies. #752
- A Start with no users to start is refused instead of hanging. #752
- Rates and times are stored as parsed, their units are not case sensitive, and a zero such as
0smeans unset. #752 - A stop, shutdown or Ctrl-C with no user running ends the load test. #752
- A WebSocket message over 131,072 bytes closes the connection with code 1009. #752
- The
configJSON has nohelpkey, lists keys in help order, and shows unset options asnull. #760 ControllerCommandcarries its parsed value, addsQuit, dropsHelpandExit, and derives onlyCloneandDebug;TestPlan::total_userssaturates, andGooseError::InvalidControllerCommandis no longer returned. #752- The
--no-autostarterror without a Controller or dashboard control has new wording. #690 - The dashboard's Target and step fields are read only, with the reason shown, when they cannot be changed. #761
- The dashboard no longer serves
/static/chart.min.js; Chart.js is bundled inapp.js. #732
Transactions, users and logs
Transaction::set_name()names only the transaction, not its requests; useset_name_for_transaction_and_requests()for the old behavior. #580- Transaction names are a
TransactionName,GooseRequestMetric.transaction_indexis ausize,TransactionDetailhas no lifetime, and request and scenario names areArc<str>. #580 Scenario,ScenarioMetric,TransactionMetricand their aggregates hold names asArc<str>instead ofString. #683- Session data types must implement
Clone. #656 TransactionError::RequestFailedandLoggerFailedbox their payloads. #691GooseUser.startedis one clock for every user, so logelapsedcounts from the start of the load test. #690GooseRawRequest.headersis empty unless the request, debug or error log is on. #692- Keys in a JSON log line follow the message's field order instead of being sorted. #772
PDF reports
- PDF reports use
CHROME, then an installed Chrome, Chromium or Edge, then a headless shell Goose downloads once. #755 - A
CHROMEthat does not exist or is not executable is an error, and a macOS app bundle resolves to its binary. #755 - With a
.pdfreport file, Goose checks that Chrome can render before any user starts. #755
Full changelog
Contributors
@jeremyandrews, @fabianx-ai, @alecsmrekar, @tstenner (first contribution), @ctron, @slashrsm, @aditanase (first contribution)