@@ -39,6 +39,7 @@ func setupMetricsTestClient(t *testing.T) func() {
3939 origClient := ddClient
4040 origCfg := cfg
4141 origFactory := clientFactory
42+ origAPIKeyFactory := apiKeyClientFactory
4243
4344 cfg = & config.Config {
4445 Site : "datadoghq.com" ,
@@ -47,8 +48,12 @@ func setupMetricsTestClient(t *testing.T) func() {
4748 AutoApprove : false ,
4849 }
4950
51+ mockErr := fmt .Errorf ("mock client: no real API connection in tests" )
5052 clientFactory = func (c * config.Config ) (* client.Client , error ) {
51- return nil , fmt .Errorf ("mock client: no real API connection in tests" )
53+ return nil , mockErr
54+ }
55+ apiKeyClientFactory = func (c * config.Config ) (* client.Client , error ) {
56+ return nil , mockErr
5257 }
5358
5459 ddClient = nil
@@ -57,6 +62,7 @@ func setupMetricsTestClient(t *testing.T) func() {
5762 ddClient = origClient
5863 cfg = origCfg
5964 clientFactory = origFactory
65+ apiKeyClientFactory = origAPIKeyFactory
6066 }
6167}
6268
@@ -578,40 +584,44 @@ func TestRunMetricsSubmit(t *testing.T) {
578584 defer cleanup ()
579585
580586 tests := []struct {
581- name string
582- metricName string
583- value float64
584- timestamp string
585- tags string
586- metricType string
587- wantErr bool
587+ name string
588+ metricName string
589+ value float64
590+ timestamp string
591+ tags string
592+ metricType string
593+ wantErr bool
594+ wantErrContains string
588595 }{
589596 {
590- name : "submit gauge" ,
591- metricName : "custom.metric" ,
592- value : 123.45 ,
593- timestamp : "now" ,
594- tags : "env:prod,team:backend" ,
595- metricType : "gauge" ,
596- wantErr : true , // Mock client error
597+ name : "submit gauge" ,
598+ metricName : "custom.metric" ,
599+ value : 123.45 ,
600+ timestamp : "now" ,
601+ tags : "env:prod,team:backend" ,
602+ metricType : "gauge" ,
603+ wantErr : true , // Mock client error
604+ wantErrContains : "mock client" ,
597605 },
598606 {
599- name : "submit count" ,
600- metricName : "custom.count" ,
601- value : 100 ,
602- timestamp : "now" ,
603- tags : "" ,
604- metricType : "count" ,
605- wantErr : true ,
607+ name : "submit count" ,
608+ metricName : "custom.count" ,
609+ value : 100 ,
610+ timestamp : "now" ,
611+ tags : "" ,
612+ metricType : "count" ,
613+ wantErr : true ,
614+ wantErrContains : "mock client" ,
606615 },
607616 {
608- name : "invalid metric type" ,
609- metricName : "custom.metric" ,
610- value : 123 ,
611- timestamp : "now" ,
612- tags : "" ,
613- metricType : "invalid" ,
614- wantErr : true , // Will error on invalid type validation
617+ name : "invalid metric type" ,
618+ metricName : "custom.metric" ,
619+ value : 123 ,
620+ timestamp : "now" ,
621+ tags : "" ,
622+ metricType : "invalid" ,
623+ wantErr : true ,
624+ wantErrContains : "mock client" ,
615625 },
616626 }
617627
@@ -634,19 +644,55 @@ func TestRunMetricsSubmit(t *testing.T) {
634644 t .Errorf ("runMetricsSubmit() error = %v, wantErr %v" , err , tt .wantErr )
635645 }
636646
637- // Check for specific error on invalid type
638- // Note: Invalid type validation happens after client creation,
639- // but with mock client, client creation fails first
640- if tt .metricType == "invalid" && err != nil {
641- // Accept either "invalid metric type" or "mock client" error
642- if ! strings .Contains (err .Error (), "invalid metric type" ) && ! strings .Contains (err .Error (), "mock client" ) {
643- t .Errorf ("runMetricsSubmit() error = %v, want 'invalid metric type' or 'mock client' error" , err )
644- }
647+ if tt .wantErrContains != "" && err != nil && ! strings .Contains (err .Error (), tt .wantErrContains ) {
648+ t .Errorf ("runMetricsSubmit() error = %v, want error containing %q" , err , tt .wantErrContains )
645649 }
646650 })
647651 }
648652}
649653
654+ func TestRunMetricsSubmit_RequiresAPIKey (t * testing.T ) {
655+ origClient := ddClient
656+ origCfg := cfg
657+ origFactory := apiKeyClientFactory
658+ defer func () {
659+ ddClient = origClient
660+ cfg = origCfg
661+ apiKeyClientFactory = origFactory
662+ }()
663+
664+ // Set config with NO API key to trigger the pre-emptive check
665+ cfg = & config.Config {
666+ Site : "datadoghq.com" ,
667+ APIKey : "" ,
668+ AppKey : "" ,
669+ }
670+ ddClient = nil
671+
672+ submitName = "custom.metric"
673+ submitValue = 42.0
674+ submitTimestamp = "now"
675+ submitTags = ""
676+ submitType = "gauge"
677+ submitInterval = 0
678+
679+ var buf bytes.Buffer
680+ outputWriter = & buf
681+ defer func () { outputWriter = os .Stdout }()
682+
683+ err := runMetricsSubmit (metricsSubmitCmd , []string {})
684+ if err == nil {
685+ t .Fatal ("expected error when DD_API_KEY is not set" )
686+ }
687+
688+ if ! strings .Contains (err .Error (), "DD_API_KEY" ) {
689+ t .Errorf ("error should mention DD_API_KEY, got: %v" , err )
690+ }
691+ if ! strings .Contains (err .Error (), "metrics submit requires" ) {
692+ t .Errorf ("error should explain the requirement, got: %v" , err )
693+ }
694+ }
695+
650696func TestRunMetricsTagsList (t * testing.T ) {
651697 cleanup := setupMetricsTestClient (t )
652698 defer cleanup ()
0 commit comments