factory_test.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package datadogexporter
  4. import (
  5. "context"
  6. "encoding/json"
  7. "path/filepath"
  8. "sync"
  9. "testing"
  10. "github.com/DataDog/opentelemetry-mapping-go/pkg/inframetadata"
  11. "github.com/DataDog/opentelemetry-mapping-go/pkg/inframetadata/payload"
  12. "github.com/stretchr/testify/assert"
  13. "github.com/stretchr/testify/require"
  14. "go.opentelemetry.io/collector/component"
  15. "go.opentelemetry.io/collector/component/componenttest"
  16. "go.opentelemetry.io/collector/config/confignet"
  17. "go.opentelemetry.io/collector/confmap/confmaptest"
  18. "go.opentelemetry.io/collector/exporter/exporterhelper"
  19. "go.opentelemetry.io/collector/exporter/exportertest"
  20. "go.opentelemetry.io/collector/pdata/ptrace"
  21. "go.uber.org/zap"
  22. "go.uber.org/zap/zaptest"
  23. "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/metadata"
  24. "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/testutil"
  25. )
  26. var _ inframetadata.Pusher = (*testPusher)(nil)
  27. type testPusher struct {
  28. mu sync.Mutex
  29. payloads []payload.HostMetadata
  30. stopped bool
  31. logger *zap.Logger
  32. t *testing.T
  33. }
  34. func newTestPusher(t *testing.T) *testPusher {
  35. return &testPusher{
  36. logger: zaptest.NewLogger(t),
  37. t: t,
  38. }
  39. }
  40. func (p *testPusher) Push(_ context.Context, hm payload.HostMetadata) error {
  41. p.mu.Lock()
  42. defer p.mu.Unlock()
  43. if p.stopped {
  44. p.logger.Error("Trying to push payload after stopping", zap.Any("payload", hm))
  45. p.t.Fail()
  46. }
  47. p.logger.Info("Storing host metadata payload", zap.Any("payload", hm))
  48. p.payloads = append(p.payloads, hm)
  49. return nil
  50. }
  51. func (p *testPusher) Payloads() []payload.HostMetadata {
  52. p.mu.Lock()
  53. p.stopped = true
  54. defer p.mu.Unlock()
  55. return p.payloads
  56. }
  57. // Test that the factory creates the default configuration
  58. func TestCreateDefaultConfig(t *testing.T) {
  59. factory := NewFactory()
  60. cfg := factory.CreateDefaultConfig()
  61. assert.Equal(t, &Config{
  62. TimeoutSettings: defaulttimeoutSettings(),
  63. RetrySettings: exporterhelper.NewDefaultRetrySettings(),
  64. QueueSettings: exporterhelper.NewDefaultQueueSettings(),
  65. API: APIConfig{
  66. Site: "datadoghq.com",
  67. },
  68. Metrics: MetricsConfig{
  69. TCPAddr: confignet.TCPAddr{
  70. Endpoint: "https://api.datadoghq.com",
  71. },
  72. DeltaTTL: 3600,
  73. HistConfig: HistogramConfig{
  74. Mode: "distributions",
  75. SendAggregations: false,
  76. },
  77. SumConfig: SumConfig{
  78. CumulativeMonotonicMode: CumulativeMonotonicSumModeToDelta,
  79. InitialCumulativeMonotonicMode: InitialValueModeAuto,
  80. },
  81. SummaryConfig: SummaryConfig{
  82. Mode: SummaryModeGauges,
  83. },
  84. },
  85. Traces: TracesConfig{
  86. TCPAddr: confignet.TCPAddr{
  87. Endpoint: "https://trace.agent.datadoghq.com",
  88. },
  89. IgnoreResources: []string{},
  90. },
  91. Logs: LogsConfig{
  92. TCPAddr: confignet.TCPAddr{
  93. Endpoint: "https://http-intake.logs.datadoghq.com",
  94. },
  95. },
  96. HostMetadata: HostMetadataConfig{
  97. Enabled: true,
  98. HostnameSource: HostnameSourceConfigOrSystem,
  99. },
  100. OnlyMetadata: false,
  101. }, cfg, "failed to create default config")
  102. assert.NoError(t, componenttest.CheckConfigStruct(cfg))
  103. }
  104. func TestLoadConfig(t *testing.T) {
  105. t.Parallel()
  106. cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml"))
  107. require.NoError(t, err)
  108. tests := []struct {
  109. id component.ID
  110. expected component.Config
  111. }{
  112. {
  113. id: component.NewIDWithName(metadata.Type, "default"),
  114. expected: &Config{
  115. TimeoutSettings: defaulttimeoutSettings(),
  116. RetrySettings: exporterhelper.NewDefaultRetrySettings(),
  117. QueueSettings: exporterhelper.NewDefaultQueueSettings(),
  118. API: APIConfig{
  119. Key: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  120. Site: "datadoghq.com",
  121. FailOnInvalidKey: false,
  122. },
  123. Metrics: MetricsConfig{
  124. TCPAddr: confignet.TCPAddr{
  125. Endpoint: "https://api.datadoghq.com",
  126. },
  127. DeltaTTL: 3600,
  128. HistConfig: HistogramConfig{
  129. Mode: "distributions",
  130. SendAggregations: false,
  131. },
  132. SumConfig: SumConfig{
  133. CumulativeMonotonicMode: CumulativeMonotonicSumModeToDelta,
  134. InitialCumulativeMonotonicMode: InitialValueModeAuto,
  135. },
  136. SummaryConfig: SummaryConfig{
  137. Mode: SummaryModeGauges,
  138. },
  139. },
  140. Traces: TracesConfig{
  141. TCPAddr: confignet.TCPAddr{
  142. Endpoint: "https://trace.agent.datadoghq.com",
  143. },
  144. IgnoreResources: []string{},
  145. },
  146. Logs: LogsConfig{
  147. TCPAddr: confignet.TCPAddr{
  148. Endpoint: "https://http-intake.logs.datadoghq.com",
  149. },
  150. },
  151. HostMetadata: HostMetadataConfig{
  152. Enabled: true,
  153. HostnameSource: HostnameSourceConfigOrSystem,
  154. },
  155. OnlyMetadata: false,
  156. },
  157. },
  158. {
  159. id: component.NewIDWithName(metadata.Type, "api"),
  160. expected: &Config{
  161. TimeoutSettings: defaulttimeoutSettings(),
  162. RetrySettings: exporterhelper.NewDefaultRetrySettings(),
  163. QueueSettings: exporterhelper.NewDefaultQueueSettings(),
  164. TagsConfig: TagsConfig{
  165. Hostname: "customhostname",
  166. },
  167. API: APIConfig{
  168. Key: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  169. Site: "datadoghq.eu",
  170. FailOnInvalidKey: true,
  171. },
  172. Metrics: MetricsConfig{
  173. TCPAddr: confignet.TCPAddr{
  174. Endpoint: "https://api.datadoghq.eu",
  175. },
  176. DeltaTTL: 3600,
  177. HistConfig: HistogramConfig{
  178. Mode: "distributions",
  179. SendAggregations: false,
  180. },
  181. SumConfig: SumConfig{
  182. CumulativeMonotonicMode: CumulativeMonotonicSumModeToDelta,
  183. InitialCumulativeMonotonicMode: InitialValueModeAuto,
  184. },
  185. SummaryConfig: SummaryConfig{
  186. Mode: SummaryModeGauges,
  187. },
  188. },
  189. Traces: TracesConfig{
  190. TCPAddr: confignet.TCPAddr{
  191. Endpoint: "https://trace.agent.datadoghq.eu",
  192. },
  193. SpanNameRemappings: map[string]string{
  194. "old_name1": "new_name1",
  195. "old_name2": "new_name2",
  196. },
  197. SpanNameAsResourceName: true,
  198. IgnoreResources: []string{},
  199. TraceBuffer: 10,
  200. },
  201. Logs: LogsConfig{
  202. TCPAddr: confignet.TCPAddr{
  203. Endpoint: "https://http-intake.logs.datadoghq.eu",
  204. },
  205. },
  206. OnlyMetadata: false,
  207. HostMetadata: HostMetadataConfig{
  208. Enabled: true,
  209. HostnameSource: HostnameSourceConfigOrSystem,
  210. },
  211. },
  212. },
  213. {
  214. id: component.NewIDWithName(metadata.Type, "api2"),
  215. expected: &Config{
  216. TimeoutSettings: defaulttimeoutSettings(),
  217. RetrySettings: exporterhelper.NewDefaultRetrySettings(),
  218. QueueSettings: exporterhelper.NewDefaultQueueSettings(),
  219. TagsConfig: TagsConfig{
  220. Hostname: "customhostname",
  221. },
  222. API: APIConfig{
  223. Key: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  224. Site: "datadoghq.eu",
  225. FailOnInvalidKey: false,
  226. },
  227. Metrics: MetricsConfig{
  228. TCPAddr: confignet.TCPAddr{
  229. Endpoint: "https://api.datadoghq.test",
  230. },
  231. DeltaTTL: 3600,
  232. HistConfig: HistogramConfig{
  233. Mode: "distributions",
  234. SendAggregations: false,
  235. },
  236. SumConfig: SumConfig{
  237. CumulativeMonotonicMode: CumulativeMonotonicSumModeToDelta,
  238. InitialCumulativeMonotonicMode: InitialValueModeAuto,
  239. },
  240. SummaryConfig: SummaryConfig{
  241. Mode: SummaryModeGauges,
  242. },
  243. },
  244. Traces: TracesConfig{
  245. TCPAddr: confignet.TCPAddr{
  246. Endpoint: "https://trace.agent.datadoghq.test",
  247. },
  248. SpanNameRemappings: map[string]string{
  249. "old_name3": "new_name3",
  250. "old_name4": "new_name4",
  251. },
  252. IgnoreResources: []string{},
  253. },
  254. Logs: LogsConfig{
  255. TCPAddr: confignet.TCPAddr{
  256. Endpoint: "https://http-intake.logs.datadoghq.test",
  257. },
  258. },
  259. HostMetadata: HostMetadataConfig{
  260. Enabled: true,
  261. HostnameSource: HostnameSourceConfigOrSystem,
  262. Tags: []string{"example:tag"},
  263. },
  264. },
  265. },
  266. }
  267. for _, tt := range tests {
  268. t.Run(tt.id.String(), func(t *testing.T) {
  269. factory := NewFactory()
  270. cfg := factory.CreateDefaultConfig()
  271. sub, err := cm.Sub(tt.id.String())
  272. require.NoError(t, err)
  273. require.NoError(t, component.UnmarshalConfig(sub, cfg))
  274. assert.NoError(t, component.ValidateConfig(cfg))
  275. assert.Equal(t, tt.expected, cfg)
  276. })
  277. }
  278. }
  279. func TestOverrideEndpoints(t *testing.T) {
  280. tests := []struct {
  281. componentID string
  282. expectedSite string
  283. expectedMetricsEndpoint string
  284. expectedTracesEndpoint string
  285. expectedLogsEndpoint string
  286. }{
  287. {
  288. componentID: "nositeandnoendpoints",
  289. expectedSite: "datadoghq.com",
  290. expectedMetricsEndpoint: "https://api.datadoghq.com",
  291. expectedTracesEndpoint: "https://trace.agent.datadoghq.com",
  292. expectedLogsEndpoint: "https://http-intake.logs.datadoghq.com",
  293. },
  294. {
  295. componentID: "nositeandmetricsendpoint",
  296. expectedSite: "datadoghq.com",
  297. expectedMetricsEndpoint: "metricsendpoint:1234",
  298. expectedTracesEndpoint: "https://trace.agent.datadoghq.com",
  299. expectedLogsEndpoint: "https://http-intake.logs.datadoghq.com",
  300. },
  301. {
  302. componentID: "nositeandtracesendpoint",
  303. expectedSite: "datadoghq.com",
  304. expectedMetricsEndpoint: "https://api.datadoghq.com",
  305. expectedTracesEndpoint: "tracesendpoint:1234",
  306. expectedLogsEndpoint: "https://http-intake.logs.datadoghq.com",
  307. },
  308. {
  309. componentID: "nositeandlogsendpoint",
  310. expectedSite: "datadoghq.com",
  311. expectedMetricsEndpoint: "https://api.datadoghq.com",
  312. expectedTracesEndpoint: "https://trace.agent.datadoghq.com",
  313. expectedLogsEndpoint: "logsendpoint:1234",
  314. },
  315. {
  316. componentID: "nositeandallendpoints",
  317. expectedSite: "datadoghq.com",
  318. expectedMetricsEndpoint: "metricsendpoint:1234",
  319. expectedTracesEndpoint: "tracesendpoint:1234",
  320. expectedLogsEndpoint: "logsendpoint:1234",
  321. },
  322. {
  323. componentID: "siteandnoendpoints",
  324. expectedSite: "datadoghq.eu",
  325. expectedMetricsEndpoint: "https://api.datadoghq.eu",
  326. expectedTracesEndpoint: "https://trace.agent.datadoghq.eu",
  327. expectedLogsEndpoint: "https://http-intake.logs.datadoghq.eu",
  328. },
  329. {
  330. componentID: "siteandmetricsendpoint",
  331. expectedSite: "datadoghq.eu",
  332. expectedMetricsEndpoint: "metricsendpoint:1234",
  333. expectedTracesEndpoint: "https://trace.agent.datadoghq.eu",
  334. expectedLogsEndpoint: "https://http-intake.logs.datadoghq.eu",
  335. },
  336. {
  337. componentID: "siteandtracesendpoint",
  338. expectedSite: "datadoghq.eu",
  339. expectedMetricsEndpoint: "https://api.datadoghq.eu",
  340. expectedTracesEndpoint: "tracesendpoint:1234",
  341. expectedLogsEndpoint: "https://http-intake.logs.datadoghq.eu",
  342. },
  343. {
  344. componentID: "siteandallendpoints",
  345. expectedSite: "datadoghq.eu",
  346. expectedMetricsEndpoint: "metricsendpoint:1234",
  347. expectedTracesEndpoint: "tracesendpoint:1234",
  348. expectedLogsEndpoint: "logsendpoint:1234",
  349. },
  350. }
  351. cm, err := confmaptest.LoadConf(filepath.Join("testdata", "unmarshal.yaml"))
  352. require.NoError(t, err)
  353. factory := NewFactory()
  354. for _, testInstance := range tests {
  355. t.Run(testInstance.componentID, func(t *testing.T) {
  356. cfg := factory.CreateDefaultConfig()
  357. sub, err := cm.Sub(component.NewIDWithName(metadata.Type, testInstance.componentID).String())
  358. require.NoError(t, err)
  359. require.NoError(t, component.UnmarshalConfig(sub, cfg))
  360. componentCfg, ok := cfg.(*Config)
  361. require.True(t, ok, "component.Config is not a Datadog exporter config (wrong ID?)")
  362. assert.Equal(t, testInstance.expectedSite, componentCfg.API.Site)
  363. assert.Equal(t, testInstance.expectedMetricsEndpoint, componentCfg.Metrics.Endpoint)
  364. assert.Equal(t, testInstance.expectedTracesEndpoint, componentCfg.Traces.Endpoint)
  365. assert.Equal(t, testInstance.expectedLogsEndpoint, componentCfg.Logs.Endpoint)
  366. })
  367. }
  368. }
  369. func TestCreateAPIMetricsExporter(t *testing.T) {
  370. server := testutil.DatadogServerMock()
  371. defer server.Close()
  372. cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml"))
  373. require.NoError(t, err)
  374. factory := NewFactory()
  375. cfg := factory.CreateDefaultConfig()
  376. sub, err := cm.Sub(component.NewIDWithName(metadata.Type, "api").String())
  377. require.NoError(t, err)
  378. require.NoError(t, component.UnmarshalConfig(sub, cfg))
  379. c := cfg.(*Config)
  380. c.Metrics.TCPAddr.Endpoint = server.URL
  381. c.HostMetadata.Enabled = false
  382. ctx := context.Background()
  383. exp, err := factory.CreateMetricsExporter(
  384. ctx,
  385. exportertest.NewNopCreateSettings(),
  386. cfg,
  387. )
  388. assert.NoError(t, err)
  389. assert.NotNil(t, exp)
  390. }
  391. func TestCreateAPIExporterFailOnInvalidKey_Zorkian(t *testing.T) {
  392. server := testutil.DatadogServerMock(testutil.ValidateAPIKeyEndpointInvalid)
  393. defer server.Close()
  394. if isMetricExportV2Enabled() {
  395. require.NoError(t, enableZorkianMetricExport())
  396. defer require.NoError(t, enableNativeMetricExport())
  397. }
  398. cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml"))
  399. require.NoError(t, err)
  400. factory := NewFactory()
  401. cfg := factory.CreateDefaultConfig()
  402. sub, err := cm.Sub(component.NewIDWithName(metadata.Type, "api").String())
  403. require.NoError(t, err)
  404. require.NoError(t, component.UnmarshalConfig(sub, cfg))
  405. // Use the mock server for API key validation
  406. c := cfg.(*Config)
  407. c.Metrics.TCPAddr.Endpoint = server.URL
  408. c.HostMetadata.Enabled = false
  409. t.Run("true", func(t *testing.T) {
  410. c.API.FailOnInvalidKey = true
  411. ctx := context.Background()
  412. // metrics exporter
  413. mexp, err := factory.CreateMetricsExporter(
  414. ctx,
  415. exportertest.NewNopCreateSettings(),
  416. cfg,
  417. )
  418. assert.EqualError(t, err, "API Key validation failed")
  419. assert.Nil(t, mexp)
  420. texp, err := factory.CreateTracesExporter(
  421. ctx,
  422. exportertest.NewNopCreateSettings(),
  423. cfg,
  424. )
  425. assert.EqualError(t, err, "API Key validation failed")
  426. assert.Nil(t, texp)
  427. lexp, err := factory.CreateLogsExporter(
  428. ctx,
  429. exportertest.NewNopCreateSettings(),
  430. cfg,
  431. )
  432. assert.EqualError(t, err, "API Key validation failed")
  433. assert.Nil(t, lexp)
  434. })
  435. t.Run("false", func(t *testing.T) {
  436. c.API.FailOnInvalidKey = false
  437. ctx := context.Background()
  438. exp, err := factory.CreateMetricsExporter(
  439. ctx,
  440. exportertest.NewNopCreateSettings(),
  441. cfg,
  442. )
  443. assert.Nil(t, err)
  444. assert.NotNil(t, exp)
  445. texp, err := factory.CreateTracesExporter(
  446. ctx,
  447. exportertest.NewNopCreateSettings(),
  448. cfg,
  449. )
  450. assert.Nil(t, err)
  451. assert.NotNil(t, texp)
  452. lexp, err := factory.CreateLogsExporter(
  453. ctx,
  454. exportertest.NewNopCreateSettings(),
  455. cfg,
  456. )
  457. assert.Nil(t, err)
  458. assert.NotNil(t, lexp)
  459. })
  460. }
  461. func TestCreateAPIExporterFailOnInvalidKey(t *testing.T) {
  462. server := testutil.DatadogServerMock(testutil.ValidateAPIKeyEndpointInvalid)
  463. defer server.Close()
  464. if !isMetricExportV2Enabled() {
  465. require.NoError(t, enableNativeMetricExport())
  466. defer require.NoError(t, enableZorkianMetricExport())
  467. }
  468. cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml"))
  469. require.NoError(t, err)
  470. factory := NewFactory()
  471. cfg := factory.CreateDefaultConfig()
  472. sub, err := cm.Sub(component.NewIDWithName(metadata.Type, "api").String())
  473. require.NoError(t, err)
  474. require.NoError(t, component.UnmarshalConfig(sub, cfg))
  475. // Use the mock server for API key validation
  476. c := cfg.(*Config)
  477. c.Metrics.TCPAddr.Endpoint = server.URL
  478. c.HostMetadata.Enabled = false
  479. t.Run("true", func(t *testing.T) {
  480. c.API.FailOnInvalidKey = true
  481. ctx := context.Background()
  482. // metrics exporter
  483. mexp, err := factory.CreateMetricsExporter(
  484. ctx,
  485. exportertest.NewNopCreateSettings(),
  486. cfg,
  487. )
  488. assert.EqualError(t, err, "API Key validation failed")
  489. assert.Nil(t, mexp)
  490. texp, err := factory.CreateTracesExporter(
  491. ctx,
  492. exportertest.NewNopCreateSettings(),
  493. cfg,
  494. )
  495. assert.EqualError(t, err, "API Key validation failed")
  496. assert.Nil(t, texp)
  497. lexp, err := factory.CreateLogsExporter(
  498. ctx,
  499. exportertest.NewNopCreateSettings(),
  500. cfg,
  501. )
  502. assert.EqualError(t, err, "API Key validation failed")
  503. assert.Nil(t, lexp)
  504. })
  505. t.Run("false", func(t *testing.T) {
  506. c.API.FailOnInvalidKey = false
  507. ctx := context.Background()
  508. exp, err := factory.CreateMetricsExporter(
  509. ctx,
  510. exportertest.NewNopCreateSettings(),
  511. cfg,
  512. )
  513. assert.Nil(t, err)
  514. assert.NotNil(t, exp)
  515. texp, err := factory.CreateTracesExporter(
  516. ctx,
  517. exportertest.NewNopCreateSettings(),
  518. cfg,
  519. )
  520. assert.Nil(t, err)
  521. assert.NotNil(t, texp)
  522. lexp, err := factory.CreateLogsExporter(
  523. ctx,
  524. exportertest.NewNopCreateSettings(),
  525. cfg,
  526. )
  527. assert.Nil(t, err)
  528. assert.NotNil(t, lexp)
  529. })
  530. }
  531. func TestCreateAPILogsExporter(t *testing.T) {
  532. server := testutil.DatadogLogServerMock()
  533. defer server.Close()
  534. cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml"))
  535. require.NoError(t, err)
  536. factory := NewFactory()
  537. cfg := factory.CreateDefaultConfig()
  538. sub, err := cm.Sub(component.NewIDWithName(metadata.Type, "api").String())
  539. require.NoError(t, err)
  540. require.NoError(t, component.UnmarshalConfig(sub, cfg))
  541. c := cfg.(*Config)
  542. c.Metrics.TCPAddr.Endpoint = server.URL
  543. c.HostMetadata.Enabled = false
  544. ctx := context.Background()
  545. exp, err := factory.CreateLogsExporter(
  546. ctx,
  547. exportertest.NewNopCreateSettings(),
  548. cfg,
  549. )
  550. assert.NoError(t, err)
  551. assert.NotNil(t, exp)
  552. }
  553. func TestOnlyMetadata(t *testing.T) {
  554. server := testutil.DatadogServerMock()
  555. defer server.Close()
  556. factory := NewFactory()
  557. ctx := context.Background()
  558. cfg := &Config{
  559. TimeoutSettings: defaulttimeoutSettings(),
  560. RetrySettings: exporterhelper.NewDefaultRetrySettings(),
  561. QueueSettings: exporterhelper.NewDefaultQueueSettings(),
  562. API: APIConfig{Key: "notnull"},
  563. Metrics: MetricsConfig{TCPAddr: confignet.TCPAddr{Endpoint: server.URL}},
  564. Traces: TracesConfig{TCPAddr: confignet.TCPAddr{Endpoint: server.URL}},
  565. OnlyMetadata: true,
  566. HostMetadata: HostMetadataConfig{
  567. Enabled: true,
  568. HostnameSource: HostnameSourceFirstResource,
  569. },
  570. }
  571. expTraces, err := factory.CreateTracesExporter(
  572. ctx,
  573. exportertest.NewNopCreateSettings(),
  574. cfg,
  575. )
  576. assert.NoError(t, err)
  577. assert.NotNil(t, expTraces)
  578. expMetrics, err := factory.CreateMetricsExporter(
  579. ctx,
  580. exportertest.NewNopCreateSettings(),
  581. cfg,
  582. )
  583. assert.NoError(t, err)
  584. assert.NotNil(t, expMetrics)
  585. err = expTraces.Start(ctx, nil)
  586. assert.NoError(t, err)
  587. defer func() {
  588. assert.NoError(t, expTraces.Shutdown(ctx))
  589. }()
  590. testTraces := ptrace.NewTraces()
  591. testutil.TestTraces.CopyTo(testTraces)
  592. err = expTraces.ConsumeTraces(ctx, testTraces)
  593. require.NoError(t, err)
  594. body := <-server.MetadataChan
  595. var recvMetadata payload.HostMetadata
  596. err = json.Unmarshal(body, &recvMetadata)
  597. require.NoError(t, err)
  598. assert.Equal(t, recvMetadata.InternalHostname, "custom-hostname")
  599. }