package selfupdate_test import ( "context" "errors" "sync" "testing" "time" "github.com/shcizo/package-updater/internal/discovery" "github.com/shcizo/package-updater/internal/selfupdate" "github.com/stretchr/testify/require" ) type recExec struct { mu sync.Mutex called bool at time.Time } func (r *recExec) Execute(_ context.Context, _ discovery.Job) error { r.mu.Lock() r.called = true r.at = time.Now() r.mu.Unlock() return nil } func TestIsSelf(t *testing.T) { require.True(t, selfupdate.IsSelf( discovery.Job{Project: "package-updater", Service: "package-updater"}, "package-updater", )) require.False(t, selfupdate.IsSelf( discovery.Job{Project: "other", Service: "web"}, "package-updater", )) } func TestWrap_DefersSelf(t *testing.T) { inner := &recExec{} wrapped := selfupdate.Wrap(inner, "package-updater", 30*time.Millisecond) flushed := make(chan time.Time, 1) flush := func() { flushed <- time.Now() } job := discovery.Job{Project: "package-updater", Service: "package-updater"} require.NoError(t, wrapped.ExecuteWithFlush(context.Background(), job, flush)) flushAt := <-flushed inner.mu.Lock() require.True(t, inner.called) require.True(t, inner.at.After(flushAt)) inner.mu.Unlock() } func TestWrap_NormalJobIsImmediate(t *testing.T) { inner := &recExec{} wrapped := selfupdate.Wrap(inner, "package-updater", 30*time.Millisecond) flushed := make(chan time.Time, 1) flush := func() { flushed <- time.Now() } job := discovery.Job{Project: "other", Service: "web"} require.NoError(t, wrapped.ExecuteWithFlush(context.Background(), job, flush)) inner.mu.Lock() require.True(t, inner.called) inner.mu.Unlock() select { case <-flushed: t.Fatal("flush should not be called for non-self jobs") default: } } func TestWrap_PropagatesError(t *testing.T) { wrapped := selfupdate.Wrap(failExec{}, "x", 1*time.Millisecond) err := wrapped.ExecuteWithFlush(context.Background(), discovery.Job{Project: "other"}, func() {}) require.Error(t, err) } type failExec struct{} func (failExec) Execute(_ context.Context, _ discovery.Job) error { return errors.New("boom") }