FEAT: Update Status Of Video Row On Media Convert Update
This commit is contained in:
@@ -2,8 +2,11 @@ package tests
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-bdd/gobdd"
|
||||
)
|
||||
@@ -352,3 +355,180 @@ func theVideoKeepsTheMetadataISent(t gobdd.StepTest, ctx gobdd.Context) {
|
||||
t.Errorf("expected the file name %q, got %q", w.sent.FileName, w.video.FileName)
|
||||
}
|
||||
}
|
||||
|
||||
func askForThatVideo(t gobdd.StepTest, ctx gobdd.Context) {
|
||||
w := worldOf(t, ctx)
|
||||
|
||||
if w.video.ID == "" {
|
||||
t.Fatalf("no video has been registered, so there is no id to ask for")
|
||||
return
|
||||
}
|
||||
|
||||
result, err := w.client.get("/api/videos/" + w.video.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("could not ask for the video: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
w.last = result
|
||||
w.video = videoBody{}
|
||||
|
||||
if result.status == 200 {
|
||||
if err := result.json(&w.video); err != nil {
|
||||
t.Fatalf("could not decode the video: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func askForVideoWithID(t gobdd.StepTest, ctx gobdd.Context, id string) {
|
||||
w := worldOf(t, ctx)
|
||||
|
||||
result, err := w.client.get("/api/videos/" + url.PathEscape(id))
|
||||
if err != nil {
|
||||
t.Fatalf("could not ask for the video: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
w.last = result
|
||||
w.video = videoBody{}
|
||||
}
|
||||
|
||||
// --- transcoding status -----------------------------------------------------
|
||||
|
||||
// statusSettleTimeout bounds how long a scenario waits for the consumer to
|
||||
// pick an event off the queue and write the record. The consumer long-polls,
|
||||
// so in practice this resolves in well under a second; the budget is for a
|
||||
// loaded machine, not for a slow path.
|
||||
const (
|
||||
statusSettleTimeout = 20 * time.Second
|
||||
statusPollInterval = 200 * time.Millisecond
|
||||
statusHoldWindow = 3 * time.Second
|
||||
)
|
||||
|
||||
func registerVideoBeingTranscoded(t gobdd.StepTest, ctx gobdd.Context) {
|
||||
w := worldOf(t, ctx)
|
||||
|
||||
requestUploadSlot(t, ctx, "transcoding.mp4", "video/mp4")
|
||||
uploadTheFile(t, ctx)
|
||||
registerUploadedVideo(t, ctx, "A Video Being Transcoded", "other")
|
||||
|
||||
if w.last.status != 201 {
|
||||
t.Fatalf("could not register a video to transcode: %s", w.last.summary())
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(w.video.MediaConvertJobID) == "" {
|
||||
t.Fatalf("the registered video carries no transcoding job id, so no event could name it")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func mediaConvertReportsState(t gobdd.StepTest, ctx gobdd.Context, state string) {
|
||||
w := worldOf(t, ctx)
|
||||
|
||||
if strings.TrimSpace(w.video.MediaConvertJobID) == "" {
|
||||
t.Fatalf("no transcoding job has been started, so there is no job to report on")
|
||||
return
|
||||
}
|
||||
publishJobState(t, w.video.MediaConvertJobID, state)
|
||||
}
|
||||
|
||||
func mediaConvertReportsStateForJob(t gobdd.StepTest, ctx gobdd.Context, jobID, state string) {
|
||||
worldOf(t, ctx) // keeps the step honest about needing a scenario world
|
||||
publishJobState(t, jobID, state)
|
||||
}
|
||||
|
||||
func publishJobState(t gobdd.StepTest, jobID, state string) {
|
||||
background := context.Background()
|
||||
|
||||
publisher, err := newEventPublisher(background)
|
||||
if err != nil {
|
||||
t.Fatalf("could not reach the job events topic: %s", err)
|
||||
return
|
||||
}
|
||||
if err := publisher.publishJobState(background, jobID, state); err != nil {
|
||||
t.Fatalf("could not publish the job state change: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func theVideoEventuallyHasStatus(t gobdd.StepTest, ctx gobdd.Context, want string) {
|
||||
w := worldOf(t, ctx)
|
||||
|
||||
deadline := time.Now().Add(statusSettleTimeout)
|
||||
last := ""
|
||||
for time.Now().Before(deadline) {
|
||||
last = currentStatus(t, w)
|
||||
if last == want {
|
||||
return
|
||||
}
|
||||
time.Sleep(statusPollInterval)
|
||||
}
|
||||
|
||||
t.Errorf("the video never reached status %q within %s; it is still %q", want, statusSettleTimeout, last)
|
||||
}
|
||||
|
||||
func theVideoKeepsStatus(t gobdd.StepTest, ctx gobdd.Context, want string) {
|
||||
w := worldOf(t, ctx)
|
||||
|
||||
// Held rather than sampled once: the consumer is asynchronous, so a status
|
||||
// that is still "processing" the instant after publishing proves nothing.
|
||||
deadline := time.Now().Add(statusHoldWindow)
|
||||
for time.Now().Before(deadline) {
|
||||
if got := currentStatus(t, w); got != want {
|
||||
t.Errorf("the video moved to status %q, but this event should have left it %q", got, want)
|
||||
return
|
||||
}
|
||||
time.Sleep(statusPollInterval)
|
||||
}
|
||||
}
|
||||
|
||||
// currentStatus re-reads the video over the API. It deliberately does not
|
||||
// touch w.last: these steps assert on the record, not on an exchange.
|
||||
func currentStatus(t gobdd.StepTest, w *world) string {
|
||||
result, err := w.client.get("/api/videos/" + w.video.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("could not re-read the video: %s", err)
|
||||
return ""
|
||||
}
|
||||
if result.status != 200 {
|
||||
t.Fatalf("could not re-read the video: %s", result.summary())
|
||||
return ""
|
||||
}
|
||||
|
||||
var body videoBody
|
||||
if err := result.json(&body); err != nil {
|
||||
t.Fatalf("could not decode the video: %s", err)
|
||||
return ""
|
||||
}
|
||||
return body.Status
|
||||
}
|
||||
|
||||
// askForThatVideoWrittenAs re-reads the video by a different, still-valid
|
||||
// spelling of the same uuid.
|
||||
func askForThatVideoWrittenAs(t gobdd.StepTest, ctx gobdd.Context, form string) {
|
||||
w := worldOf(t, ctx)
|
||||
|
||||
if w.video.ID == "" {
|
||||
t.Fatalf("no video has been registered, so there is no id to rewrite")
|
||||
return
|
||||
}
|
||||
|
||||
var id string
|
||||
switch form {
|
||||
case "braced":
|
||||
id = "{" + w.video.ID + "}"
|
||||
case "unhyphenated":
|
||||
id = strings.ReplaceAll(w.video.ID, "-", "")
|
||||
case "as a urn":
|
||||
id = "urn:uuid:" + w.video.ID
|
||||
default:
|
||||
t.Fatalf("no such spelling of a uuid: %q", form)
|
||||
return
|
||||
}
|
||||
|
||||
askForVideoWithID(t, ctx, id)
|
||||
if w.last.status == 200 {
|
||||
if err := w.last.json(&w.video); err != nil {
|
||||
t.Fatalf("could not decode the video: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user