package releasekit_test import ( "encoding/binary" "errors" "net/http" "net/http/httptest" "syscall" "testing" releasekit "gitea.maximumdirect.net/eric/ReleaseKit" ) func TestDeliverReadsLocalBinaryOnceForVerificationAndOnceForUpload(t *testing.T) { repository, build, expected := newDeliveryBenchmarkFixture(t) watcher, err := syscall.InotifyInit1(syscall.IN_NONBLOCK | syscall.IN_CLOEXEC) if err != nil { t.Fatal(err) } defer syscall.Close(watcher) // Close events separate successive opens so inotify cannot coalesce them. if _, err := syscall.InotifyAddWatch(watcher, build.Artifacts[0].Path, syscall.IN_OPEN|syscall.IN_CLOSE_NOWRITE); err != nil { t.Fatal(err) } state := &deliveryBenchmarkServer{commit: build.CandidateCommit, assets: expected} state.reset(false) server := httptest.NewServer(http.HandlerFunc(state.serveHTTP)) defer server.Close() state.baseURL = server.URL result, err := releasekit.Deliver(t.Context(), releasekit.DeliveryRequest{ RepositoryDir: repository, Product: "Sample App", Version: build.Version, Destination: facadeDeliveryDestination(server.URL), Prebuilt: &build, }) if err != nil || result.State != releasekit.DeliveryComplete || len(result.Uploaded) != len(expected) { t.Fatalf("delivery = %#v, error = %v", result, err) } state.verifyUploads(t) opens := 0 var events [256]byte for { n, err := syscall.Read(watcher, events[:]) if errors.Is(err, syscall.EAGAIN) { break } if errors.Is(err, syscall.EINTR) { continue } if err != nil { t.Fatal(err) } for offset := 0; offset < n; { mask := binary.NativeEndian.Uint32(events[offset+4:]) if mask&syscall.IN_Q_OVERFLOW != 0 { t.Fatal("artifact event queue overflowed") } if mask&syscall.IN_OPEN != 0 { opens++ } nameLength := binary.NativeEndian.Uint32(events[offset+12:]) offset += syscall.SizeofInotifyEvent + int(nameLength) } } if opens != 2 { t.Fatalf("local binary opened %d times; want one verification read and one upload read", opens) } }