1// Copyright 2017 syzkaller project authors. All rights reserved. 2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4package ast 5 6import ( 7 "bytes" 8 "io/ioutil" 9 "path/filepath" 10 "reflect" 11 "strings" 12 "testing" 13) 14 15func TestParseAll(t *testing.T) { 16 files, err := filepath.Glob(filepath.Join("..", "..", "sys", "linux", "*.txt")) 17 if err != nil || len(files) == 0 { 18 t.Fatalf("failed to read sys dir: %v", err) 19 } 20 for _, file := range files { 21 data, err := ioutil.ReadFile(file) 22 if err != nil { 23 t.Fatalf("failed to read file: %v", err) 24 } 25 t.Run(file, func(t *testing.T) { 26 eh := func(pos Pos, msg string) { 27 t.Fatalf("%v: %v", pos, msg) 28 } 29 desc := Parse(data, file, eh) 30 if desc == nil { 31 t.Fatalf("parsing failed, but no error produced") 32 } 33 data2 := Format(desc) 34 desc2 := Parse(data2, file, eh) 35 if desc2 == nil { 36 t.Fatalf("parsing failed, but no error produced") 37 } 38 if len(desc.Nodes) != len(desc2.Nodes) { 39 t.Fatalf("formatting number of top level decls: %v/%v", 40 len(desc.Nodes), len(desc2.Nodes)) 41 } 42 for i := range desc.Nodes { 43 n1, n2 := desc.Nodes[i], desc2.Nodes[i] 44 if n1 == nil { 45 t.Fatalf("got nil node") 46 } 47 if !reflect.DeepEqual(n1, n2) { 48 t.Fatalf("formatting changed code:\n%#v\nvs:\n%#v", n1, n2) 49 } 50 } 51 data3 := Format(desc.Clone()) 52 if !bytes.Equal(data, data3) { 53 t.Fatalf("Clone lost data") 54 } 55 }) 56 } 57} 58 59func TestParse(t *testing.T) { 60 for _, test := range parseTests { 61 t.Run(test.name, func(t *testing.T) { 62 errorHandler := func(pos Pos, msg string) { 63 t.Logf("%v: %v", pos, msg) 64 } 65 Parse([]byte(test.input), "foo", errorHandler) 66 }) 67 } 68} 69 70var parseTests = []struct { 71 name string 72 input string 73 result []interface{} 74}{ 75 { 76 "empty", 77 ``, 78 []interface{}{}, 79 }, 80 { 81 "new-line", 82 ` 83 84`, 85 []interface{}{}, 86 }, 87 { 88 "nil", 89 "\x00", 90 []interface{}{}, 91 }, 92} 93 94func TestErrors(t *testing.T) { 95 files, err := ioutil.ReadDir("testdata") 96 if err != nil { 97 t.Fatal(err) 98 } 99 if len(files) == 0 { 100 t.Fatal("no input files") 101 } 102 for _, f := range files { 103 if !strings.HasSuffix(f.Name(), ".txt") { 104 continue 105 } 106 name := f.Name() 107 t.Run(name, func(t *testing.T) { 108 em := NewErrorMatcher(t, filepath.Join("testdata", name)) 109 desc := Parse(em.Data, name, em.ErrorHandler) 110 if desc != nil && em.Count() != 0 { 111 em.DumpErrors(t) 112 t.Fatalf("parsing succeed, but got errors") 113 } 114 if desc == nil && em.Count() == 0 { 115 t.Fatalf("parsing failed, but got no errors") 116 } 117 em.Check(t) 118 }) 119 } 120} 121