github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/secrets/mariadb/mariadb_test.go (about)

     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  package mariadb_test
    16  
    17  import (
    18  	"testing"
    19  
    20  	"github.com/google/go-cmp/cmp"
    21  	"github.com/google/go-cmp/cmp/cmpopts"
    22  	"github.com/google/osv-scalibr/extractor/filesystem/secrets/mariadb"
    23  	"github.com/google/osv-scalibr/extractor/filesystem/simplefileapi"
    24  	"github.com/google/osv-scalibr/inventory"
    25  	"github.com/google/osv-scalibr/testing/extracttest"
    26  )
    27  
    28  func TestExtractor_FileRequired(t *testing.T) {
    29  	tests := []struct {
    30  		name      string
    31  		inputPath string
    32  		want      bool
    33  	}{
    34  		{inputPath: "", want: false},
    35  
    36  		// linux
    37  		{inputPath: `my.cnf`, want: true},
    38  		{inputPath: `/Users/example/.my.cnf`, want: true},
    39  
    40  		// windows
    41  		{inputPath: `System Windows Directory\my.cnf`, want: true},
    42  		{inputPath: `c:\my.ini`, want: true},
    43  		{inputPath: `installdir\data\my.cnf`, want: true},
    44  		{inputPath: `installdir\data\my.ini`, want: true},
    45  
    46  		// wrong paths
    47  		{inputPath: `/etc/ssl/openssl.cnf`, want: false},
    48  		{inputPath: `go.mod`, want: false},
    49  	}
    50  	for _, tt := range tests {
    51  		t.Run(tt.inputPath, func(t *testing.T) {
    52  			e := mariadb.Extractor{}
    53  			got := e.FileRequired(simplefileapi.New(tt.inputPath, nil))
    54  			if got != tt.want {
    55  				t.Errorf("FileRequired(%s) got = %v, want %v", tt.inputPath, got, tt.want)
    56  			}
    57  		})
    58  	}
    59  }
    60  
    61  func TestExtractor_Extract(t *testing.T) {
    62  	type entry struct {
    63  		Name          string
    64  		FollowInclude bool
    65  		Path          string
    66  		WantSecrets   []*inventory.Secret
    67  		WantErr       error
    68  	}
    69  
    70  	tests := []*entry{
    71  		{
    72  			Name: "empty",
    73  			Path: "empty.cnf",
    74  		},
    75  		{
    76  			Name:          "real_cnf",
    77  			FollowInclude: false,
    78  			Path:          "real.cnf",
    79  		},
    80  		{
    81  			Name:          "real_ini",
    82  			FollowInclude: false,
    83  			Path:          "real.ini",
    84  		},
    85  		{
    86  			Name:          "bad_format",
    87  			FollowInclude: false,
    88  			Path:          "bad_format.cnf",
    89  			WantErr:       extracttest.ContainsErrStr{Str: "bad format: key-value found"},
    90  		},
    91  		{
    92  			Name:          "secret",
    93  			FollowInclude: false,
    94  			Path:          "secret.cnf",
    95  			WantSecrets: []*inventory.Secret{
    96  				{
    97  					Secret: mariadb.Credentials{
    98  						Section: "mariadb-client", User: "root", Password: "secret_password", Port: "3306",
    99  					},
   100  					Location: "secret.cnf",
   101  				},
   102  			},
   103  		},
   104  		{
   105  			Name:          "include_file",
   106  			FollowInclude: true,
   107  			Path:          "include_file.cnf",
   108  			WantSecrets: []*inventory.Secret{
   109  				{
   110  					Secret: mariadb.Credentials{
   111  						Section: "mariadb-client", User: "root", Password: "secret_password", Port: "3306",
   112  					},
   113  					Location: "to_include/to_include.cnf",
   114  				},
   115  			},
   116  		},
   117  		{
   118  			Name:          "include_file_windows",
   119  			FollowInclude: true,
   120  			Path:          "include_file_windows.ini",
   121  			WantSecrets: []*inventory.Secret{
   122  				{
   123  					Secret: mariadb.Credentials{
   124  						Section: "mariadb-client", User: "root", Password: "secret_password", Port: "3306",
   125  					},
   126  					Location: "to_include/to_include.cnf",
   127  				},
   128  			},
   129  		},
   130  		{
   131  			Name:          "include_dir",
   132  			FollowInclude: true,
   133  			Path:          "include_dir.cnf",
   134  			WantSecrets: []*inventory.Secret{
   135  				{
   136  					Secret: mariadb.Credentials{
   137  						Section: "mariadb-client", User: "user", Password: "another_password", Port: "3306",
   138  					},
   139  					Location: "to_include/another_to_include.ini",
   140  				},
   141  				{
   142  					Secret: mariadb.Credentials{
   143  						Section: "mariadb-client", User: "root", Password: "secret_password", Port: "3306",
   144  					},
   145  					Location: "to_include/to_include.cnf",
   146  				},
   147  			},
   148  		},
   149  		{
   150  			Name:          "include_dir_windows",
   151  			FollowInclude: true,
   152  			Path:          "include_dir_windows.ini",
   153  			WantSecrets: []*inventory.Secret{
   154  				{
   155  					Secret: mariadb.Credentials{
   156  						Section: "mariadb-client", User: "user", Password: "another_password", Port: "3306",
   157  					},
   158  					Location: "to_include/another_to_include.ini",
   159  				},
   160  				{
   161  					Secret: mariadb.Credentials{
   162  						Section: "mariadb-client", User: "root", Password: "secret_password", Port: "3306",
   163  					},
   164  					Location: "to_include/to_include.cnf",
   165  				},
   166  			},
   167  		},
   168  		{
   169  			Name:          "bad_include",
   170  			FollowInclude: true,
   171  			Path:          "bad_include.cnf",
   172  			WantErr:       extracttest.ContainsErrStr{Str: "could not open"},
   173  		},
   174  	}
   175  
   176  	for _, tt := range tests {
   177  		t.Run(tt.Name, func(t *testing.T) {
   178  			extr := mariadb.New(mariadb.Config{
   179  				FollowInclude: tt.FollowInclude,
   180  			})
   181  
   182  			inputCfg := extracttest.ScanInputMockConfig{
   183  				Path:         tt.Path,
   184  				FakeScanRoot: "testdata",
   185  			}
   186  
   187  			scanInput := extracttest.GenerateScanInputMock(t, inputCfg)
   188  			defer extracttest.CloseTestScanInput(t, scanInput)
   189  
   190  			got, err := extr.Extract(t.Context(), &scanInput)
   191  
   192  			if diff := cmp.Diff(tt.WantErr, err, cmpopts.EquateErrors()); diff != "" {
   193  				t.Errorf("%s.Extract(%q) error diff (-want +got):\n%s", extr.Name(), tt.Path, diff)
   194  				return
   195  			}
   196  
   197  			wantInv := inventory.Inventory{Secrets: tt.WantSecrets}
   198  			opts := []cmp.Option{cmpopts.SortSlices(extracttest.PackageCmpLess), cmpopts.EquateEmpty()}
   199  			if diff := cmp.Diff(wantInv, got, opts...); diff != "" {
   200  				t.Errorf("%s.Extract(%q) diff (-want +got):\n%s", extr.Name(), tt.Path, diff)
   201  			}
   202  		})
   203  	}
   204  }