github.com/influxdata/telegraf@v1.30.3/testutil/plugin_input/plugin.go (about) 1 package input 2 3 import ( 4 _ "embed" 5 "errors" 6 "os" 7 "path/filepath" 8 "time" 9 10 "github.com/influxdata/telegraf" 11 "github.com/influxdata/telegraf/plugins/inputs" 12 "github.com/influxdata/telegraf/plugins/parsers/influx/influx_upstream" 13 "github.com/influxdata/telegraf/testutil" 14 ) 15 16 //go:embed sample.conf 17 var sampleConfig string 18 19 // Example struct should be named the same as the Plugin 20 type Plugin struct { 21 Files []string `toml:"files"` 22 DefaultTags map[string]string `toml:"default_tag_defs"` 23 AdditionalParams map[string]interface{} `toml:"additional_params"` 24 Parser telegraf.Parser `toml:"-"` 25 Log telegraf.Logger `toml:"-"` 26 27 // Settings used by test-code 28 Path string `toml:"-"` // start path for relative files 29 ExpectedFilename string `toml:"-"` // filename of the expected metrics (default: expected.out) 30 UseTypeTag string `toml:"-"` // if specified use this tag to infer metric type 31 32 // Test-data derived from the files 33 Expected []telegraf.Metric `toml:"-"` // expected metrics 34 ExpectedErrors []string `toml:"-"` // expected errors 35 ShouldIgnoreTimestamp bool `toml:"-"` // flag indicating if the expected metrics do have timestamps 36 37 // Internal data 38 inputFilenames []string 39 } 40 41 func (*Plugin) SampleConfig() string { 42 return sampleConfig 43 } 44 45 func (p *Plugin) Init() error { 46 // Setup the filenames 47 p.inputFilenames = make([]string, 0, len(p.Files)) 48 for _, fn := range p.Files { 49 if !filepath.IsAbs(fn) && p.Path != "" { 50 fn = filepath.Join(p.Path, fn) 51 } 52 p.inputFilenames = append(p.inputFilenames, fn) 53 } 54 55 // Setup an influx parser for reading the expected metrics 56 expectedParser := &influx_upstream.Parser{} 57 if err := expectedParser.Init(); err != nil { 58 return err 59 } 60 expectedParser.SetTimeFunc(func() time.Time { return time.Time{} }) 61 62 // Read the expected metrics if any 63 expectedFn := "expected.out" 64 if p.ExpectedFilename != "" { 65 expectedFn = p.ExpectedFilename 66 } 67 if !filepath.IsAbs(expectedFn) && p.Path != "" { 68 expectedFn = filepath.Join(p.Path, expectedFn) 69 } 70 if _, err := os.Stat(expectedFn); err == nil { 71 var err error 72 p.Expected, err = testutil.ParseMetricsFromFile(expectedFn, expectedParser) 73 if err != nil { 74 return err 75 } 76 } 77 78 // Read the expected errors if any 79 expectedErrorFn := "expected.err" 80 if !filepath.IsAbs(expectedErrorFn) && p.Path != "" { 81 expectedErrorFn = filepath.Join(p.Path, expectedErrorFn) 82 } 83 if _, err := os.Stat(expectedErrorFn); err == nil { 84 var err error 85 p.ExpectedErrors, err = testutil.ParseLinesFromFile(expectedErrorFn) 86 if err != nil { 87 return err 88 } 89 if len(p.ExpectedErrors) == 0 { 90 return errors.New("got empty expected errors file") 91 } 92 } 93 94 // Fixup the metric type if requested 95 if p.UseTypeTag != "" { 96 for i, m := range p.Expected { 97 typeTag, found := m.GetTag(p.UseTypeTag) 98 if !found { 99 continue 100 } 101 var mtype telegraf.ValueType 102 switch typeTag { 103 case "counter": 104 mtype = telegraf.Counter 105 case "gauge": 106 mtype = telegraf.Gauge 107 case "untyped": 108 mtype = telegraf.Untyped 109 case "summary": 110 mtype = telegraf.Summary 111 case "histogram": 112 mtype = telegraf.Histogram 113 default: 114 continue 115 } 116 m.SetType(mtype) 117 m.RemoveTag(p.UseTypeTag) 118 p.Expected[i] = m 119 } 120 } 121 122 // Determine if we should check the timestamps indicated by a missing 123 // timestamp in the expected input 124 for i, m := range p.Expected { 125 missingTimestamp := m.Time().IsZero() 126 if i == 0 { 127 p.ShouldIgnoreTimestamp = missingTimestamp 128 continue 129 } 130 if missingTimestamp != p.ShouldIgnoreTimestamp { 131 return errors.New("mixed timestamp and non-timestamp data in expected metrics") 132 } 133 } 134 135 // Set the parser's default tags, just in case 136 if p.Parser != nil { 137 p.Parser.SetDefaultTags(p.DefaultTags) 138 } 139 140 return nil 141 } 142 143 func (p *Plugin) Gather(acc telegraf.Accumulator) error { 144 if p.Parser == nil { 145 return errors.New("no parser defined") 146 } 147 148 for _, fn := range p.inputFilenames { 149 data, err := os.ReadFile(fn) 150 if err != nil { 151 return err 152 } 153 metrics, err := p.Parser.Parse(data) 154 if err != nil { 155 return err 156 } 157 for _, m := range metrics { 158 acc.AddMetric(m) 159 } 160 } 161 162 return nil 163 } 164 165 func (p *Plugin) SetParser(parser telegraf.Parser) { 166 p.Parser = parser 167 if len(p.DefaultTags) > 0 { 168 p.Parser.SetDefaultTags(p.DefaultTags) 169 } 170 } 171 172 // Register the plugin 173 func init() { 174 inputs.Add("test", func() telegraf.Input { 175 return &Plugin{} 176 }) 177 }