Skip to content

Commit

Permalink
fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-burt committed Oct 17, 2024
1 parent 47721ba commit 59dc57d
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 41 deletions.
5 changes: 2 additions & 3 deletions receiver/tlscheckreceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (

// Predefined error responses for configuration validation failures
var (
errMissingHost = errors.New(`"host" must be specified`)
errInvalidHost = errors.New(`"host" must be in the form of <hostname>:<port>`)
)

Expand All @@ -36,7 +35,7 @@ func (cfg *targetConfig) Validate() error {
var err error

if cfg.Host == "" {
err = multierr.Append(err, errMissingHost)
err = multierr.Append(err, ErrMissingTargets)
} else {
_, parseErr := url.ParseRequestURI(cfg.Host)
if parseErr != nil {
Expand All @@ -52,7 +51,7 @@ func (cfg *Config) Validate() error {
var err error

if len(cfg.Targets) == 0 {
err = multierr.Append(err, errMissingHost)
err = multierr.Append(err, ErrMissingTargets)
}

for _, target := range cfg.Targets {
Expand Down
4 changes: 2 additions & 2 deletions receiver/tlscheckreceiver/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ func TestValidate(t *testing.T) {
Targets: []*targetConfig{},
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedErr: errMissingHost,
expectedErr: ErrMissingTargets,
},
{
desc: "invalid url",
desc: "invalid host",
cfg: &Config{
Targets: []*targetConfig{
{
Expand Down
24 changes: 14 additions & 10 deletions receiver/tlscheckreceiver/scraper.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ package tlscheckreceiver // import "github.com/open-telemetry/opentelemetry-coll
import (
"context"
"crypto/tls"
"errors"
"sync"
"time"

"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/pdata/pmetric"
"go.opentelemetry.io/collector/receiver"
"go.uber.org/zap"
Expand All @@ -15,7 +19,7 @@ import (
)

var (
errMissingHost = errors.New(`No targets specified`)
ErrMissingTargets = errors.New(`No targets specified`)
)

type scraper struct {
Expand All @@ -25,25 +29,24 @@ type scraper struct {
}

func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) {
if len(t.cfg.Targets) == 0 {
return pmetric.NewMetrics(), errMissingHost
if len(s.cfg.Targets) == 0 {
return pmetric.NewMetrics(), ErrMissingTargets
}

var wg sync.WaitGroup
wg.Add(len(s.cfg.Targets))
var mux sync.Mutex
for _, host := range s.cfg.Targets {
for _, target := range s.cfg.Targets {
go func(host string) {
defer wg.Done()

now := pcommon.NewTimestampFromTime(time.Now())
start := time.Now()

conn, err := tls.Dial("tcp", host, &tls.Config{
conn, err := tls.Dial("tcp", target.Host, &tls.Config{
InsecureSkipVerify: true,
})
if err != nil {
s.logger.error("TCP connection error encountered", zap.String("host", host), zap.Error(err))
s.logger.Error("TCP connection error encountered", zap.String("host", target.Host), zap.Error(err))
}
defer conn.Close()

Expand All @@ -56,14 +59,15 @@ func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) {

currentTime := time.Now()
timeLeft := cert.NotAfter.Sub(currentTime).Seconds()
timeLeftInt := int64(timeLeft)

s.mb.RecordTlscheckTimeLeftDataPoint(now, timeLeft, host, issuer, commonName)
s.mb.RecordTlscheckTimeLeftDataPoint(now, timeLeftInt, issuer, commonName)

}(endpoint)
}(target.Host)
}

wg.Wait()
return t.mb.Emit(), nil
return s.mb.Emit(), nil
}

func newScraper(cfg *Config, settings receiver.Settings) *scraper {
Expand Down
72 changes: 46 additions & 26 deletions receiver/tlscheckreceiver/scraper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/pdata/pmetric"
"go.opentelemetry.io/collector/receiver/receivertest"
"go.uber.org/zap"

"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/tlscheckreceiver/internal/metadata"
)

type MockTLSConn struct {
Expand All @@ -25,7 +25,7 @@ func (m *MockTLSConn) ConnectionState() tls.ConnectionState {
return m.state
}

func mockTLSDial(network, address string, config *tls.Config, validity string) (*tls.Conn, error) {
func mockTLSDial(network, address string, config *tls.Config, validity string) (*MockTLSConn, error) {
var cert *x509.Certificate
now := time.Now()
switch validity {
Expand All @@ -52,25 +52,33 @@ func mockTLSDial(network, address string, config *tls.Config, validity string) (
}
}

mockConn := &MockTLSConn{
return &MockTLSConn{
state: tls.ConnectionState{
PeerCertificates: []*x509.Certificate{cert},
},
}
return (*tls.Conn)(mockConn), nil
}, nil
}

var tlsDial = func(network, addr string, config *tls.Config) (*MockTLSConn, error) {
mockConn, err := mockTLSDial(network, addr, config, "valid") // default to "valid"
return (*MockTLSConn)(mockConn), err
}

func TestScrape_ValidCertificate(t *testing.T) {
originalDial := tlsDial
defer func() { tlsDial = originalDial }()
tlsDial = func(network, addr string, config *tls.Config) (*tls.Conn, error) {
tlsDial = func(network, addr string, config *tls.Config) (*MockTLSConn, error) {
return mockTLSDial(network, addr, config, "valid")
}

cfg := &Config{Targets: []string{"valid.com:443"}}
settings := receivertest.NewNopCreateSettings()
cfg := &Config{
Targets: []*targetConfig{
{Host: "valid.com:443"},
},
}
settings := receivertest.NewNopSettings()
s := newScraper(cfg, settings)
s.mb = metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings.TelemetrySettings)
s.mb = metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings)

metrics, err := s.scrape(context.Background())
require.NoError(t, err)
Expand All @@ -81,21 +89,25 @@ func TestScrape_ValidCertificate(t *testing.T) {
metric := ilms.Metrics().At(0)
dp := metric.Gauge().DataPoints().At(0)

timeLeft := dp.IntVal()
timeLeft := dp.IntValue()
assert.Greater(t, timeLeft, int64(0), "Time left should be positive for a valid certificate")
}

func TestScrape_ExpiredCertificate(t *testing.T) {
originalDial := tlsDial
defer func() { tlsDial = originalDial }()
tlsDial = func(network, addr string, config *tls.Config) (*tls.Conn, error) {
tlsDial = func(network, addr string, config *tls.Config) (*MockTLSConn, error) {
return mockTLSDial(network, addr, config, "expired")
}

cfg := &Config{Targets: []string{"expired.com:9999"}}
settings := receivertest.NewNopCreateSettings()
cfg := &Config{
Targets: []*targetConfig{
{Host: "expired.com:9999"},
},
}
settings := receivertest.NewNopSettings()
s := newScraper(cfg, settings)
s.mb = metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings.TelemetrySettings)
s.mb = metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings)

metrics, err := s.scrape(context.Background())
require.NoError(t, err)
Expand All @@ -106,21 +118,25 @@ func TestScrape_ExpiredCertificate(t *testing.T) {
metric := ilms.Metrics().At(0)
dp := metric.Gauge().DataPoints().At(0)

timeLeft := dp.IntVal()
timeLeft := dp.IntValue()
assert.Less(t, timeLeft, int64(0), "Time left should be negative for an expired certificate")
}

func TestScrape_NotYetValidCertificate(t *testing.T) {
originalDial := tlsDial
defer func() { tlsDial = originalDial }()
tlsDial = func(network, addr string, config *tls.Config) (*tls.Conn, error) {
tlsDial = func(network, addr string, config *tls.Config) (*MockTLSConn, error) {
return mockTLSDial(network, addr, config, "notYetValid")
}

cfg := &Config{Targets: []string{"notyetvalid.com:8080"}}
settings := receivertest.NewNopCreateSettings()
cfg := &Config{
Targets: []*targetConfig{
{Host: "notyetvalid.com:8080"},
},
}
settings := receivertest.NewNopSettings()
s := newScraper(cfg, settings)
s.mb = metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings.TelemetrySettings)
s.mb = metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings)

metrics, err := s.scrape(context.Background())
require.NoError(t, err)
Expand All @@ -131,22 +147,26 @@ func TestScrape_NotYetValidCertificate(t *testing.T) {
metric := ilms.Metrics().At(0)
dp := metric.Gauge().DataPoints().At(0)

timeLeft := dp.IntVal()
timeLeft := dp.IntValue()
assert.Greater(t, timeLeft, int64(0), "Time left should be positive for a certificate not yet valid")
}

func TestScrape_NoTargets(t *testing.T) {
cfg := &Config{Targets: []string{}}
s := newScraper(cfg, receivertest.NewNopCreateSettings())
cfg := &Config{Targets: []*targetConfig{}}
s := newScraper(cfg, receivertest.NewNopSettings())
metrics, err := s.scrape(context.Background())
assert.Error(t, err)
assert.Equal(t, errMissingHost, err)
assert.Equal(t, ErrMissingTargets, err)
assert.Equal(t, 0, metrics.DataPointCount())
}

func TestScrape_InvalidHost(t *testing.T) {
cfg := &Config{Targets: []string{"invalid:1234"}}
s := newScraper(cfg, receivertest.NewNopCreateSettings())
cfg := &Config{
Targets: []*targetConfig{
{Host: "invalid:1234"},
},
}
s := newScraper(cfg, receivertest.NewNopSettings())
metrics, err := s.scrape(context.Background())
assert.NoError(t, err)
assert.Equal(t, 0, metrics.DataPointCount())
Expand Down

0 comments on commit 59dc57d

Please sign in to comment.