Adjust + Test

This commit is contained in:
mr
2026-02-18 12:24:19 +01:00
parent 842e09f22f
commit fa5c3a3c60
45 changed files with 1166 additions and 1192 deletions

View File

@@ -0,0 +1,172 @@
package workflow_execution_test
import (
"testing"
"time"
"cloud.o-forge.io/core/oc-lib/models/common/enum"
"cloud.o-forge.io/core/oc-lib/models/workflow_execution"
"cloud.o-forge.io/core/oc-lib/tools"
"github.com/stretchr/testify/assert"
)
// ---- WorkflowExecution model ----
func TestWorkflowExecution_StoreDraftDefault(t *testing.T) {
we := &workflow_execution.WorkflowExecution{}
we.StoreDraftDefault()
assert.False(t, we.IsDraft)
assert.Equal(t, enum.SCHEDULED, we.State)
}
func TestWorkflowExecution_CanDelete_Draft(t *testing.T) {
we := &workflow_execution.WorkflowExecution{}
we.IsDraft = true
assert.True(t, we.CanDelete())
}
func TestWorkflowExecution_CanDelete_NonDraft(t *testing.T) {
we := &workflow_execution.WorkflowExecution{}
we.IsDraft = false
assert.False(t, we.CanDelete())
}
func TestWorkflowExecution_CanUpdate_StateChange(t *testing.T) {
we := &workflow_execution.WorkflowExecution{State: enum.SCHEDULED}
set := &workflow_execution.WorkflowExecution{State: enum.STARTED}
ok, returned := we.CanUpdate(set)
assert.True(t, ok)
// Only the state should be propagated
assert.Equal(t, enum.STARTED, returned.(*workflow_execution.WorkflowExecution).State)
}
func TestWorkflowExecution_CanUpdate_SameState_NonDraft(t *testing.T) {
we := &workflow_execution.WorkflowExecution{State: enum.SCHEDULED}
we.IsDraft = false
set := &workflow_execution.WorkflowExecution{State: enum.SCHEDULED}
ok, _ := we.CanUpdate(set)
// !r.IsDraft == true → ok
assert.True(t, ok)
}
func TestWorkflowExecution_CanUpdate_SameState_Draft(t *testing.T) {
we := &workflow_execution.WorkflowExecution{State: enum.SCHEDULED}
we.IsDraft = true
set := &workflow_execution.WorkflowExecution{State: enum.SCHEDULED}
ok, _ := we.CanUpdate(set)
// !r.IsDraft == false (it is draft) → ok false
assert.False(t, ok)
}
func TestWorkflowExecution_Equals_True(t *testing.T) {
now := time.Now()
a := &workflow_execution.WorkflowExecution{WorkflowID: "wf-1"}
a.ExecDate = now
b := &workflow_execution.WorkflowExecution{WorkflowID: "wf-1"}
b.ExecDate = now
assert.True(t, a.Equals(b))
}
func TestWorkflowExecution_Equals_DifferentDate(t *testing.T) {
a := &workflow_execution.WorkflowExecution{WorkflowID: "wf-1"}
a.ExecDate = time.Now()
b := &workflow_execution.WorkflowExecution{WorkflowID: "wf-1"}
b.ExecDate = time.Now().Add(time.Hour)
assert.False(t, a.Equals(b))
}
func TestWorkflowExecution_Equals_DifferentWorkflow(t *testing.T) {
now := time.Now()
a := &workflow_execution.WorkflowExecution{WorkflowID: "wf-1"}
a.ExecDate = now
b := &workflow_execution.WorkflowExecution{WorkflowID: "wf-2"}
b.ExecDate = now
assert.False(t, a.Equals(b))
}
func TestWorkflowExecution_GetName(t *testing.T) {
we := &workflow_execution.WorkflowExecution{}
we.UUID = "exec-uuid"
we.ExecDate = time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)
name := we.GetName()
assert.Contains(t, name, "exec-uuid")
assert.Contains(t, name, "2026")
}
func TestWorkflowExecution_GenerateID(t *testing.T) {
we := &workflow_execution.WorkflowExecution{}
we.GenerateID()
assert.NotEmpty(t, we.UUID)
}
func TestWorkflowExecution_GenerateID_KeepsExisting(t *testing.T) {
we := &workflow_execution.WorkflowExecution{}
we.UUID = "existing-uuid"
we.GenerateID()
assert.Equal(t, "existing-uuid", we.UUID)
}
func TestWorkflowExecution_VerifyAuth_AlwaysTrue(t *testing.T) {
we := &workflow_execution.WorkflowExecution{}
assert.True(t, we.VerifyAuth("get", nil))
assert.True(t, we.VerifyAuth("delete", &tools.APIRequest{}))
}
func TestWorkflowExecution_GetAccessor(t *testing.T) {
we := &workflow_execution.WorkflowExecution{}
acc := we.GetAccessor(&tools.APIRequest{})
assert.NotNil(t, acc)
}
// ---- ArgoStatusToState ----
func TestArgoStatusToState_Succeeded(t *testing.T) {
we := &workflow_execution.WorkflowExecution{}
we.ArgoStatusToState("succeeded")
assert.Equal(t, enum.SUCCESS, we.State)
}
func TestArgoStatusToState_Pending(t *testing.T) {
we := &workflow_execution.WorkflowExecution{}
we.ArgoStatusToState("pending")
assert.Equal(t, enum.SCHEDULED, we.State)
}
func TestArgoStatusToState_Running(t *testing.T) {
we := &workflow_execution.WorkflowExecution{}
we.ArgoStatusToState("running")
assert.Equal(t, enum.STARTED, we.State)
}
func TestArgoStatusToState_Default_Failed(t *testing.T) {
we := &workflow_execution.WorkflowExecution{}
we.ArgoStatusToState("failed")
assert.Equal(t, enum.FAILURE, we.State)
}
func TestArgoStatusToState_CaseInsensitive(t *testing.T) {
we := &workflow_execution.WorkflowExecution{}
we.ArgoStatusToState("SUCCEEDED")
assert.Equal(t, enum.SUCCESS, we.State)
}
func TestArgoStatusToState_ReturnsPointer(t *testing.T) {
we := &workflow_execution.WorkflowExecution{}
result := we.ArgoStatusToState("running")
assert.Equal(t, we, result)
}
// ---- NewAccessor ----
func TestNewWorkflowExecutionAccessor(t *testing.T) {
acc := workflow_execution.NewAccessor(&tools.APIRequest{Admin: true})
assert.NotNil(t, acc)
assert.Equal(t, tools.WORKFLOW_EXECUTION, acc.GetType())
}
func TestNewWorkflowExecutionAccessor_NilRequest(t *testing.T) {
acc := workflow_execution.NewAccessor(nil)
assert.NotNil(t, acc)
assert.Equal(t, "", acc.GetUser())
assert.Equal(t, "", acc.GetPeerID())
}

