github.com/mier85/go-sensor@v1.30.1-0.20220920111756-9bf41b3bc7e0/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/testify/assert"
    14  	"github.com/instana/testify/require"
    15  	"github.com/mier85/go-sensor/aws"
    16  	"github.com/mier85/go-sensor/docker"
    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  }