<commit_before>package job_test

import (
	"context"
	"testing"
	"time"

	jobs "github.com/cozy/cozy-stack/model/job"
	"github.com/cozy/cozy-stack/pkg/couchdb"
	"github.com/cozy/cozy-stack/pkg/realtime"
	"github.com/stretchr/testify/assert"
)

func TestTriggersBadArguments(t *testing.T) {
	var err error
	_, err = jobs.NewTrigger(testInstance, jobs.TriggerInfos{
		Type:      "@at",
		Arguments: "garbage",
	}, nil)
	assert.Error(t, err)

	_, err = jobs.NewTrigger(testInstance, jobs.TriggerInfos{
		Type:      "@in",
		Arguments: "garbage",
	}, nil)
	assert.Error(t, err)

	_, err = jobs.NewTrigger(testInstance, jobs.TriggerInfos{
		Type:      "@unknown",
		Arguments: "",
	}, nil)
	if assert.Error(t, err) {
		assert.Equal(t, jobs.ErrUnknownTrigger, err)
	}
}

func TestMemSchedulerWithDebounce(t *testing.T) {
	called := 0
	bro := jobs.NewMemBroker()
	assert.NoError(t, bro.StartWorkers(jobs.WorkersList{
		{
			WorkerType:   "worker",
			Concurrency:  1,
			MaxExecCount: 1,
			Timeout:      1 * time.Millisecond,
			WorkerFunc: func(ctx *jobs.WorkerContext) error {
				called++
				return nil
			},
		},
	}))

	msg, _ := jobs.NewMessage("@event")
	ti := jobs.TriggerInfos{
		Type:       "@event",
		Arguments:  "io.cozy.testdebounce io.cozy.moredebounce",
		Debounce:   "2s",
		WorkerType: "worker",
		Message:    msg,
	}

	var triggers []jobs.Trigger
	triggersInfos := []jobs.TriggerInfos{ti}
	sch := jobs.NewMemScheduler()
	assert.NoError(t, sch.StartScheduler(bro))

	// Clear the existing triggers before testing with our triggers
	ts, err := sch.GetAllTriggers(testInstance)
	assert.NoError(t, err)
	for _, trigger := range ts {
		err = sch.DeleteTrigger(testInstance, trigger.ID())
		assert.NoError(t, err)
	}

	for _, infos := range triggersInfos {
		trigger, err := jobs.NewTrigger(testInstance, infos, msg)
		if !assert.NoError(t, err) {
			return
		}
		err = sch.AddTrigger(trigger)
		if !assert.NoError(t, err) {
			return
		}
		triggers = append(triggers, trigger)
	}

	ts, err = sch.GetAllTriggers(testInstance)
	assert.NoError(t, err)
	assert.Len(t, ts, len(triggers))

	doc := couchdb.JSONDoc{
		Type: "io.cozy.testdebounce",
		M: map[string]interface{}{
			"_id":  "test-id",
			"_rev": "1-xxabxx",
			"test": "value",
		},
	}

	for i := 0; i < 24; i++ {
		time.Sleep(200 * time.Millisecond)
		realtime.GetHub().Publish(testInstance, realtime.EventCreate, &doc, nil)
	}

	time.Sleep(3000 * time.Millisecond)
	assert.Equal(t, 3, called)

	realtime.GetHub().Publish(testInstance, realtime.EventCreate, &doc, nil)
	doc.Type = "io.cozy.moredebounce"
	realtime.GetHub().Publish(testInstance, realtime.EventCreate, &doc, nil)
	time.Sleep(3000 * time.Millisecond)
	assert.Equal(t, 4, called)

	for _, trigger := range triggers {
		err = sch.DeleteTrigger(testInstance, trigger.ID())
		assert.NoError(t, err)
	}

	err = sch.ShutdownScheduler(context.Background())
	assert.NoError(t, err)
}<commit_msg>Try to debug the flaking TestMemSchedulerWithDebounce<commit_after>package job_test

import (
	"context"
	"fmt"
	"testing"
	"time"

	jobs "github.com/cozy/cozy-stack/model/job"
	"github.com/cozy/cozy-stack/pkg/couchdb"
	"github.com/cozy/cozy-stack/pkg/realtime"
	"github.com/stretchr/testify/assert"
)

