Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

16 unit tests #86

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
38 changes: 35 additions & 3 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.19
go-version: 1.21
check-latest: true
cache: true

Expand All @@ -28,6 +28,38 @@ jobs:

- name: Test
run: export CI=true && go test -v ./...

test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Apt update
run: sudo apt update --fix-missing

- name: Install dependencies
run: sudo apt install libasound2-dev libudev-dev pkg-config

- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.21
check-latest: true
cache: true

- name: Run Tests
run: go test -coverprofile coverage.out

- name: Create Coverage Report
run: go tool cover -html coverage.out -o coverage.html

- name: Upload test coverage
uses: actions/upload-artifact@v3
with:
name: Unit Test Results
path: coverage.html

# configuration: https://github.com/golangci/golangci-lint-action
golangci:
name: lint
Expand All @@ -36,12 +68,12 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.20'
go-version: '1.21'
cache: false
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
# Require: The version of golangci-lint to use.
# When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version.
# When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit.
version: v1.53
version: v1.55.2
19 changes: 19 additions & 0 deletions cache/cache_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package cache

import "testing"

func TestClearPodcastPlayedCache(t *testing.T) {
tests := []struct {
name string
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := ClearPodcastPlayedCache(); (err != nil) != tt.wantErr {
t.Errorf("ClearPodcastPlayedCache() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
8 changes: 4 additions & 4 deletions content/file.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package content

import (
"errors"
"fmt"
"io"
"os"
Expand All @@ -18,6 +17,7 @@ import (
"github.com/faiface/beep/wav"
"github.com/h2non/filetype"
"github.com/hcl/audioduration"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)

Expand All @@ -43,7 +43,7 @@ func (l *LocalFile) Get() error {

f, err := os.Open(l.Path)
if err != nil {
return errors.New(fmt.Sprintf("unable to open file from path: %v", err)) //nolint:lll,revive,gosimple,nolintlint // error pref
return errors.New(fmt.Sprintf("unable to open file from path %s", err.Error())) //nolint:lll,revive,gosimple,nolintlint // error pref
}

log.Infof("decoding file from %v", l.Path)
Expand All @@ -58,7 +58,7 @@ func (l *LocalFile) Play() error {

err := l.setDecoder()
if err != nil {
return errors.New(fmt.Sprintf("error setting decoder: %v", err)) //nolint:revive,gosimple // error pref
return errors.New(fmt.Sprintf("error setting decoder: %v", err)) //nolint:revive
}

_, err = l.Content.Seek(0, 0)
Expand All @@ -69,7 +69,7 @@ func (l *LocalFile) Play() error {
if l.fileType == wavFile || l.fileType == flacFile {
streamer, format, err = l.decodeReader(l.Content)
if err != nil {
return errors.New(fmt.Sprintf("unable to decode file: %v", err)) //nolint:revive,gosimple // error pref
return errors.New(fmt.Sprintf("unable to decode file: %v", err)) //nolint:revive
}
}

Expand Down
80 changes: 73 additions & 7 deletions content/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing"

"github.com/faiface/beep"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)

Expand All @@ -15,6 +16,7 @@ const (
)

func TestLocalFile_Get(t *testing.T) {
t.Parallel()
type fields struct {
Name string
Content *os.File
Expand All @@ -23,22 +25,86 @@ func TestLocalFile_Get(t *testing.T) {
decodeReadCloser func(rc io.ReadCloser) (s beep.StreamSeekCloser, format beep.Format, err error)
fileType string
}
type want struct {
err error
}
tests := []struct {
name string
fields fields
prepare func(t *testing.T, f *fields) *LocalFile
wantErr bool
want want
}{
//nolint:godox // TODO: Add test cases.
{
name: "Success: Open file without error",
fields: fields{
Name: "localfile_test",
Path: "./",
decodeReader: nil,
decodeReadCloser: nil,
fileType: ".txt",
},
prepare: func(t *testing.T, f *fields) *LocalFile {
t.Helper()
return &LocalFile{
Name: f.Name,
Path: f.Path,
decodeReader: f.decodeReader,
decodeReadCloser: f.decodeReadCloser,
fileType: f.fileType,
}
},
wantErr: false,
},
{
name: "Error: failed to open file",
fields: fields{
Name: "adsadsada",
Path: "32190da",
decodeReader: nil,
decodeReadCloser: nil,
fileType: ".txt",
},
prepare: func(t *testing.T, f *fields) *LocalFile {
t.Helper()
f.decodeReader = func(r io.Reader) (s beep.StreamSeekCloser, format beep.Format, err error) {
return nil, beep.Format{}, err
}
f.decodeReadCloser = func(rc io.ReadCloser) (s beep.StreamSeekCloser, format beep.Format, err error) {
return nil, beep.Format{}, err
}
return &LocalFile{
Name: f.Name,
Path: f.Path,
decodeReader: f.decodeReader,
decodeReadCloser: f.decodeReadCloser,
fileType: f.fileType,
}
},
wantErr: true,
want: want{
err: errors.New("unable to open file from path open 32190da: no such file or directory"),
},
},
}
for _, tt := range tests {
tt := tt // pin
t.Run(tt.name, func(t *testing.T) {
l := &LocalFile{
Name: tt.fields.Name,
Content: tt.fields.Content,
Path: tt.fields.Path,
t.Parallel()

// create temporary file
tmpFile, err := os.CreateTemp("", "localfile_test.txt")
if err != nil {
t.Fatalf("failed to create temporary file: %v", err)
}
if err := l.Get(); (err != nil) != tt.wantErr {
t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr)
defer os.Remove(tmpFile.Name())

getErr := tt.prepare(t, &tt.fields).Get()
if tt.wantErr {
if getErr == nil {
t.Fatalf("getErr shoold not be nil")
}
assert.EqualError(t, getErr, tt.want.err.Error())
}
})
}
Expand Down
8 changes: 5 additions & 3 deletions content/podcast.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,12 @@ func (p *Podcast) Play() error {
log.Infof("time remaining: %v", p.Duration)
time.Sleep(p.Duration)
log.Info("stopping web radio")
err := p.Stop()
if err != nil {
log.WithError(err).Error("error stopping web radio")

podcastStopErr := p.Stop()
if podcastStopErr != nil {
log.WithError(podcastStopErr).Error("error stopping web radio")
}

close(done)
}()

Expand Down
2 changes: 1 addition & 1 deletion content/podcast_episodes_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (p *podcasts) getOldestEpisode() episode {
func (p *podcasts) getRandomEpisode() episode {
var randomEpisode episode

rand.Seed(time.Now().UnixNano())
rand.New(rand.NewSource(time.Now().UnixNano())) //nolint:gosec // weak generator fine fo this purpose

item := p.Episodes[rand.Intn(len(p.Episodes))] //nolint:gosec // weak generator fine fo this purpose
_, cacheHit := cache.PodcastPlayedCache.Get(item.GUID)
Expand Down
24 changes: 13 additions & 11 deletions content/schedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (s *Scheduler) Run() error { //nolint:godox,funlen,gocognit,cyclop,nolintli

// if content is scheduled, retrieve and play
scheduled := p.Timeslot.IsScheduledNow(now)
if scheduled {
if scheduled { //nolint:nestif
log.Infof("scheduler.Run::getting media type: %v", p.Type)

content := p.GetMedia()
Expand All @@ -78,7 +78,7 @@ func (s *Scheduler) Run() error { //nolint:godox,funlen,gocognit,cyclop,nolintli

// if p.getMediaType is webRadioContent or podcastContent start a timer and stop content from inside a go routine
// because these are streams rather than files they behave differently from local content.
switch p.getMediaType() { //nolint:exhaustive // TODO consider refactoring into function
switch p.getMediaType() { //nolint:exhaustive,dupl // TODO consider refactoring into function
case webRadioContent:
log.Info("web radio content detected")

Expand All @@ -91,9 +91,10 @@ func (s *Scheduler) Run() error { //nolint:godox,funlen,gocognit,cyclop,nolintli
go func() {
defer wg.Done()
log.Info("Run::playing web radio inside of a go routine")
err := content.Play()
if err != nil {
log.WithError(err).Error("Run::content.Play")

contentPlayErr := content.Play()
if contentPlayErr != nil {
log.WithError(contentPlayErr).Error("Run::content.Play")
} // play will block until done
}()

Expand All @@ -105,19 +106,19 @@ func (s *Scheduler) Run() error { //nolint:godox,funlen,gocognit,cyclop,nolintli
// If the StrictPodcastSchedule is set to false, use the duration of the podcast to set the countdown.
if !s.Content.StrictPodcastSchedule {
podcast.Duration = podcast.Player.duration

} else {
podcast.Duration = getDurationToEndTime(p.Timeslot.End)
}

wg.Add(1)

go func() {
defer wg.Done()
log.Info("playing podcast inside of a go routine")

err = content.Play()
contentPlayErr := content.Play()
if err != nil {
log.WithError(err).Error("Run::content.Play")
log.WithError(contentPlayErr).Error("Run::content.Play")
} // play will block until done
}()
default:
Expand Down Expand Up @@ -175,7 +176,7 @@ func (s *Scheduler) Shuffle() error { //nolint:godox,funlen,gocognit,cyclop,noli

log.Info("Starting Daemon")

rand.Seed(time.Now().UnixNano())
rand.New(rand.NewSource(time.Now().UnixNano())) //nolint:gosec // weak generator fine fo this purpose
rand.Shuffle(len(s.Content.Programs),
func(i, j int) {
s.Content.Programs[i], s.Content.Programs[j] = s.Content.Programs[j], s.Content.Programs[i]
Expand Down Expand Up @@ -228,7 +229,8 @@ func (s *Scheduler) Shuffle() error { //nolint:godox,funlen,gocognit,cyclop,noli
go func() {
defer wg.Done()
log.Info("Run::playing web radio inside of a go routine")
err := content.Play()

err = content.Play()
if err != nil {
log.WithError(err).Error("Run::content.Play")
} // play will block until done
Expand All @@ -241,12 +243,12 @@ func (s *Scheduler) Shuffle() error { //nolint:godox,funlen,gocognit,cyclop,noli
// If the StrictPodcastSchedule is set to false, use the duration of the podcast to set the countdown.
if !s.Content.StrictPodcastSchedule {
podcast.Duration = podcast.Player.duration

} else {
podcast.Duration = getDurationToEndTime(p.Timeslot.End)
}

wg.Add(1)

go func() {
defer wg.Done()
log.Info("playing podcast inside of a go routine")
Expand Down
15 changes: 11 additions & 4 deletions content/web_radio.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,23 @@ func (w *WebRadio) Play() error {
log.Infof("time remaining: %v", w.Duration)
time.Sleep(w.Duration)
log.Info("stopping web radio")
err := w.Stop()
if err != nil {
log.WithError(err).Error("error stopping web radio")

webRadioStopErr := w.Stop()
if webRadioStopErr != nil {
log.WithError(webRadioStopErr).Error("error stopping web radio")
}

close(done)
}()

go func() {
w.Player.pipeChan <- w.Player.out
}()
<-done // wait for done signal from the duration routine

}

log.Info("WebRadio.Play::returning nil")

return nil
}

Expand All @@ -87,7 +90,9 @@ func (w *WebRadio) Stop() error {

if w.Player.isPlaying {
log.Debug("WebRadio.Stop::setting isPlaying to false")

w.Player.isPlaying = false

_, err := w.Player.in.Write([]byte("q"))
if err != nil {
log.WithError(err).Error("error stopping web radio streamPlayerName: w.Player.in.Write()")
Expand All @@ -106,6 +111,8 @@ func (w *WebRadio) Stop() error {
w.Player.command = nil
w.Player.url = ""
}

log.Debug("WebRadio.Stop::returning nil")

return nil
}
Loading