config_test.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package sqlqueryreceiver
  4. import (
  5. "path/filepath"
  6. "testing"
  7. "time"
  8. "github.com/stretchr/testify/assert"
  9. "github.com/stretchr/testify/require"
  10. "go.opentelemetry.io/collector/component"
  11. "go.opentelemetry.io/collector/confmap/confmaptest"
  12. "go.opentelemetry.io/collector/receiver/scraperhelper"
  13. "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlqueryreceiver/internal/metadata"
  14. )
  15. func TestLoadConfig(t *testing.T) {
  16. t.Parallel()
  17. tests := []struct {
  18. fname string
  19. id component.ID
  20. expected component.Config
  21. errorMessage string
  22. }{
  23. {
  24. id: component.NewIDWithName(metadata.Type, ""),
  25. fname: "config.yaml",
  26. expected: &Config{
  27. ScraperControllerSettings: scraperhelper.ScraperControllerSettings{
  28. CollectionInterval: 10 * time.Second,
  29. InitialDelay: time.Second,
  30. },
  31. Driver: "mydriver",
  32. DataSource: "host=localhost port=5432 user=me password=s3cr3t sslmode=disable",
  33. Queries: []Query{
  34. {
  35. SQL: "select count(*) as count, type from mytable group by type",
  36. Metrics: []MetricCfg{
  37. {
  38. MetricName: "val.count",
  39. ValueColumn: "count",
  40. AttributeColumns: []string{"type"},
  41. Monotonic: false,
  42. ValueType: MetricValueTypeInt,
  43. DataType: MetricTypeSum,
  44. Aggregation: MetricAggregationCumulative,
  45. StaticAttributes: map[string]string{"foo": "bar"},
  46. },
  47. },
  48. },
  49. },
  50. },
  51. },
  52. {
  53. fname: "config-invalid-datatype.yaml",
  54. id: component.NewIDWithName(metadata.Type, ""),
  55. errorMessage: "unsupported data_type: 'xyzgauge'",
  56. },
  57. {
  58. fname: "config-invalid-valuetype.yaml",
  59. id: component.NewIDWithName(metadata.Type, ""),
  60. errorMessage: "unsupported value_type: 'xyzint'",
  61. },
  62. {
  63. fname: "config-invalid-aggregation.yaml",
  64. id: component.NewIDWithName(metadata.Type, ""),
  65. errorMessage: "unsupported aggregation: 'xyzcumulative'",
  66. },
  67. {
  68. fname: "config-invalid-missing-metricname.yaml",
  69. id: component.NewIDWithName(metadata.Type, ""),
  70. errorMessage: "'metric_name' cannot be empty",
  71. },
  72. {
  73. fname: "config-invalid-missing-valuecolumn.yaml",
  74. id: component.NewIDWithName(metadata.Type, ""),
  75. errorMessage: "'value_column' cannot be empty",
  76. },
  77. {
  78. fname: "config-invalid-missing-sql.yaml",
  79. id: component.NewIDWithName(metadata.Type, ""),
  80. errorMessage: "'query.sql' cannot be empty",
  81. },
  82. {
  83. fname: "config-invalid-missing-queries.yaml",
  84. id: component.NewIDWithName(metadata.Type, ""),
  85. errorMessage: "'queries' cannot be empty",
  86. },
  87. {
  88. fname: "config-invalid-missing-driver.yaml",
  89. id: component.NewIDWithName(metadata.Type, ""),
  90. errorMessage: "'driver' cannot be empty",
  91. },
  92. {
  93. fname: "config-invalid-missing-logs-metrics.yaml",
  94. id: component.NewIDWithName(metadata.Type, ""),
  95. errorMessage: "at least one of 'query.logs' and 'query.metrics' must not be empty",
  96. },
  97. {
  98. fname: "config-invalid-missing-datasource.yaml",
  99. id: component.NewIDWithName(metadata.Type, ""),
  100. errorMessage: "'datasource' cannot be empty",
  101. },
  102. {
  103. fname: "config-logs.yaml",
  104. id: component.NewIDWithName(metadata.Type, ""),
  105. expected: &Config{
  106. ScraperControllerSettings: scraperhelper.ScraperControllerSettings{
  107. CollectionInterval: 10 * time.Second,
  108. InitialDelay: time.Second,
  109. },
  110. Driver: "mydriver",
  111. DataSource: "host=localhost port=5432 user=me password=s3cr3t sslmode=disable",
  112. Queries: []Query{
  113. {
  114. SQL: "select * from test_logs where log_id > ?",
  115. TrackingColumn: "log_id",
  116. TrackingStartValue: "10",
  117. Logs: []LogsCfg{
  118. {
  119. BodyColumn: "log_body",
  120. },
  121. },
  122. },
  123. },
  124. },
  125. },
  126. {
  127. fname: "config-logs-missing-body-column.yaml",
  128. id: component.NewIDWithName(metadata.Type, ""),
  129. errorMessage: "'body_column' must not be empty",
  130. },
  131. {
  132. fname: "config-unnecessary-aggregation.yaml",
  133. id: component.NewIDWithName(metadata.Type, ""),
  134. errorMessage: "aggregation=cumulative but data_type=gauge does not support aggregation",
  135. },
  136. }
  137. for _, tt := range tests {
  138. t.Run(tt.fname, func(t *testing.T) {
  139. cm, err := confmaptest.LoadConf(filepath.Join("testdata", tt.fname))
  140. require.NoError(t, err)
  141. factory := NewFactory()
  142. cfg := factory.CreateDefaultConfig()
  143. sub, err := cm.Sub(tt.id.String())
  144. require.NoError(t, err)
  145. require.NoError(t, component.UnmarshalConfig(sub, cfg))
  146. if tt.expected == nil {
  147. assert.ErrorContains(t, component.ValidateConfig(cfg), tt.errorMessage)
  148. return
  149. }
  150. assert.NoError(t, component.ValidateConfig(cfg))
  151. assert.Equal(t, tt.expected, cfg)
  152. })
  153. }
  154. }
  155. func TestCreateDefaultConfig(t *testing.T) {
  156. cfg := createDefaultConfig().(*Config)
  157. assert.Equal(t, 10*time.Second, cfg.ScraperControllerSettings.CollectionInterval)
  158. }
  159. func TestConfig_Validate_Multierr(t *testing.T) {
  160. cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config-invalid-multierr.yaml"))
  161. require.NoError(t, err)
  162. factory := NewFactory()
  163. cfg := factory.CreateDefaultConfig()
  164. sub, err := cm.Sub(component.NewIDWithName(metadata.Type, "").String())
  165. require.NoError(t, err)
  166. require.NoError(t, component.UnmarshalConfig(sub, cfg))
  167. err = component.ValidateConfig(cfg)
  168. assert.ErrorContains(t, err, "invalid metric config with metric_name 'my.metric'")
  169. assert.ErrorContains(t, err, "metric config has unsupported value_type: 'xint'")
  170. assert.ErrorContains(t, err, "metric config has unsupported data_type: 'xgauge'")
  171. assert.ErrorContains(t, err, "metric config has unsupported aggregation: 'xcumulative'")
  172. }