Announcing Hurl 4.3.0
The Hurl team is thrilled to announce Hurl 4.3.0 !
Hurl is a command line tool powered by curl, that runs HTTP requests defined in a simple plain text format:
GET https://example.org/api/tests/4567
HTTP 200
[Asserts]
header "x-foo" contains "bar"
certificate "Expire-Date" daysAfterNow > 15
jsonpath "$.status" == "RUNNING" # Check the status code
jsonpath "$.tests" count == 25 # Check the number of items
jsonpath "$.id" matches /\d{4}/ # Check the format of the id
What’s New in This Release
Quality of Life Improvements
Hurl 4.3.0 is about bringing various quality of life improvements. Nothing fancy, but Hurl keeps iterating, improving and increasing usefulness on each new release.
Error display
Errors display have been slightly improved, with request line displayed to give context without having to look in the Hurl source file.
Before 4.3.0:
error: Undefined variable
--> tests_ok/post_file.hurl:6:8
|
6 | file,{{filename}};
| ^^^^^^^^ you must set the variable filename
|
With 4.3.0:
error: Undefined variable
--> tests_ok/post_file.hurl:6:8
|
| POST http://localhost:8000/post-file
| ...
6 | file,{{filename}};
| ^^^^^^^^ you must set the variable filename
|
--netrc, --netrc-file, --netrc-optional
Like its HTTP engine curl, Hurl supports now the classic .netrc
file (typically stored in a user’s home directory).
With --netrc
option, you can tells Hurl to look for and use the .netrc
file. --netrc-file
is similar to --netrc
, except that you can provide the path to the actual file to use.
$ hurl --test --netrc-file /home/foo/.netrc *.hurl
Per request --user
Let’s keep talking about curl options. Like curl, one can use the command line option --user
to add basic authentication to all the requests of a Hurl file:
$ hurl --user bob:secret login.hurl
--user
option can now be set per request, in an [Options]
section:
# Login with Bob is OK
POST http://foo.com/login
[Options]
user: bob:secret
location: true
HTTP 200
# Login with Alice is KO
POST http://foo.com/login
[Options]
user: alice:secret
location: true
HTTP 401
--user
is useful when using AWS Signature Version 4: Amazon S3 authenticated sessions can be set now per
request:
GET https://foo.execute-api.us-east-1.amazonas.com/dev/bafe12
[Options]
aws-sigv4: aws:amz:eu-central-1:foo
user: someAccessKeyId:someSecretKey
HTTP 200
And, last but not least, --user
option can use variables:
GET https://foo.execute-api.us-east-1.amazonas.com/dev/bafe12
[Options]
aws-sigv4: aws:amz:eu-central-1:foo
user: {{login}}:{{password}}
HTTP 200
Like many other Hurl option, --user
option can be used in the command line (take effect for all requests of a Hurl
file), or per request, with an [Options]
section:
GET https://example.org
# An options section, each option is optional and applied only to this request...
[Options]
aws-sigv4: aws:amz:sts # generate AWS SigV4 Authorization header
cacert: /etc/cert.pem # custom certificate file
compressed: true # request a compressed response
delay: 3000 # delay in ms for this request
http3: true # use HTTP/3 protocol version
insecure: true # allow insecure SSL connections and transfers
ipv6: true # use IPv6 addresses
location: true # follow redirection for this request
max-redirs: 10 # maximum number of redirections
output: out.html # dump the response to this file
path-as-is: true # do not handle sequences of /../ or /./ in URL path
skip: false # skip this request
unix-socket: sock # use Unix socket for transfer
user: bob:secret # use basic authentication
variable: country=Italy # define variable country
variable: planet=Earth # define variable planet
verbose: true # allow verbose output
very-verbose: true # allow more verbose output
The options documentation and the Hurl man page have been improved to show which option can be used only in command line
and which option can be used in command line and in an [Options]
section. When option can only be used in command line
the option is tagged “cli-only option”. For instance:
--color
Colorize debug output (the HTTP response output is not colorized).
This is a cli-only option.
When “cli-only option” is not specified, the option can be set per request within an [Options]
section.
--max-filesize
One last new option backported from curl, --max-filesize
allows to limit the size of HTTP response data (in bytes):
$ hurl --max-filesize 100000 https://example.com/
New Predicates: isNumber, isIsoDate
Predicates are used to check HTTP responses:
GET http://httpbin.org/json
HTTP 200
[Asserts]
jsonpath "$.slideshow.author" == "Yours Truly"
jsonpath "$.slideshow.slides[0].title" contains "Wonder"
jsonpath "$.slideshow.slides" count == 2
jsonpath "$.slideshow.date" != null
jsonpath "$.slideshow.slides[*].title" includes "Mind Blowing!"
Two new predicates are introduced with 4.3.0:
isNumber
: a companion toisInteger
/isFloat
existing predicates to test if a certain value is a numberisIsoDate
: check if a string value conforms to the RFC-3339 date formatYYYY-MM-DDTHH:mm:sssZ
GET http://httpbin.org/json
HTTP 200
[Asserts]
jsonpath "$.slideshow.version" isNumber
jsonpath "$.slideshow.date" isIsoDate
jsonpath "$.slideshow.date" == "1937-01-01T12:00:27.87+00:20"
Shell Completion
Hurl now offers shell completion scripts for various shell: bash, fish, zsh and PowerShell. Usually, packet managers package the completion scripts, but you can still install it yourself from Hurl’s GitHub repository.
One More Thing...
One last thing, and this is a pretty big thing (at least for us ) !
In Hurl 4.3.0, we’ve addressed one of our oldest issue, proposed in 2020: a --parallel
option!
It has been a long run since this issue, but we always kept in our mind that, at a moment, we want to be able to
run Hurl files in parallel. Now, with 4.3.0, we’re introducing an opt-in --parallel
option that will enable parallel
execution of Hurl files.
In Hurl 4.3.0, running files in test mode is (no change):
$ hurl --test *.hurl
With --parallel
, you can choose to run your tests in parallel:
$ hurl --test --parallel *.hurl
To develop this feature, we take a lot of inspiration of the venerable GNU Parallel.
In the parallel mode, each Hurl file is executed on its own thread, sharing nothing with other jobs. There is a thread
pool which size is roughly the current amount of CPUs and that can be configured with --jobs
option. During parallel execution, standard output and error are buffered for each file and only displayed on screen when a job file is finished. This way, debug logs and messages are never interleaved between execution. Order of execution is not guaranteed
in --parallel
mode but reports (HTML, TAP, JUnit) keep the input files order.
The parallelism used is multithread sync: the thread pool is instantiated for the whole run, each Hurl file is run in its own thread, synchronously. We’ve not gone through the full multithreaded async route for implementation simplicity. Moreover, there is no additional dependency, only the standard Rust lib with “classic” threads and multiple producers / single consumer channels to communicate between threads.
For the 4.3.0, we’ve marked the --parallel
option as “experimental” as we want to have feedbacks on it and insure that
everything works as designed. We plan to make this mode of execution the default when executing Hurl files with --test
in the Hurl 5.0.0 version.
Give it a try, if you think Hurl is fast, Oh Boy... Wait until you see the new parallel mode!
Others
There are a lot other improvements with Hurl 4.3.0 and also a lot of bug fixes, you can check the complete list of enhancements and bug fixes in our release note.
If you like Hurl, don’t hesitate to give us a star on GitHub or share it on Twitter!
We’ll be happy to hear from you, either for enhancement requests or for sharing your success story using Hurl!