github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/subsystem/linux/parents_test.go (about)

     1  // Copyright 2023 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  
     4  package linux
     5  
     6  import (
     7  	"testing"
     8  	"testing/fstest"
     9  
    10  	"github.com/google/syzkaller/pkg/subsystem"
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  func TestDropSmallSubsystems(t *testing.T) {
    15  	kernel := &subsystem.Subsystem{}
    16  	net := &subsystem.Subsystem{}
    17  	fs := &subsystem.Subsystem{}
    18  	legal := &subsystem.Subsystem{}
    19  
    20  	matrix := MakeCoincidenceMatrix()
    21  	matrix.Record(kernel, net)
    22  	matrix.Record(kernel, fs)
    23  	matrix.Record(kernel, net, fs)
    24  	matrix.Record(kernel, net, fs)
    25  	matrix.Record(kernel, net, fs)
    26  
    27  	ret := dropSmallSubsystems(matrix, []*subsystem.Subsystem{kernel, net, fs, legal})
    28  	assert.ElementsMatch(t, []*subsystem.Subsystem{kernel, net, fs}, ret)
    29  }
    30  
    31  func TestDropDuplicateSubsystems(t *testing.T) {
    32  	input, expected := []*subsystem.Subsystem{}, []*subsystem.Subsystem{}
    33  	matrix := MakeCoincidenceMatrix()
    34  
    35  	// Always present.
    36  	kernel := &subsystem.Subsystem{Name: "kernel"}
    37  	input = append(input, kernel)
    38  	expected = append(expected, kernel)
    39  
    40  	// Fully overlap.
    41  	sameA := &subsystem.Subsystem{Lists: []string{"SameA@gmail.com"}}
    42  	sameB := &subsystem.Subsystem{Lists: []string{"SameB@gmail.com"}}
    43  	matrix.Record(kernel, sameA, sameB)
    44  	matrix.Record(kernel, sameA, sameB)
    45  	matrix.Record(kernel, sameA, sameB)
    46  	input = append(input, sameA, sameB)
    47  	expected = append(expected, sameA)
    48  
    49  	// Overlap, but the smaller one is not so significant.
    50  	ext4, fs := &subsystem.Subsystem{Name: "ext4"}, &subsystem.Subsystem{Name: "fs"}
    51  	matrix.Record(kernel, ext4, fs)
    52  	matrix.Record(kernel, ext4, fs)
    53  	matrix.Record(kernel, fs) // 66%.
    54  	input = append(input, ext4, fs)
    55  	expected = append(expected, ext4, fs)
    56  
    57  	// Overlap, and the smaller one takes a big part.
    58  	toDrop, stays := &subsystem.Subsystem{Name: "to-drop"}, &subsystem.Subsystem{Name: "stays"}
    59  	for i := 0; i < 5; i++ {
    60  		matrix.Record(kernel, toDrop, stays)
    61  	}
    62  	matrix.Record(kernel, stays)
    63  	input = append(input, toDrop, stays)
    64  	expected = append(expected, stays)
    65  
    66  	// Run the analysis.
    67  	ret := dropDuplicateSubsystems(matrix, input)
    68  	assert.ElementsMatch(t, ret, expected)
    69  }
    70  
    71  func TestTransitiveReduction(t *testing.T) {
    72  	// (d, c), (c, b), (b, a)
    73  	// (d, a)
    74  	// (d, b)
    75  	// (d, e)
    76  	// (c, a)
    77  	a := &subsystem.Subsystem{}
    78  	b := &subsystem.Subsystem{Parents: []*subsystem.Subsystem{a}}
    79  	c := &subsystem.Subsystem{Parents: []*subsystem.Subsystem{a, b}}
    80  	e := &subsystem.Subsystem{}
    81  	d := &subsystem.Subsystem{Parents: []*subsystem.Subsystem{a, b, c, e}}
    82  	transitiveReduction([]*subsystem.Subsystem{a, b, c, d, e})
    83  
    84  	// The result should be:
    85  	// (d, c), (c, b), (b, a)
    86  	// (d, e)
    87  	assert.ElementsMatch(t, d.Parents, []*subsystem.Subsystem{c, e})
    88  	assert.ElementsMatch(t, c.Parents, []*subsystem.Subsystem{b})
    89  }
    90  
    91  func TestSetParents(t *testing.T) {
    92  	kernel := &subsystem.Subsystem{PathRules: []subsystem.PathRule{{
    93  		IncludeRegexp: `.*`,
    94  	}}}
    95  	net := &subsystem.Subsystem{PathRules: []subsystem.PathRule{{
    96  		IncludeRegexp: `^net/`,
    97  	}}}
    98  	wireless := &subsystem.Subsystem{PathRules: []subsystem.PathRule{{
    99  		IncludeRegexp: `^net/wireless`,
   100  	}}}
   101  	drivers := &subsystem.Subsystem{PathRules: []subsystem.PathRule{{
   102  		IncludeRegexp: `^drivers/`,
   103  	}}}
   104  
   105  	tree := fstest.MapFS{
   106  		"include/net/cfg80211.h":   {},
   107  		"net/socket.c":             {},
   108  		"net/nfc/core.c":           {},
   109  		"net/wireless/nl80211.c":   {},
   110  		"net/wireless/sysfs.c":     {},
   111  		"net/ipv4/arp.c":           {},
   112  		"drivers/usb/host/xhci.c":  {},
   113  		"drivers/android/binder.c": {},
   114  	}
   115  
   116  	matrix, err := BuildCoincidenceMatrix(tree,
   117  		[]*subsystem.Subsystem{kernel, net, wireless, drivers}, nil)
   118  	assert.NoError(t, err)
   119  
   120  	// Calculate parents.
   121  
   122  	err = setParents(matrix, []*subsystem.Subsystem{kernel, net, wireless, drivers})
   123  	if err != nil {
   124  		t.Fatal(err)
   125  	}
   126  
   127  	// Verify parents.
   128  	assert.ElementsMatch(t, net.Parents, []*subsystem.Subsystem{kernel})
   129  	assert.ElementsMatch(t, wireless.Parents, []*subsystem.Subsystem{net})
   130  	assert.ElementsMatch(t, drivers.Parents, []*subsystem.Subsystem{kernel})
   131  	assert.ElementsMatch(t, kernel.Parents, []*subsystem.Subsystem{})
   132  }