github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/scripts/metricsgen/metricsgen_test.go (about) 1 package main_test 2 3 import ( 4 "bytes" 5 "fmt" 6 "go/parser" 7 "go/token" 8 "io" 9 "io/ioutil" 10 "os" 11 "path" 12 "path/filepath" 13 "testing" 14 15 metricsgen "github.com/ari-anchor/sei-tendermint/scripts/metricsgen" 16 "github.com/stretchr/testify/require" 17 ) 18 19 const testDataDir = "./testdata" 20 21 func TestSimpleTemplate(t *testing.T) { 22 m := metricsgen.ParsedMetricField{ 23 TypeName: "Histogram", 24 FieldName: "MyMetric", 25 MetricName: "request_count", 26 Description: "how many requests were made since the start of the process", 27 Labels: "first, second, third", 28 } 29 td := metricsgen.TemplateData{ 30 Package: "mypack", 31 ParsedMetrics: []metricsgen.ParsedMetricField{m}, 32 } 33 b := bytes.NewBuffer([]byte{}) 34 err := metricsgen.GenerateMetricsFile(b, td) 35 if err != nil { 36 t.Fatalf("unable to parse template %v", err) 37 } 38 } 39 40 func TestFromData(t *testing.T) { 41 infos, err := ioutil.ReadDir(testDataDir) 42 if err != nil { 43 t.Fatalf("unable to open file %v", err) 44 } 45 for _, dir := range infos { 46 t.Run(dir.Name(), func(t *testing.T) { 47 if !dir.IsDir() { 48 t.Fatalf("expected file %s to be directory", dir.Name()) 49 } 50 dirName := path.Join(testDataDir, dir.Name()) 51 pt, err := metricsgen.ParseMetricsDir(dirName, "Metrics") 52 if err != nil { 53 t.Fatalf("unable to parse from dir %q: %v", dir, err) 54 } 55 outFile := path.Join(dirName, "out.go") 56 if err != nil { 57 t.Fatalf("unable to open file %s: %v", outFile, err) 58 } 59 of, err := os.Create(outFile) 60 if err != nil { 61 t.Fatalf("unable to open file %s: %v", outFile, err) 62 } 63 defer os.Remove(outFile) 64 if err := metricsgen.GenerateMetricsFile(of, pt); err != nil { 65 t.Fatalf("unable to generate metrics file %s: %v", outFile, err) 66 } 67 if _, err := parser.ParseFile(token.NewFileSet(), outFile, nil, parser.AllErrors); err != nil { 68 t.Fatalf("unable to parse generated file %s: %v", outFile, err) 69 } 70 bNew, err := ioutil.ReadFile(outFile) 71 if err != nil { 72 t.Fatalf("unable to read generated file %s: %v", outFile, err) 73 } 74 goldenFile := path.Join(dirName, "metrics.gen.go") 75 bOld, err := ioutil.ReadFile(goldenFile) 76 if err != nil { 77 t.Fatalf("unable to read file %s: %v", goldenFile, err) 78 } 79 if !bytes.Equal(bNew, bOld) { 80 t.Fatalf("newly generated code in file %s does not match golden file %s\n"+ 81 "if the output of the metricsgen tool is expected to change run the following make target: \n"+ 82 "\tmake metrics", outFile, goldenFile) 83 } 84 }) 85 } 86 } 87 88 func TestParseMetricsStruct(t *testing.T) { 89 const pkgName = "mypkg" 90 metricsTests := []struct { 91 name string 92 shouldError bool 93 metricsStruct string 94 expected metricsgen.TemplateData 95 }{ 96 { 97 name: "basic", 98 metricsStruct: `type Metrics struct { 99 myGauge metrics.Gauge 100 }`, 101 expected: metricsgen.TemplateData{ 102 Package: pkgName, 103 ParsedMetrics: []metricsgen.ParsedMetricField{ 104 { 105 TypeName: "Gauge", 106 FieldName: "myGauge", 107 MetricName: "my_gauge", 108 }, 109 }, 110 }, 111 }, 112 { 113 name: "histogram", 114 metricsStruct: "type Metrics struct {\n" + 115 "myHistogram metrics.Histogram `metrics_buckettype:\"exp\" metrics_bucketsizes:\"1, 100, .8\"`\n" + 116 "}", 117 expected: metricsgen.TemplateData{ 118 Package: pkgName, 119 ParsedMetrics: []metricsgen.ParsedMetricField{ 120 { 121 TypeName: "Histogram", 122 FieldName: "myHistogram", 123 MetricName: "my_histogram", 124 125 HistogramOptions: metricsgen.HistogramOpts{ 126 BucketType: "stdprometheus.ExponentialBuckets", 127 BucketSizes: "1, 100, .8", 128 }, 129 }, 130 }, 131 }, 132 }, 133 { 134 name: "labeled name", 135 metricsStruct: "type Metrics struct {\n" + 136 "myCounter metrics.Counter `metrics_name:\"new_name\"`\n" + 137 "}", 138 expected: metricsgen.TemplateData{ 139 Package: pkgName, 140 ParsedMetrics: []metricsgen.ParsedMetricField{ 141 { 142 TypeName: "Counter", 143 FieldName: "myCounter", 144 MetricName: "new_name", 145 }, 146 }, 147 }, 148 }, 149 { 150 name: "metric labels", 151 metricsStruct: "type Metrics struct {\n" + 152 "myCounter metrics.Counter `metrics_labels:\"label1,label2\"`\n" + 153 "}", 154 expected: metricsgen.TemplateData{ 155 Package: pkgName, 156 ParsedMetrics: []metricsgen.ParsedMetricField{ 157 { 158 TypeName: "Counter", 159 FieldName: "myCounter", 160 MetricName: "my_counter", 161 Labels: "\"label1\",\"label2\"", 162 }, 163 }, 164 }, 165 }, 166 { 167 name: "ignore non-metric field", 168 metricsStruct: `type Metrics struct { 169 myCounter metrics.Counter 170 nonMetric string 171 }`, 172 expected: metricsgen.TemplateData{ 173 Package: pkgName, 174 ParsedMetrics: []metricsgen.ParsedMetricField{ 175 { 176 TypeName: "Counter", 177 FieldName: "myCounter", 178 MetricName: "my_counter", 179 }, 180 }, 181 }, 182 }, 183 } 184 for _, testCase := range metricsTests { 185 t.Run(testCase.name, func(t *testing.T) { 186 dir, err := os.MkdirTemp(os.TempDir(), "metricsdir") 187 if err != nil { 188 t.Fatalf("unable to create directory: %v", err) 189 } 190 defer os.Remove(dir) 191 f, err := os.Create(filepath.Join(dir, "metrics.go")) 192 if err != nil { 193 t.Fatalf("unable to open file: %v", err) 194 } 195 pkgLine := fmt.Sprintf("package %s\n", pkgName) 196 importClause := ` 197 import( 198 "github.com/go-kit/kit/metrics" 199 ) 200 ` 201 202 _, err = io.WriteString(f, pkgLine) 203 require.NoError(t, err) 204 _, err = io.WriteString(f, importClause) 205 require.NoError(t, err) 206 _, err = io.WriteString(f, testCase.metricsStruct) 207 require.NoError(t, err) 208 209 td, err := metricsgen.ParseMetricsDir(dir, "Metrics") 210 if testCase.shouldError { 211 require.Error(t, err) 212 } else { 213 require.NoError(t, err) 214 require.Equal(t, testCase.expected, td) 215 } 216 }) 217 } 218 } 219 220 func TestParseAliasedMetric(t *testing.T) { 221 aliasedData := ` 222 package mypkg 223 224 import( 225 mymetrics "github.com/go-kit/kit/metrics" 226 ) 227 type Metrics struct { 228 m mymetrics.Gauge 229 } 230 ` 231 dir, err := os.MkdirTemp(os.TempDir(), "metricsdir") 232 if err != nil { 233 t.Fatalf("unable to create directory: %v", err) 234 } 235 defer os.Remove(dir) 236 f, err := os.Create(filepath.Join(dir, "metrics.go")) 237 if err != nil { 238 t.Fatalf("unable to open file: %v", err) 239 } 240 _, err = io.WriteString(f, aliasedData) 241 if err != nil { 242 t.Fatalf("unable to write to file: %v", err) 243 } 244 td, err := metricsgen.ParseMetricsDir(dir, "Metrics") 245 require.NoError(t, err) 246 247 expected := 248 metricsgen.TemplateData{ 249 Package: "mypkg", 250 ParsedMetrics: []metricsgen.ParsedMetricField{ 251 { 252 TypeName: "Gauge", 253 FieldName: "m", 254 MetricName: "m", 255 }, 256 }, 257 } 258 require.Equal(t, expected, td) 259 }