func TestTriggersBadArguments(t *testing.T) {
	var err error
	_, err = jobs.NewTrigger(testInstance, jobs.TriggerInfos{
		Type:      "@at",
		Arguments: "garbage",
	}, nil)
	assert.Error(t, err)

	_, err = jobs.NewTrigger(testInstance, jobs.TriggerInfos{
		Type:      "@in",
		Arguments: "garbage",
	}, nil)
	assert.Error(t, err)

	_, err = jobs.NewTrigger(testInstance, jobs.TriggerInfos{
		Type:      "@unknown",
		Arguments: "",
	}, nil)
	if assert.Error(t, err) {
		assert.Equal(t, jobs.ErrUnknownTrigger, err)
	}
}

func TestMemSchedulerWithDebounce(t *testing.T) {
	called := 0
	bro := jobs.NewMemBroker()
	assert.NoError(t, bro.StartWorkers(jobs.WorkersList{
		{
			WorkerType:   "worker",
			Concurrency:  1,
			MaxExecCount: 1,
			Timeout:      1 * time.Millisecond,
			WorkerFunc: func(ctx *jobs.WorkerContext) error {
				called++
				return nil
			},
		},
	}))

	msg, _ := jobs.NewMessage("@event")
	ti := jobs.TriggerInfos{
		Type:       "@event",
		Arguments:  "io.cozy.testdebounce io.cozy.moredebounce",
		Debounce:   "2s",
		WorkerType: "worker",
		Message:    msg,
	}

	var triggers []jobs.Trigger
	triggersInfos := []jobs.TriggerInfos{ti}
	sch := jobs.NewMemScheduler()
	if !assert.NoError(t, sch.StartScheduler(bro)) {
		fmt.Printf("err = %v\n", sch.StartScheduler(bro))
		fmt.Printf("err = %v\n", sch.StartScheduler(bro))
		return
	}

	// Clear the existing triggers before testing with our triggers
	ts, err := sch.GetAllTriggers(testInstance)
	assert.NoError(t, err)
	for _, trigger := range ts {
		err = sch.DeleteTrigger(testInstance, trigger.ID())
		assert.NoError(t, err)
	}

	for _, infos := range triggersInfos {
		trigger, err := jobs.NewTrigger(testInstance, infos, msg)
		if !assert.NoError(t, err) {
			return
		}
		err = sch.AddTrigger(trigger)
		if !assert.NoError(t, err) {
			return
		}
		triggers = append(triggers, trigger)
	}

	ts, err = sch.GetAllTriggers(testInstance)
	assert.NoError(t, err)
	assert.Len(t, ts, len(triggers))

	doc := couchdb.JSONDoc{
		Type: "io.cozy.testdebounce",
		M: map[string]interface{}{
			"_id":  "test-id",
			"_rev": "1-xxabxx",
			"test": "value",
		},
	}

	for i := 0; i < 24; i++ {
		time.Sleep(200 * time.Millisecond)
		realtime.GetHub().Publish(testInstance, realtime.EventCreate, &doc, nil)
	}

	time.Sleep(3000 * time.Millisecond)
	assert.Equal(t, 3, called)

	doc2 := doc.Clone().(couchdb.JSONDoc)
	doc2.Type = "io.cozy.moredebounce"
	realtime.GetHub().Publish(testInstance, realtime.EventCreate, &doc, nil)
	realtime.GetHub().Publish(testInstance, realtime.EventCreate, &doc2, nil)
	time.Sleep(3000 * time.Millisecond)
	assert.Equal(t, 4, called)

	for _, trigger := range triggers {
		err = sch.DeleteTrigger(testInstance, trigger.ID())
		assert.NoError(t, err)
	}

	err = sch.ShutdownScheduler(context.Background())
	assert.NoError(t, err)
}
{'fraction_non_alphanumeric': 0.1555261416280609, 'fraction_numerical': 0.0077763070814030446, 'mean_word_length': 4.029118136439268, 'pattern_counts': {'":': 6, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5372547', 'n_tokens_mistral': 2486, 'n_tokens_neox': 2283, 'n_words': 434}