mirror of
https://github.com/netdata/netdata.git
synced 2025-04-14 01:29:11 +00:00
go.d icecast single source response (#18195)
This commit is contained in:
parent
4e2076d8b1
commit
073e2d4110
6 changed files with 116 additions and 25 deletions
src/go/plugin/go.d/modules/icecast
|
@ -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/
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
45
src/go/plugin/go.d/modules/icecast/server_stats.go
Normal file
45
src/go/plugin/go.d/modules/icecast/server_stats.go
Normal 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
|
||||
}
|
27
src/go/plugin/go.d/modules/icecast/testdata/stats_single_source.json
vendored
Normal file
27
src/go/plugin/go.d/modules/icecast/testdata/stats_single_source.json
vendored
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue