Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
393
plugins/inputs/modbus/configuration_metric_test.go
Normal file
393
plugins/inputs/modbus/configuration_metric_test.go
Normal file
|
@ -0,0 +1,393 @@
|
|||
package modbus
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
mb "github.com/grid-x/modbus"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tbrandon/mbserver"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/metric"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
func TestMetric(t *testing.T) {
|
||||
plugin := Modbus{
|
||||
Name: "Test",
|
||||
Controller: "tcp://localhost:1502",
|
||||
ConfigurationType: "metric",
|
||||
Log: testutil.Logger{},
|
||||
}
|
||||
plugin.Metrics = []metricDefinition{
|
||||
{
|
||||
SlaveID: 1,
|
||||
ByteOrder: "ABCD",
|
||||
Measurement: "test",
|
||||
Fields: []metricFieldDefinition{
|
||||
{
|
||||
Name: "coil-0",
|
||||
Address: uint16(0),
|
||||
RegisterType: "coil",
|
||||
},
|
||||
{
|
||||
Name: "coil-1",
|
||||
Address: uint16(1),
|
||||
RegisterType: "coil",
|
||||
},
|
||||
{
|
||||
Name: "holding-0",
|
||||
Address: uint16(0),
|
||||
InputType: "INT16",
|
||||
},
|
||||
{
|
||||
Name: "holding-1",
|
||||
Address: uint16(1),
|
||||
InputType: "UINT16",
|
||||
RegisterType: "holding",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
SlaveID: 1,
|
||||
ByteOrder: "ABCD",
|
||||
Fields: []metricFieldDefinition{
|
||||
{
|
||||
Name: "coil-0",
|
||||
Address: uint16(2),
|
||||
RegisterType: "coil",
|
||||
},
|
||||
{
|
||||
Name: "coil-1",
|
||||
Address: uint16(3),
|
||||
RegisterType: "coil",
|
||||
},
|
||||
{
|
||||
Name: "holding-0",
|
||||
Address: uint16(2),
|
||||
InputType: "INT64",
|
||||
Scale: 1.2,
|
||||
OutputType: "FLOAT64",
|
||||
},
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"location": "main building",
|
||||
"device": "mydevice",
|
||||
},
|
||||
},
|
||||
{
|
||||
SlaveID: 2,
|
||||
Fields: []metricFieldDefinition{
|
||||
{
|
||||
Name: "coil-6",
|
||||
Address: uint16(6),
|
||||
RegisterType: "coil",
|
||||
},
|
||||
{
|
||||
Name: "coil-7",
|
||||
Address: uint16(7),
|
||||
RegisterType: "coil",
|
||||
},
|
||||
{
|
||||
Name: "discrete-0",
|
||||
Address: uint16(0),
|
||||
RegisterType: "discrete",
|
||||
},
|
||||
{
|
||||
Name: "holding-99",
|
||||
Address: uint16(99),
|
||||
InputType: "INT16",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
SlaveID: 2,
|
||||
Fields: []metricFieldDefinition{
|
||||
{
|
||||
Name: "coil-4",
|
||||
Address: uint16(4),
|
||||
RegisterType: "coil",
|
||||
},
|
||||
{
|
||||
Name: "coil-5",
|
||||
Address: uint16(5),
|
||||
RegisterType: "coil",
|
||||
},
|
||||
{
|
||||
Name: "input-0",
|
||||
Address: uint16(0),
|
||||
RegisterType: "input",
|
||||
InputType: "UINT16",
|
||||
},
|
||||
{
|
||||
Name: "input-1",
|
||||
Address: uint16(2),
|
||||
RegisterType: "input",
|
||||
InputType: "UINT16",
|
||||
},
|
||||
{
|
||||
Name: "holding-9",
|
||||
Address: uint16(9),
|
||||
InputType: "INT16",
|
||||
},
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"location": "main building",
|
||||
"device": "mydevice",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, plugin.Init())
|
||||
require.NotEmpty(t, plugin.requests)
|
||||
|
||||
require.NotNil(t, plugin.requests[1])
|
||||
require.Len(t, plugin.requests[1].coil, 1, "coil 1")
|
||||
require.Len(t, plugin.requests[1].holding, 1, "holding 1")
|
||||
require.Empty(t, plugin.requests[1].discrete)
|
||||
require.Empty(t, plugin.requests[1].input)
|
||||
|
||||
require.NotNil(t, plugin.requests[2])
|
||||
require.Len(t, plugin.requests[2].coil, 1, "coil 2")
|
||||
require.Len(t, plugin.requests[2].holding, 2, "holding 2")
|
||||
require.Len(t, plugin.requests[2].discrete, 1, "discrete 2")
|
||||
require.Len(t, plugin.requests[2].input, 2, "input 2")
|
||||
}
|
||||
|
||||
func TestMetricResult(t *testing.T) {
|
||||
data := []byte{
|
||||
0x00, 0x0A, // 10
|
||||
0x00, 0x2A, // 42
|
||||
0x00, 0x00, 0x08, 0x98, // 2200
|
||||
0x00, 0x00, 0x08, 0x99, // 2201
|
||||
0x00, 0x00, 0x08, 0x9A, // 2202
|
||||
0x40, 0x49, 0x0f, 0xdb, // float32 of 3.1415927410125732421875
|
||||
0x4d, 0x6f, 0x64, 0x62, 0x75, 0x73, 0x20, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, // String "Modbus String"
|
||||
}
|
||||
|
||||
// Write the data to a fake server
|
||||
serv := mbserver.NewServer()
|
||||
require.NoError(t, serv.ListenTCP("localhost:1502"))
|
||||
defer serv.Close()
|
||||
|
||||
handler := mb.NewTCPClientHandler("localhost:1502")
|
||||
require.NoError(t, handler.Connect())
|
||||
defer handler.Close()
|
||||
client := mb.NewClient(handler)
|
||||
|
||||
quantity := uint16(len(data) / 2)
|
||||
_, err := client.WriteMultipleRegisters(1, quantity, data)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Setup the plugin
|
||||
plugin := Modbus{
|
||||
Name: "FAKEMETER",
|
||||
Controller: "tcp://localhost:1502",
|
||||
ConfigurationType: "metric",
|
||||
Log: testutil.Logger{},
|
||||
}
|
||||
plugin.Metrics = []metricDefinition{
|
||||
{
|
||||
SlaveID: 1,
|
||||
ByteOrder: "ABCD",
|
||||
Measurement: "machine",
|
||||
Fields: []metricFieldDefinition{
|
||||
{
|
||||
Name: "hours",
|
||||
Address: uint16(1),
|
||||
InputType: "UINT16",
|
||||
RegisterType: "holding",
|
||||
},
|
||||
{
|
||||
Name: "temperature",
|
||||
Address: uint16(2),
|
||||
InputType: "INT16",
|
||||
RegisterType: "holding",
|
||||
},
|
||||
{
|
||||
Name: "comment",
|
||||
Address: uint16(11),
|
||||
Length: 7,
|
||||
InputType: "STRING",
|
||||
RegisterType: "holding",
|
||||
},
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"location": "main building",
|
||||
"device": "machine A",
|
||||
},
|
||||
},
|
||||
{
|
||||
SlaveID: 1,
|
||||
ByteOrder: "ABCD",
|
||||
Measurement: "machine",
|
||||
Fields: []metricFieldDefinition{
|
||||
{
|
||||
Name: "hours",
|
||||
Address: uint16(3),
|
||||
InputType: "UINT32",
|
||||
Scale: 0.01,
|
||||
},
|
||||
{
|
||||
Name: "temperature",
|
||||
Address: uint16(5),
|
||||
InputType: "INT32",
|
||||
Scale: 0.02,
|
||||
},
|
||||
{
|
||||
Name: "output",
|
||||
Address: uint16(7),
|
||||
InputType: "UINT32",
|
||||
},
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"location": "main building",
|
||||
"device": "machine B",
|
||||
},
|
||||
},
|
||||
{
|
||||
SlaveID: 1,
|
||||
Fields: []metricFieldDefinition{
|
||||
{
|
||||
Name: "pi",
|
||||
Address: uint16(9),
|
||||
InputType: "FLOAT32",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
SlaveID: 1,
|
||||
Measurement: "bitvalues",
|
||||
Fields: []metricFieldDefinition{
|
||||
{
|
||||
Name: "bit 0",
|
||||
Address: uint16(1),
|
||||
InputType: "BIT",
|
||||
Bit: 0,
|
||||
},
|
||||
{
|
||||
Name: "bit 1",
|
||||
Address: uint16(1),
|
||||
InputType: "BIT",
|
||||
Bit: 1,
|
||||
},
|
||||
{
|
||||
Name: "bit 2",
|
||||
Address: uint16(1),
|
||||
InputType: "BIT",
|
||||
Bit: 2,
|
||||
},
|
||||
{
|
||||
Name: "bit 3",
|
||||
Address: uint16(1),
|
||||
InputType: "BIT",
|
||||
Bit: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
require.NoError(t, plugin.Init())
|
||||
|
||||
// Check the generated requests
|
||||
require.Len(t, plugin.requests, 1)
|
||||
require.NotNil(t, plugin.requests[1])
|
||||
require.Len(t, plugin.requests[1].holding, 5)
|
||||
require.Empty(t, plugin.requests[1].coil)
|
||||
require.Empty(t, plugin.requests[1].discrete)
|
||||
require.Empty(t, plugin.requests[1].input)
|
||||
|
||||
// Gather the data and verify the resulting metrics
|
||||
var acc testutil.Accumulator
|
||||
require.NoError(t, plugin.Gather(&acc))
|
||||
|
||||
expected := []telegraf.Metric{
|
||||
metric.New(
|
||||
"machine",
|
||||
map[string]string{
|
||||
"name": "FAKEMETER",
|
||||
"location": "main building",
|
||||
"device": "machine A",
|
||||
"slave_id": "1",
|
||||
"type": "holding_register",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"hours": uint64(10),
|
||||
"temperature": int64(42),
|
||||
"comment": "Modbus String",
|
||||
},
|
||||
time.Unix(0, 0),
|
||||
),
|
||||
metric.New(
|
||||
"machine",
|
||||
map[string]string{
|
||||
"name": "FAKEMETER",
|
||||
"location": "main building",
|
||||
"device": "machine B",
|
||||
"slave_id": "1",
|
||||
"type": "holding_register",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"hours": float64(22.0),
|
||||
"temperature": float64(44.02),
|
||||
"output": uint64(2202),
|
||||
},
|
||||
time.Unix(0, 0),
|
||||
),
|
||||
metric.New(
|
||||
"modbus",
|
||||
map[string]string{
|
||||
"name": "FAKEMETER",
|
||||
"slave_id": "1",
|
||||
"type": "holding_register",
|
||||
},
|
||||
map[string]interface{}{"pi": float64(3.1415927410125732421875)},
|
||||
time.Unix(0, 0),
|
||||
),
|
||||
metric.New(
|
||||
"bitvalues",
|
||||
map[string]string{
|
||||
"name": "FAKEMETER",
|
||||
"slave_id": "1",
|
||||
"type": "holding_register",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"bit 0": uint64(0),
|
||||
"bit 1": uint64(1),
|
||||
"bit 2": uint64(0),
|
||||
"bit 3": uint64(1),
|
||||
},
|
||||
time.Unix(0, 0),
|
||||
),
|
||||
}
|
||||
|
||||
actual := acc.GetTelegrafMetrics()
|
||||
testutil.RequireMetricsEqual(t, expected, actual, testutil.IgnoreTime(), testutil.SortMetrics())
|
||||
}
|
||||
|
||||
func TestMetricAddressOverflow(t *testing.T) {
|
||||
logger := &testutil.CaptureLogger{}
|
||||
plugin := Modbus{
|
||||
Name: "Test",
|
||||
Controller: "tcp://localhost:1502",
|
||||
ConfigurationType: "metric",
|
||||
Log: logger,
|
||||
Workarounds: workarounds{ReadCoilsStartingAtZero: true},
|
||||
}
|
||||
plugin.Metrics = []metricDefinition{
|
||||
{
|
||||
SlaveID: 1,
|
||||
ByteOrder: "ABCD",
|
||||
Measurement: "test",
|
||||
Fields: []metricFieldDefinition{
|
||||
{
|
||||
Name: "field",
|
||||
Address: uint16(65534),
|
||||
InputType: "UINT64",
|
||||
RegisterType: "holding",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
require.ErrorIs(t, plugin.Init(), errAddressOverflow)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue