github.com/mier85/go-sensor@v1.30.1-0.20220920111756-9bf41b3bc7e0/gcr_agent_test.go (about)

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