telegraf/plugins/inputs/minecraft/minecraft_test.go

235 lines
5.3 KiB
Go

package minecraft
import (
"fmt"
"reflect"
"testing"
"github.com/influxdata/telegraf/testutil"
)
// TestParsePlayerName tests different Minecraft RCON inputs for players
func TestParsePlayerName(t *testing.T) {
// Test a valid input string to ensure player is extracted
input := "1 tracked objective(s) for divislight:- jumps: 178 (jumps)"
got, err := ParsePlayerName(input)
want := "divislight"
if err != nil {
t.Fatalf("player returned error. Error: %s\n", err)
}
if got != want {
t.Errorf("got %s\nwant %s\n", got, want)
}
// Test an invalid input string to ensure error is returned
input = ""
got, err = ParsePlayerName(input)
want = ""
if err == nil {
t.Fatal("Expected error when player not present. No error found.")
}
if got != want {
t.Errorf("got %s\n want %s\n", got, want)
}
// Test an invalid input string to ensure error is returned
input = "1 tracked objective(s) for 😂:- jumps: 178 (jumps)"
got, err = ParsePlayerName(input)
want = "😂"
if err != nil {
t.Fatalf("player returned error. Error: %s\n", err)
}
if got != want {
t.Errorf("got %s\n want %s\n", got, want)
}
}
// TestParseScoreboard tests different Minecraft RCON inputs for scoreboard stats.
func TestParseScoreboard(t *testing.T) {
// test a valid input string to ensure stats are parsed correctly.
input := `1 tracked objective(s) for divislight:- jumps: 178 (jumps)- sword: 5 (sword)`
got, err := ParseScoreboard(input)
if err != nil {
t.Fatal("Unexpected error")
}
want := []Score{
{
Name: "jumps",
Value: 178,
},
{
Name: "sword",
Value: 5,
},
}
if !reflect.DeepEqual(got, want) {
t.Errorf("Got: \n%#v\nWant: %#v", got, want)
}
// Tests a partial input string.
input = `1 tracked objective(s) for divislight:- jumps: (jumps)- sword: 5 (sword)`
got, err = ParseScoreboard(input)
if err != nil {
t.Fatal("Unexpected error")
}
want = []Score{
{
Name: "sword",
Value: 5,
},
}
if !reflect.DeepEqual(got, want) {
t.Errorf("Got: \n%#v\nWant:\n%#v", got, want)
}
// Tests an empty string.
input = ``
_, err = ParseScoreboard(input)
if err == nil {
t.Fatal("Expected input error, but error was nil")
}
// Tests when a number isn't an integer.
input = `1 tracked objective(s) for divislight:- jumps: 178.5 (jumps)- sword: 5 (sword)`
got, err = ParseScoreboard(input)
if err != nil {
t.Fatal("Unexpected error")
}
want = []Score{
{
Name: "sword",
Value: 5,
},
}
if !reflect.DeepEqual(got, want) {
t.Errorf("Got: \n%#v\nWant: %#v", got, want)
}
//Testing a real life data scenario with unicode characters
input = `7 tracked objective(s) for mauxlaim:- total_kills: 39 (total_kills)- "howdy doody": 37 (dalevel)- howdy: 37 (lvl)- jumps: 1290 (jumps)- iron_pickaxe: 284 (iron_pickaxe)- cow_kills: 1 (cow_kills)- "asdf": 37 (😂)`
got, err = ParseScoreboard(input)
if err != nil {
t.Fatal("Unexpected error")
}
want = []Score{
{
Name: "total_kills",
Value: 39,
},
{
Name: "dalevel",
Value: 37,
},
{
Name: "lvl",
Value: 37,
},
{
Name: "jumps",
Value: 1290,
},
{
Name: "iron_pickaxe",
Value: 284,
},
{
Name: "cow_kills",
Value: 1,
},
{
Name: "😂",
Value: 37,
},
}
if !reflect.DeepEqual(got, want) {
t.Errorf("Got: \n%#v\nWant: %#v", got, want)
}
}
type MockClient struct {
Result []string
Err error
}
func (m *MockClient) Gather(d RCONClientProducer) ([]string, error) {
return m.Result, m.Err
}
func TestGather(t *testing.T) {
var acc testutil.Accumulator
testConfig := Minecraft{
Server: "biffsgang.net",
Port: "25575",
client: &MockClient{
Result: []string{
`1 tracked objective(s) for divislight:- jumps: 178 (jumps)`,
`7 tracked objective(s) for mauxlaim:- total_kills: 39 (total_kills)- "howdy doody": 37 (dalevel)- howdy: 37 (lvl)- jumps: 1290 (jumps)- iron_pickaxe: 284 (iron_pickaxe)- cow_kills: 1 (cow_kills)- "asdf": 37 (😂)`,
`5 tracked objective(s) for torham:- total_kills: 29 (total_kills)- "howdy doody": 33 (dalevel)- howdy: 33 (lvl)- jumps: 263 (jumps)- "asdf": 33 (😂)`,
},
Err: nil,
},
clientSet: true,
}
err := testConfig.Gather(&acc)
if err != nil {
t.Fatalf("gather returned error. Error: %s\n", err)
}
if !testConfig.clientSet {
t.Fatalf("clientSet should be true, client should be set")
}
tags := map[string]string{
"player": "divislight",
"server": "biffsgang.net:25575",
}
assertContainsTaggedStat(t, &acc, "minecraft", "jumps", 178, tags)
tags["player"] = "mauxlaim"
assertContainsTaggedStat(t, &acc, "minecraft", "cow_kills", 1, tags)
tags["player"] = "torham"
assertContainsTaggedStat(t, &acc, "minecraft", "total_kills", 29, tags)
}
func assertContainsTaggedStat(
t *testing.T,
acc *testutil.Accumulator,
measurement string,
field string,
expectedValue int,
tags map[string]string,
) {
var actualValue int
for _, pt := range acc.Metrics {
if pt.Measurement == measurement && reflect.DeepEqual(pt.Tags, tags) {
for fieldname, value := range pt.Fields {
if fieldname == field {
actualValue = value.(int)
if value == expectedValue {
return
}
t.Errorf("Expected value %d\n got value %d\n", expectedValue, value)
}
}
}
}
msg := fmt.Sprintf(
"Could not find measurement \"%s\" with requested tags within %s, Actual: %d",
measurement, field, actualValue)
t.Fatal(msg)
}