Skip to content

Commit

Permalink
make job name optional (#4005)
Browse files Browse the repository at this point in the history
  • Loading branch information
wdbaruni committed May 22, 2024
1 parent 5c482d4 commit fa27190
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 2 deletions.
4 changes: 4 additions & 0 deletions pkg/models/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ func (j *Job) Normalize() {
j.Namespace = DefaultNamespace
}

if j.Name == "" {
j.Name = j.ID
}

if (j.Type == JobTypeDaemon || j.Type == JobTypeOps) && j.Count == 0 {
j.Count = 1
}
Expand Down
164 changes: 164 additions & 0 deletions pkg/models/job_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
//go:build unit || !integration

package models_test

import (
"testing"
"time"

"github.com/stretchr/testify/suite"

"github.com/bacalhau-project/bacalhau/pkg/models"
"github.com/bacalhau-project/bacalhau/pkg/test/mock"
)

type JobTestSuite struct {
suite.Suite
}

func (suite *JobTestSuite) TestJobNormalization() {
testCases := []struct {
jobType string
expectedCount int
}{
{models.JobTypeBatch, 0},
{models.JobTypeService, 0},
{models.JobTypeOps, 1},
{models.JobTypeDaemon, 1},
}

for _, tc := range testCases {
job := &models.Job{
ID: "test-job",
Type: tc.jobType,
Name: "",
Namespace: "",
Meta: nil,
Labels: nil,
Constraints: nil,
Tasks: nil,
}

job.Normalize()

suite.Equal(models.DefaultNamespace, job.Namespace)
suite.Equal("test-job", job.Name)
suite.Equal(tc.jobType, job.Type)
suite.Equal(tc.expectedCount, job.Count)
suite.NotNil(job.Meta)
suite.NotNil(job.Labels)
suite.NotNil(job.Constraints)
suite.NotNil(job.Tasks)
}
}

func (suite *JobTestSuite) TestJobValidation() {
job := &models.Job{
ID: "invalid job id",
Name: "",
Namespace: "",
}

err := job.Validate()
suite.Error(err)
suite.Contains(err.Error(), "missing job name")
suite.Contains(err.Error(), "job ID contains a space")
suite.Contains(err.Error(), "job must be in a namespace")
}

func (suite *JobTestSuite) TestJobSanitization() {
job := &models.Job{
ID: "test-job",
Name: "test-job",
Namespace: "default",
State: models.State[models.JobStateType]{StateType: models.JobStateTypeRunning},
Revision: 1,
Version: 1,
CreateTime: time.Now().UnixNano(),
ModifyTime: time.Now().UnixNano(),
Tasks: []*models.Task{
{
Name: "test-task",
},
},
}

warnings := job.SanitizeSubmission()

suite.NotEmpty(warnings)
suite.Equal(models.JobStateTypeUndefined, job.State.StateType)
suite.Equal(uint64(0), job.Revision)
suite.Equal(uint64(0), job.Version)
suite.Equal(int64(0), job.CreateTime)
suite.Equal(int64(0), job.ModifyTime)
}

func (suite *JobTestSuite) TestJobCopy() {
job := mock.Job()
cpy := job.Copy()

suite.NotNil(cpy)
suite.Equal(job, cpy, "The job and its copy should be deeply equal")
suite.NotSame(job, cpy, "The job and its copy should not be the same instance")

// Ensure nested objects are deeply copied
for i := range job.Tasks {
suite.NotSame(job.Tasks[i], cpy.Tasks[i], "The tasks in the job and its copy should not be the same instance")
}
}

func (suite *JobTestSuite) TestJobTask() {
job := mock.Job()
suite.Equal(job.Tasks[0], job.Task())
}

func (suite *JobTestSuite) TestIsTerminal() {
job := &models.Job{
State: models.State[models.JobStateType]{StateType: models.JobStateTypeCompleted},
}
suite.True(job.IsTerminal())

job.State.StateType = models.JobStateTypeFailed
suite.True(job.IsTerminal())

job.State.StateType = models.JobStateTypeStopped
suite.True(job.IsTerminal())

job.State.StateType = models.JobStateTypeRunning
suite.False(job.IsTerminal())
}

func (suite *JobTestSuite) TestNamespacedID() {
job := mock.Job()
nsID := job.NamespacedID()
suite.Equal(job.ID, nsID.ID)
suite.Equal(job.Namespace, nsID.Namespace)
}

func (suite *JobTestSuite) TestAllStorageTypes() {
job := mock.Job()
job.Tasks = []*models.Task{
{
InputSources: []*models.InputSource{
{
Source: &models.SpecConfig{
Type: "s3",
},
},
{
Source: &models.SpecConfig{
Type: "url",
},
},
},
},
}

storageTypes := job.AllStorageTypes()
suite.ElementsMatch([]string{"s3", "url"}, storageTypes)
}

// Run the test suite
func TestJobTestSuite(t *testing.T) {
suite.Run(t, new(JobTestSuite))
}
11 changes: 9 additions & 2 deletions testdata/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import (
"os"
"testing"

"github.com/bacalhau-project/bacalhau/pkg/lib/marshaller"
"github.com/bacalhau-project/bacalhau/pkg/models"
"github.com/ipld/go-ipld-prime/codec/json"
"github.com/stretchr/testify/require"

"github.com/bacalhau-project/bacalhau/pkg/lib/marshaller"
"github.com/bacalhau-project/bacalhau/pkg/models"

"github.com/bacalhau-project/bacalhau/pkg/model"
)

Expand Down Expand Up @@ -65,6 +66,9 @@ var dockerS3YAML []byte
//go:embed jobs/empty.yaml
var emptyJobYAML []byte

//go:embed jobs/nameless.yaml
var namelessJobYAML []byte

//go:embed jobs/noop.yaml
var noopJobYAML []byte

Expand Down Expand Up @@ -92,6 +96,7 @@ var (
DockerOutputJSON *Fixture
DockerS3YAML *Fixture
EmptyJobYAML *Fixture
NamelessJobYAML *Fixture
NoopJobYAML *Fixture
WasmJobYAML *Fixture
)
Expand Down Expand Up @@ -121,6 +126,7 @@ func init() {
DockerOutputJSON = NewJobFixture("docker with output json", dockerOutputJSON, false)
DockerS3YAML = NewJobFixture("docker with s3", dockerS3YAML, false)
EmptyJobYAML = NewJobFixture("empty job", emptyJobYAML, true)
NamelessJobYAML = NewJobFixture("nameless job", namelessJobYAML, false)
NoopJobYAML = NewJobFixture("noop", noopJobYAML, false)
WasmJobYAML = NewJobFixture("wasm", wasmJobYAML, false)
}
Expand All @@ -139,6 +145,7 @@ func AllFixtures() []*Fixture {
DockerOutputJSON,
DockerS3YAML,
EmptyJobYAML,
NamelessJobYAML,
NoopJobYAML,
WasmJobYAML,
}
Expand Down
6 changes: 6 additions & 0 deletions testdata/jobs/nameless.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Type: batch
Count: 1
Tasks:
- Name: main
Engine:
Type: noop

0 comments on commit fa27190

Please sign in to comment.