1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package logging
16
17 import (
18 "sync"
19 "testing"
20
21 "github.com/google/go-cmp/cmp"
22 "github.com/google/go-cmp/cmp/cmpopts"
23 mrpb "google.golang.org/genproto/googleapis/api/monitoredres"
24 )
25
26 const (
27 there = "anyvalue"
28 projectID = "test-project"
29 zoneID = "test-region-zone"
30 regionID = "test-region"
31 serviceName = "test-service"
32 version = "1.0"
33 instanceName = "test-12345"
34 qualifiedZoneName = "projects/" + projectID + "/zones/" + zoneID
35 qualifiedRegionName = "projects/" + projectID + "/regions/" + regionID
36 funcSignature = "test-cf-signature"
37 funcTarget = "test-cf-target"
38 crConfig = "test-cr-config"
39 clusterName = "test-k8s-cluster"
40 podName = "test-k8s-pod-name"
41 containerName = "test-k8s-container-name"
42 namespaceName = "test-k8s-namespace-name"
43 instanceID = "test-instance-12345"
44 )
45
46
47 type fakeResourceGetter struct {
48 envVars map[string]string
49 metaVars map[string]string
50 fsPaths map[string]string
51 }
52
53 func (g *fakeResourceGetter) EnvVar(name string) string {
54 if g.envVars != nil {
55 if v, ok := g.envVars[name]; ok {
56 return v
57 }
58 }
59 return ""
60 }
61
62 func (g *fakeResourceGetter) Metadata(path string) string {
63 if g.metaVars != nil {
64 if v, ok := g.metaVars[path]; ok {
65 return v
66 }
67 }
68 return ""
69 }
70
71 func (g *fakeResourceGetter) ReadAll(path string) string {
72 if g.fsPaths != nil {
73 if v, ok := g.fsPaths[path]; ok {
74 return v
75 }
76 }
77 return ""
78 }
79
80
81 func setupDetectedResource(envVars, metaVars, fsPaths map[string]string) {
82 detectedResource.once = new(sync.Once)
83 detectedResource.attrs = &fakeResourceGetter{
84 envVars: envVars,
85 metaVars: metaVars,
86 fsPaths: fsPaths,
87 }
88 detectedResource.pb = nil
89 }
90
91 func TestResourceDetection(t *testing.T) {
92 tests := []struct {
93 name string
94 envVars map[string]string
95 metaVars map[string]string
96 fsPaths map[string]string
97 want *mrpb.MonitoredResource
98 }{
99 {
100 name: "detect GAE resource",
101 envVars: map[string]string{"GAE_SERVICE": serviceName, "GAE_VERSION": version, "GAE_INSTANCE": instanceName},
102 metaVars: map[string]string{"": there, "project/project-id": projectID, "instance/zone": qualifiedZoneName, "instance/attributes/gae_app_bucket": there},
103 want: &mrpb.MonitoredResource{
104 Type: "gae_app",
105 Labels: map[string]string{
106 "project_id": projectID,
107 "module_id": serviceName,
108 "version_id": version,
109 "zone": zoneID,
110 },
111 },
112 },
113 {
114 name: "detect Cloud Function resource",
115 envVars: map[string]string{"FUNCTION_TARGET": funcTarget, "FUNCTION_SIGNATURE_TYPE": funcSignature, "K_SERVICE": serviceName},
116 metaVars: map[string]string{"": there, "project/project-id": projectID, "instance/region": qualifiedRegionName},
117 want: &mrpb.MonitoredResource{
118 Type: "cloud_function",
119 Labels: map[string]string{
120 "project_id": projectID,
121 "region": regionID,
122 "function_name": serviceName,
123 },
124 },
125 },
126 {
127 name: "detect Cloud Run service resource",
128 envVars: map[string]string{"K_CONFIGURATION": crConfig, "K_SERVICE": serviceName, "K_REVISION": version},
129 metaVars: map[string]string{"": there, "project/project-id": projectID, "instance/region": qualifiedRegionName},
130 want: &mrpb.MonitoredResource{
131 Type: "cloud_run_revision",
132 Labels: map[string]string{
133 "project_id": projectID,
134 "location": regionID,
135 "service_name": serviceName,
136 "revision_name": version,
137 "configuration_name": crConfig,
138 },
139 },
140 },
141 {
142 name: "detect Cloud Run job resource",
143 envVars: map[string]string{"CLOUD_RUN_JOB": serviceName, "CLOUD_RUN_EXECUTION": crConfig, "CLOUD_RUN_TASK_INDEX": version, "CLOUD_RUN_TASK_ATTEMPT": instanceID},
144 metaVars: map[string]string{"": there, "project/project-id": projectID, "instance/region": qualifiedRegionName},
145 want: &mrpb.MonitoredResource{
146 Type: "cloud_run_job",
147 Labels: map[string]string{
148 "project_id": projectID,
149 "location": regionID,
150 "job_name": serviceName,
151 },
152 },
153 },
154 {
155 name: "detect GKE resource for a zonal cluster",
156 envVars: map[string]string{"HOSTNAME": podName},
157 metaVars: map[string]string{"": there, "project/project-id": projectID, "instance/attributes/cluster-location": zoneID, "instance/attributes/cluster-name": clusterName},
158 fsPaths: map[string]string{"/var/run/secrets/kubernetes.io/serviceaccount/namespace": namespaceName},
159 want: &mrpb.MonitoredResource{
160 Type: "k8s_container",
161 Labels: map[string]string{
162 "cluster_name": clusterName,
163 "location": zoneID,
164 "project_id": projectID,
165 "pod_name": podName,
166 "namespace_name": namespaceName,
167 "container_name": "",
168 },
169 },
170 },
171 {
172 name: "detect GKE resource for a regional cluster",
173 envVars: map[string]string{"HOSTNAME": podName},
174 metaVars: map[string]string{"": there, "project/project-id": projectID, "instance/attributes/cluster-location": regionID, "instance/attributes/cluster-name": clusterName},
175 fsPaths: map[string]string{"/var/run/secrets/kubernetes.io/serviceaccount/namespace": namespaceName},
176 want: &mrpb.MonitoredResource{
177 Type: "k8s_container",
178 Labels: map[string]string{
179 "cluster_name": clusterName,
180 "location": regionID,
181 "project_id": projectID,
182 "pod_name": podName,
183 "namespace_name": namespaceName,
184 "container_name": "",
185 },
186 },
187 },
188 {
189 name: "detect GKE resource with custom container and namespace config",
190 envVars: map[string]string{"HOSTNAME": podName, "CONTAINER_NAME": containerName, "NAMESPACE_NAME": namespaceName},
191 metaVars: map[string]string{"": there, "project/project-id": projectID, "instance/attributes/cluster-location": zoneID, "instance/attributes/cluster-name": clusterName},
192 want: &mrpb.MonitoredResource{
193 Type: "k8s_container",
194 Labels: map[string]string{
195 "cluster_name": clusterName,
196 "location": zoneID,
197 "project_id": projectID,
198 "pod_name": podName,
199 "namespace_name": namespaceName,
200 "container_name": containerName,
201 },
202 },
203 },
204 {
205 name: "detect Compute Engine resource",
206 envVars: map[string]string{},
207 metaVars: map[string]string{"": there, "project/project-id": projectID, "instance/id": instanceID, "instance/zone": qualifiedZoneName, "instance/preempted": there, "instance/cpu-platform": there},
208 want: &mrpb.MonitoredResource{
209 Type: "gce_instance",
210 Labels: map[string]string{
211 "project_id": projectID,
212 "instance_id": instanceID,
213 "zone": zoneID,
214 },
215 },
216 },
217 {
218 name: "detect GAE resource by product name",
219 envVars: map[string]string{},
220 metaVars: map[string]string{"": there, "project/project-id": projectID, "instance/zone": qualifiedZoneName, "instance/attributes/gae_app_bucket": there},
221 fsPaths: map[string]string{"/sys/class/dmi/id/product_name": "Google App Engine"},
222 want: &mrpb.MonitoredResource{
223 Type: "gae_app",
224 Labels: map[string]string{
225 "project_id": projectID,
226 "module_id": "",
227 "version_id": "",
228 "zone": zoneID,
229 },
230 },
231 },
232 {
233 name: "detect Cloud Function resource by product name",
234 envVars: map[string]string{},
235 metaVars: map[string]string{"": there, "project/project-id": projectID, "instance/region": qualifiedRegionName},
236 fsPaths: map[string]string{"/sys/class/dmi/id/product_name": "Google Cloud Functions"},
237 want: &mrpb.MonitoredResource{
238 Type: "cloud_function",
239 Labels: map[string]string{
240 "project_id": projectID,
241 "region": regionID,
242 "function_name": "",
243 },
244 },
245 },
246 {
247 name: "unknown resource detection",
248 envVars: map[string]string{},
249 metaVars: map[string]string{"": there, "project/project-id": projectID},
250 want: nil,
251 },
252 {
253 name: "resource without metadata detection",
254 envVars: map[string]string{},
255 metaVars: map[string]string{},
256 want: nil,
257 },
258 }
259
260
261 oldAttrs := detectedResource.attrs
262 defer func() {
263 detectedResource.attrs = oldAttrs
264 detectedResource.once = new(sync.Once)
265 }()
266 for _, tc := range tests {
267 t.Run(tc.name, func(t *testing.T) {
268 setupDetectedResource(tc.envVars, tc.metaVars, tc.fsPaths)
269 got := detectResource()
270 if diff := cmp.Diff(got, tc.want, cmpopts.IgnoreUnexported(mrpb.MonitoredResource{})); diff != "" {
271 t.Errorf("got(-),want(+):\n%s", diff)
272 }
273 })
274 }
275 }
276
277 var benchmarkResultHolder *mrpb.MonitoredResource
278
279 func BenchmarkDetectResource(b *testing.B) {
280 var result *mrpb.MonitoredResource
281
282 for n := 0; n < b.N; n++ {
283 result = detectResource()
284 }
285
286 benchmarkResultHolder = result
287 }
288
View as plain text