func TestPrometheusFiltersMetrics(t *testing.T) {
	assert := assert.New(t)

	//Create a prometheus collector using the config file 'sample_config_prometheus_filtered.json'
	configFile, err := ioutil.ReadFile("config/sample_config_prometheus_filtered.json")
	containerHandler := containertest.NewMockContainerHandler("mockContainer")
	collector, err := NewPrometheusCollector("Prometheus", configFile, 100, containerHandler, http.DefaultClient)
	assert.NoError(err)
	assert.Equal(collector.name, "Prometheus")
	assert.Equal(collector.configFile.Endpoint.URL, "http://localhost:8080/metrics")

	tempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

		text := "# HELP go_gc_duration_seconds A summary of the GC invocation durations.\n"
		text += "# TYPE go_gc_duration_seconds summary\n"
		text += "go_gc_duration_seconds{quantile=\"0\"} 5.8348000000000004e-05\n"
		text += "go_gc_duration_seconds{quantile=\"1\"} 0.000499764\n"
		text += "# HELP go_goroutines Number of goroutines that currently exist.\n"
		text += "# TYPE go_goroutines gauge\n"
		text += "go_goroutines 16"
		fmt.Fprintln(w, text)
	}))

	defer tempServer.Close()

	collector.configFile.Endpoint.URL = tempServer.URL
	metrics := map[string][]v1.MetricVal{}
	_, metrics, errMetric := collector.Collect(metrics)

	assert.NoError(errMetric)
	assert.Len(metrics, 1)

	goRoutines := metrics["go_goroutines"]
	assert.Equal(goRoutines[0].FloatValue, 16)
}
func TestMetricCollection(t *testing.T) {
	assert := assert.New(t)

	//Collect nginx metrics from a fake nginx endpoint
	configFile, err := ioutil.ReadFile("config/sample_config.json")
	assert.NoError(err)

	containerHandler := containertest.NewMockContainerHandler("mockContainer")
	fakeCollector, err := NewCollector("nginx", configFile, 100, containerHandler, http.DefaultClient)
	assert.NoError(err)

	tempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "Active connections: 3\nserver accepts handled requests")
		fmt.Fprintln(w, "5 5 32\nReading: 0 Writing: 1 Waiting: 2")
	}))
	defer tempServer.Close()
	fakeCollector.configFile.Endpoint.URL = tempServer.URL

	metrics := map[string][]v1.MetricVal{}
	_, metrics, errMetric := fakeCollector.Collect(metrics)
	assert.NoError(errMetric)
	metricNames := []string{"activeConnections", "reading", "writing", "waiting"}
	// activeConnections = 3
	assert.Equal(metrics[metricNames[0]][0].IntValue, 3)
	assert.Equal(metrics[metricNames[0]][0].FloatValue, 0)
	// reading = 0
	assert.Equal(metrics[metricNames[1]][0].IntValue, 0)
	assert.Equal(metrics[metricNames[1]][0].FloatValue, 0)
	// writing = 1
	assert.Equal(metrics[metricNames[2]][0].IntValue, 1)
	assert.Equal(metrics[metricNames[2]][0].FloatValue, 0)
	// waiting = 2
	assert.Equal(metrics[metricNames[3]][0].IntValue, 2)
	assert.Equal(metrics[metricNames[3]][0].FloatValue, 0)
}
func TestPrometheusMetricCountLimit(t *testing.T) {
	assert := assert.New(t)

	//Create a prometheus collector using the config file 'sample_config_prometheus.json'
	configFile, err := ioutil.ReadFile("config/sample_config_prometheus.json")
	containerHandler := containertest.NewMockContainerHandler("mockContainer")
	collector, err := NewPrometheusCollector("Prometheus", configFile, 10, containerHandler, http.DefaultClient)
	assert.NoError(err)
	assert.Equal(collector.name, "Prometheus")
	assert.Equal(collector.configFile.Endpoint.URL, "http://localhost:8080/metrics")

	tempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		for i := 0; i < 30; i++ {
			fmt.Fprintf(w, "# HELP m%d Number of goroutines that currently exist.\n", i)
			fmt.Fprintf(w, "# TYPE m%d gauge\n", i)
			fmt.Fprintf(w, "m%d %d", i, i)
		}
	}))
	defer tempServer.Close()

	collector.configFile.Endpoint.URL = tempServer.URL
	metrics := map[string][]v1.MetricVal{}
	_, result, errMetric := collector.Collect(metrics)

	assert.Error(errMetric)
	assert.Equal(len(metrics), 0)
	assert.Nil(result)
}
func TestConfigWithErrors(t *testing.T) {
	assert := assert.New(t)

	//Syntax error: Missed '"' after activeConnections
	invalid := `
	{
		"endpoint" : "http://localhost:8000/nginx_status",
		"metrics_config"  : [
			{
				 "name" : "activeConnections,  
		  		 "metric_type" : "gauge",
		 	 	 "data_type" : "int",
		  		 "polling_frequency" : 10,
		    		 "regex" : "Active connections: ([0-9]+)"			
			}
		]
	}
	`

	//Create a temporary config file 'temp.json' with invalid json format
	assert.NoError(ioutil.WriteFile("temp.json", []byte(invalid), 0777))
	configFile, err := ioutil.ReadFile("temp.json")
	assert.NoError(err)

	containerHandler := containertest.NewMockContainerHandler("mockContainer")
	_, err = NewCollector("tempCollector", configFile, 100, containerHandler, http.DefaultClient)
	assert.Error(err)

	assert.NoError(os.Remove("temp.json"))
}
func TestPrometheusFiltersMetricsCountLimit(t *testing.T) {
	assert := assert.New(t)

	//Create a prometheus collector using the config file 'sample_config_prometheus_filtered.json'
	configFile, err := ioutil.ReadFile("config/sample_config_prometheus_filtered.json")
	containerHandler := containertest.NewMockContainerHandler("mockContainer")
	_, err = NewPrometheusCollector("Prometheus", configFile, 1, containerHandler, http.DefaultClient)
	assert.Error(err)
}
Beispiel #6
0
func TestGetContainerInfoV2Failure(t *testing.T) {
	successful := "/"
	statless := "/c1"
	failing := "/c2"
	containers := []string{
		successful, statless, failing,
	}

	options := v2.RequestOptions{
		IdType:    v2.TypeName,
		Count:     1,
		Recursive: true,
	}
	query := &info.ContainerInfoRequest{
		NumStats: 2,
	}

	m, _, handlerMap := expectManagerWithContainers(containers, query, t)

	// Remove /c1 stats
	err := m.memoryCache.RemoveContainer(statless)
	if err != nil {
		t.Fatalf("RemoveContainer failed: %v", err)
	}

	// Make GetSpec fail on /c2
	mockErr := fmt.Errorf("intentional GetSpec failure")
	failingHandler := containertest.NewMockContainerHandler(failing)
	failingHandler.On("GetSpec").Return(info.ContainerSpec{}, mockErr)
	failingHandler.On("Exists").Return(true)
	*handlerMap[failing] = *failingHandler
	m.containers[namespacedContainerName{Name: failing}].lastUpdatedTime = time.Time{} // Force GetSpec.

	infos, err := m.GetContainerInfoV2("/", options)
	if err == nil {
		t.Error("Expected error calling GetContainerInfoV2")
	}

	// Successful containers still successful.
	info, ok := infos[successful]
	assert.True(t, ok, "Missing info for container %q", successful)
	assert.NotEqual(t, v2.ContainerSpec{}, info.Spec, "Empty spec for container %q", successful)
	assert.NotEmpty(t, info.Stats, "Missing stats for container %q", successful)

	// "/c1" present with spec.
	info, ok = infos[statless]
	assert.True(t, ok, "Missing info for container %q", statless)
	assert.NotEqual(t, v2.ContainerSpec{}, info.Spec, "Empty spec for container %q", statless)
	assert.Empty(t, info.Stats, "Missing stats for container %q", successful)

	// "/c2" should be present but empty.
	info, ok = infos[failing]
	assert.True(t, ok, "Missing info for failed container")
	assert.Equal(t, v2.ContainerInfo{}, info, "Empty spec for failed container")
	assert.Empty(t, info.Stats, "Missing stats for failed container")
}
func TestMetricCollectionLimit(t *testing.T) {
	assert := assert.New(t)

	//Collect nginx metrics from a fake nginx endpoint
	configFile, err := ioutil.ReadFile("config/sample_config.json")
	assert.NoError(err)

	containerHandler := containertest.NewMockContainerHandler("mockContainer")
	_, err = NewCollector("nginx", configFile, 1, containerHandler, http.DefaultClient)
	assert.Error(err)
}
Beispiel #8
0
// Create a containerData instance for a test.
func setupContainerData(t *testing.T, spec info.ContainerSpec) (*containerData, *containertest.MockContainerHandler, *memory.InMemoryCache) {
	mockHandler := containertest.NewMockContainerHandler(containerName)
	mockHandler.On("GetSpec").Return(
		spec,
		nil,
	)
	memoryCache := memory.New(60, nil)
	ret, err := newContainerData(containerName, memoryCache, mockHandler, false, &collector.GenericCollectorManager{}, 60*time.Second, true)
	if err != nil {
		t.Fatal(err)
	}
	return ret, mockHandler, memoryCache
}
func TestConfig(t *testing.T) {
	assert := assert.New(t)

	//Create an nginx collector using the config file 'sample_config.json'
	configFile, err := ioutil.ReadFile("config/sample_config.json")
	assert.NoError(err)

	containerHandler := containertest.NewMockContainerHandler("mockContainer")
	collector, err := NewCollector("nginx", configFile, 100, containerHandler, http.DefaultClient)
	assert.NoError(err)
	assert.Equal(collector.name, "nginx")
	assert.Equal(collector.configFile.Endpoint.URL, "http://localhost:8000/nginx_status")
	assert.Equal(collector.configFile.MetricsConfig[0].Name, "activeConnections")
}
func TestPrometheusEndpointConfig(t *testing.T) {
	assert := assert.New(t)

	//Create a prometheus collector using the config file 'sample_config_prometheus.json'
	configFile, err := ioutil.ReadFile("config/sample_config_prometheus_endpoint_config.json")
	containerHandler := containertest.NewMockContainerHandler("mockContainer")
	containerHandler.On("GetContainerIPAddress").Return(
		"222.222.222.222",
	)

	collector, err := NewPrometheusCollector("Prometheus", configFile, 100, containerHandler, http.DefaultClient)
	assert.NoError(err)
	assert.Equal(collector.name, "Prometheus")
	assert.Equal(collector.configFile.Endpoint.URL, "http://222.222.222.222:8081/METRICS")
}
Beispiel #11
0
func TestEndpointConfig(t *testing.T) {
	assert := assert.New(t)
	configFile, err := ioutil.ReadFile("config/sample_config_endpoint_config.json")
	assert.NoError(err)

	containerHandler := containertest.NewMockContainerHandler("mockContainer")
	containerHandler.On("GetContainerIPAddress").Return(
		"111.111.111.111",
	)

	collector, err := NewCollector("nginx", configFile, 100, containerHandler, http.DefaultClient)
	assert.NoError(err)
	assert.Equal(collector.name, "nginx")
	assert.Equal(collector.configFile.Endpoint.URL, "https://111.111.111.111:8000/nginx_status")
	assert.Equal(collector.configFile.MetricsConfig[0].Name, "activeConnections")
}
func TestPrometheusShortResponse(t *testing.T) {
	assert := assert.New(t)

	//Create a prometheus collector using the config file 'sample_config_prometheus.json'
	configFile, err := ioutil.ReadFile("config/sample_config_prometheus.json")
	containerHandler := containertest.NewMockContainerHandler("mockContainer")
	collector, err := NewPrometheusCollector("Prometheus", configFile, 100, containerHandler, http.DefaultClient)
	assert.NoError(err)
	assert.Equal(collector.name, "Prometheus")
	assert.Equal(collector.configFile.Endpoint.URL, "http://localhost:8080/metrics")

	tempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		text := "# HELP empty_metric A metric without any values"
		fmt.Fprint(w, text)
	}))

	defer tempServer.Close()

	collector.configFile.Endpoint.URL = tempServer.URL

	assert.NotPanics(func() { collector.GetSpec() })
}
Beispiel #13
0
func TestConfigWithRegexErrors(t *testing.T) {
	assert := assert.New(t)

	//Error: Missed operand for '+' in activeConnections regex
	invalid := `
        {
                "endpoint" : "host:port/nginx_status",
                "metrics_config"  : [
                        {
                                 "name" : "activeConnections",
                                 "metric_type" : "gauge",
                                 "data_type" : "int",
                                 "polling_frequency" : 10,
                                 "regex" : "Active connections: (+)"
                        },
                        {
                                 "name" : "reading",
                                 "metric_type" : "gauge",
                                 "data_type" : "int",
                                 "polling_frequency" : 10,
                                 "regex" : "Reading: ([0-9]+) .*"
                        }
                ]
        }
        `

	//Create a temporary config file 'temp.json'
	assert.NoError(ioutil.WriteFile("temp.json", []byte(invalid), 0777))

	configFile, err := ioutil.ReadFile("temp.json")
	assert.NoError(err)

	containerHandler := containertest.NewMockContainerHandler("mockContainer")
	_, err = NewCollector("tempCollector", configFile, 100, containerHandler, http.DefaultClient)
	assert.Error(err)

	assert.NoError(os.Remove("temp.json"))
}
Beispiel #14
0
func createManagerAndAddContainers(
	memoryCache *memory.InMemoryCache,
	sysfs *fakesysfs.FakeSysFs,
	containers []string,
	f func(*containertest.MockContainerHandler),
	t *testing.T,
) *manager {
	container.ClearContainerHandlerFactories()
	mif := &manager{
		containers:   make(map[namespacedContainerName]*containerData),
		quitChannels: make([]chan error, 0, 2),
		memoryCache:  memoryCache,
	}
	for _, name := range containers {
		mockHandler := containertest.NewMockContainerHandler(name)
		spec := itest.GenerateRandomContainerSpec(4)
		mockHandler.On("GetSpec").Return(
			spec,
			nil,
		).Once()
		cont, err := newContainerData(name, memoryCache, mockHandler, false, &collector.GenericCollectorManager{}, 60*time.Second, true)
		if err != nil {
			t.Fatal(err)
		}
		mif.containers[namespacedContainerName{
			Name: name,
		}] = cont
		// Add Docker containers under their namespace.
		if strings.HasPrefix(name, "/docker") {
			mif.containers[namespacedContainerName{
				Namespace: docker.DockerNamespace,
				Name:      strings.TrimPrefix(name, "/docker/"),
			}] = cont
		}
		f(mockHandler)
	}
	return mif
}
Beispiel #15
0
func TestEmptyConfig(t *testing.T) {
	assert := assert.New(t)

	emptyConfig := `
        {
                "endpoint" : "http://localhost:8000/nginx_status",
                "metrics_config"  : [
                ]
        }
        `

	//Create a temporary config file 'temp.json' with invalid json format
	assert.NoError(ioutil.WriteFile("temp.json", []byte(emptyConfig), 0777))

	configFile, err := ioutil.ReadFile("temp.json")
	assert.NoError(err)

	containerHandler := containertest.NewMockContainerHandler("mockContainer")
	_, err = NewCollector("tempCollector", configFile, 100, containerHandler, http.DefaultClient)
	assert.Error(err)

	assert.NoError(os.Remove("temp.json"))
}