Skip to content

Commit

Permalink
Render null/zero times as null in JSON output
Browse files Browse the repository at this point in the history
  • Loading branch information
sersorrel committed Feb 12, 2024
1 parent f24b126 commit 889fef7
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 18 deletions.
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# go-softpack-builder (gsb)
Go implementation of a softpack builder service.

After receiving a POST (see Testing section below) with desired environment
details, this service does the following:
After receiving a POST to `/environments/build` (see Testing section below) with
desired environment details, this service does the following:

1. A singularity definition file, singularity.def, is created and uploaded to
an environment-specific subdirectory of your S3 build location.
Expand Down Expand Up @@ -43,6 +43,23 @@ details, this service does the following:
It can be reproduced exactly at any time using the singularity.def, assuming
you configure specific images (ie. not :latest) to use.

After receiving a GET to `/environments/status`, this service returns a JSON
response with the following structure:

```json
[
{
"Name": "users/foo/bar",
"Requested": "2024-02-12T11:58:49.808672303Z",
"BuildStart": "2024-02-12T11:58:55.430080969Z",
"BuildDone": "2024-02-12T11:59:00.532174828Z"
}
]
```

The times are quoted strings in the RFC 3339 format with sub-second precision,
or null.

## Initial setup

You'll need an S3 bucket to be a binary cache, which needs GPG keys. Here's one
Expand Down
15 changes: 9 additions & 6 deletions build/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,9 @@ type Runner interface {
// actually being built, and when its build finished.
type Status struct {
Name string
Requested time.Time
BuildStart time.Time
BuildDone time.Time
Requested *time.Time
BuildStart *time.Time
BuildDone *time.Time
}

// Builder lets you do builds given config, S3 and a wr runner.
Expand Down Expand Up @@ -317,9 +317,10 @@ func (b *Builder) buildStatus(def *Definition) *Status {

status, exists := b.statuses[name]
if !exists {
now := time.Now()
status = &Status{
Name: name,
Requested: time.Now(),
Requested: &now,
}

b.statuses[name] = status
Expand Down Expand Up @@ -413,13 +414,15 @@ func (b *Builder) asyncBuild(def *Definition, wrInput, s3Path, singDef string) e
}

b.statusMu.Lock()
status.BuildStart = time.Now()
buildStart := time.Now()
status.BuildStart = &buildStart
b.statusMu.Unlock()

_, err = b.runner.Wait(jobID)

b.statusMu.Lock()
status.BuildDone = time.Now()
buildDone := time.Now()
status.BuildDone = &buildDone
b.statusMu.Unlock()

b.postBuildMu.RLock()
Expand Down
20 changes: 10 additions & 10 deletions server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (m *mockBuilder) Status() []build.Status {
for i, def := range m.received {
statuses[i] = build.Status{
Name: filepath.Join(def.EnvironmentPath, def.EnvironmentName) + "-" + def.EnvironmentVersion,
Requested: m.requested[i],
Requested: &m.requested[i],
}
}

Expand Down Expand Up @@ -160,7 +160,7 @@ func TestServerMock(t *testing.T) {
So(err, ShouldBeNil)
So(len(statuses), ShouldEqual, 1)
So(statuses[0].Name, ShouldEqual, "users/user/myenv-0.8.1")
So(statuses[0].Requested, ShouldEqual, mb.requested[0])
So(*statuses[0].Requested, ShouldHappenWithin, 0*time.Microsecond, mb.requested[0])

postToBuildEndpoint(server, "users/user/myotherenv", "1")

Expand All @@ -175,7 +175,7 @@ func TestServerMock(t *testing.T) {
So(len(statuses), ShouldEqual, 2)
So(statuses[0].Name, ShouldEqual, "users/user/myenv-0.8.1")
So(statuses[1].Name, ShouldEqual, "users/user/myotherenv-1")
So(statuses[1].Requested, ShouldEqual, mb.requested[1])
So(*statuses[1].Requested, ShouldHappenWithin, 0*time.Microsecond, mb.requested[1])
})
})
}
Expand Down Expand Up @@ -215,23 +215,23 @@ func TestServerReal(t *testing.T) {
statuses := getTestStatuses(server)
So(len(statuses), ShouldEqual, 1)
So(statuses[0].Name, ShouldEqual, "users/user/myenv-0.8.1")
So(statuses[0].Requested, ShouldHappenAfter, buildSubmitted)
So(statuses[0].BuildStart.IsZero(), ShouldBeTrue)
So(statuses[0].BuildDone.IsZero(), ShouldBeTrue)
So(*statuses[0].Requested, ShouldHappenAfter, buildSubmitted)
So(statuses[0].BuildStart, ShouldBeNil)
So(statuses[0].BuildDone, ShouldBeNil)

runT := time.Now()
mwr.SetRunning()
<-time.After(2 * mockStatusPollInterval)
statuses = getTestStatuses(server)
So(len(statuses), ShouldEqual, 1)
So(statuses[0].Requested, ShouldHappenAfter, buildSubmitted)
buildStart := statuses[0].BuildStart
So(*statuses[0].Requested, ShouldHappenAfter, buildSubmitted)
buildStart := *statuses[0].BuildStart
So(buildStart, ShouldHappenAfter, runT)
So(statuses[0].BuildDone.IsZero(), ShouldBeTrue)
So(statuses[0].BuildDone, ShouldBeNil)

<-time.After(mwr.JobDuration)
statuses = getTestStatuses(server)
So(statuses[0].BuildDone, ShouldHappenAfter, buildStart)
So(*statuses[0].BuildDone, ShouldHappenAfter, buildStart)
})
})
}
Expand Down

0 comments on commit 889fef7

Please sign in to comment.