Example #1
0
func NewManager(sources []source_api.Source, sinkManager sinks.ExternalSinkManager, res, bufferDuration time.Duration, useModel bool, modelRes time.Duration, align bool) (Manager, error) {
	// TimeStore constructor passed to the cluster implementation.
	tsConstructor := func() store.TimeStore {
		// TODO(afein): determine default analogy of cache duration to Timestore durations.
		return store.NewGCStore(store.NewCMAStore(), 5*bufferDuration)
	}
	var newCluster model.Cluster = nil
	if useModel {
		newCluster = model.NewCluster(tsConstructor, modelRes)
	}
	firstSync := time.Now()
	if align {
		firstSync = firstSync.Truncate(res).Add(res)
	}
	return &realManager{
		sources:     sources,
		sinkManager: sinkManager,
		cache:       cache.NewCache(bufferDuration),
		model:       newCluster,
		lastSync:    firstSync,
		resolution:  res,
		align:       align,
		decoder:     sink_api.NewDecoder(),
	}, nil
}
Example #2
0
func doWork() ([]source_api.Source, sinks.ExternalSinkManager, manager.Manager, error) {
	c := cache.NewCache(*argCacheDuration, time.Minute)
	sources, err := newSources(c)
	if err != nil {
		return nil, nil, nil, err
	}
	sinkManager, err := sinks.NewExternalSinkManager(nil)
	if err != nil {
		return nil, nil, nil, err
	}
	manager, err := manager.NewManager(sources, sinkManager, *argStatsResolution, *argCacheDuration, c, *argUseModel, *argModelResolution, *argAlignStats)
	if err != nil {
		return nil, nil, nil, err
	}
	if err := manager.SetSinkUris(argSinks); err != nil {
		return nil, nil, nil, err
	}

	// Spawn the Model Housekeeping goroutine even if the model is not enabled.
	// This will allow the model to be activated/deactivated in runtime.
	modelDuration := 2 * *argModelResolution
	if (*argCacheDuration).Nanoseconds() < modelDuration.Nanoseconds() {
		modelDuration = *argCacheDuration
	}
	go util.Until(manager.HousekeepModel, modelDuration, util.NeverStop)

	go util.Until(manager.Housekeep, *argPollDuration, util.NeverStop)
	return sources, sinkManager, manager, nil
}
Example #3
0
func NewManager(sources []source_api.Source, sinkManager sinks.ExternalSinkManager, res, bufferDuration time.Duration) (Manager, error) {
	return &realManager{
		sources:     sources,
		sinkManager: sinkManager,
		cache:       cache.NewCache(bufferDuration),
		lastSync:    time.Now(),
		resolution:  res,
		decoder:     sink_api.NewDecoder(),
	}, nil
}
Example #4
0
// TestUpdate tests the normal flows of Update.
// TestUpdate performs consecutive calls to Update with both empty and non-empty caches
func TestUpdate(t *testing.T) {
	var (
		cluster      = newRealCluster(newTimeStore, time.Minute)
		source_cache = cacheFactory()
		assert       = assert.New(t)
		empty_cache  = cache.NewCache(24*time.Hour, time.Hour)
		zeroTime     = time.Time{}
	)

	// Invocation with empty cache
	assert.NoError(cluster.Update(empty_cache))
	assert.Empty(cluster.Nodes)
	assert.Empty(cluster.Namespaces)
	assert.Empty(cluster.Metrics)

	// Invocation with regular parameters
	assert.NoError(cluster.Update(source_cache))
	verifyCacheFactoryCluster(&cluster.ClusterInfo, t)

	// Assert Node Metric aggregation
	assert.NotEmpty(cluster.Nodes)
	assert.NotEmpty(cluster.Metrics)
	assert.NotNil(cluster.Metrics[memWorking])
	mem_work_ts := *(cluster.Metrics[memWorking])
	actual := mem_work_ts.Get(zeroTime, zeroTime)
	assert.Len(actual, 2)
	// Datapoint present in both nodes, added up to 1024
	assert.Equal(actual[1].Value.(uint64), uint64(1204))
	// Datapoint present in only one node
	assert.Equal(actual[0].Value.(uint64), uint64(602))

	assert.NotNil(cluster.Metrics[memUsage])
	mem_usage_ts := *(cluster.Metrics[memUsage])
	actual = mem_usage_ts.Get(zeroTime, zeroTime)
	assert.Len(actual, 2)
	// Datapoint present in both nodes, added up to 10000
	assert.Equal(actual[1].Value.(uint64), uint64(10000))
	// Datapoint present in only one node
	assert.Equal(actual[0].Value.(uint64), uint64(5000))

	// Assert Kubernetes Metric aggregation up to namespaces
	ns := cluster.Namespaces["test"]
	mem_work_ts = *(ns.Metrics[memWorking])
	actual = mem_work_ts.Get(zeroTime, zeroTime)
	assert.Len(actual, 1)
	assert.Equal(actual[0].Value.(uint64), uint64(2408))

	// Invocation with no fresh data - expect no change in cluster
	assert.NoError(cluster.Update(source_cache))
	verifyCacheFactoryCluster(&cluster.ClusterInfo, t)

	// Invocation with empty cache - expect no change in cluster
	assert.NoError(cluster.Update(empty_cache))
	verifyCacheFactoryCluster(&cluster.ClusterInfo, t)
}
Example #5
0
func TestEventsBasic(t *testing.T) {
	handler := util.FakeHandler{
		StatusCode:   200,
		RequestBody:  "something",
		ResponseBody: body(&kube_api.EventList{}),
		T:            t,
	}
	server := httptest.NewServer(&handler)
	defer server.Close()
	client := client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Version()})
	cache := cache.NewCache(time.Hour, time.Hour)
	source := NewKubeEvents(client, cache)
	_, err := source.GetInfo(time.Now(), time.Now().Add(time.Minute), time.Second, false)
	require.NoError(t, err)
	require.NotEmpty(t, source.DebugInfo())
}
Example #6
0
// cacheFactory generates a cache with a predetermined structure.
// The cache contains two pods, one with two containers and one without any containers.
// The cache also contains a free container and a "machine"-tagged container.
func cacheFactory() cache.Cache {
	source_cache := cache.NewCache(24*time.Hour, time.Hour)

	// Generate Container CMEs - same timestamp for aggregation
	cme_1 := cmeFactory()
	cme_2 := cmeFactory()
	cme_2.Stats.Timestamp = cme_1.Stats.Timestamp

	// Genete Machine CMEs - same timestamp for aggregation
	cme_3 := cmeFactory()
	cme_4 := cmeFactory()
	cme_4.Stats.Timestamp = cme_3.Stats.Timestamp

	cme_5 := cmeFactory()
	cme_5.Stats.Timestamp = cme_4.Stats.Timestamp.Add(time.Hour)
	cme_5.Stats.Cpu.Usage.Total = cme_4.Stats.Cpu.Usage.Total + uint64(3600000000000)

	// Generate a pod with two containers, and a pod without any containers
	container1 := source_api.Container{
		Name:     "container1",
		Hostname: "hostname2",
		Spec:     *cme_1.Spec,
		Stats:    []*cadvisor.ContainerStats{cme_1.Stats},
	}
	container2 := source_api.Container{
		Name:     "container2",
		Hostname: "hostname3",
		Spec:     *cme_2.Spec,
		Stats:    []*cadvisor.ContainerStats{cme_2.Stats},
	}

	containers := []source_api.Container{container1, container2}
	pods := []source_api.Pod{
		{
			PodMetadata: source_api.PodMetadata{
				Name:      "pod1",
				ID:        "123",
				Namespace: "test",
				Hostname:  "hostname2",
				Status:    "Running",
			},
			Containers: containers,
		},
		{
			PodMetadata: source_api.PodMetadata{
				Name:      "pod2",
				ID:        "1234",
				Namespace: "test",
				Hostname:  "hostname3",
				Status:    "Running",
			},
			Containers: containers,
		},
	}

	// Generate two machine containers
	machine_container := source_api.Container{
		Name:     "/",
		Hostname: "hostname2",
		Spec:     *cme_3.Spec,
		Stats:    []*cadvisor.ContainerStats{cme_3.Stats},
	}
	machine_container2 := source_api.Container{
		Name:     "/",
		Hostname: "hostname3",
		Spec:     *cme_4.Spec,
		Stats:    []*cadvisor.ContainerStats{cme_5.Stats, cme_4.Stats},
	}
	// Generate a free container
	free_container := source_api.Container{
		Name:     "free_container1",
		Hostname: "hostname2",
		Spec:     *cme_5.Spec,
		Stats:    []*cadvisor.ContainerStats{cme_5.Stats},
	}

	other_containers := []source_api.Container{
		machine_container,
		machine_container2,
		free_container,
	}

	// Enter everything in the cache
	source_cache.StorePods(pods)
	source_cache.StoreContainers(other_containers)

	return source_cache
}
Example #7
0
// cacheFactory generates a cache with a predetermined structure.
// The cache contains two pods, one with two containers and one without any containers.
// The cache also contains a free container and a "machine"-tagged container.
func cacheFactory() cache.Cache {
	source_cache := cache.NewCache(time.Hour)

	// Generate 4 ContainerMetricElements
	cme_1 := cmeFactory()
	cme_2 := cmeFactory()
	cme_3 := cmeFactory()
	cme_4 := cmeFactory()

	// Generate a pod with two containers, and a pod without any containers
	container1 := source_api.Container{
		Name:     "container1",
		Hostname: "hostname2",
		Spec:     *cme_1.Spec,
		Stats:    []*cadvisor.ContainerStats{cme_1.Stats},
	}
	container2 := source_api.Container{
		Name:     "container2",
		Hostname: "hostname3",
		Spec:     *cme_2.Spec,
		Stats:    []*cadvisor.ContainerStats{cme_2.Stats},
	}

	containers := []source_api.Container{container1, container2}
	pods := []source_api.Pod{
		{
			PodMetadata: source_api.PodMetadata{
				Name:      "pod1",
				ID:        "123",
				Namespace: "test",
				Hostname:  "hostname2",
				Status:    "Running",
			},
			Containers: containers,
		},
		{
			PodMetadata: source_api.PodMetadata{
				Name:      "pod2",
				ID:        "1234",
				Namespace: "test",
				Hostname:  "hostname3",
				Status:    "Running",
			},
			Containers: []source_api.Container{},
		},
	}

	// Generate a machine container
	machine_container := source_api.Container{
		Name:     "/",
		Hostname: "hostname2",
		Spec:     *cme_3.Spec,
		Stats:    []*cadvisor.ContainerStats{cme_3.Stats},
	}
	// Generate a free container
	free_container := source_api.Container{
		Name:     "free_container1",
		Hostname: "hostname2",
		Spec:     *cme_4.Spec,
		Stats:    []*cadvisor.ContainerStats{cme_4.Stats},
	}

	other_containers := []source_api.Container{machine_container, free_container}

	// Enter everything in the cache
	source_cache.StorePods(pods)
	source_cache.StoreContainers(other_containers)

	return source_cache
}