0
0
Fork 0
mirror of https://github.com/netdata/netdata.git synced 2025-04-14 01:29:11 +00:00

go.d icecast single source response ()

This commit is contained in:
Ilya Mashchenko 2024-07-18 12:55:42 +03:00 committed by GitHub
parent 4e2076d8b1
commit 073e2d4110
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 116 additions and 25 deletions

View file

@ -11,19 +11,6 @@ import (
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
)
type (
serverStats struct {
IceStats *struct {
Source []sourceStats `json:"source"`
} `json:"icestats"`
}
sourceStats struct {
ServerName string `json:"server_name"`
StreamStart string `json:"stream_start"`
Listeners int64 `json:"listeners"`
}
)
const (
urlPathServerStats = "/status-json.xsl" // https://icecast.org/docs/icecast-trunk/server_stats/
)

View file

@ -19,16 +19,18 @@ var (
dataConfigJSON, _ = os.ReadFile("testdata/config.json")
dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
dataServerStats, _ = os.ReadFile("testdata/server_stats.json")
dataServerStatsNoSources, _ = os.ReadFile("testdata/server_stats_no_sources.json")
dataServerStatsMultiSource, _ = os.ReadFile("testdata/stats_multi_source.json")
dataServerStatsSingleSource, _ = os.ReadFile("testdata/stats_single_source.json")
dataServerStatsNoSources, _ = os.ReadFile("testdata/stats_no_sources.json")
)
func Test_testDataIsValid(t *testing.T) {
for name, data := range map[string][]byte{
"dataConfigJSON": dataConfigJSON,
"dataConfigYAML": dataConfigYAML,
"dataServerStats": dataServerStats,
"dataServerStatsNoSources": dataServerStatsNoSources,
"dataConfigJSON": dataConfigJSON,
"dataConfigYAML": dataConfigYAML,
"dataServerStats": dataServerStatsMultiSource,
"dataServerStatsSingleSource": dataServerStatsSingleSource,
"dataServerStatsNoSources": dataServerStatsNoSources,
} {
require.NotNil(t, data, name)
}
@ -80,9 +82,13 @@ func TestIcecast_Check(t *testing.T) {
wantFail bool
prepare func(t *testing.T) (*Icecast, func())
}{
"success default config": {
"success multiple sources": {
wantFail: false,
prepare: prepareCaseOk,
prepare: prepareCaseMultipleSources,
},
"success single source": {
wantFail: false,
prepare: prepareCaseMultipleSources,
},
"fails on no sources": {
wantFail: true,
@ -122,14 +128,21 @@ func TestIcecast_Collect(t *testing.T) {
wantMetrics map[string]int64
wantCharts int
}{
"success default config": {
prepare: prepareCaseOk,
"success multiple sources": {
prepare: prepareCaseMultipleSources,
wantCharts: len(sourceChartsTmpl) * 2,
wantMetrics: map[string]int64{
"source_abc_listeners": 1,
"source_efg_listeners": 10,
},
},
"success single source": {
prepare: prepareCaseSingleSource,
wantCharts: len(sourceChartsTmpl) * 1,
wantMetrics: map[string]int64{
"source_abc_listeners": 1,
},
},
"fails on no sources": {
prepare: prepareCaseNoSources,
},
@ -160,13 +173,32 @@ func TestIcecast_Collect(t *testing.T) {
}
}
func prepareCaseOk(t *testing.T) (*Icecast, func()) {
func prepareCaseMultipleSources(t *testing.T) (*Icecast, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case urlPathServerStats:
_, _ = w.Write(dataServerStats)
_, _ = w.Write(dataServerStatsMultiSource)
default:
w.WriteHeader(http.StatusNotFound)
}
}))
icecast := New()
icecast.URL = srv.URL
require.NoError(t, icecast.Init())
return icecast, srv.Close
}
func prepareCaseSingleSource(t *testing.T) (*Icecast, func()) {
t.Helper()
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case urlPathServerStats:
_, _ = w.Write(dataServerStatsSingleSource)
default:
w.WriteHeader(http.StatusNotFound)
}

View file

@ -0,0 +1,45 @@
// SPDX-License-Identifier: GPL-3.0-or-later
package icecast
import (
"encoding/json"
"fmt"
)
type (
serverStats struct {
IceStats *struct {
Source iceSource `json:"source"`
} `json:"icestats"`
}
iceSource []sourceStats
sourceStats struct {
ServerName string `json:"server_name"`
StreamStart string `json:"stream_start"`
Listeners int64 `json:"listeners"`
}
)
func (i *iceSource) UnmarshalJSON(data []byte) error {
var v any
if err := json.Unmarshal(data, &v); err != nil {
return err
}
switch v.(type) {
case []any:
type plain iceSource
return json.Unmarshal(data, (*plain)(i))
case map[string]any:
var s sourceStats
if err := json.Unmarshal(data, &s); err != nil {
return err
}
*i = []sourceStats{s}
default:
return fmt.Errorf("invalid source data type: expected array or object")
}
return nil
}

View file

@ -0,0 +1,27 @@
{
"icestats": {
"admin": "icemaster@localhost",
"host": "localhost",
"location": "Earth",
"server_id": "Icecast 2.4.4",
"server_start": "Wed, 17 Jul 2024 11:27:40 +0300",
"server_start_iso8601": "2024-07-17T11:27:40+0300",
"source": {
"audio_info": "ice-bitrate=128;ice-channels=2;ice-samplerate=44100",
"genre": "(null)",
"ice-bitrate": 128,
"ice-channels": 2,
"ice-samplerate": 44100,
"listener_peak": 2,
"listeners": 1,
"listenurl": "http://localhost:8000/line.nsv",
"server_description": "(null)",
"server_name": "abc",
"server_type": "audio/mpeg",
"server_url": "(null)",
"stream_start": "Wed, 17 Jul 2024 12:10:20 +0300",
"stream_start_iso8601": "2024-07-17T12:10:20+0300",
"dummy": null
}
}
}