github.com/instana/go-sensor@v1.62.2-0.20240520081010-4919868049e1/gcr_agent_test.go (about) 1 // (c) Copyright IBM Corp. 2021 2 // (c) Copyright Instana Inc. 2020 3 4 //go:build gcr && integration 5 // +build gcr,integration 6 7 package instana_test 8 9 import ( 10 "context" 11 "encoding/json" 12 "log" 13 "net/http" 14 "net/http/httptest" 15 "os" 16 "testing" 17 "time" 18 19 instana "github.com/instana/go-sensor" 20 "github.com/stretchr/testify/assert" 21 "github.com/stretchr/testify/require" 22 ) 23 24 var agent *serverlessAgent 25 26 func TestMain(m *testing.M) { 27 teardownEnv := setupGCREnv() 28 defer teardownEnv() 29 30 teardownSrv := setupMetadataServer() 31 defer teardownSrv() 32 33 defer restoreEnvVarFunc("INSTANA_AGENT_KEY") 34 os.Setenv("INSTANA_AGENT_KEY", "testkey1") 35 36 defer restoreEnvVarFunc("INSTANA_ZONE") 37 os.Setenv("INSTANA_ZONE", "testzone") 38 39 defer restoreEnvVarFunc("INSTANA_TAGS") 40 os.Setenv("INSTANA_TAGS", "key1=value1,key2") 41 42 defer restoreEnvVarFunc("INSTANA_SECRETS") 43 os.Setenv("INSTANA_SECRETS", "contains-ignore-case:key,password,secret,classified") 44 45 defer restoreEnvVarFunc("CLASSIFIED_DATA") 46 os.Setenv("CLASSIFIED_DATA", "classified") 47 48 var err error 49 agent, err = setupServerlessAgent() 50 if err != nil { 51 log.Fatalf("failed to initialize serverless agent: %s", err) 52 } 53 54 instana.InitSensor(instana.DefaultOptions()) 55 56 os.Exit(m.Run()) 57 } 58 59 func TestGCRAgent_SendMetrics(t *testing.T) { 60 defer agent.Reset() 61 62 require.Eventually(t, func() bool { return len(agent.Bundles) > 0 }, 2*time.Second, 500*time.Millisecond) 63 64 collected := agent.Bundles[0] 65 66 assert.Equal(t, "gcp:cloud-run:revision:test-revision", collected.Header.Get("X-Instana-Host")) 67 assert.Equal(t, "testkey1", collected.Header.Get("X-Instana-Key")) 68 assert.NotEmpty(t, collected.Header.Get("X-Instana-Time")) 69 70 var payload struct { 71 Metrics struct { 72 Plugins []struct { 73 Name string `json:"name"` 74 EntityID string `json:"entityId"` 75 Data map[string]interface{} `json:"data"` 76 } `json:"plugins"` 77 } `json:"metrics"` 78 } 79 require.NoError(t, json.Unmarshal(collected.Body, &payload)) 80 81 pluginData := make(map[string][]serverlessAgentPluginPayload) 82 for _, plugin := range payload.Metrics.Plugins { 83 pluginData[plugin.Name] = append(pluginData[plugin.Name], serverlessAgentPluginPayload{plugin.EntityID, plugin.Data}) 84 } 85 86 t.Run("GCR service revision instance plugin payload", func(t *testing.T) { 87 require.Len(t, pluginData["com.instana.plugin.gcp.run.revision.instance"], 1) 88 d := pluginData["com.instana.plugin.gcp.run.revision.instance"][0] 89 90 assert.Equal(t, "id1", d.EntityID) 91 92 assert.Equal(t, "go", d.Data["runtime"]) 93 assert.Equal(t, "us-central1", d.Data["region"]) 94 assert.Equal(t, "test-service", d.Data["service"]) 95 assert.Equal(t, "test-configuration", d.Data["configuration"]) 96 assert.Equal(t, "test-revision", d.Data["revision"]) 97 assert.Equal(t, "id1", d.Data["instanceId"]) 98 assert.Equal(t, "8081", d.Data["port"]) 99 assert.EqualValues(t, 1234567890, d.Data["numericProjectId"]) 100 assert.Equal(t, "test-project", d.Data["projectId"]) 101 }) 102 103 t.Run("Process plugin payload", func(t *testing.T) { 104 require.Len(t, pluginData["com.instana.plugin.process"], 1) 105 d := pluginData["com.instana.plugin.process"][0] 106 107 assert.NotEmpty(t, d.EntityID) 108 109 assert.Equal(t, "gcpCloudRunInstance", d.Data["containerType"]) 110 assert.Equal(t, "id1", d.Data["container"]) 111 assert.Equal(t, "gcp:cloud-run:revision:test-revision", d.Data["com.instana.plugin.host.name"]) 112 113 if assert.IsType(t, map[string]interface{}{}, d.Data["env"]) { 114 env := d.Data["env"].(map[string]interface{}) 115 116 assert.Equal(t, os.Getenv("INSTANA_ZONE"), env["INSTANA_ZONE"]) 117 assert.Equal(t, os.Getenv("INSTANA_TAGS"), env["INSTANA_TAGS"]) 118 assert.Equal(t, os.Getenv("INSTANA_AGENT_KEY"), env["INSTANA_AGENT_KEY"]) 119 120 assert.Equal(t, "<redacted>", env["INSTANA_SECRETS"]) 121 assert.Equal(t, "<redacted>", env["CLASSIFIED_DATA"]) 122 } 123 }) 124 125 t.Run("Go process plugin payload", func(t *testing.T) { 126 require.Len(t, pluginData["com.instana.plugin.golang"], 1) 127 d := pluginData["com.instana.plugin.golang"][0] 128 129 assert.NotEmpty(t, d.EntityID) 130 131 require.NotEmpty(t, pluginData["com.instana.plugin.process"]) 132 assert.Equal(t, pluginData["com.instana.plugin.process"][0].EntityID, d.EntityID) 133 134 assert.NotEmpty(t, d.Data["metrics"]) 135 }) 136 } 137 138 func TestGCRAgent_SendSpans(t *testing.T) { 139 defer agent.Reset() 140 141 sensor := instana.NewSensor("testing") 142 143 sp := sensor.Tracer().StartSpan("entry") 144 sp.SetTag("value", "42") 145 sp.Finish() 146 147 require.Eventually(t, func() bool { 148 if len(agent.Bundles) == 0 { 149 return false 150 } 151 152 for _, bundle := range agent.Bundles { 153 var payload struct { 154 Spans []json.RawMessage `json:"spans"` 155 } 156 157 json.Unmarshal(bundle.Body, &payload) 158 if len(payload.Spans) > 0 { 159 return true 160 } 161 } 162 163 return false 164 }, 4*time.Second, 500*time.Millisecond) 165 166 var spans []map[string]json.RawMessage 167 for _, bundle := range agent.Bundles { 168 var payload struct { 169 Spans []map[string]json.RawMessage `json:"spans"` 170 } 171 172 require.NoError(t, json.Unmarshal(bundle.Body, &payload), "%s", string(bundle.Body)) 173 spans = append(spans, payload.Spans...) 174 } 175 176 require.Len(t, spans, 1) 177 assert.JSONEq(t, `{"hl": true, "cp": "gcp", "e": "id1"}`, string(spans[0]["f"])) 178 } 179 180 func TestGCRAgent_FlushSpans(t *testing.T) { 181 defer agent.Reset() 182 183 tracer := instana.NewTracer() 184 sensor := instana.NewSensorWithTracer(tracer) 185 186 sp := sensor.Tracer().StartSpan("entry") 187 sp.SetTag("value", "42") 188 sp.Finish() 189 190 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 191 defer cancel() 192 193 require.NoError(t, tracer.Flush(ctx)) 194 } 195 196 func setupGCREnv() func() { 197 var teardownFns []func() 198 199 teardownFns = append(teardownFns, restoreEnvVarFunc("K_SERVICE")) 200 os.Setenv("K_SERVICE", "test-service") 201 202 teardownFns = append(teardownFns, restoreEnvVarFunc("K_CONFIGURATION")) 203 os.Setenv("K_CONFIGURATION", "test-configuration") 204 205 teardownFns = append(teardownFns, restoreEnvVarFunc("K_REVISION")) 206 os.Setenv("K_REVISION", "test-revision") 207 208 teardownFns = append(teardownFns, restoreEnvVarFunc("PORT")) 209 os.Setenv("PORT", "8081") 210 211 return func() { 212 for _, fn := range teardownFns { 213 fn() 214 } 215 } 216 } 217 218 func setupMetadataServer() func() { 219 mux := http.NewServeMux() 220 mux.HandleFunc("/computeMetadata/v1", func(w http.ResponseWriter, req *http.Request) { 221 http.ServeFile(w, req, "gcloud/testdata/computeMetadata.json") 222 }) 223 224 srv := httptest.NewServer(mux) 225 226 teardown := restoreEnvVarFunc("GOOGLE_CLOUD_RUN_METADATA_ENDPOINT") 227 os.Setenv("GOOGLE_CLOUD_RUN_METADATA_ENDPOINT", srv.URL) 228 229 return func() { 230 teardown() 231 srv.Close() 232 } 233 }