How do you test periodic jobs?

How do you properly test the behavior in a periodic job?

Let’s take some of my real code as an example:

func authorizationJanitor() {
	for {
		time.Sleep(5 * time.Minute)
		
		cullTime := time.Now().Add(-30 * time.Minute)

		PendingAuthLock.Lock()

		newPendingAuths := make([]PendingAuthorization, 0, len(PendingAuths))

		for _, v := range PendingAuths {
			if !cullTime.After(v.EnteredAt) {
				newPendingAuths = append(newPendingAuths, v)
			}
		}

		PendingAuths = newPendingAuths
		PendingAuthLock.Unlock()
	}
}

Okay, I can see what this is supposed to do. It’s a pretty small routine, not too hard to figure out.

But… how do I test it?
If I start the routine during the test, it’ll be trapped in the Sleep at the top for 5 minutes.

Of the top of my head it seems to be best to extract the time methods into an interface and ignore the sleep arguments in the test implementation.

Wait, wouldn’t that just make it spin in the method?

Better would be to be able to trigger one on-demand from the testing function.

Actually, I think I found something that works just fine:

func authorizationJanitor() {
	for {
		time.Sleep(5 * time.Minute)
		authorizationJanitor_do()
	}
}

func authorizationJanitor_do() {
	cullTime := time.Now().Add(-30 * time.Minute)

	PendingAuthLock.Lock()
	defer PendingAuthLock.Unlock()

	newPendingAuths := make([]PendingAuthorization, 0, len(PendingAuths))

	for _, v := range PendingAuths {
		if !cullTime.After(v.EnteredAt) {
			newPendingAuths = append(newPendingAuths, v)
		} else {
			v.Callback(v.Client, false)
		}
	}

	PendingAuths = newPendingAuths
}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.