github.com/google/go-safeweb@v0.0.0-20231219055052-64d8cfc90fbb/cmd/bancheck/bannedapi/banned_api_test.go (about)

     1  // Copyright 2020 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  //	https://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  package bannedapi
    16  
    17  import (
    18  	"path/filepath"
    19  	"strings"
    20  	"testing"
    21  
    22  	"golang.org/x/tools/go/analysis/analysistest"
    23  )
    24  
    25  func TestBannedAPIAnalyzer(t *testing.T) {
    26  	t.Parallel()
    27  	tests := []struct {
    28  		desc  string
    29  		files map[string]string
    30  	}{
    31  		{
    32  			desc: "No banned APIs",
    33  			files: map[string]string{
    34  				"config.json": `
    35  				{}
    36  				`,
    37  				"main/test.go": `
    38  				package main;
    39  				func main() {}
    40  				`,
    41  			},
    42  		},
    43  		{
    44  			desc: "Banned APIs exist",
    45  			files: map[string]string{
    46  				"config.json": `
    47  				{
    48  					"functions": [
    49  						{
    50  							"name": "fmt.Printf",
    51  							"msg": "Banned by team A"
    52  						}
    53  					],
    54  					"imports": [
    55  						{
    56  							"name": "fmt",
    57  							"msg": "Banned by team A"
    58  						}
    59  					]
    60  				}
    61  				`,
    62  				"main/test.go": `
    63  				package main
    64  
    65  				import "fmt" // want "Banned API found \"fmt\". Additional info: Banned by team A"
    66  
    67  				func main() {
    68  					fmt.Printf("Hello") // want "Banned API found \"fmt.Printf\". Additional info: Banned by team A"
    69  				}
    70  				`,
    71  			},
    72  		},
    73  		{
    74  			desc: "Banned APIs in exempted package",
    75  			files: map[string]string{
    76  				"config.json": `
    77  				{
    78  					"functions": [
    79  						{
    80  							"name": "fmt.Printf",
    81  							"msg": "Banned by team A",
    82  							"exemptions": [
    83  								{
    84  									"justification": "#yolo",
    85  									"allowedPkg": "main"
    86  								}
    87  							]
    88  						}
    89  					],
    90  					"imports": [
    91  						{
    92  							"name": "fmt",
    93  							"msg": "Banned by team A",
    94  							"exemptions": [
    95  								{
    96  									"justification": "#yolo",
    97  									"allowedPkg": "main"
    98  								}
    99  							]
   100  						}
   101  					]
   102  				}
   103  				`,
   104  				"main/test.go": `
   105  				package main
   106  
   107  				import "fmt"
   108  
   109  				func main() {
   110  					fmt.Printf("Hello")
   111  				}
   112  				`,
   113  			},
   114  		},
   115  		{
   116  			desc: "Banned renamed import",
   117  			files: map[string]string{
   118  				"config.json": `
   119  				{
   120  					"imports": [
   121  						{
   122  							"name": "fmt",
   123  							"msg": "Banned by team A"
   124  						}
   125  					]
   126  				}
   127  				`,
   128  				"main/test.go": `
   129  				package main
   130  
   131  				import renamed "fmt" // want "Banned API found \"fmt\". Additional info: Banned by team A"
   132  
   133  				func main() {
   134  					renamed.Printf("Hello")
   135  				}
   136  				`,
   137  			},
   138  		},
   139  		{
   140  			desc: "Banned function from renamed import",
   141  			files: map[string]string{
   142  				"config.json": `
   143  				{
   144  					"functions": [
   145  						{
   146  							"name": "fmt.Printf",
   147  							"msg": "Banned by team A"
   148  						}
   149  					]
   150  				}
   151  				`,
   152  				"main/test.go": `
   153  				package main
   154  
   155  				import renamed "fmt"
   156  
   157  				func main() {
   158  					renamed.Printf("Hello") // want "Banned API found \"fmt.Printf\". Additional info: Banned by team A"
   159  				}
   160  				`,
   161  			},
   162  		},
   163  		{
   164  			desc: "Package and function name collission",
   165  			files: map[string]string{
   166  				"config.json": `
   167  				{
   168  					"functions": [
   169  						{
   170  							"name": "fmt.Printf",
   171  							"msg": "Banned by team A"
   172  						}
   173  					]
   174  				}
   175  				`,
   176  				"main/test.go": `
   177  				package main
   178  
   179  				type Foo struct{}
   180  
   181  				func (f *Foo) Printf(txt string) {}
   182  
   183  				func main() {
   184  					var fmt = &Foo{}
   185  					fmt.Printf("Hello")
   186  				}
   187  				`,
   188  			},
   189  		},
   190  		{
   191  			desc: "Banned API from multiple config files",
   192  			files: map[string]string{
   193  				"team_a_config.json": `
   194  				{
   195  					"functions": [
   196  						{
   197  							"name": "fmt.Printf",
   198  							"msg": "Banned by team A"
   199  						}
   200  					]
   201  				}
   202  				`,
   203  				"team_b_config.json": `
   204  				{
   205  					"functions": [
   206  						{
   207  							"name": "fmt.Printf",
   208  							"msg": "Banned by team B"
   209  						}
   210  					]
   211  				}
   212  				`,
   213  				"main/test.go": `
   214  				package main
   215  
   216  				import "fmt"
   217  
   218  				func main() {
   219  					fmt.Printf("Hello") // want "Banned API found \"fmt.Printf\". Additional info: Banned by team A" "Banned API found \"fmt.Printf\". Additional info: Banned by team B"
   220  				}
   221  				`,
   222  			},
   223  		},
   224  		{
   225  			desc: "Banned API in one of many config files",
   226  			files: map[string]string{
   227  				"team_a_config.json": `
   228  				{
   229  					"functions": [
   230  						{
   231  							"name": "fmt.Printf",
   232  							"msg": "Banned by team A",
   233  							"exemptions": [
   234  								{
   235  									"justification": "#yolo",
   236  									"allowedPkg": "main"
   237  								}
   238  							]
   239  						}
   240  					]
   241  				}
   242  				`,
   243  				"team_b_config.json": `
   244  				{
   245  					"functions": [
   246  						{
   247  							"name": "fmt.Printf",
   248  							"msg": "Banned by team B for realz"
   249  						}
   250  					]
   251  				}
   252  				`,
   253  				"main/test.go": `
   254  				package main
   255  
   256  				import "fmt"
   257  
   258  				func main() {
   259  					fmt.Printf("Hello") // want "Banned API found \"fmt.Printf\". Additional info: Banned by team B for realz"
   260  				}
   261  				`,
   262  			},
   263  		},
   264  	}
   265  
   266  	for _, test := range tests {
   267  		test := test
   268  		t.Run(test.desc, func(t *testing.T) {
   269  			t.Parallel()
   270  			dir, cleanup, err := analysistest.WriteFiles(test.files)
   271  			if err != nil {
   272  				t.Fatalf("WriteFiles() returned err: %v", err)
   273  			}
   274  			defer cleanup()
   275  
   276  			var configFiles []string
   277  			for name := range test.files {
   278  				if strings.HasSuffix(name, "config.json") {
   279  					configFiles = append(configFiles, filepath.Join(dir, "src", name))
   280  				}
   281  			}
   282  
   283  			a := NewAnalyzer()
   284  			a.Flags.Set("configs", strings.Join(configFiles, ","))
   285  			analysistest.Run(t, dir, a, "main")
   286  		})
   287  	}
   288  }