Skip to content

Commit f441088

Browse files
committed
[Frontend-go] Add unit test for channels and goroutine
Signed-off-by: Arthur Chan <[email protected]>
1 parent 93cf063 commit f441088

File tree

3 files changed

+99
-2
lines changed

3 files changed

+99
-2
lines changed

src/fuzz_introspector/frontends/frontend_go.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,7 @@ def _detect_variable_type(
662662
args = child.child_by_field_name('arguments')
663663
target_name = self._process_call_expr_child(
664664
call, all_funcs_meths)
665+
665666
if target_name in all_funcs_meths:
666667
return all_funcs_meths[target_name].return_type
667668

@@ -670,6 +671,16 @@ def _detect_variable_type(
670671
if arg.type.endswith('identifier'):
671672
return arg.text.decode()
672673

674+
elif target_name == 'make':
675+
for arg in args.children:
676+
type_node = arg.child_by_field_name('value')
677+
if type_node:
678+
return type_node.text.decode()
679+
680+
type_node = arg.child_by_field_name('element')
681+
if type_node:
682+
return type_node.text.decode()
683+
673684
# Selector expression
674685
elif child.type == 'selector_expression':
675686
target_name = self._process_call_expr_child(
@@ -705,6 +716,8 @@ def extract_local_variable_type(self,
705716
for decl_node in exprs:
706717
left = decl_node.child_by_field_name('left')
707718
right = decl_node.child_by_field_name('right')
719+
if not left or not right:
720+
continue
708721

709722
for child in left.children:
710723
if child.type == 'identifier':
@@ -722,13 +735,15 @@ def extract_local_variable_type(self,
722735
if child.type == 'range_clause':
723736
left = child.child_by_field_name('left')
724737
right = child.child_by_field_name('right')
738+
if not left or not right:
739+
continue
725740

726741
for left_child in left.children:
727742
if left_child.type == 'identifier':
728743
decl_name = left_child.text.decode()
729744

730745
if right.type == 'identifier':
731-
decl_type = self.var_map[right.text.decode()]
746+
decl_type = self.var_map.get(right.text.decode(), '')
732747
if '[' in decl_type and ']' in decl_type:
733748
decl_type = decl_type.split(']', 1)[-1]
734749
elif decl_type == 'string':
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
16+
package channels
17+
18+
import (
19+
"fmt"
20+
"testing"
21+
"time"
22+
)
23+
24+
type Square struct {
25+
Side float64
26+
}
27+
28+
type Circle struct {
29+
Radius float64
30+
}
31+
32+
func (s Square) Describe() string {
33+
return fmt.Sprintf("Square with side length %.2f", s.Side)
34+
}
35+
36+
func (c Circle) Describe() string {
37+
return fmt.Sprintf("Circle with radius %.2f", c.Radius)
38+
}
39+
40+
func unreachableGoroutine() {
41+
ch := make(chan Square)
42+
43+
go func() {
44+
square := Square{Side: 4.0}
45+
ch <- square
46+
close(ch)
47+
}()
48+
49+
for shape := range ch {
50+
fmt.Println(shape.Describe())
51+
}
52+
}
53+
54+
func FuzzChannels(f *testing.F) {
55+
f.Fuzz(func(t *testing.T, durationString string) {
56+
duration, err := time.ParseDuration(durationString)
57+
if err != nil || duration < 0 {
58+
return
59+
}
60+
61+
ch := make(chan Circle)
62+
63+
go func() {
64+
time.Sleep(duration)
65+
circle := Circle{Radius: 5.5}
66+
ch <- circle
67+
close(ch)
68+
}()
69+
70+
for shape := range ch {
71+
fmt.Println(shape.Describe())
72+
}
73+
})
74+
}

src/test/test_frontends_go.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,15 @@ def test_tree_sitter_go_sample6():
140140

141141
# Project check
142142
harness = project.get_source_codes_with_harnesses()
143-
assert len(harness) == 0
143+
assert len(harness) == 1
144+
145+
functions_reached = project.get_reachable_functions(harness[0].source_file, harness[0])
146+
147+
# Callsite check
148+
assert 'Circle.Describe' in functions_reached
149+
assert 'time.Sleep' in functions_reached
150+
assert 'Square.Describe' not in functions_reached
151+
assert 'unreachableGoroutine' not in functions_reached
144152

145153

146154
def test_tree_sitter_go_sample7():

0 commit comments

Comments
 (0)