mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2026-01-15 09:11:45 +01:00
275 lines
5.9 KiB
Go
275 lines
5.9 KiB
Go
// Copyright (C) NHR@FAU, University Erlangen-Nuremberg.
|
|
// All rights reserved. This file is part of cc-backend.
|
|
// Use of this source code is governed by a MIT-style
|
|
// license that can be found in the LICENSE file.
|
|
package repository
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/ClusterCockpit/cc-lib/v2/schema"
|
|
_ "github.com/mattn/go-sqlite3"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type MockJobHook struct {
|
|
startCalled bool
|
|
stopCalled bool
|
|
startJobs []*schema.Job
|
|
stopJobs []*schema.Job
|
|
}
|
|
|
|
func (m *MockJobHook) JobStartCallback(job *schema.Job) {
|
|
m.startCalled = true
|
|
m.startJobs = append(m.startJobs, job)
|
|
}
|
|
|
|
func (m *MockJobHook) JobStopCallback(job *schema.Job) {
|
|
m.stopCalled = true
|
|
m.stopJobs = append(m.stopJobs, job)
|
|
}
|
|
|
|
func TestRegisterJobHook(t *testing.T) {
|
|
t.Run("register single hook", func(t *testing.T) {
|
|
hooks = nil
|
|
mock := &MockJobHook{}
|
|
|
|
RegisterJobHook(mock)
|
|
|
|
assert.NotNil(t, hooks)
|
|
assert.Len(t, hooks, 1)
|
|
assert.Equal(t, mock, hooks[0])
|
|
|
|
hooks = nil
|
|
})
|
|
|
|
t.Run("register multiple hooks", func(t *testing.T) {
|
|
hooks = nil
|
|
mock1 := &MockJobHook{}
|
|
mock2 := &MockJobHook{}
|
|
|
|
RegisterJobHook(mock1)
|
|
RegisterJobHook(mock2)
|
|
|
|
assert.Len(t, hooks, 2)
|
|
assert.Equal(t, mock1, hooks[0])
|
|
assert.Equal(t, mock2, hooks[1])
|
|
|
|
hooks = nil
|
|
})
|
|
|
|
t.Run("register nil hook does not add to hooks", func(t *testing.T) {
|
|
hooks = nil
|
|
RegisterJobHook(nil)
|
|
|
|
if hooks != nil {
|
|
assert.Len(t, hooks, 0, "Nil hook should not be added")
|
|
}
|
|
|
|
hooks = nil
|
|
})
|
|
}
|
|
|
|
func TestCallJobStartHooks(t *testing.T) {
|
|
t.Run("call start hooks with single job", func(t *testing.T) {
|
|
hooks = nil
|
|
mock := &MockJobHook{}
|
|
RegisterJobHook(mock)
|
|
|
|
job := &schema.Job{
|
|
JobID: 123,
|
|
User: "testuser",
|
|
Cluster: "testcluster",
|
|
}
|
|
|
|
CallJobStartHooks([]*schema.Job{job})
|
|
|
|
assert.True(t, mock.startCalled)
|
|
assert.False(t, mock.stopCalled)
|
|
assert.Len(t, mock.startJobs, 1)
|
|
assert.Equal(t, int64(123), mock.startJobs[0].JobID)
|
|
|
|
hooks = nil
|
|
})
|
|
|
|
t.Run("call start hooks with multiple jobs", func(t *testing.T) {
|
|
hooks = nil
|
|
mock := &MockJobHook{}
|
|
RegisterJobHook(mock)
|
|
|
|
jobs := []*schema.Job{
|
|
{JobID: 1, User: "user1", Cluster: "cluster1"},
|
|
{JobID: 2, User: "user2", Cluster: "cluster2"},
|
|
{JobID: 3, User: "user3", Cluster: "cluster3"},
|
|
}
|
|
|
|
CallJobStartHooks(jobs)
|
|
|
|
assert.True(t, mock.startCalled)
|
|
assert.Len(t, mock.startJobs, 3)
|
|
assert.Equal(t, int64(1), mock.startJobs[0].JobID)
|
|
assert.Equal(t, int64(2), mock.startJobs[1].JobID)
|
|
assert.Equal(t, int64(3), mock.startJobs[2].JobID)
|
|
|
|
hooks = nil
|
|
})
|
|
|
|
t.Run("call start hooks with multiple registered hooks", func(t *testing.T) {
|
|
hooks = nil
|
|
mock1 := &MockJobHook{}
|
|
mock2 := &MockJobHook{}
|
|
RegisterJobHook(mock1)
|
|
RegisterJobHook(mock2)
|
|
|
|
job := &schema.Job{
|
|
JobID: 456, User: "testuser", Cluster: "testcluster",
|
|
}
|
|
|
|
CallJobStartHooks([]*schema.Job{job})
|
|
|
|
assert.True(t, mock1.startCalled)
|
|
assert.True(t, mock2.startCalled)
|
|
assert.Len(t, mock1.startJobs, 1)
|
|
assert.Len(t, mock2.startJobs, 1)
|
|
|
|
hooks = nil
|
|
})
|
|
|
|
t.Run("call start hooks with nil hooks", func(t *testing.T) {
|
|
hooks = nil
|
|
|
|
job := &schema.Job{
|
|
JobID: 789, User: "testuser", Cluster: "testcluster",
|
|
}
|
|
|
|
CallJobStartHooks([]*schema.Job{job})
|
|
|
|
hooks = nil
|
|
})
|
|
|
|
t.Run("call start hooks with empty job list", func(t *testing.T) {
|
|
hooks = nil
|
|
mock := &MockJobHook{}
|
|
RegisterJobHook(mock)
|
|
|
|
CallJobStartHooks([]*schema.Job{})
|
|
|
|
assert.False(t, mock.startCalled)
|
|
assert.Len(t, mock.startJobs, 0)
|
|
|
|
hooks = nil
|
|
})
|
|
}
|
|
|
|
func TestCallJobStopHooks(t *testing.T) {
|
|
t.Run("call stop hooks with single job", func(t *testing.T) {
|
|
hooks = nil
|
|
mock := &MockJobHook{}
|
|
RegisterJobHook(mock)
|
|
|
|
job := &schema.Job{
|
|
JobID: 123,
|
|
User: "testuser",
|
|
Cluster: "testcluster",
|
|
}
|
|
|
|
CallJobStopHooks(job)
|
|
|
|
assert.True(t, mock.stopCalled)
|
|
assert.False(t, mock.startCalled)
|
|
assert.Len(t, mock.stopJobs, 1)
|
|
assert.Equal(t, int64(123), mock.stopJobs[0].JobID)
|
|
|
|
hooks = nil
|
|
})
|
|
|
|
t.Run("call stop hooks with multiple registered hooks", func(t *testing.T) {
|
|
hooks = nil
|
|
mock1 := &MockJobHook{}
|
|
mock2 := &MockJobHook{}
|
|
RegisterJobHook(mock1)
|
|
RegisterJobHook(mock2)
|
|
|
|
job := &schema.Job{
|
|
JobID: 456, User: "testuser", Cluster: "testcluster",
|
|
}
|
|
|
|
CallJobStopHooks(job)
|
|
|
|
assert.True(t, mock1.stopCalled)
|
|
assert.True(t, mock2.stopCalled)
|
|
assert.Len(t, mock1.stopJobs, 1)
|
|
assert.Len(t, mock2.stopJobs, 1)
|
|
|
|
hooks = nil
|
|
})
|
|
|
|
t.Run("call stop hooks with nil hooks", func(t *testing.T) {
|
|
hooks = nil
|
|
|
|
job := &schema.Job{
|
|
JobID: 789, User: "testuser", Cluster: "testcluster",
|
|
}
|
|
|
|
CallJobStopHooks(job)
|
|
|
|
hooks = nil
|
|
})
|
|
}
|
|
|
|
func TestSQLHooks(t *testing.T) {
|
|
_ = setup(t)
|
|
|
|
t.Run("hooks log queries in debug mode", func(t *testing.T) {
|
|
h := &Hooks{}
|
|
|
|
ctx := context.Background()
|
|
query := "SELECT * FROM job WHERE job_id = ?"
|
|
args := []any{123}
|
|
|
|
ctxWithTime, err := h.Before(ctx, query, args...)
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, ctxWithTime)
|
|
|
|
beginTime := ctxWithTime.Value("begin")
|
|
require.NotNil(t, beginTime)
|
|
_, ok := beginTime.(time.Time)
|
|
assert.True(t, ok, "Begin time should be time.Time")
|
|
|
|
time.Sleep(10 * time.Millisecond)
|
|
|
|
ctxAfter, err := h.After(ctxWithTime, query, args...)
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, ctxAfter)
|
|
})
|
|
}
|
|
|
|
func TestHookIntegration(t *testing.T) {
|
|
t.Run("hooks are called during job lifecycle", func(t *testing.T) {
|
|
hooks = nil
|
|
mock := &MockJobHook{}
|
|
RegisterJobHook(mock)
|
|
|
|
job := &schema.Job{
|
|
JobID: 999,
|
|
User: "integrationuser",
|
|
Cluster: "integrationcluster",
|
|
}
|
|
|
|
CallJobStartHooks([]*schema.Job{job})
|
|
assert.True(t, mock.startCalled)
|
|
assert.Equal(t, 1, len(mock.startJobs))
|
|
|
|
CallJobStopHooks(job)
|
|
assert.True(t, mock.stopCalled)
|
|
assert.Equal(t, 1, len(mock.stopJobs))
|
|
|
|
assert.Equal(t, mock.startJobs[0].JobID, mock.stopJobs[0].JobID)
|
|
|
|
hooks = nil
|
|
})
|
|
}
|