github.com/filecoin-project/bacalhau@v0.3.23-0.20230228154132-45c989550ace/cmd/bacalhau/describe_test.go (about) 1 //go:build unit || !integration 2 3 package bacalhau 4 5 import ( 6 "context" 7 "fmt" 8 "testing" 9 10 "github.com/filecoin-project/bacalhau/pkg/bacerrors" 11 "github.com/filecoin-project/bacalhau/pkg/model" 12 testutils "github.com/filecoin-project/bacalhau/pkg/test/utils" 13 "github.com/google/uuid" 14 "github.com/stretchr/testify/require" 15 "github.com/stretchr/testify/suite" 16 ) 17 18 // Define the suite, and absorb the built-in basic suite 19 // functionality from testify - including a T() method which 20 // returns the current testing context 21 type DescribeSuite struct { 22 BaseSuite 23 } 24 25 func (suite *DescribeSuite) TestDescribeJob() { 26 tests := []struct { 27 numberOfAcceptNodes int 28 numberOfRejectNodes int 29 jobState string 30 }{ 31 {numberOfAcceptNodes: 1, numberOfRejectNodes: 0, jobState: model.JobEventResultsPublished.String()}, // Run and accept 32 {numberOfAcceptNodes: 2, numberOfRejectNodes: 0, jobState: model.JobEventResultsPublished.String()}, // Run and accept 33 {numberOfAcceptNodes: 1, numberOfRejectNodes: 1, jobState: model.JobEventResultsPublished.String()}, // Run and accept 34 } 35 36 numOfJobsTests := []struct { 37 numOfJobs int 38 }{ 39 {numOfJobs: 1}, 40 {numOfJobs: 21}, // one more than the default list length 41 } 42 43 for _, tc := range tests { 44 for _, n := range numOfJobsTests { 45 func() { 46 var submittedJob *model.Job 47 ctx := context.Background() 48 49 for i := 0; i < tc.numberOfAcceptNodes; i++ { 50 for k := 0; k < n.numOfJobs; k++ { 51 j := testutils.MakeNoopJob() 52 j.Spec.Docker.Entrypoint = []string{"Entrypoint-Unique-Array", uuid.NewString()} 53 s, err := suite.client.Submit(ctx, j) 54 require.NoError(suite.T(), err) 55 submittedJob = s // Default to the last job submitted, should be fine? 56 } 57 } 58 returnedJobDescription := &model.JobWithInfo{} 59 60 // No job id (should error) 61 _, out, err := ExecuteTestCobraCommand(suite.T(), "describe", 62 "--api-host", suite.host, 63 "--api-port", suite.port, 64 ) 65 require.Error(suite.T(), err, "Submitting a describe request with no id should error.") 66 67 // Job Id at the end 68 _, out, err = ExecuteTestCobraCommand(suite.T(), "describe", 69 "--api-host", suite.host, 70 "--api-port", suite.port, 71 submittedJob.Metadata.ID, 72 ) 73 require.NoError(suite.T(), err, "Error in describing job: %+v", err) 74 75 err = model.YAMLUnmarshalWithMax([]byte(out), returnedJobDescription) 76 require.NoError(suite.T(), err, "Error in unmarshalling description: %+v", err) 77 78 require.Equal(suite.T(), submittedJob.Metadata.ID, returnedJobDescription.Job.Metadata.ID, "IDs do not match.") 79 require.Equal(suite.T(), 80 submittedJob.Spec.Docker.Entrypoint[0], 81 returnedJobDescription.Job.Spec.Docker.Entrypoint[0], 82 fmt.Sprintf("Submitted job entrypoints not the same as the description. %d - %d - %s - %d", tc.numberOfAcceptNodes, tc.numberOfRejectNodes, tc.jobState, n.numOfJobs)) 83 84 // Job Id in the middle 85 _, out, err = ExecuteTestCobraCommand(suite.T(), "describe", 86 "--api-host", suite.host, 87 submittedJob.Metadata.ID, 88 "--api-port", suite.port, 89 ) 90 91 require.NoError(suite.T(), err, "Error in describing job: %+v", err) 92 err = model.YAMLUnmarshalWithMax([]byte(out), returnedJobDescription) 93 require.NoError(suite.T(), err, "Error in unmarshalling description: %+v", err) 94 require.Equal(suite.T(), submittedJob.Metadata.ID, returnedJobDescription.Job.Metadata.ID, "IDs do not match.") 95 require.Equal(suite.T(), 96 submittedJob.Spec.Docker.Entrypoint[0], 97 returnedJobDescription.Job.Spec.Docker.Entrypoint[0], 98 fmt.Sprintf("Submitted job entrypoints not the same as the description. %d - %d - %s - %d", tc.numberOfAcceptNodes, tc.numberOfRejectNodes, tc.jobState, n.numOfJobs)) 99 100 // Short job id 101 _, out, err = ExecuteTestCobraCommand(suite.T(), "describe", 102 "--api-host", suite.host, 103 submittedJob.Metadata.ID[0:model.ShortIDLength], 104 "--api-port", suite.port, 105 ) 106 107 require.NoError(suite.T(), err, "Error in describing job: %+v", err) 108 err = model.YAMLUnmarshalWithMax([]byte(out), returnedJobDescription) 109 require.NoError(suite.T(), err, "Error in unmarshalling description: %+v", err) 110 require.Equal(suite.T(), submittedJob.Metadata.ID, returnedJobDescription.Job.Metadata.ID, "IDs do not match.") 111 require.Equal(suite.T(), 112 submittedJob.Spec.Docker.Entrypoint[0], 113 returnedJobDescription.Job.Spec.Docker.Entrypoint[0], 114 fmt.Sprintf("Submitted job entrypoints not the same as the description. %d - %d - %s - %d", tc.numberOfAcceptNodes, tc.numberOfRejectNodes, tc.jobState, n.numOfJobs)) 115 116 }() 117 } 118 } 119 120 } 121 122 func (suite *DescribeSuite) TestDescribeJobIncludeEvents() { 123 tests := []struct { 124 includeEvents bool 125 }{ 126 {includeEvents: false}, 127 {includeEvents: true}, 128 } 129 130 for _, tc := range tests { 131 func() { 132 var submittedJob *model.Job 133 ctx := context.Background() 134 135 j := testutils.MakeNoopJob() 136 s, err := suite.client.Submit(ctx, j) 137 require.NoError(suite.T(), err) 138 submittedJob = s // Default to the last job submitted, should be fine? 139 140 var returnedJob = &model.Job{} 141 142 var args []string 143 144 args = append(args, "describe", "--api-host", suite.host, "--api-port", suite.port, submittedJob.Metadata.ID) 145 if tc.includeEvents { 146 args = append(args, "--include-events") 147 } 148 149 // Job Id at the end 150 _, out, err := ExecuteTestCobraCommand(suite.T(), args...) 151 require.NoError(suite.T(), err, "Error in describing job: %+v", err) 152 153 err = model.YAMLUnmarshalWithMax([]byte(out), &returnedJob) 154 require.NoError(suite.T(), err, "Error in unmarshalling description: %+v", err) 155 156 // TODO: #600 When we figure out how to add events to a noop job, uncomment the below 157 // require.True(suite.T(), eventsWereIncluded == tc.includeEvents, 158 // fmt.Sprintf("Events include: %v\nExpected: %v", eventsWereIncluded, tc.includeEvents)) 159 160 // require.True(suite.T(), localEventsWereIncluded == tc.includeEvents, 161 // fmt.Sprintf("Events included: %v\nExpected: %v", localEventsWereIncluded, tc.includeEvents)) 162 163 }() 164 } 165 166 } 167 168 func (s *DescribeSuite) TestDescribeJobEdgeCases() { 169 tests := []struct { 170 describeIDEdgecase string 171 errorMessage string 172 }{ 173 {describeIDEdgecase: "", errorMessage: ""}, 174 {describeIDEdgecase: "BAD_JOB_ID", errorMessage: "No job ID found."}, 175 } 176 177 numOfJobsTests := []struct { 178 numOfJobs int 179 }{ 180 {numOfJobs: 1}, // just enough that describe could get screwed up 181 } 182 183 for _, tc := range tests { 184 for _, n := range numOfJobsTests { 185 func() { 186 Fatal = FakeFatalErrorHandler 187 188 var submittedJob *model.Job 189 ctx := context.Background() 190 191 for i := 0; i < n.numOfJobs; i++ { 192 j := testutils.MakeNoopJob() 193 j.Spec.Docker.Entrypoint = []string{"Entrypoint-Unique-Array", uuid.NewString()} 194 jj, err := s.client.Submit(ctx, j) 195 require.Nil(s.T(), err) 196 submittedJob = jj // Default to the last job submitted, should be fine? 197 } 198 199 var returnedJobDescription = &model.JobWithInfo{} 200 var err error 201 var out string 202 var jobID string 203 204 // If describeID is empty, should return use submitted ID. Otherwise, use describeID 205 if tc.describeIDEdgecase == "" { 206 jobID = submittedJob.Metadata.ID 207 } else { 208 jobID = tc.describeIDEdgecase 209 } 210 211 _, out, err = ExecuteTestCobraCommand(s.T(), "describe", 212 "--api-host", s.host, 213 "--api-port", s.port, 214 jobID, 215 ) 216 if tc.describeIDEdgecase == "" { 217 require.NoError(s.T(), err, "Error in describing job: %+v", err) 218 219 err = model.YAMLUnmarshalWithMax([]byte(out), &returnedJobDescription) 220 require.NoError(s.T(), err, "Error in unmarshalling description: %+v", err) 221 require.Equal(s.T(), submittedJob.Metadata.ID, returnedJobDescription.Job.Metadata.ID, "IDs do not match.") 222 require.Equal(s.T(), 223 submittedJob.Spec.Docker.Entrypoint[0], 224 returnedJobDescription.Job.Spec.Docker.Entrypoint[0], 225 fmt.Sprintf("Submitted job entrypoints not the same as the description. Edgecase: %s", tc.describeIDEdgecase)) 226 } else { 227 c := &model.TestFatalErrorHandlerContents{} 228 model.JSONUnmarshalWithMax([]byte(out), &c) 229 e := bacerrors.NewJobNotFound(tc.describeIDEdgecase) 230 require.Contains(s.T(), c.Message, e.GetMessage(), "Job not found error string not found.", err) 231 } 232 233 }() 234 } 235 } 236 237 } 238 239 // In order for 'go test' to run this suite, we need to create 240 // a normal test function and pass our suite to suite.Run 241 func TestDescribeSuite(t *testing.T) { 242 suite.Run(t, new(DescribeSuite)) 243 }