Metrics are served on METRICS_PORT (default 2112, "off" to disable), never on the public port. Besides the Go runtime and process metrics this adds: - http_requests_total and http_request_duration_seconds per route pattern, from an Echo middleware. - musicserver_songs_requested_total and musicserver_songs_played_total by pick mode (random, low, classic). The mode is now stored with each queued song (migration 000006, not released yet). - Library size, sync duration, last successful sync, broken songs from the last full sync, and the database connection pool. Refs #35, #36, #37 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
103 lines
3.1 KiB
Go
103 lines
3.1 KiB
Go
//go:build integration
|
|
|
|
package backend
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"music-server/internal/db/repository"
|
|
"music-server/internal/testutil/pgtest"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestLibraryAndStatisticsWithPostgres checks the UUID and statistics queries against a real database.
|
|
func TestLibraryAndStatisticsWithPostgres(t *testing.T) {
|
|
ctx := context.Background()
|
|
q := repository.New(pgtest.NewMigratedDatabase(t).Pool)
|
|
musicDir := copyTestMusic(t)
|
|
require.NoError(t, os.Mkdir(filepath.Join(musicDir, "Empty Soundtrack"), 0o755))
|
|
writeFile(t, filepath.Join(musicDir, "Empty Soundtrack", "cover.jpg"), "image")
|
|
|
|
s := NewSyncService(q, musicDir, nil)
|
|
require.True(t, s.Start(false))
|
|
s.Wait()
|
|
require.Empty(t, s.Result().CatchedErrors)
|
|
|
|
count, err := q.CountLibrary(ctx)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(4), count.Soundtracks)
|
|
require.NoError(t, s.UpdateLibraryMetrics(ctx))
|
|
|
|
library := NewLibraryService(q)
|
|
soundtracks, err := library.Soundtracks(ctx)
|
|
require.NoError(t, err)
|
|
require.Len(t, soundtracks, 4)
|
|
|
|
bird, err := library.Soundtrack(ctx, soundtracks[0].Uuid)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "A Bird Story", bird.Name)
|
|
require.Len(t, bird.Songs, 6)
|
|
song := bird.Songs[0]
|
|
assert.Equal(t, bird.Uuid, song.SoundtrackUuid)
|
|
|
|
info, err := library.Song(ctx, song.Uuid)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "A Bird Story", info.SoundtrackName)
|
|
path, err := library.SongPath(ctx, song.Uuid)
|
|
require.NoError(t, err)
|
|
assert.FileExists(t, path)
|
|
_, err = library.Song(ctx, uuid.New())
|
|
assert.ErrorIs(t, err, ErrNotFound)
|
|
|
|
// Play counts by UUID.
|
|
require.NoError(t, q.AddSongPlayedByUUID(ctx, song.Uuid))
|
|
require.NoError(t, q.AddSoundtrackPlayedByUUID(ctx, bird.Uuid))
|
|
info, err = library.Song(ctx, song.Uuid)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int32(1), info.TimesPlayed)
|
|
|
|
stats := NewStatisticsService(q)
|
|
most, err := stats.MostPlayedSoundtracks(ctx, 10)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, most)
|
|
assert.Equal(t, bird.Uuid, most[0].SoundtrackUuid)
|
|
assert.Len(t, most[0].Songs, 6)
|
|
assert.NotEqual(t, uuid.Nil, most[0].Songs[0].SongUuid)
|
|
|
|
songs, err := stats.MostPlayedSongs(ctx, 1)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, song.Uuid, songs[0].SongUuid)
|
|
assert.Equal(t, bird.Uuid, songs[0].SoundtrackUuid)
|
|
|
|
all, err := stats.AllSoundtracks(ctx)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, all)
|
|
for i := 1; i < len(all); i++ {
|
|
assert.LessOrEqual(t, all[i-1].SoundtrackName, all[i].SoundtrackName, "sorted by name")
|
|
}
|
|
for _, st := range all {
|
|
if st.SoundtrackUuid == bird.Uuid {
|
|
assert.Equal(t, int32(1), st.SoundtrackPlayed)
|
|
assert.Len(t, st.Songs, 6)
|
|
}
|
|
if st.SoundtrackName == "Empty Soundtrack" {
|
|
assert.Empty(t, st.Songs, "a soundtrack without songs has an empty song list")
|
|
}
|
|
}
|
|
|
|
never, err := stats.NeverPlayedSoundtracks(ctx)
|
|
require.NoError(t, err)
|
|
for _, st := range never {
|
|
assert.NotEqual(t, uuid.Nil, st.SoundtrackUuid)
|
|
if st.SoundtrackName == "Empty Soundtrack" {
|
|
assert.Empty(t, st.Songs, "a soundtrack without songs has an empty song list")
|
|
}
|
|
}
|
|
}
|