about summary refs log tree commit homepage
path: root/t
DateCommit message (Collapse)
2024-04-15t/lib.perl: fix Perl integration tests w/o installation HEAD master
We can't rely on `ruby -I $PATH' args being passed to subprocesses, so rely on the RUBYLIB environment instead.
2024-03-31treewide: future-proof frozen_string_literal changes
Once again Ruby seems ready to introduce more incompatibilities and force busywork upon maintainers[1]. In order to avoid incompatibilities in the future, I used a Perl script[2] to prepend `frozen_string_literal: false' to every Ruby file. Somebody interested will have to go through every Ruby source file and enable frozen_string_literal once they've thoroughly verified it's safe to do so. [1] https://bugs.ruby-lang.org/issues/20205 [2] https://yhbt.net/add-fsl.git/74d7689/s/?b=add-fsl.perl
2024-03-31tests: port back-out-of-upgrade to Perl 5
Another place where we can be faster without adding more dependencies on Ruby maintaining stable behavior.
2024-03-31t/integration: disable proxies when running curl(1)
This was also done in t/test-lib.sh, but using '*' is more encompassing.
2024-01-15update dependency to Ruby 2.5+
We actually need Ruby 2.3+ for `accept_nonblock(exception: false)'; and (AFAIK) we can't easily use a subclass of `Socket' while using Socket#accept_nonblock to inject WriteSplat support for `IO#write(*multi_args)' So just depend on Ruby 2.5+ since all my Ruby is already on the already-ancient Ruby 2.7+ anyways.
2024-01-15kill off remaining kgio uses
kgio is an extra download and shared object which costs users bandwidth, disk space, startup time and memory. Ruby 2.3+ provides `Socket#accept_nonblock(exception: false)' support in addition to `exception: false' support in IO#*_nonblock methods from Ruby 2.1. We no longer distinguish between TCPServer and UNIXServer as separate classes internally; instead favoring the `Socket' class of Ruby for both. This allows us to use `Socket#accept_nonblock' and get a populated `Addrinfo' object off accept4(2)/accept(2) without resorting to a getpeername(2) syscall (kgio avoided getpeername(2) in the same way). The downside is there's more Ruby-level argument passing and stack usage on our end with HttpRequest#read_headers (formerly HttpRequest#read). I chose this tradeoff since advancements in Ruby itself can theoretically mitigate the cost of argument passing, while syscalls are a high fixed cost given modern CPU vulnerability mitigations. Note: no benchmarks have been run since I don't have a suitable system.
2023-09-10tests: fold early shutdown() tests into t/integration.t
This means fewer redundant tests and more chances to notice Ruby incompatibilities.
2023-09-10tests: move broken app test to Perl 5 integration test
Less Ruby means fewer incompatibilities to worry about with every new version.
2023-09-10tests: fold SO_KEEPALIVE check to Perl 5 integration
No need to startup more processes than necessary.
2023-09-10tests: use Time::HiRes `sleep' and `time' everywhere
The time(2) syscall use by CORE::time is inaccurate[1]. It's also easier to read `sleep 0.01' rather than the longer `select' equivalent. [1] a6463151bd1db5b9 (httpdate: favor gettimeofday(2) over time(2) for correctness, 2023-06-01)
2023-09-10tests: use more common variable names between tests
Stuff like $u_conf, $daemon_pid, $pid_file, etc. will reduce cognitive overhead.
2023-09-10tests: introduce `do_req' helper sub
While early tests required fine-grained control in trickling requests, many of our later tests can use a short one-liner w/o having to spawn curl.
2023-09-10tests: rewrite SIGWINCH && SIGTTIN test in Perl 5
No need to deal with full second sleeps, here.
2023-09-10tests: port reopen logs test over to Perl 5
Being able to do subsecond sleeps is one welcome advantage over POSIX (not GNU) sleep(1) in portable Bourne sh.
2023-09-10tests: port t/heartbeat-timeout to Perl 5
I absolutely detest and regret adding this feature, but I'm hell bent on supporting it until the end of days because we don't break compatibility.
2023-09-10tests: port working_directory tests to Perl 5
We can fold a bunch of them into one test to save startup time, inodes, and FS activity.
2023-09-10tests: port some bad config tests to Perl 5
We can fold some tests into one test to save on Perl startup time (but Ruby startup time is a lost cause).
2023-06-20t/active-unix-socket: sleep for init(8) to reap worker
Unfortunately, we need a sleep loop here since kill(2) succeeds on zombies and init(8) doesn't reap the worker soon enough on a FreeBSD VM.
2023-06-20t/lib.perl: FreeBSD: ignore accf_* messages
Testers may not have accf_http loaded nor the permissions to run `kldload accf_http', thus we must ignore these messages.
2023-06-05LISTEN_FDS-inherited sockets are immortal across SIGHUP
When using systemd-style socket activation, consider the inherited socket immortal and do not drop it on SIGHUP. This means configs w/o any `listen' directives at all can continue to work after SIGHUP. I only noticed this while writing some tests in Perl 5 and the test suite is two lines shorter to test this feature :>
2023-06-05tests: move test_upload.rb tests to t/integration.t
The overread tests are ported over, and checksumming alone is enough to guard against data corruption. Randomizing the size of `read' calls on the client side will shake out any boundary bugs on the server side.
2023-06-05t/integration.t: switch PUT tests to MD5, reuse buffers
MD5 is faster, and these tests aren't meant to be secure, they're just for checking for data corruption. Furthermore, Content-MD5 is a supported HTTP trailer and we can verify that here to obsolete other tests. Furthermore, we can reuse buffers on env['rack.input'].read calls to avoid malloc(3) and GC overhead. Combined, these give roughly a 3% speedup for t/integration.t on my system.
2023-06-05early_hints supports Rack 3 array headers
We can hoist out append_headers into a new method and use it in both e103_response_write and http_response_write. t/integration.t now tests early_hints with both possible values of check_client_connection.
2023-06-05tests: get rid of sha1sum.rb and rsha1() sh function
These are no longer needed since Perl has long included Digest::SHA
2023-06-05port t/t0116-client_body_buffer_size.sh to Perl 5
While I'm fine with depending on curl for certain things, there's no need for it here since unicorn has had lazy rack.input for over a decade, at this point.
2023-06-05port t9000-preread-input.sh to Perl 5
Stuffing it into t/integration.t for now so we can save on startup costs.
2023-06-05tests: consistent tcp_start and unix_start across Perl 5 tests
I'll be using Unix sockets more in tests since there's no risk of system-wide conflicts with TCP port allocation. Furthermore, curl supports `--unix-socket' nowadays; so there's little reason to rely on TCP sockets and the conflicts they bring in tests.
2023-06-05tests: check_stderr consistently in Perl 5 tests
The Bourne shell tests did, so lets not let stuff sneak past us.
2023-06-05port t0019-max_header_len.sh to Perl 5
This was the final socat requirement for integration tests. I think curl will remain an optional dependency for tests since it's probably the most widely-installed HTTP client.
2023-06-05tests: use autodie to simplify error checking
autodie is bundled with Perl 5.10+ and simplifies error checking in most cases. Some subroutines aren't perfectly translatable and their call sites had to be tweaked, but most of them are.
2023-06-05port t0100-rack-input-tests.sh to Perl 5
Yet another socat dependency gone \o/
2023-06-05port t0011-active-unix-socket.sh to Perl 5
Another socat dependency down... I've also started turning FD_CLOEXEC off on a pipe as a mechanism to detect daemonized process death in tests.
2023-06-05t/integration.t: use start_req to simplify test slighly
Less code is usually better.
2023-06-05port t0002-parser-error.sh to Perl 5
Another socat dependency down...
2023-06-05port t0000-http-basic.sh to Perl 5
One more socat dependency down...
2023-06-05port t0018-write-on-close.sh to Perl 5
This doesn't require restarting, so it's a perfect candidate.
2023-06-05support rack 3 multi-value headers
The first step in adding Rack 3 support. Rack supports multi-value headers via array rather than newlines. Tested-by: Martin Posthumus <martin.posthumus@gmail.com> Link: https://yhbt.net/unicorn-public/7c851d8a-bc57-7df8-3240-2f5ab831c47c@gmail.com/
2023-06-05switch unit/test_response.rb to Perl 5 integration test
http_response_write may benefit from API changes for Rack 3 support. Since there's no benefit I can see from using a unit test, switch to an integration test to avoid having to maintain the unit test if our internal http_response_write method changes. Of course, I can't trust tests written in Ruby since I've had to put up with a constant stream of incompatibilities over the past two decades :< Perl is more widely installed than socat[1], and nearly all the Perl I wrote 20 years ago still works unmodified today. [1] the rarest dependency of the Bourne shell integration tests
2023-06-05Support Rack 3 and fix tests on Rack 3
Most changes are to the tests to avoid uppercase characters in header keys, which are no longer allowed in rack 3 (to allow for O(1) access). This also changes a few places where an array of headers was used to switch to a hash, as a hash is requierd in Rack 3. Newer versions of curl use a 000 http_code for invalid http codes, so switch from "42 -eq" to "500 -ne" in the test, as Rack::Lint will always raise a 500 error. There is one test that fails on OpenBSD when opening a fifo. This is unrelated to unicorn as far as I can see, so skip the remaining part of the test in that case on OpenBSD. Tests still pass on Rack 2, and presumably Rack 1 as well, though I didn't test Rack 1. Co-authored-by: Eric Wong <bofh@yhbt.net>
2021-10-04use EPOLLEXCLUSIVE on Linux 4.5+
While the capabilities of epoll cannot be fully exploited given our primitive design; avoiding thundering herd wakeups on larger SMP machines while below 100% utilization is possible with Linux 4.5+. With this change, only one worker wakes up per-connect(2) (instead of all of them via select(2)), avoiding the thundering herd effect when the system is mostly idle. Saturated instances should not notice the difference if they rarely had multiple workers sleeping in select(2). This change benefits non-saturated instances. With 2 parallel clients and 8 workers on a nominally (:P) 8-core CPU (AMD FX-8320), the uconnect.perl test script invocation showed a reduction from ~3.4s to ~2.5s when reading an 11-byte response body: echo worker_processes 8 >u.conf.rb bs=11 ruby -I lib -I test/ruby-2.5.5/ext/unicorn_http/ bin/unicorn \ test/benchmark/dd.ru -E none -l /tmp/u.sock -c u.conf.rb time perl -I lib -w test/benchmark/uconnect.perl \ -n 100000 -c 2 /tmp/u.sock Times improve less as "-c" increases for uconnect.perl (system noise and timings are inconsistent). The benefit of this change should be more noticeable on systems with more workers (and more cores). I wanted to use EPOLLET (Edge-Triggered) to further reduce syscalls, here, (similar to the old select()-avoidance bet) but that would've either added too much complexity to deduplicate wakeup sources, or run into the same starvation problem we solved in April 2020[1]. Since the kernel already has the complexity and deduplication built-in for Level-Triggered epoll support, we'll just let the kernel deal with it. Note: do NOT take this as an example of how epoll should be used in a sophisticated server. unicorn is primitive by design and cannot use threads nor handle multiple clients at once, thus it it only uses epoll in this extremely limited manner. Linux 4.5+ users will notice a regression of one extra epoll FD per-worker and at least two epoll watches, so /proc/sys/fs/epoll/max_user_watches may need to be changed along with RLIMIT_NOFILE. This change has also been tested on Linux 3.10.x (CentOS 7.x) and FreeBSD 11.x to ensure compatibility with systems without EPOLLEXCLUSIVE. Various EPOLLEXCLUSIVE discussions over the years: https://yhbt.net/lore/lkml/?q=s:EPOLLEXCLUSIVE+d:..20211001&x=t&o=-1 [1] https://yhbt.net/unicorn-public/CAMBWrQ=Yh42MPtzJCEO7XryVknDNetRMuA87irWfqVuLdJmiBQ@mail.gmail.com/
2021-09-26drop Ruby 1.9.3 support, require 2.0+ for now
Ruby 1.9.3 was released nearly a decade ago, so there's probably few (if any) legacy users left, and they can continue using old versions of unicorn. We'll be able to take advantage of some Ruby 2.0+-only features down the road (and hopefully 2.3+). Also, I no longer have a installation of Ruby 1.8 and getting it working probably isn't worth the effort, so 4.x support is gone.
2021-03-13Allocate a new request for each client
This removes the reuse of the parser between requests. Reusing these is risky in the context of running any other threads within the unicorn process, also for threads that run background tasks. If any other thread accidentally grabs hold of the request it can modify things for the next request in flight. The downside here is that we allocate more for each request, but that is worth the trade off here and the security risk we otherwise would carry to leaking wrong and incorrect data.
2020-07-30build: revamp and avoid unnecessary rebuilds
We can limit the amount of Ruby-version-specific code to just the stuff in ext/* and bin/*, reducing I/O traffic and FS + page cache footprint. Furthermore, rely on GNU make behavior to copy all the necessary files so we don't trigger unnecessary extconf.rb invocations just by touching a .rb file in lib.
2018-10-18doc: update more URLs to use HTTPS and avoid redirects
Latency from redirects is painful, and HTTPS can protect privacy in some cases.
2018-09-18tests: ensure -N/--no-default-middleware not supported in config.ru
Continue to make it easy to migrate AWAY from unicorn because vendor lock-in is the worst thing, especially if it's on us.
2017-12-16avoid reusing env on hijack
Hijackers may capture and reuse `env' indefinitely, so we must not use it in those cases for future requests. For non-hijack requests, we continue to reuse the `env' object to reduce memory recycling. Reported-and-tested-by: Sam Saffron <sam.saffron@gmail.com>
2017-03-14test-lib: expr(1) portability fix
GNU expr supports '+' to match one or more occurrences, but it seems the expr(1) on my FreeBSD installation does not.
2017-03-01t0011-active-unix-socket.sh: fix race condition in test
Killing the master process may lead to the worker dying on its own (as designed); before kill(1) has had an opportunity to send the second kill(2) syscall on the worker process. Killing the worker before the master might also lead to a needless respawn, so merely kill the master and let the worker follow it in death. This race condition occasionally caused test failures on slow, uniprocessor hardware.
2017-02-21t/t0012-reload-empty-config.sh: access ivars directly if needed
We'll be moving to direct ivar access to reduce the API (and method entry) overhead of internal unicorn classes. This means some tests like this one will reach deeper into internals. This will be necessary for the upcoming changes to add new configuration options to unicorn.
2015-06-10ensure body is closed during hijack
Middlewares such as Rack::Lock (used by Rails) break badly unless the response body is closed on hijack, so we will close it to follow the lead of other popular Rack servers. While it's unclear if there's anybody using rack.hijack with unicorn, we'll try to emulate the behavior of other servers as much as possible. ref: https://github.com/ngauthier/tubesock/issues/10