Skip to content

Commit

Permalink
fix(server): use UTC and portable path composition
Browse files Browse the repository at this point in the history
This diff implements portable path composition theoretically
allowing the server to run under Windows systems.

Additionally, this diff implements tests to ensure that we're
still composing the output file path correctly.

While there, notice we're not using UTC and enforce UTC.
  • Loading branch information
bassosimone committed Jan 29, 2024
1 parent cd6674a commit 49a6010
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 13 deletions.
15 changes: 9 additions & 6 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ type sessionInfo struct {
stamp time.Time
}

// timeNowUTC returns the current time using UTC.
func timeNowUTC() time.Time {
return time.Now().UTC()
}

// dependencies abstracts the dependencies used by [*Handler].
type dependencies struct {
GzipNewWriterLevel func(w io.Writer, level int) (*gzip.Writer, error)
Expand Down Expand Up @@ -104,7 +109,7 @@ func NewHandler(datadir string, logger model.Logger) *Handler {
//
// This method LOCKS and MUTATES the .sessions field.
func (h *Handler) createSession(UUID string) {
now := time.Now()
now := timeNowUTC()
session := &sessionInfo{
stamp: now,
serverSchema: model.ServerSchema{
Expand Down Expand Up @@ -156,7 +161,7 @@ func (h *Handler) getSessionState(UUID string) sessionState {
// The integer argument, currently ignored, contains the number of bytes
// that were sent as part of the current DASH iteration.
func (h *Handler) updateSession(UUID string, _ int) {
now := time.Now()
now := timeNowUTC()
h.mtx.Lock()
defer h.mtx.Unlock()
session, ok := h.sessions[UUID]
Expand Down Expand Up @@ -198,7 +203,7 @@ func (h *Handler) reapStaleSessions() {
h.mtx.Lock()
defer h.mtx.Unlock()
h.logger.Debugf("reapStaleSessions: inspecting %d sessions", len(h.sessions))
now := time.Now()
now := timeNowUTC()
var stale []string
for UUID, session := range h.sessions {
const toomuch = 60 * time.Second
Expand Down Expand Up @@ -381,9 +386,7 @@ func (h *Handler) savedata(session *sessionInfo) error {
}

// append the file name to the path
//
// TODO(bassosimone): this code does not work as intended on Windows
name += "/neubot-dash-" + session.stamp.Format("20060102T150405.000000000Z") + ".json.gz"
name = path.Join(name, "/neubot-dash-"+session.stamp.Format("20060102T150405.000000000Z")+".json.gz")

// open the results file
//
Expand Down
20 changes: 13 additions & 7 deletions server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
Expand Down Expand Up @@ -72,7 +71,7 @@ func TestServerNegotiate(t *testing.T) {
if resp.StatusCode != 200 {
t.Fatal("Expected different status code")
}
data, err := ioutil.ReadAll(resp.Body)
data, err := io.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -213,7 +212,7 @@ func TestServerDownload(t *testing.T) {
if resp.StatusCode != 200 {
t.Fatal("Expected different status code")
}
data, err := ioutil.ReadAll(resp.Body)
data, err := io.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -268,7 +267,7 @@ func TestServerSaveData(t *testing.T) {
handler.deps.OSOpenFile = func(
name string, flag int, perm os.FileMode,
) (*os.File, error) {
return ioutil.TempFile("", "neubot-dash-tests")
return os.CreateTemp("", "neubot-dash-tests")
}
handler.deps.GzipNewWriterLevel = func(
w io.Writer, level int,
Expand All @@ -292,7 +291,7 @@ func TestServerSaveData(t *testing.T) {
handler.deps.OSOpenFile = func(
name string, flag int, perm os.FileMode,
) (*os.File, error) {
return ioutil.TempFile("", "neubot-dash-tests")
return os.CreateTemp("", "neubot-dash-tests")
}
handler.deps.JSONMarshal = func(v interface{}) ([]byte, error) {
return nil, errors.New("Mocked error")
Expand All @@ -311,15 +310,22 @@ func TestServerSaveData(t *testing.T) {
handler.deps.OSMkdirAll = func(path string, perm os.FileMode) error {
return nil
}
sessionInfo.stamp = time.Date(2024, time.January, 29, 20, 23, 0, 0, time.UTC) // predictable
expectFilename := "dash/2024/01/29/neubot-dash-20240129T202300.000000000Z.json.gz"
var gotFilename string
handler.deps.OSOpenFile = func(
name string, flag int, perm os.FileMode,
) (*os.File, error) {
return ioutil.TempFile("", "neubot-dash-tests")
gotFilename = name
return os.CreateTemp("", "neubot-dash-tests")
}
err := handler.savedata(sessionInfo)
if err != nil {
t.Fatal(err)
}
if gotFilename != expectFilename {
t.Fatal("expected", expectFilename, "got", gotFilename)
}
})
}

Expand All @@ -335,7 +341,7 @@ func TestServerCollect(t *testing.T) {
}
})

t.Run("ioutil.ReadAll failure", func(t *testing.T) {
t.Run("io.ReadAll failure", func(t *testing.T) {
const session = "deadbeef"
handler := NewHandler("", log.Log)
handler.createSession(session)
Expand Down

0 comments on commit 49a6010

Please sign in to comment.