github.com/adevinta/lava@v0.7.2/internal/config/config_test.go (about)

     1  // Copyright 2023 Adevinta
     2  
     3  package config
     4  
     5  import (
     6  	"errors"
     7  	"io"
     8  	"log/slog"
     9  	"regexp"
    10  	"testing"
    11  
    12  	agentconfig "github.com/adevinta/vulcan-agent/config"
    13  	types "github.com/adevinta/vulcan-types"
    14  	"github.com/google/go-cmp/cmp"
    15  )
    16  
    17  func TestParse(t *testing.T) {
    18  	tests := []struct {
    19  		name          string
    20  		file          string
    21  		envs          map[string]string
    22  		want          Config
    23  		wantErr       error
    24  		wantErrRegexp *regexp.Regexp
    25  	}{
    26  		{
    27  			name: "valid",
    28  			file: "testdata/valid.yaml",
    29  			want: Config{
    30  				LavaVersion: "v1.0.0",
    31  				ChecktypeURLs: []string{
    32  					"checktypes.json",
    33  				},
    34  				Targets: []Target{
    35  					{
    36  						Identifier: "example.com",
    37  						AssetType:  types.DomainName,
    38  					},
    39  				},
    40  			},
    41  		},
    42  		{
    43  			name: "valid env",
    44  			file: "testdata/valid_env.yaml",
    45  			want: Config{
    46  				LavaVersion: "v1.0.0",
    47  				ChecktypeURLs: []string{
    48  					"checktypes.json",
    49  				},
    50  				Targets: []Target{
    51  					{
    52  						Identifier: "example.com",
    53  						AssetType:  types.DomainName,
    54  					},
    55  				},
    56  			},
    57  			envs: map[string]string{
    58  				"TARGET":           "example.com",
    59  				"CHECK_types_URL1": "checktypes.json",
    60  			},
    61  		},
    62  		{
    63  			name: "invalid env",
    64  			file: "testdata/invalid_env.yaml",
    65  			want: Config{
    66  				LavaVersion: "v1.0.0",
    67  				ChecktypeURLs: []string{
    68  					"checktypes.json",
    69  				},
    70  				Targets: []Target{
    71  					{
    72  						Identifier: "${1NVALID}",
    73  						AssetType:  types.DomainName,
    74  					},
    75  				},
    76  			},
    77  		},
    78  		{
    79  			name:    "empty",
    80  			file:    "testdata/empty.yaml",
    81  			want:    Config{},
    82  			wantErr: io.EOF,
    83  		},
    84  		{
    85  			name:    "invalid lava version",
    86  			file:    "testdata/invalid_lava_version.yaml",
    87  			want:    Config{},
    88  			wantErr: ErrInvalidLavaVersion,
    89  		},
    90  		{
    91  			name:    "no checktypes URLs",
    92  			file:    "testdata/no_checktypes_urls.yaml",
    93  			want:    Config{},
    94  			wantErr: ErrNoChecktypeURLs,
    95  		},
    96  		{
    97  			name:    "no targets",
    98  			file:    "testdata/no_targets.yaml",
    99  			want:    Config{},
   100  			wantErr: ErrNoTargets,
   101  		},
   102  		{
   103  			name:    "no target identifier",
   104  			file:    "testdata/no_target_identifier.yaml",
   105  			want:    Config{},
   106  			wantErr: ErrNoTargetIdentifier,
   107  		},
   108  		{
   109  			name:    "no target asset type",
   110  			file:    "testdata/no_target_asset_type.yaml",
   111  			want:    Config{},
   112  			wantErr: ErrNoTargetAssetType,
   113  		},
   114  		{
   115  			name: "critical severity",
   116  			file: "testdata/critical_severity.yaml",
   117  			want: Config{
   118  				LavaVersion: "v1.0.0",
   119  				ChecktypeURLs: []string{
   120  					"checktypes.json",
   121  				},
   122  				ReportConfig: ReportConfig{
   123  					Severity: SeverityCritical,
   124  				},
   125  				Targets: []Target{
   126  					{
   127  						Identifier: "example.com",
   128  						AssetType:  types.DomainName,
   129  					},
   130  				},
   131  			},
   132  		},
   133  		{
   134  			name:    "invalid severity",
   135  			file:    "testdata/invalid_severity.yaml",
   136  			want:    Config{},
   137  			wantErr: ErrInvalidSeverity,
   138  		},
   139  		{
   140  			name: "never pull policy",
   141  			file: "testdata/never_pull_policy.yaml",
   142  			want: Config{
   143  				LavaVersion: "v1.0.0",
   144  				ChecktypeURLs: []string{
   145  					"checktypes.json",
   146  				},
   147  				AgentConfig: AgentConfig{
   148  					PullPolicy: agentconfig.PullPolicyNever,
   149  				},
   150  				Targets: []Target{
   151  					{
   152  						Identifier: "example.com",
   153  						AssetType:  types.DomainName,
   154  					},
   155  				},
   156  			},
   157  		},
   158  		{
   159  			name:          "invalid pull policy",
   160  			file:          "testdata/invalid_pull_policy.yaml",
   161  			want:          Config{},
   162  			wantErrRegexp: regexp.MustCompile(`value .* is not a valid PullPolicy value`),
   163  		},
   164  		{
   165  			name:    "invalid target asset type",
   166  			file:    "testdata/invalid_target_asset_type.yaml",
   167  			want:    Config{},
   168  			wantErr: ErrInvalidAssetType,
   169  		},
   170  		{
   171  			name: "JSON output format",
   172  			file: "testdata/json_output_format.yaml",
   173  			want: Config{
   174  				LavaVersion: "v1.0.0",
   175  				ChecktypeURLs: []string{
   176  					"checktypes.json",
   177  				},
   178  				Targets: []Target{
   179  					{
   180  						Identifier: "example.com",
   181  						AssetType:  types.DomainName,
   182  					},
   183  				},
   184  				ReportConfig: ReportConfig{
   185  					Format: OutputFormatJSON,
   186  				},
   187  			},
   188  		},
   189  		{
   190  			name:    "invalid output format",
   191  			file:    "testdata/invalid_output_format.yaml",
   192  			want:    Config{},
   193  			wantErr: ErrInvalidOutputFormat,
   194  		},
   195  		{
   196  			name: "debug log level",
   197  			file: "testdata/debug_log_level.yaml",
   198  			want: Config{
   199  				LavaVersion: "v1.0.0",
   200  				ChecktypeURLs: []string{
   201  					"checktypes.json",
   202  				},
   203  				Targets: []Target{
   204  					{
   205  						Identifier: "example.com",
   206  						AssetType:  types.DomainName,
   207  					},
   208  				},
   209  				LogLevel: slog.LevelDebug,
   210  			},
   211  		},
   212  		{
   213  			name:          "invalid log level",
   214  			file:          "testdata/invalid_log_level.yaml",
   215  			want:          Config{},
   216  			wantErrRegexp: regexp.MustCompile(`level string ".*": unknown name`),
   217  		},
   218  	}
   219  
   220  	for _, tt := range tests {
   221  		t.Run(tt.name, func(t *testing.T) {
   222  			for k, v := range tt.envs {
   223  				t.Setenv(k, v)
   224  			}
   225  			got, err := ParseFile(tt.file)
   226  
   227  			switch {
   228  			case tt.wantErr != nil:
   229  				if !errors.Is(err, tt.wantErr) {
   230  					t.Errorf("unexpected error: got: %v, want: %v", err, tt.wantErr)
   231  				}
   232  			case tt.wantErrRegexp != nil:
   233  				if err == nil {
   234  					t.Errorf("unexpected nil error: want: %v", tt.wantErrRegexp)
   235  				} else if !tt.wantErrRegexp.MatchString(err.Error()) {
   236  					t.Errorf("unexpected error: got: %v, want: %v", err, tt.wantErrRegexp)
   237  				}
   238  			default:
   239  				if err != nil {
   240  					t.Errorf("unexpected error: %v", err)
   241  				}
   242  			}
   243  
   244  			if diff := cmp.Diff(tt.want, got); diff != "" {
   245  				t.Errorf("configs mismatch (-want +got):\n%v", diff)
   246  			}
   247  		})
   248  	}
   249  }
   250  
   251  func TestConfig_IsCompatible(t *testing.T) {
   252  	tests := []struct {
   253  		name string
   254  		cfg  Config
   255  		v    string
   256  		want bool
   257  	}{
   258  		{
   259  			name: "same version",
   260  			cfg:  Config{LavaVersion: "v1.0.0"},
   261  			v:    "v1.0.0",
   262  			want: true,
   263  		},
   264  		{
   265  			name: "lower version",
   266  			cfg:  Config{LavaVersion: "v1.1.0"},
   267  			v:    "1.0.0",
   268  			want: false,
   269  		},
   270  		{
   271  			name: "higher version",
   272  			cfg:  Config{LavaVersion: "v1.0.0"},
   273  			v:    "v1.1.0",
   274  			want: true,
   275  		},
   276  		{
   277  			name: "pre-release",
   278  			cfg:  Config{LavaVersion: "v0.0.0"},
   279  			v:    "v0.0.0-20231216173526-1150d51c5272",
   280  			want: false,
   281  		},
   282  		{
   283  			name: "invalid version",
   284  			cfg:  Config{LavaVersion: "v1.0.0"},
   285  			v:    "invalid",
   286  			want: false,
   287  		},
   288  	}
   289  
   290  	for _, tt := range tests {
   291  		t.Run(tt.name, func(t *testing.T) {
   292  			got := tt.cfg.IsCompatible(tt.v)
   293  			if got != tt.want {
   294  				t.Errorf("unexpected result: %v, minimum required version: %v, v: %v", got, tt.cfg.LavaVersion, tt.v)
   295  			}
   296  		})
   297  	}
   298  }
   299  
   300  func TestSeverity_MarshalText(t *testing.T) {
   301  	tests := []struct {
   302  		name     string
   303  		severity Severity
   304  		want     string
   305  		wantErr  error
   306  	}{
   307  		{
   308  			name:     "critical",
   309  			severity: SeverityCritical,
   310  			want:     "critical",
   311  			wantErr:  nil,
   312  		},
   313  		{
   314  			name:     "high",
   315  			severity: SeverityHigh,
   316  			want:     "high",
   317  			wantErr:  nil,
   318  		},
   319  		{
   320  			name:     "medium",
   321  			severity: SeverityMedium,
   322  			want:     "medium",
   323  			wantErr:  nil,
   324  		},
   325  		{
   326  			name:     "low",
   327  			severity: SeverityLow,
   328  			want:     "low",
   329  			wantErr:  nil,
   330  		},
   331  		{
   332  			name:     "info",
   333  			severity: SeverityInfo,
   334  			want:     "info",
   335  			wantErr:  nil,
   336  		},
   337  		{
   338  			name:     "invalid",
   339  			severity: 7,
   340  			want:     "",
   341  			wantErr:  ErrInvalidSeverity,
   342  		},
   343  	}
   344  
   345  	for _, tt := range tests {
   346  		t.Run(tt.name, func(t *testing.T) {
   347  			got, err := tt.severity.MarshalText()
   348  			if !errors.Is(err, tt.wantErr) {
   349  				t.Errorf("unexpected error: want: %v, got: %v", tt.wantErr, err)
   350  			}
   351  			if string(got) != tt.want {
   352  				t.Errorf("unexpected severity string: want: %v, got: %v", tt.want, got)
   353  			}
   354  		})
   355  	}
   356  }