github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/kconfig/minimize_test.go (about)

     1  // Copyright 2020 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 kconfig
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/google/syzkaller/pkg/debugtracer"
    12  	"github.com/google/syzkaller/sys/targets"
    13  	"github.com/stretchr/testify/assert"
    14  )
    15  
    16  func TestMinimize(t *testing.T) {
    17  	const (
    18  		kconfig = `
    19  mainmenu "test"
    20  config A
    21  config B
    22  config C
    23  config D
    24  config I
    25  config S
    26  
    27  menuconfig HAMRADIO
    28  	depends on NET && !S390
    29  	bool "Amateur Radio support"
    30  
    31  config AX25
    32  	tristate "Amateur Radio AX.25 Level 2 protocol"
    33  	depends on HAMRADIO
    34  
    35  config ROSE
    36  	tristate "Amateur Radio X.25 PLP (Rose)"
    37  	depends on AX25
    38  `
    39  		baseConfig = `
    40  CONFIG_A=y
    41  CONFIG_I=1
    42  `
    43  		fullConfig = `
    44  CONFIG_A=y
    45  CONFIG_B=y
    46  CONFIG_C=y
    47  CONFIG_D=y
    48  CONFIG_I=42
    49  CONFIG_S="foo"
    50  CONFIG_HAMRADIO=y
    51  CONFIG_AX25=y
    52  CONFIG_ROSE=y
    53  `
    54  	)
    55  	type Test struct {
    56  		pred   func(*ConfigFile) (bool, error)
    57  		result string
    58  	}
    59  	tests := []Test{
    60  		{
    61  			pred: func(cf *ConfigFile) (bool, error) {
    62  				return true, nil
    63  			},
    64  			result: baseConfig,
    65  		},
    66  		{
    67  			pred: func(cf *ConfigFile) (bool, error) {
    68  				return false, nil
    69  			},
    70  			result: fullConfig,
    71  		},
    72  		{
    73  			pred: func(cf *ConfigFile) (bool, error) {
    74  				return cf.Value("C") != No, nil
    75  			},
    76  			result: `
    77  CONFIG_A=y
    78  CONFIG_I=42
    79  CONFIG_S="foo"
    80  CONFIG_C=y
    81  `,
    82  		},
    83  		{
    84  			pred: func(cf *ConfigFile) (bool, error) {
    85  				return cf.Value("HAMRADIO") == Yes && cf.Value("AX25") == Yes && cf.Value("ROSE") == Yes, nil
    86  			},
    87  			result: `
    88  CONFIG_A=y
    89  CONFIG_I=42
    90  CONFIG_S="foo"
    91  CONFIG_AX25=y
    92  CONFIG_HAMRADIO=y
    93  CONFIG_ROSE=y
    94  `,
    95  		},
    96  		{
    97  			// Check if it works fine with several diffs.
    98  			pred: func(cf *ConfigFile) (bool, error) {
    99  				return cf.Value("D") != No && cf.Value("C") != No, nil
   100  			},
   101  			result: `
   102  CONFIG_A=y
   103  CONFIG_I=42
   104  CONFIG_S="foo"
   105  CONFIG_C=y
   106  CONFIG_D=y
   107  `,
   108  		},
   109  	}
   110  	kconf, err := ParseData(targets.Get("linux", "amd64"), []byte(kconfig), "kconf")
   111  	if err != nil {
   112  		t.Fatal(err)
   113  	}
   114  	base, err := ParseConfigData([]byte(baseConfig), "base")
   115  	if err != nil {
   116  		t.Fatal(err)
   117  	}
   118  	full, err := ParseConfigData([]byte(fullConfig), "full")
   119  	if err != nil {
   120  		t.Fatal(err)
   121  	}
   122  	for i, test := range tests {
   123  		t.Run(fmt.Sprint(i), func(t *testing.T) {
   124  			res, err := kconf.Minimize(base, full, test.pred, 0, &debugtracer.TestTracer{T: t})
   125  			if err != nil {
   126  				t.Fatal(err)
   127  			}
   128  			result := string(res.Serialize())
   129  			assert.ElementsMatch(t,
   130  				strings.Split(result, "\n"),
   131  				strings.Split(test.result, "\n"))
   132  		})
   133  	}
   134  }