View File

@@ -1,164 +0,0 @@
package workflow_execution_test
import (
"testing"
"time"
"cloud.o-forge.io/core/oc-lib/models/common/enum"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/models/workflow_execution"
"cloud.o-forge.io/core/oc-lib/tools"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
type MockAccessor struct {
mock.Mock
}
func (m *MockAccessor) LoadOne(id string) (interface{}, int, error) {
args := m.Called(id)
return args.Get(0), args.Int(1), args.Error(2)
}
func (m *MockAccessor) DeleteOne(id string) (utils.DBObject, int, error) {
args := m.Called(id)
return nil, args.Int(1), args.Error(2)
}
func (m *MockAccessor) Search(filters interface{}, search string, isDraft bool) ([]utils.ShallowDBObject, int, error) {
args := m.Called(filters, search, isDraft)
return args.Get(0).([]utils.ShallowDBObject), args.Int(1), args.Error(2)
}
func TestStoreDraftDefault(t *testing.T) {
exec := &workflow_execution.WorkflowExecution{}
exec.StoreDraftDefault()
assert.False(t, exec.IsDraft)
assert.Equal(t, enum.SCHEDULED, exec.State)
}
func TestCanUpdate_StateChange(t *testing.T) {
existing := &workflow_execution.WorkflowExecution{State: enum.DRAFT}
newExec := &workflow_execution.WorkflowExecution{State: enum.SCHEDULED}
canUpdate, updated := existing.CanUpdate(newExec)
assert.True(t, canUpdate)
assert.Equal(t, enum.SCHEDULED, updated.(*workflow_execution.WorkflowExecution).State)
}
func TestCanUpdate_SameState_Draft(t *testing.T) {
existing := &workflow_execution.WorkflowExecution{AbstractObject: utils.AbstractObject{IsDraft: true}, State: enum.DRAFT}
newExec := &workflow_execution.WorkflowExecution{AbstractObject: utils.AbstractObject{IsDraft: true}, State: enum.DRAFT}
canUpdate, _ := existing.CanUpdate(newExec)
assert.False(t, canUpdate)
}
func TestCanDelete_TrueIfDraft(t *testing.T) {
exec := &workflow_execution.WorkflowExecution{AbstractObject: utils.AbstractObject{IsDraft: true}}
assert.True(t, exec.CanDelete())
}
func TestCanDelete_FalseIfNotDraft(t *testing.T) {
exec := &workflow_execution.WorkflowExecution{AbstractObject: utils.AbstractObject{IsDraft: false}}
assert.False(t, exec.CanDelete())
}
func TestEquals_True(t *testing.T) {
d := time.Now()
exec1 := &workflow_execution.WorkflowExecution{ExecDate: d, WorkflowID: "123"}
exec2 := &workflow_execution.WorkflowExecution{ExecDate: d, WorkflowID: "123"}
assert.True(t, exec1.Equals(exec2))
}
func TestEquals_False(t *testing.T) {
exec1 := &workflow_execution.WorkflowExecution{ExecDate: time.Now(), WorkflowID: "abc"}
exec2 := &workflow_execution.WorkflowExecution{ExecDate: time.Now().Add(time.Hour), WorkflowID: "def"}
assert.False(t, exec1.Equals(exec2))
}
func TestArgoStatusToState_Success(t *testing.T) {
exec := &workflow_execution.WorkflowExecution{}
exec.ArgoStatusToState("succeeded")
assert.Equal(t, enum.SUCCESS, exec.State)
}
func TestArgoStatusToState_DefaultToFailure(t *testing.T) {
exec := &workflow_execution.WorkflowExecution{}
exec.ArgoStatusToState("unknown")
assert.Equal(t, enum.FAILURE, exec.State)
}
func TestGenerateID_AssignsUUID(t *testing.T) {
exec := &workflow_execution.WorkflowExecution{}
exec.GenerateID()
assert.NotEmpty(t, exec.UUID)
}
func TestGetName_ReturnsCorrectFormat(t *testing.T) {
time := time.Now()
exec := &workflow_execution.WorkflowExecution{AbstractObject: utils.AbstractObject{UUID: "abc"}, ExecDate: time}
assert.Contains(t, exec.GetName(), "abc")
assert.Contains(t, exec.GetName(), time.String())
}
func TestVerifyAuth_AlwaysTrue(t *testing.T) {
exec := &workflow_execution.WorkflowExecution{}
assert.True(t, exec.VerifyAuth("get", nil))
}
func TestUpdateOne_RejectsZeroState(t *testing.T) {
accessor := &workflow_execution.WorkflowExecutionMongoAccessor{}
set := &workflow_execution.WorkflowExecution{State: 0}
_, code, err := accessor.UpdateOne(set, "someID")
assert.Equal(t, 400, code)
assert.Error(t, err)
}
func TestLoadOne_DraftExpired_ShouldDelete(t *testing.T) {
// Normally would mock time.Now and delete call; for now we test structure
accessor := workflow_execution.NewAccessor(&tools.APIRequest{})
exec := &workflow_execution.WorkflowExecution{
ExecDate: time.Now().Add(-2 * time.Minute),
State: enum.DRAFT,
AbstractObject: utils.AbstractObject{UUID: "to-delete"},
}
_, _, _ = accessor.LoadOne(exec.GetID())
// No panic = good enough placeholder
}
func TestLoadOne_ScheduledExpired_ShouldUpdateToForgotten(t *testing.T) {
accessor := workflow_execution.NewAccessor(&tools.APIRequest{})
exec := &workflow_execution.WorkflowExecution{
ExecDate: time.Now().Add(-2 * time.Minute),
State: enum.SCHEDULED,
AbstractObject: utils.AbstractObject{UUID: "to-forget"},
}
_, _, _ = accessor.LoadOne(exec.GetID())
}
func TestDeleteOne_NotImplemented(t *testing.T) {
accessor := workflow_execution.NewAccessor(&tools.APIRequest{})
_, code, err := accessor.DeleteOne("someID")
assert.Equal(t, 404, code)
assert.Error(t, err)
}
func TestStoreOne_NotImplemented(t *testing.T) {
accessor := workflow_execution.NewAccessor(&tools.APIRequest{})
_, code, err := accessor.StoreOne(nil)
assert.Equal(t, 404, code)
assert.Error(t, err)
}
func TestCopyOne_NotImplemented(t *testing.T) {
accessor := workflow_execution.NewAccessor(&tools.APIRequest{})
_, code, err := accessor.CopyOne(nil)
assert.Equal(t, 404, code)
assert.Error(t, err)
}
func TestGetExecFilters_BasicPattern(t *testing.T) {
a := workflow_execution.NewAccessor(&tools.APIRequest{})
filters := a.GetExecFilters("foo")
assert.Contains(t, filters.Or["abstractobject.name"][0].Value, "foo")
}

View File

@@ -12,17 +12,19 @@ import (
)
type WorkflowExecutionMongoAccessor struct {
utils.AbstractAccessor
utils.AbstractAccessor[*WorkflowExecution]
shallow bool
}
func newShallowAccessor(request *tools.APIRequest) *WorkflowExecutionMongoAccessor {
return &WorkflowExecutionMongoAccessor{
shallow: true,
AbstractAccessor: utils.AbstractAccessor{
Logger: logs.CreateLogger(tools.WORKFLOW_EXECUTION.String()), // Create a logger with the data type
Request: request,
Type: tools.WORKFLOW_EXECUTION,
AbstractAccessor: utils.AbstractAccessor[*WorkflowExecution]{
Logger: logs.CreateLogger(tools.WORKFLOW_EXECUTION.String()), // Create a logger with the data type
Request: request,
Type: tools.WORKFLOW_EXECUTION,
New: func() *WorkflowExecution { return &WorkflowExecution{} },
NotImplemented: []string{"DeleteOne", "StoreOne", "CopyOne"},
},
}
}
@@ -30,18 +32,16 @@ func newShallowAccessor(request *tools.APIRequest) *WorkflowExecutionMongoAccess
func NewAccessor(request *tools.APIRequest) *WorkflowExecutionMongoAccessor {
return &WorkflowExecutionMongoAccessor{
shallow: false,
AbstractAccessor: utils.AbstractAccessor{
Logger: logs.CreateLogger(tools.WORKFLOW_EXECUTION.String()), // Create a logger with the data type
Request: request,
Type: tools.WORKFLOW_EXECUTION,
AbstractAccessor: utils.AbstractAccessor[*WorkflowExecution]{
Logger: logs.CreateLogger(tools.WORKFLOW_EXECUTION.String()), // Create a logger with the data type
Request: request,
Type: tools.WORKFLOW_EXECUTION,
New: func() *WorkflowExecution { return &WorkflowExecution{} },
NotImplemented: []string{"DeleteOne", "StoreOne", "CopyOne"},
},
}
}
func (wfa *WorkflowExecutionMongoAccessor) DeleteOne(id string) (utils.DBObject, int, error) {
return nil, 404, errors.New("not implemented")
}
func (wfa *WorkflowExecutionMongoAccessor) UpdateOne(set utils.DBObject, id string) (utils.DBObject, int, error) {
if set.(*WorkflowExecution).State == 0 {
return nil, 400, errors.New("state is required")
@@ -50,14 +50,6 @@ func (wfa *WorkflowExecutionMongoAccessor) UpdateOne(set utils.DBObject, id stri
return utils.GenericUpdateOne(&realSet, id, wfa, &WorkflowExecution{})
}
func (wfa *WorkflowExecutionMongoAccessor) StoreOne(data utils.DBObject) (utils.DBObject, int, error) {
return nil, 404, errors.New("not implemented")
}
func (wfa *WorkflowExecutionMongoAccessor) CopyOne(data utils.DBObject) (utils.DBObject, int, error) {
return nil, 404, errors.New("not implemented")
}
func (a *WorkflowExecutionMongoAccessor) LoadOne(id string) (utils.DBObject, int, error) {
return utils.GenericLoadOne[*WorkflowExecution](id, func(d utils.DBObject) (utils.DBObject, int, error) {
now := time.Now()
@@ -73,16 +65,7 @@ func (a *WorkflowExecutionMongoAccessor) LoadOne(id string) (utils.DBObject, int
return d, 200, nil
}, a)
}
func (a *WorkflowExecutionMongoAccessor) LoadAll(isDraft bool) ([]utils.ShallowDBObject, int, error) {
return utils.GenericLoadAll[*WorkflowExecution](a.getExec(), isDraft, a)
}
func (a *WorkflowExecutionMongoAccessor) Search(filters *dbs.Filters, search string, isDraft bool) ([]utils.ShallowDBObject, int, error) {
return utils.GenericSearch[*WorkflowExecution](filters, search, a.GetExecFilters(search), a.getExec(), isDraft, a)
}
func (a *WorkflowExecutionMongoAccessor) getExec() func(utils.DBObject) utils.ShallowDBObject {
func (a *WorkflowExecutionMongoAccessor) GetExec(isDraft bool) func(utils.DBObject) utils.ShallowDBObject {
return func(d utils.DBObject) utils.ShallowDBObject {
now := time.Now()
now = now.Add(time.Second * -60)
@@ -99,7 +82,7 @@ func (a *WorkflowExecutionMongoAccessor) getExec() func(utils.DBObject) utils.Sh
}
}
func (a *WorkflowExecutionMongoAccessor) GetExecFilters(search string) *dbs.Filters {
func (a *WorkflowExecutionMongoAccessor) GetObjectFilters(search string) *dbs.Filters {
return &dbs.Filters{
Or: map[string][]dbs.Filter{ // filter by name if no filters are provided
"abstractobject.name": {{Operator: dbs.LIKE.String(), Value: search + "_execution"}},