aboutsummaryrefslogtreecommitdiffstats
path: root/executor/style_test.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-08-06 14:55:39 +0200
committerDmitry Vyukov <dvyukov@google.com>2020-08-06 15:27:41 +0200
commitcb436c69d9bcb0330518a48559649c9436ed5e7a (patch)
tree1b1d474ad40b0748d3565c51938c1ed79b23f83e /executor/style_test.go
parent56fe5665461fbbc19704e44c23e42d5f6ecb5361 (diff)
executor: add some code style checks
Move the test from pkg/csource to executor/ in order to be able to (1) run it on *.cc files, (2) run on unprocessed *.h files, (3) produce line numbers. Add a check for missed space after //.
Diffstat (limited to 'executor/style_test.go')
-rw-r--r--executor/style_test.go107
1 files changed, 107 insertions, 0 deletions
diff --git a/executor/style_test.go b/executor/style_test.go
new file mode 100644
index 000000000..c3fde4889
--- /dev/null
+++ b/executor/style_test.go
@@ -0,0 +1,107 @@
+// Copyright 2020 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package executor
+
+import (
+ "bytes"
+ "io/ioutil"
+ "path/filepath"
+ "regexp"
+ "sort"
+ "strings"
+ "testing"
+)
+
+func TestExecutorMistakes(t *testing.T) {
+ checks := []*struct {
+ pattern string
+ suppression string
+ message string
+ tests []string
+ commonOnly bool
+ }{
+ {
+ pattern: `\)\n\t*(debug|debug_dump_data)\(`,
+ message: "debug() calls are stripped from C reproducers, this code will break. Use {} around debug() to fix",
+ commonOnly: true,
+ tests: []string{
+ `
+if (foo)
+ debug("foo failed");
+`, `
+ if (x + y)
+ debug_dump_data(data, len);
+`,
+ },
+ },
+ {
+ // These are also not properly stripped by pkg/csource.
+ pattern: `/\*[^{]`,
+ message: "Don't use /* */ block comments. Use // line comments instead",
+ tests: []string{
+ `/* C++ comment */`,
+ },
+ },
+ {
+ pattern: `//[^\s]`,
+ suppression: `https?://`,
+ message: "Add a space after //",
+ tests: []string{
+ `//foo`,
+ },
+ },
+ }
+ for _, check := range checks {
+ re := regexp.MustCompile(check.pattern)
+ for _, test := range check.tests {
+ if !re.MatchString(test) {
+ t.Fatalf("patter %q does not match test %q", check.pattern, test)
+ }
+ }
+ }
+ for _, file := range executorFiles(t) {
+ data, err := ioutil.ReadFile(file)
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, check := range checks {
+ if check.commonOnly && !strings.Contains(file, "common") {
+ continue
+ }
+ re := regexp.MustCompile(check.pattern)
+ supp := regexp.MustCompile(check.suppression)
+ for _, match := range re.FindAllIndex(data, -1) {
+ start, end := match[0], match[1]
+ for start != 0 && data[start-1] != '\n' {
+ start--
+ }
+ for end != len(data) && data[end] != '\n' {
+ end++
+ }
+ if supp.Match(data[start:end]) {
+ continue
+ }
+ line := bytes.Count(data[:start], []byte{'\n'}) + 1
+ t.Errorf("\nexecutor/%v:%v: %v\n%s\n", file, line, check.message, data[start:end])
+ }
+ }
+ }
+}
+
+func executorFiles(t *testing.T) []string {
+ cc, err := filepath.Glob("*.cc")
+ if err != nil {
+ t.Fatal(err)
+ }
+ h, err := filepath.Glob("*.h")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(cc) == 0 || len(h) == 0 {
+ t.Fatal("found no executor files")
+ }
+ res := append(cc, h...)
+ sort.Strings(res)
+ return res
+}