func (a *Api) exportMetricsSchema(request *restful.Request, response *restful.Response) { result := TimeseriesSchema{} for _, label := range sinksApi.CommonLabels() { result.CommonLabels = append(result.CommonLabels, LabelDescriptor{ Key: label.Key, Description: label.Description, }) } for _, label := range sinksApi.PodLabels() { result.PodLabels = append(result.PodLabels, LabelDescriptor{ Key: label.Key, Description: label.Description, }) } for _, metric := range sinksApi.SupportedStatMetrics() { md := MetricDescriptor{ Name: metric.Name, Description: metric.Description, Type: metric.Type.String(), ValueType: metric.ValueType.String(), Units: metric.Units.String(), } for _, label := range metric.Labels { md.Labels = append(md.Labels, LabelDescriptor{ Key: label.Key, Description: label.Description, }) } result.Metrics = append(result.Metrics, md) } response.WriteEntity(result) }
func runHeapsterMetricsTest(fm kubeFramework, svc *kube_api.Service, expectedNodes, expectedPods []string) error { timeseries, err := getTimeseries(fm, svc) if err != nil { return err } if len(timeseries) == 0 { return fmt.Errorf("expected non zero timeseries") } schema, err := getSchema(fm, svc) if err != nil { return err } // Build a map of metric names to metric descriptors. mdMap := map[string]*heapster_api.MetricDescriptor{} for idx := range schema.Metrics { mdMap[schema.Metrics[idx].Name] = &schema.Metrics[idx] } actualPods := map[string]bool{} actualNodes := map[string]bool{} actualSystemContainers := map[string]map[string]struct{}{} for _, ts := range timeseries { // Verify the relevant labels are present. // All common labels must be present. for _, label := range sink_api.CommonLabels() { _, exists := ts.Labels[label.Key] if !exists { return fmt.Errorf("timeseries: %v does not contain common label: %v", ts, label) } } podName, podMetric := ts.Labels[sink_api.LabelPodName.Key] if podMetric { for _, label := range sink_api.PodLabels() { _, exists := ts.Labels[label.Key] if !exists { return fmt.Errorf("timeseries: %v does not contain pod label: %v", ts, label) } } } if podMetric { actualPods[podName] = true } else { if cName, ok := ts.Labels[sink_api.LabelContainerName.Key]; ok { hostname, ok := ts.Labels[sink_api.LabelHostname.Key] if !ok { return fmt.Errorf("hostname label missing on container %+v", ts) } if cName == cache.NodeContainerName { actualNodes[hostname] = true } if _, exists := expectedSystemContainers[cName]; exists { if actualSystemContainers[cName] == nil { actualSystemContainers[cName] = map[string]struct{}{} } actualSystemContainers[cName][hostname] = struct{}{} } } else { return fmt.Errorf("container_name label missing on timeseries - %v", ts) } } for metricName, points := range ts.Metrics { md, exists := mdMap[metricName] if !exists { return fmt.Errorf("unexpected metric %q", metricName) } for _, point := range points { for _, label := range md.Labels { _, exists := point.Labels[label.Key] if !exists { return fmt.Errorf("metric %q point %v does not contain metric label: %v", metricName, point, label) } } } } } // Validate that system containers are running on all the nodes. // This test could fail if one of the containers was down while the metrics sample was collected. for cName, hosts := range actualSystemContainers { for _, host := range expectedNodes { if _, ok := hosts[host]; !ok { return fmt.Errorf("System container %q not found on host: %q - %v", cName, host, actualSystemContainers) } } } if !expectedItemsExist(expectedPods, actualPods) { return fmt.Errorf("expected pods don't exist.\nExpected: %v\nActual:%v", expectedPods, actualPods) } if !expectedItemsExist(expectedNodes, actualNodes) { return fmt.Errorf("expected nodes don't exist.\nExpected: %v\nActual:%v", expectedNodes, actualNodes) } return nil }
func runHeapsterMetricsTest(fm kubeFramework, svc *kube_api.Service, expectedNodes, expectedPods []string) error { body, err := fm.Client().Get(). Namespace(svc.Namespace). Prefix("proxy"). Resource("services"). Name(svc.Name). Suffix(metricsEndpoint). Do().Raw() if err != nil { return err } var timeseries []*heapster_api.Timeseries if err := json.Unmarshal(body, ×eries); err != nil { glog.V(2).Infof("response body: %v", string(body)) return err } if len(timeseries) == 0 { return fmt.Errorf("expected non zero timeseries") } body, err = fm.Client().Get(). Namespace(svc.Namespace). Prefix("proxy"). Resource("services"). Name(svc.Name). Suffix(metricsSchemaEndpoint). Do().Raw() if err != nil { return err } var timeseriesSchema heapster_api.TimeseriesSchema if err := json.Unmarshal(body, ×eriesSchema); err != nil { glog.V(2).Infof("response body: %v", string(body)) return err } // Build a map of metric names to metric descriptors. mdMap := map[string]*heapster_api.MetricDescriptor{} for idx := range timeseriesSchema.Metrics { mdMap[timeseriesSchema.Metrics[idx].Name] = ×eriesSchema.Metrics[idx] } actualPods := map[string]bool{} actualNodes := map[string]bool{} for _, ts := range timeseries { // Verify the relevant labels are present. // All common labels must be present. for _, label := range sink_api.CommonLabels() { _, exists := ts.Labels[label.Key] if !exists { return fmt.Errorf("timeseries: %v does not contain common label: %v", ts, label) } } podName, podMetric := ts.Labels[sink_api.LabelPodName.Key] if podMetric { for _, label := range sink_api.PodLabels() { _, exists := ts.Labels[label.Key] if !exists { return fmt.Errorf("timeseries: %v does not contain pod label: %v", ts, label) } } } if podMetric { actualPods[podName] = true } else if cName, ok := ts.Labels[sink_api.LabelContainerName.Key]; ok && cName == cache.NodeContainerName { hostname, ok := ts.Labels[sink_api.LabelHostname.Key] if !ok { return fmt.Errorf("hostname label missing on node container %+v", ts.Labels) } actualNodes[hostname] = true } for metricName, points := range ts.Metrics { md, exists := mdMap[metricName] if !exists { return fmt.Errorf("unexpected metric %q", metricName) } for _, point := range points { for _, label := range md.Labels { _, exists := point.Labels[label.Key] if !exists { return fmt.Errorf("metric %q point %v does not contain metric label: %v", metricName, point, label) } } } } } if !expectedItemsExist(expectedPods, actualPods) { return fmt.Errorf("expected pods don't exist.\nExpected: %v\nActual:%v", expectedPods, actualPods) } if !expectedItemsExist(expectedNodes, actualNodes) { return fmt.Errorf("expected nodes don't exist.\nExpected: %v\nActual:%v", expectedNodes, actualNodes) } return nil }