scraper_test.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. //go:build windows
  4. // +build windows
  5. package activedirectorydsreceiver
  6. import (
  7. "context"
  8. "errors"
  9. "path/filepath"
  10. "testing"
  11. "github.com/stretchr/testify/require"
  12. "go.opentelemetry.io/collector/receiver/receivertest"
  13. "go.opentelemetry.io/collector/receiver/scrapererror"
  14. "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden"
  15. "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/pmetrictest"
  16. "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/winperfcounters"
  17. "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/activedirectorydsreceiver/internal/metadata"
  18. )
  19. var goldenScrapePath = filepath.Join("testdata", "golden_scrape.yaml")
  20. var partialScrapePath = filepath.Join("testdata", "partial_scrape.yaml")
  21. func TestScrape(t *testing.T) {
  22. t.Run("Fully successful scrape", func(t *testing.T) {
  23. t.Parallel()
  24. mockWatchers, err := getWatchers(&mockCounterCreater{
  25. availableCounterNames: getAvailableCounters(t),
  26. })
  27. require.NoError(t, err)
  28. scraper := &activeDirectoryDSScraper{
  29. mb: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()),
  30. w: mockWatchers,
  31. }
  32. scrapeData, err := scraper.scrape(context.Background())
  33. require.NoError(t, err)
  34. expectedMetrics, err := golden.ReadMetrics(goldenScrapePath)
  35. require.NoError(t, err)
  36. require.NoError(t, pmetrictest.CompareMetrics(expectedMetrics, scrapeData, pmetrictest.IgnoreStartTimestamp(),
  37. pmetrictest.IgnoreTimestamp()))
  38. err = scraper.shutdown(context.Background())
  39. require.NoError(t, err)
  40. })
  41. t.Run("Scrape with errors", func(t *testing.T) {
  42. t.Parallel()
  43. fullSyncObjectsRemainingErr := errors.New("failed to scrape sync objects remaining")
  44. draInboundValuesDNErr := errors.New("failed to scrape sync inbound value DNs")
  45. mockWatchers, err := getWatchers(&mockCounterCreater{
  46. availableCounterNames: getAvailableCounters(t),
  47. })
  48. require.NoError(t, err)
  49. mockWatchers.counterNameToWatcher[draInboundFullSyncObjectsRemaining].(*mockPerfCounterWatcher).scrapeErr = fullSyncObjectsRemainingErr
  50. mockWatchers.counterNameToWatcher[draInboundValuesDNs].(*mockPerfCounterWatcher).scrapeErr = draInboundValuesDNErr
  51. scraper := &activeDirectoryDSScraper{
  52. mb: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()),
  53. w: mockWatchers,
  54. }
  55. scrapeData, err := scraper.scrape(context.Background())
  56. require.Error(t, err)
  57. require.True(t, scrapererror.IsPartialScrapeError(err))
  58. require.Contains(t, err.Error(), fullSyncObjectsRemainingErr.Error())
  59. require.Contains(t, err.Error(), draInboundValuesDNErr.Error())
  60. expectedMetrics, err := golden.ReadMetrics(partialScrapePath)
  61. require.NoError(t, err)
  62. require.NoError(t, pmetrictest.CompareMetrics(expectedMetrics, scrapeData, pmetrictest.IgnoreStartTimestamp(),
  63. pmetrictest.IgnoreTimestamp()))
  64. err = scraper.shutdown(context.Background())
  65. require.NoError(t, err)
  66. })
  67. t.Run("Close with errors", func(t *testing.T) {
  68. t.Parallel()
  69. fullSyncObjectsRemainingErr := errors.New("failed to close sync objects remaining")
  70. draInboundValuesDNErr := errors.New("failed to close sync inbound value DNs")
  71. mockWatchers, err := getWatchers(&mockCounterCreater{
  72. availableCounterNames: getAvailableCounters(t),
  73. })
  74. require.NoError(t, err)
  75. mockWatchers.counterNameToWatcher[draInboundFullSyncObjectsRemaining].(*mockPerfCounterWatcher).closeErr = fullSyncObjectsRemainingErr
  76. mockWatchers.counterNameToWatcher[draInboundValuesDNs].(*mockPerfCounterWatcher).closeErr = draInboundValuesDNErr
  77. scraper := &activeDirectoryDSScraper{
  78. mb: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()),
  79. w: mockWatchers,
  80. }
  81. err = scraper.shutdown(context.Background())
  82. require.Error(t, err)
  83. require.Contains(t, err.Error(), fullSyncObjectsRemainingErr.Error())
  84. require.Contains(t, err.Error(), draInboundValuesDNErr.Error())
  85. })
  86. t.Run("Double shutdown does not error", func(t *testing.T) {
  87. t.Parallel()
  88. mockWatchers, err := getWatchers(&mockCounterCreater{
  89. availableCounterNames: getAvailableCounters(t),
  90. })
  91. require.NoError(t, err)
  92. scraper := &activeDirectoryDSScraper{
  93. mb: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()),
  94. w: mockWatchers,
  95. }
  96. err = scraper.shutdown(context.Background())
  97. require.NoError(t, err)
  98. err = scraper.shutdown(context.Background())
  99. require.NoError(t, err)
  100. })
  101. }
  102. type mockPerfCounterWatcher struct {
  103. val float64
  104. scrapeErr error
  105. closeErr error
  106. closed bool
  107. }
  108. // Path panics; It should not be called
  109. func (mockPerfCounterWatcher) Path() string {
  110. panic("mockPerfCounterWatcher::Path is not implemented")
  111. }
  112. // ScrapeData returns scrapeErr if it's set, otherwise it returns a single countervalue with the mock's val
  113. func (w mockPerfCounterWatcher) ScrapeData() ([]winperfcounters.CounterValue, error) {
  114. if w.scrapeErr != nil {
  115. return nil, w.scrapeErr
  116. }
  117. return []winperfcounters.CounterValue{
  118. {
  119. Value: w.val,
  120. },
  121. }, nil
  122. }
  123. // Close all counters/handles related to the query and free all associated memory.
  124. func (w mockPerfCounterWatcher) Close() error {
  125. if w.closed {
  126. panic("mockPerfCounterWatcher was already closed!")
  127. }
  128. return w.closeErr
  129. }