github.com/instana/go-sensor@v1.62.2-0.20240520081010-4919868049e1/aws/ecs_metadata_test.go (about) 1 // (c) Copyright IBM Corp. 2021 2 // (c) Copyright Instana Inc. 2020 3 4 package aws_test 5 6 import ( 7 "context" 8 "net/http" 9 "net/http/httptest" 10 "testing" 11 "time" 12 13 "github.com/instana/go-sensor/aws" 14 "github.com/instana/go-sensor/docker" 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestECSMetadataProvider_ContainerMetadata(t *testing.T) { 20 endpoint, mux, teardown := setupTS() 21 defer teardown() 22 23 mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { 24 http.ServeFile(w, req, "testdata/container_metadata.json") 25 }) 26 27 c := aws.NewECSMetadataProvider(endpoint, nil) 28 29 container, err := c.ContainerMetadata(context.Background()) 30 require.NoError(t, err) 31 32 assert.Equal(t, aws.ECSContainerMetadata{ 33 DockerID: "43481a6ce4842eec8fe72fc28500c6b52edcc0917f105b83379f88cac1ff3946", 34 Name: "nginx-curl", 35 DockerName: "ecs-nginx-5-nginx-curl-ccccb9f49db0dfe0d901", 36 Image: "nrdlngr/nginx-curl", 37 ImageID: "sha256:2e00ae64383cfc865ba0a2ba37f61b50a120d2d9378559dcd458dc0de47bc165", 38 DesiredStatus: "RUNNING", 39 KnownStatus: "RUNNING", 40 Limits: aws.ContainerLimits{CPU: 512, Memory: 512}, 41 CreatedAt: time.Date(2018, time.February, 1, 20, 55, 10, 554941919, time.UTC), 42 StartedAt: time.Date(2018, time.February, 1, 20, 55, 11, 64236631, time.UTC), 43 Type: "NORMAL", 44 Networks: []aws.ContainerNetwork{ 45 {Mode: "awsvpc", IPv4Addresses: []string{"10.0.2.106"}}, 46 }, 47 ContainerLabels: aws.ContainerLabels{ 48 Cluster: "default", 49 TaskARN: "arn:aws:ecs:us-east-2:012345678910:task/9781c248-0edd-4cdb-9a93-f63cb662a5d3", 50 TaskDefinition: "nginx", 51 TaskDefinitionVersion: "5", 52 }, 53 }, container) 54 } 55 56 func TestECSMetadataProvider_ContainerMetadata_ServerError(t *testing.T) { 57 endpoint, mux, teardown := setupTS() 58 defer teardown() 59 60 mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { 61 http.Error(w, "aws error", http.StatusInternalServerError) 62 }) 63 64 c := aws.NewECSMetadataProvider(endpoint, nil) 65 66 _, err := c.ContainerMetadata(context.Background()) 67 require.Error(t, err) 68 assert.Contains(t, err.Error(), "500 Internal Server Error") 69 } 70 71 func TestECSMetadataProvider_ContainerMetadata_MalformedResponse(t *testing.T) { 72 endpoint, mux, teardown := setupTS() 73 defer teardown() 74 75 mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { 76 w.Write([]byte("here is your data")) 77 }) 78 79 c := aws.NewECSMetadataProvider(endpoint, nil) 80 81 _, err := c.ContainerMetadata(context.Background()) 82 require.Error(t, err) 83 assert.Contains(t, err.Error(), "malformed") 84 } 85 86 func TestECSMetadataProvider_TaskMetadata(t *testing.T) { 87 endpoint, mux, teardown := setupTS() 88 defer teardown() 89 90 mux.HandleFunc("/task", func(w http.ResponseWriter, req *http.Request) { 91 http.ServeFile(w, req, "testdata/task_metadata.json") 92 }) 93 94 c := aws.NewECSMetadataProvider(endpoint, nil) 95 96 task, err := c.TaskMetadata(context.Background()) 97 require.NoError(t, err) 98 99 assert.Equal(t, aws.ECSTaskMetadata{ 100 TaskARN: "arn:aws:ecs:us-east-2:012345678910:task/9781c248-0edd-4cdb-9a93-f63cb662a5d3", 101 Family: "nginx", 102 Revision: "5", 103 AvailabilityZone: "us-east-2b", 104 DesiredStatus: "RUNNING", 105 KnownStatus: "RUNNING", 106 Containers: []aws.ECSContainerMetadata{ 107 { 108 DockerID: "731a0d6a3b4210e2448339bc7015aaa79bfe4fa256384f4102db86ef94cbbc4c", 109 Name: "~internal~ecs~pause", 110 DockerName: "ecs-nginx-5-internalecspause-acc699c0cbf2d6d11700", 111 Image: "amazon/amazon-ecs-pause:0.1.0", 112 ImageID: "", 113 DesiredStatus: "RESOURCES_PROVISIONED", 114 KnownStatus: "RESOURCES_PROVISIONED", 115 Limits: aws.ContainerLimits{CPU: 0, Memory: 0}, 116 CreatedAt: time.Date(2018, time.February, 1, 20, 55, 8, 366329616, time.UTC), 117 StartedAt: time.Date(2018, time.February, 1, 20, 55, 9, 58354915, time.UTC), 118 Type: "CNI_PAUSE", 119 Networks: []aws.ContainerNetwork{ 120 {Mode: "awsvpc", IPv4Addresses: []string{"10.0.2.106"}}, 121 }, 122 ContainerLabels: aws.ContainerLabels{ 123 Cluster: "default", 124 TaskARN: "arn:aws:ecs:us-east-2:012345678910:task/9781c248-0edd-4cdb-9a93-f63cb662a5d3", 125 TaskDefinition: "nginx", 126 TaskDefinitionVersion: "5", 127 }, 128 }, 129 { 130 DockerID: "43481a6ce4842eec8fe72fc28500c6b52edcc0917f105b83379f88cac1ff3946", 131 Name: "nginx-curl", 132 DockerName: "ecs-nginx-5-nginx-curl-ccccb9f49db0dfe0d901", 133 Image: "nrdlngr/nginx-curl", 134 ImageID: "sha256:2e00ae64383cfc865ba0a2ba37f61b50a120d2d9378559dcd458dc0de47bc165", 135 DesiredStatus: "RUNNING", 136 KnownStatus: "RUNNING", 137 Limits: aws.ContainerLimits{CPU: 512, Memory: 512}, 138 CreatedAt: time.Date(2018, time.February, 1, 20, 55, 10, 554941919, time.UTC), 139 StartedAt: time.Date(2018, time.February, 1, 20, 55, 11, 64236631, time.UTC), 140 Type: "NORMAL", 141 Networks: []aws.ContainerNetwork{ 142 {Mode: "awsvpc", IPv4Addresses: []string{"10.0.2.106"}}, 143 }, 144 ContainerLabels: aws.ContainerLabels{ 145 Cluster: "default", 146 TaskARN: "arn:aws:ecs:us-east-2:012345678910:task/9781c248-0edd-4cdb-9a93-f63cb662a5d3", 147 TaskDefinition: "nginx", 148 TaskDefinitionVersion: "5", 149 }, 150 }, 151 }, 152 PullStartedAt: time.Date(2018, time.February, 1, 20, 55, 9, 372495529, time.UTC), 153 PullStoppedAt: time.Date(2018, time.February, 1, 20, 55, 10, 552018345, time.UTC), 154 }, task) 155 } 156 157 func TestECSMetadataProvider_TaskMetadata_ServerError(t *testing.T) { 158 endpoint, mux, teardown := setupTS() 159 defer teardown() 160 161 mux.HandleFunc("/task", func(w http.ResponseWriter, req *http.Request) { 162 http.Error(w, "aws error", http.StatusInternalServerError) 163 }) 164 165 c := aws.NewECSMetadataProvider(endpoint, nil) 166 167 _, err := c.TaskMetadata(context.Background()) 168 require.Error(t, err) 169 assert.Contains(t, err.Error(), "500 Internal Server Error") 170 } 171 172 func TestECSMetadataProvider_TaskMetadata_MalformedResponse(t *testing.T) { 173 endpoint, mux, teardown := setupTS() 174 defer teardown() 175 176 mux.HandleFunc("/task", func(w http.ResponseWriter, req *http.Request) { 177 w.Write([]byte("here is your data")) 178 }) 179 180 c := aws.NewECSMetadataProvider(endpoint, nil) 181 182 _, err := c.TaskMetadata(context.Background()) 183 require.Error(t, err) 184 assert.Contains(t, err.Error(), "malformed") 185 } 186 187 func TestECSMetadataProvider_TaskStats(t *testing.T) { 188 endpoint, mux, teardown := setupTS() 189 defer teardown() 190 191 mux.HandleFunc("/task/stats", func(w http.ResponseWriter, req *http.Request) { 192 http.ServeFile(w, req, "testdata/task_stats.json") 193 }) 194 195 c := aws.NewECSMetadataProvider(endpoint, nil) 196 197 data, err := c.TaskStats(context.Background()) 198 require.NoError(t, err) 199 200 require.Contains(t, data, "43481a6ce4842eec8fe72fc28500c6b52edcc0917f105b83379f88cac1ff3946") 201 202 stats := data["43481a6ce4842eec8fe72fc28500c6b52edcc0917f105b83379f88cac1ff3946"] 203 stats.ReadAt = stats.ReadAt.UTC().Truncate(time.Second) 204 205 assert.Equal(t, docker.ContainerStats{ 206 ReadAt: time.Date(2020, time.September, 9, 9, 54, 21, 0, time.UTC), 207 Networks: map[string]docker.ContainerNetworkStats{ 208 "eth1": { 209 TxDropped: 1, 210 TxErrors: 2, 211 TxPackets: 444, 212 TxBytes: 106367, 213 RxDropped: 3, 214 RxErrors: 4, 215 RxPackets: 3105, 216 RxBytes: 4172695, 217 }, 218 }, 219 Memory: docker.ContainerMemoryStats{ 220 Stats: docker.MemoryStats{ 221 ActiveAnon: 4681728, 222 ActiveFile: 12288, 223 InactiveAnon: 100, 224 InactiveFile: 602112, 225 TotalRss: 5283840, 226 TotalCache: 12290, 227 }, 228 MaxUsage: 6549504, 229 Usage: 6148096, 230 Limit: 536870912, 231 }, 232 CPU: docker.ContainerCPUStats{ 233 System: 360200000000, 234 OnlineCPUs: 2, 235 Usage: docker.CPUUsageStats{ 236 Total: 281318382, 237 Kernel: 20000000, 238 User: 180000000, 239 }, 240 Throttling: docker.CPUThrottlingStats{ 241 Periods: 1, 242 Time: 3, 243 }, 244 }, 245 BlockIO: docker.ContainerBlockIOStats{ 246 ServiceBytes: []docker.BlockIOOpStats{ 247 {Operation: docker.BlockIOReadOp, Value: 1}, 248 {Operation: docker.BlockIOWriteOp, Value: 2}, 249 {Operation: docker.BlockIOReadOp, Value: 3}, 250 }, 251 }, 252 }, stats) 253 } 254 255 func TestECSMetadataProvider_TaskStats_ServerError(t *testing.T) { 256 endpoint, mux, teardown := setupTS() 257 defer teardown() 258 259 mux.HandleFunc("/task/stats", func(w http.ResponseWriter, req *http.Request) { 260 http.Error(w, "aws error", http.StatusInternalServerError) 261 }) 262 263 c := aws.NewECSMetadataProvider(endpoint, nil) 264 265 _, err := c.TaskStats(context.Background()) 266 require.Error(t, err) 267 assert.Contains(t, err.Error(), "500 Internal Server Error") 268 } 269 270 func TestECSMetadataProvider_TaskStats_MalformedResponse(t *testing.T) { 271 endpoint, mux, teardown := setupTS() 272 defer teardown() 273 274 mux.HandleFunc("/task/stats", func(w http.ResponseWriter, req *http.Request) { 275 w.Write([]byte("here is your data")) 276 }) 277 278 c := aws.NewECSMetadataProvider(endpoint, nil) 279 280 _, err := c.TaskStats(context.Background()) 281 require.Error(t, err) 282 assert.Contains(t, err.Error(), "malformed") 283 } 284 285 func setupTS() (string, *http.ServeMux, func()) { 286 mux := http.NewServeMux() 287 srv := httptest.NewServer(mux) 288 289 return srv.URL, mux, srv.Close 290 }