Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Implement with_tasks option to expand the task information #3343

Merged
merged 7 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/ApiService/ApiService/Functions/Jobs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,14 @@ private async Task<HttpResponseData> Get(HttpRequestData req) {

static JobTaskInfo TaskToJobTaskInfo(Task t) => new(t.TaskId, t.Config.Task.Type, t.State);

// TODO: search.WithTasks is not checked in Python code?

var taskInfo = await _context.TaskOperations.SearchStates(jobId).Select(TaskToJobTaskInfo).ToListAsync();
return await RequestHandling.Ok(req, JobResponse.ForJob(job, taskInfo));
var tasks = _context.TaskOperations.SearchStates(jobId);
if (search.WithTasks ?? false) {
chkeita marked this conversation as resolved.
Show resolved Hide resolved
var ts = await tasks.ToListAsync();
return await RequestHandling.Ok(req, JobResponse.ForJob(job, ts));
} else {
var taskInfo = await tasks.Select(TaskToJobTaskInfo).ToListAsync();
return await RequestHandling.Ok(req, JobResponse.ForJob(job, taskInfo));
}
}

var jobs = await _context.JobOperations.SearchState(states: search.State ?? Enumerable.Empty<JobState>()).ToListAsync();
Expand Down
29 changes: 27 additions & 2 deletions src/ApiService/ApiService/OneFuzzTypes/Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,8 @@ public record Task(
ISecret<Authentication>? Auth = null,
DateTimeOffset? Heartbeat = null,
DateTimeOffset? EndTime = null,
StoredUserInfo? UserInfo = null) : StatefulEntityBase<TaskState>(State) {
StoredUserInfo? UserInfo = null) : StatefulEntityBase<TaskState>(State), IJobTaskInfo {
public TaskType Type => Config.Task.Type;
}

public record TaskEvent(
Expand Down Expand Up @@ -898,11 +899,35 @@ public JobConfig Truncate(int maxLength) {
}
}

[JsonConverter(typeof(IJobTaskInfoConverter))]
public interface IJobTaskInfo {
Guid TaskId { get; }
TaskType Type { get; }
TaskState State { get; }

}

public class IJobTaskInfoConverter : JsonConverter<IJobTaskInfo> {
public override IJobTaskInfo Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options) {
throw new NotImplementedException();
}

public override void Write(
Utf8JsonWriter writer,
IJobTaskInfo value,
JsonSerializerOptions options) {
var type = value.GetType();
JsonSerializer.Serialize(writer, value, type, options);
}
}
public record JobTaskInfo(
Guid TaskId,
TaskType Type,
TaskState State
);
) : IJobTaskInfo;

public record Job(
[PartitionKey][RowKey] Guid JobId,
Expand Down
4 changes: 2 additions & 2 deletions src/ApiService/ApiService/OneFuzzTypes/Responses.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,13 @@ public record JobResponse(
JobConfig Config,
string? Error,
DateTimeOffset? EndTime,
List<JobTaskInfo>? TaskInfo,
IEnumerable<IJobTaskInfo>? TaskInfo,
StoredUserInfo? UserInfo,
[property: JsonPropertyName("Timestamp")] // must retain capital T for backcompat
DateTimeOffset? Timestamp
// not including UserInfo from Job model
) : BaseResponse() {
public static JobResponse ForJob(Job j, List<JobTaskInfo>? taskInfo)
public static JobResponse ForJob(Job j, IEnumerable<IJobTaskInfo>? taskInfo)
=> new(
JobId: j.JobId,
State: j.State,
Expand Down
6 changes: 4 additions & 2 deletions src/cli/onefuzz/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1308,14 +1308,16 @@ def delete(self, job_id: UUID_EXPANSION) -> models.Job:
"DELETE", models.Job, data=requests.JobGet(job_id=job_id_expanded)
)

def get(self, job_id: UUID_EXPANSION) -> models.Job:
def get(self, job_id: UUID_EXPANSION, with_tasks: bool = False) -> models.Job:
"""Get information about a specific job"""
job_id_expanded = self._disambiguate_uuid(
"job_id", job_id, lambda: [str(x.job_id) for x in self.list()]
)
self.logger.debug("get job: %s", job_id_expanded)
job = self._req_model(
"GET", models.Job, data=requests.JobGet(job_id=job_id_expanded)
"GET",
models.Job,
data=requests.JobGet(job_id=job_id_expanded, with_tasks=with_tasks),
)
return job

Expand Down
22 changes: 11 additions & 11 deletions src/pytypes/onefuzztypes/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,17 +463,6 @@ class JobTaskInfo(BaseModel):
state: TaskState


class Job(BaseModel):
timestamp: Optional[datetime] = Field(alias="Timestamp")
job_id: UUID = Field(default_factory=uuid4)
state: JobState = Field(default=JobState.init)
config: JobConfig
error: Optional[str]
end_time: Optional[datetime] = None
task_info: Optional[List[JobTaskInfo]]
user_info: Optional[UserInfo]


class TaskHeartbeatEntry(BaseModel):
task_id: UUID
job_id: Optional[UUID]
Expand Down Expand Up @@ -757,6 +746,17 @@ class Task(BaseModel):
user_info: Optional[UserInfo]


class Job(BaseModel):
timestamp: Optional[datetime] = Field(alias="Timestamp")
job_id: UUID = Field(default_factory=uuid4)
state: JobState = Field(default=JobState.init)
config: JobConfig
error: Optional[str]
end_time: Optional[datetime] = None
task_info: Optional[List[Union[Task, JobTaskInfo]]]
user_info: Optional[UserInfo]


class NetworkConfig(BaseModel):
address_space: str = Field(default="10.0.0.0/8")
subnet: str = Field(default="10.0.0.0/16")
Expand Down
2 changes: 1 addition & 1 deletion src/pytypes/onefuzztypes/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ class BaseRequest(BaseModel):

class JobGet(BaseRequest):
job_id: UUID
with_tasks: Optional[bool]


class JobSearch(BaseRequest):
job_id: Optional[UUID]
state: Optional[List[JobState]]
task_state: Optional[List[TaskState]]
with_tasks: Optional[bool]


class NotificationCreate(BaseRequest, NotificationConfig):
Expand Down