Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af79b46d17 | ||
|
|
e93c2664b8 | ||
|
|
bde047f2a3 |
@@ -22,6 +22,10 @@ https://git.eeqj.de/sneak/dnswatcher/issues/104
|
|||||||
|
|
||||||
- 2026-10-01: the image built by `make docker` reports the `git describe`
|
- 2026-10-01: the image built by `make docker` reports the `git describe`
|
||||||
version, not `dev`, and the startup log now shows it (closes #109).
|
version, not `dev`, and the startup log now shows it (closes #109).
|
||||||
|
- 2026-10-01: two notify shutdown tests always release the delivery they hold,
|
||||||
|
so a drain that returns early fails them instead of hanging (closes #176).
|
||||||
|
- 2026-10-01: `script/install-precommit` asks git for the repository's git
|
||||||
|
directory, so `make hooks` also works where `.git` is a file (closes #129).
|
||||||
- 2026-10-01: `TODO.md` brought up to date: open issues listed by URL, every
|
- 2026-10-01: `TODO.md` brought up to date: open issues listed by URL, every
|
||||||
Completed Steps entry cut to at most two lines (closes #146).
|
Completed Steps entry cut to at most two lines (closes #146).
|
||||||
- 2026-10-01: wildcard CORS now applies only to the public routes, not to
|
- 2026-10-01: wildcard CORS now applies only to the public routes, not to
|
||||||
@@ -102,12 +106,8 @@ https://git.eeqj.de/sneak/dnswatcher/issues/104
|
|||||||
- `goimports` in `make fmt-check`, Markdown formatting:
|
- `goimports` in `make fmt-check`, Markdown formatting:
|
||||||
https://git.eeqj.de/sneak/dnswatcher/issues/119
|
https://git.eeqj.de/sneak/dnswatcher/issues/119
|
||||||
- final state save at shutdown: https://git.eeqj.de/sneak/dnswatcher/issues/114
|
- final state save at shutdown: https://git.eeqj.de/sneak/dnswatcher/issues/114
|
||||||
- `internal/notify` shutdown tests hang when a drain returns early:
|
|
||||||
https://git.eeqj.de/sneak/dnswatcher/issues/176
|
|
||||||
- README accuracy sweep: https://git.eeqj.de/sneak/dnswatcher/issues/108
|
- README accuracy sweep: https://git.eeqj.de/sneak/dnswatcher/issues/108
|
||||||
- README sections required by policy:
|
- README sections required by policy:
|
||||||
https://git.eeqj.de/sneak/dnswatcher/issues/173
|
https://git.eeqj.de/sneak/dnswatcher/issues/173
|
||||||
- `script/install-precommit` in a linked worktree:
|
|
||||||
https://git.eeqj.de/sneak/dnswatcher/issues/129
|
|
||||||
- fixed root server order: https://git.eeqj.de/sneak/dnswatcher/issues/138
|
- fixed root server order: https://git.eeqj.de/sneak/dnswatcher/issues/138
|
||||||
- review toward 1.0: https://git.eeqj.de/sneak/dnswatcher/issues/144
|
- review toward 1.0: https://git.eeqj.de/sneak/dnswatcher/issues/144
|
||||||
|
|||||||
@@ -143,6 +143,12 @@ func TestDrainWaitsForInFlightDelivery(t *testing.T) {
|
|||||||
srv := blockingNtfyServer(entered, release, &served)
|
srv := blockingNtfyServer(entered, release, &served)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
|
// srv.Close waits for the handler, so release it however the
|
||||||
|
// test ends; otherwise a drain that returns early hangs the
|
||||||
|
// package instead of failing this test.
|
||||||
|
releaseHandler := sync.OnceFunc(func() { close(release) })
|
||||||
|
defer releaseHandler()
|
||||||
|
|
||||||
topicURL, _ := url.Parse(srv.URL)
|
topicURL, _ := url.Parse(srv.URL)
|
||||||
|
|
||||||
svc := notify.NewTestService(http.DefaultTransport)
|
svc := notify.NewTestService(http.DefaultTransport)
|
||||||
@@ -167,9 +173,7 @@ func TestDrainWaitsForInFlightDelivery(t *testing.T) {
|
|||||||
// delay alone.
|
// delay alone.
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
timer := time.AfterFunc(inFlightHold, func() {
|
timer := time.AfterFunc(inFlightHold, releaseHandler)
|
||||||
close(release)
|
|
||||||
})
|
|
||||||
defer timer.Stop()
|
defer timer.Stop()
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(
|
ctx, cancel := context.WithTimeout(
|
||||||
@@ -268,7 +272,7 @@ func TestDrainBoundedByContextDeadline(t *testing.T) {
|
|||||||
// all never returns here (the delivery is parked in a backoff
|
// all never returns here (the delivery is parked in a backoff
|
||||||
// that never fires), so an unbounded drain must fail this
|
// that never fires), so an unbounded drain must fail this
|
||||||
// test promptly instead of hanging the package until the test
|
// test promptly instead of hanging the package until the test
|
||||||
// binary's 30s timeout.
|
// binary's -timeout.
|
||||||
returned := make(chan struct{})
|
returned := make(chan struct{})
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@@ -447,6 +451,11 @@ func TestNewRegistersDrainingStopHook(t *testing.T) {
|
|||||||
srv := blockingNtfyServer(entered, release, &served)
|
srv := blockingNtfyServer(entered, release, &served)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
|
// As in TestDrainWaitsForInFlightDelivery: release the handler
|
||||||
|
// however the test ends, before srv.Close waits for it.
|
||||||
|
releaseHandler := sync.OnceFunc(func() { close(release) })
|
||||||
|
defer releaseHandler()
|
||||||
|
|
||||||
lifecycle := &recordingLifecycle{}
|
lifecycle := &recordingLifecycle{}
|
||||||
svc := newNotifyService(t, lifecycle, srv.URL)
|
svc := newNotifyService(t, lifecycle, srv.URL)
|
||||||
|
|
||||||
@@ -472,9 +481,7 @@ func TestNewRegistersDrainingStopHook(t *testing.T) {
|
|||||||
t.Fatal("delivery never reached the endpoint")
|
t.Fatal("delivery never reached the endpoint")
|
||||||
}
|
}
|
||||||
|
|
||||||
timer := time.AfterFunc(inFlightHold, func() {
|
timer := time.AfterFunc(inFlightHold, releaseHandler)
|
||||||
close(release)
|
|
||||||
})
|
|
||||||
defer timer.Stop()
|
defer timer.Stop()
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(
|
ctx, cancel := context.WithTimeout(
|
||||||
|
|||||||
@@ -7,7 +7,20 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
|||||||
|
|
||||||
main() {
|
main() {
|
||||||
cd "$ROOT"
|
cd "$ROOT"
|
||||||
hook=".git/hooks/pre-commit"
|
# Stop if this directory is not the top of its own git checkout, for
|
||||||
|
# example a copy inside another repository, whose hook must not be
|
||||||
|
# replaced.
|
||||||
|
if [ "$(git rev-parse --show-toplevel)" != "$ROOT" ]; then
|
||||||
|
echo "install-precommit: $ROOT is not the top of a git checkout" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# Ask git for the repository's own git directory: .git is a file, not
|
||||||
|
# a directory, in some checkouts (for example a clone made with
|
||||||
|
# --separate-git-dir). core.hooksPath is deliberately not followed, so
|
||||||
|
# the hook is never written outside this repository.
|
||||||
|
hooks="$(git rev-parse --git-common-dir)/hooks"
|
||||||
|
mkdir -p "$hooks"
|
||||||
|
hook="$hooks/pre-commit"
|
||||||
printf '#!/bin/sh\nset -e\nscript/precommit\n' > "$hook"
|
printf '#!/bin/sh\nset -e\nscript/precommit\n' > "$hook"
|
||||||
chmod +x "$hook"
|
chmod +x "$hook"
|
||||||
echo "pre-commit hook installed: runs script/precommit"
|
echo "pre-commit hook installed: runs script/precommit"
|
||||||
|
|||||||
Reference in New Issue
Block a user