From 7c23ba1b344bf3ae9e23285175f6545b82e4da26 Mon Sep 17 00:00:00 2001 From: Kenichi Omichi Date: Thu, 29 Aug 2019 00:11:53 +0000 Subject: [PATCH] Copy PrettyPrintJSON to core framework PrettyPrintJSON is most used e2emetrics function and that doesn't seem specific for metrics. The implementation itself is generic, so it is nice to move it to core framework for avoiding circular dependency. --- test/e2e/framework/flake_reporting_util.go | 4 +--- test/e2e/framework/log_size_monitoring.go | 3 +-- test/e2e/framework/metrics/e2e_metrics.go | 2 ++ test/e2e/framework/resource_usage_gatherer.go | 3 +-- test/e2e/framework/timer/BUILD | 2 +- test/e2e/framework/timer/timer.go | 4 ++-- test/e2e/framework/util.go | 15 +++++++++++++++ test/e2e/node/BUILD | 1 - test/e2e/node/kubelet_perf.go | 3 +-- test/e2e/scalability/density.go | 2 +- test/e2e_node/benchmark_util.go | 6 +++--- test/e2e_node/density_test.go | 2 +- 12 files changed, 29 insertions(+), 18 deletions(-) diff --git a/test/e2e/framework/flake_reporting_util.go b/test/e2e/framework/flake_reporting_util.go index 6f0512ac320..3527f071f43 100644 --- a/test/e2e/framework/flake_reporting_util.go +++ b/test/e2e/framework/flake_reporting_util.go @@ -20,8 +20,6 @@ import ( "bytes" "fmt" "sync" - - e2emetrics "k8s.io/kubernetes/test/e2e/framework/metrics" ) // FlakeReport is a struct for managing the flake report. @@ -90,7 +88,7 @@ func (f *FlakeReport) PrintHumanReadable() string { func (f *FlakeReport) PrintJSON() string { f.lock.RLock() defer f.lock.RUnlock() - return e2emetrics.PrettyPrintJSON(f) + return PrettyPrintJSON(f) } // SummaryKind returns the summary of flake report. diff --git a/test/e2e/framework/log_size_monitoring.go b/test/e2e/framework/log_size_monitoring.go index 5efc10e6411..4bfdaf9a60a 100644 --- a/test/e2e/framework/log_size_monitoring.go +++ b/test/e2e/framework/log_size_monitoring.go @@ -26,7 +26,6 @@ import ( "time" clientset "k8s.io/client-go/kubernetes" - e2emetrics "k8s.io/kubernetes/test/e2e/framework/metrics" e2essh "k8s.io/kubernetes/test/e2e/framework/ssh" ) @@ -108,7 +107,7 @@ func (s *LogsSizeDataSummary) PrintHumanReadable() string { // PrintJSON returns the summary of log size data with JSON format. func (s *LogsSizeDataSummary) PrintJSON() string { - return e2emetrics.PrettyPrintJSON(*s) + return PrettyPrintJSON(*s) } // SummaryKind returns the summary of log size data summary. diff --git a/test/e2e/framework/metrics/e2e_metrics.go b/test/e2e/framework/metrics/e2e_metrics.go index 7dad19648ab..10f1027caeb 100644 --- a/test/e2e/framework/metrics/e2e_metrics.go +++ b/test/e2e/framework/metrics/e2e_metrics.go @@ -111,6 +111,8 @@ func (m *ComponentCollection) PrintHumanReadable() string { } // PrettyPrintJSON converts metrics to JSON format. +// TODO: This function should be replaced with framework.PrettyPrintJSON after solving +// circulary dependency between core framework and this metrics subpackage. func PrettyPrintJSON(metrics interface{}) string { output := &bytes.Buffer{} if err := json.NewEncoder(output).Encode(metrics); err != nil { diff --git a/test/e2e/framework/resource_usage_gatherer.go b/test/e2e/framework/resource_usage_gatherer.go index b97580699e3..1e9aeea2077 100644 --- a/test/e2e/framework/resource_usage_gatherer.go +++ b/test/e2e/framework/resource_usage_gatherer.go @@ -33,7 +33,6 @@ import ( clientset "k8s.io/client-go/kubernetes" e2ekubelet "k8s.io/kubernetes/test/e2e/framework/kubelet" e2elog "k8s.io/kubernetes/test/e2e/framework/log" - e2emetrics "k8s.io/kubernetes/test/e2e/framework/metrics" "k8s.io/kubernetes/test/e2e/system" ) @@ -74,7 +73,7 @@ func (s *ResourceUsageSummary) PrintHumanReadable() string { // PrintJSON prints resource usage summary in JSON. func (s *ResourceUsageSummary) PrintJSON() string { - return e2emetrics.PrettyPrintJSON(*s) + return PrettyPrintJSON(*s) } // SummaryKind returns string of ResourceUsageSummary diff --git a/test/e2e/framework/timer/BUILD b/test/e2e/framework/timer/BUILD index bd6ed627bd7..64d0b7160e4 100644 --- a/test/e2e/framework/timer/BUILD +++ b/test/e2e/framework/timer/BUILD @@ -6,7 +6,7 @@ go_library( importpath = "k8s.io/kubernetes/test/e2e/framework/timer", visibility = ["//visibility:public"], deps = [ - "//test/e2e/framework/metrics:go_default_library", + "//test/e2e/framework:go_default_library", "//test/e2e/perftype:go_default_library", ], ) diff --git a/test/e2e/framework/timer/timer.go b/test/e2e/framework/timer/timer.go index 552aaaaafd3..9620ae021c5 100644 --- a/test/e2e/framework/timer/timer.go +++ b/test/e2e/framework/timer/timer.go @@ -22,7 +22,7 @@ import ( "bytes" "fmt" - e2emetrics "k8s.io/kubernetes/test/e2e/framework/metrics" + "k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/perftype" "sync" ) @@ -124,5 +124,5 @@ func (timer *TestPhaseTimer) PrintJSON() string { data.DataItems[0].Labels["ended"] = "false" } } - return e2emetrics.PrettyPrintJSON(data) + return framework.PrettyPrintJSON(data) } diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go index d05da0481ee..417d2f2afc3 100644 --- a/test/e2e/framework/util.go +++ b/test/e2e/framework/util.go @@ -3277,3 +3277,18 @@ func GetFileModeRegex(filePath string, mask *int32) string { return fmt.Sprintf("(%s|%s)", linuxOutput, windowsOutput) } + +// PrettyPrintJSON converts metrics to JSON format. +func PrettyPrintJSON(metrics interface{}) string { + output := &bytes.Buffer{} + if err := json.NewEncoder(output).Encode(metrics); err != nil { + Logf("Error building encoder: %v", err) + return "" + } + formatted := &bytes.Buffer{} + if err := json.Indent(formatted, output.Bytes(), "", " "); err != nil { + Logf("Error indenting: %v", err) + return "" + } + return string(formatted.Bytes()) +} diff --git a/test/e2e/node/BUILD b/test/e2e/node/BUILD index 95ce1bd5f36..7bbab2eb19f 100644 --- a/test/e2e/node/BUILD +++ b/test/e2e/node/BUILD @@ -42,7 +42,6 @@ go_library( "//test/e2e/framework:go_default_library", "//test/e2e/framework/job:go_default_library", "//test/e2e/framework/kubelet:go_default_library", - "//test/e2e/framework/metrics:go_default_library", "//test/e2e/framework/node:go_default_library", "//test/e2e/framework/perf:go_default_library", "//test/e2e/framework/pod:go_default_library", diff --git a/test/e2e/node/kubelet_perf.go b/test/e2e/node/kubelet_perf.go index 9a57b13df33..de7d238bbee 100644 --- a/test/e2e/node/kubelet_perf.go +++ b/test/e2e/node/kubelet_perf.go @@ -27,7 +27,6 @@ import ( kubeletstatsv1alpha1 "k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1" "k8s.io/kubernetes/test/e2e/framework" e2ekubelet "k8s.io/kubernetes/test/e2e/framework/kubelet" - e2emetrics "k8s.io/kubernetes/test/e2e/framework/metrics" e2eperf "k8s.io/kubernetes/test/e2e/framework/perf" "k8s.io/kubernetes/test/e2e/perftype" testutils "k8s.io/kubernetes/test/utils" @@ -285,7 +284,7 @@ var _ = SIGDescribe("Kubelet [Serial] [Slow]", func() { // If an error occurs, nothing will be printed. func printPerfData(p *perftype.PerfData) { // Notice that we must make sure the perftype.PerfResultEnd is in a new line. - if str := e2emetrics.PrettyPrintJSON(p); str != "" { + if str := framework.PrettyPrintJSON(p); str != "" { framework.Logf("%s %s\n%s", perftype.PerfResultTag, str, perftype.PerfResultEnd) } } diff --git a/test/e2e/scalability/density.go b/test/e2e/scalability/density.go index df633bd63ee..2ad1805219f 100644 --- a/test/e2e/scalability/density.go +++ b/test/e2e/scalability/density.go @@ -448,7 +448,7 @@ var _ = SIGDescribe("Density", func() { NumberOfPods: totalPods, Throughput: float32(totalPods) / float32(e2eStartupTime/time.Second), } - framework.Logf("Cluster saturation time: %s", e2emetrics.PrettyPrintJSON(saturationData)) + framework.Logf("Cluster saturation time: %s", framework.PrettyPrintJSON(saturationData)) summaries := make([]framework.TestDataSummary, 0, 2) // Verify latency metrics. diff --git a/test/e2e_node/benchmark_util.go b/test/e2e_node/benchmark_util.go index 8bae2e009c7..2e514c773e3 100644 --- a/test/e2e_node/benchmark_util.go +++ b/test/e2e_node/benchmark_util.go @@ -47,7 +47,7 @@ func dumpDataToFile(data interface{}, labels map[string]string, prefix string) { fileName := path.Join(framework.TestContext.ReportDir, fmt.Sprintf("%s-%s-%s.json", prefix, framework.TestContext.ReportPrefix, testName)) labels["timestamp"] = strconv.FormatInt(time.Now().UTC().Unix(), 10) framework.Logf("Dumping perf data for test %q to %q.", testName, fileName) - if err := ioutil.WriteFile(fileName, []byte(e2emetrics.PrettyPrintJSON(data)), 0644); err != nil { + if err := ioutil.WriteFile(fileName, []byte(framework.PrettyPrintJSON(data)), 0644); err != nil { framework.Logf("Failed to write perf data for test %q to %q: %v", testName, fileName, err) } } @@ -82,7 +82,7 @@ func logDensityTimeSeries(rc *ResourceCollector, create, watch map[string]metav1 timeSeries.ResourceData = rc.GetResourceTimeSeries() if framework.TestContext.ReportDir == "" { - framework.Logf("%s %s\n%s", TimeSeriesTag, e2emetrics.PrettyPrintJSON(timeSeries), TimeSeriesEnd) + framework.Logf("%s %s\n%s", TimeSeriesTag, framework.PrettyPrintJSON(timeSeries), TimeSeriesEnd) return } dumpDataToFile(timeSeries, timeSeries.Labels, "time_series") @@ -194,7 +194,7 @@ func getTestNodeInfo(f *framework.Framework, testName, testDesc string) map[stri // If an error occurs, nothing will be printed. func printPerfData(p *perftype.PerfData) { // Notice that we must make sure the perftype.PerfResultEnd is in a new line. - if str := e2emetrics.PrettyPrintJSON(p); str != "" { + if str := framework.PrettyPrintJSON(p); str != "" { framework.Logf("%s %s\n%s", perftype.PerfResultTag, str, perftype.PerfResultEnd) } } diff --git a/test/e2e_node/density_test.go b/test/e2e_node/density_test.go index 0335bdbe26e..a33f0bc47e3 100644 --- a/test/e2e_node/density_test.go +++ b/test/e2e_node/density_test.go @@ -540,7 +540,7 @@ func logAndVerifyLatency(batchLag time.Duration, e2eLags []e2emetrics.PodLatency // TODO(coufon): do not trust 'kubelet' metrics since they are not reset! latencyMetrics, _ := getPodStartLatency(kubeletAddr) - framework.Logf("Kubelet Prometheus metrics (not reset):\n%s", e2emetrics.PrettyPrintJSON(latencyMetrics)) + framework.Logf("Kubelet Prometheus metrics (not reset):\n%s", framework.PrettyPrintJSON(latencyMetrics)) podStartupLatency := e2emetrics.ExtractLatencyMetrics(e2eLags)