@@ -2427,3 +2427,125 @@ func TestAnalyze_headers_more(t *testing.T) {
2427
2427
})
2428
2428
}
2429
2429
}
2430
+
2431
+ //nolint:funlen
2432
+ func TestAnalyze_directiveSources (t * testing.T ) {
2433
+ t .Parallel ()
2434
+ // two self defined maps and matchFn to ensure it is a separate test
2435
+ testDirectiveMap1 := map [string ][]uint {
2436
+ "common_dir" : {ngxAnyConf | ngxConfTake1 },
2437
+ "test_dir1" : {ngxAnyConf | ngxConfTake1 },
2438
+ }
2439
+ testSource1 := func (directive string ) ([]uint , bool ) {
2440
+ masks , matched := testDirectiveMap1 [directive ]
2441
+ return masks , matched
2442
+ }
2443
+
2444
+ testDirectiveMap2 := map [string ][]uint {
2445
+ "common_dir" : {ngxAnyConf | ngxConfTake2 },
2446
+ "test_dir2" : {ngxAnyConf | ngxConfTake2 },
2447
+ }
2448
+ testSource2 := func (directive string ) ([]uint , bool ) {
2449
+ masks , matched := testDirectiveMap2 [directive ]
2450
+ return masks , matched
2451
+ }
2452
+
2453
+ testcases := map [string ]struct {
2454
+ stmt * Directive
2455
+ ctx blockCtx
2456
+ wantErr bool
2457
+ }{
2458
+ // The directive only found in source1 and satisfies the bitmask in it
2459
+ "DirectiveFoundOnlyInSource1_pass" : {
2460
+ & Directive {
2461
+ Directive : "test_dir1" ,
2462
+ Args : []string {"arg1" },
2463
+ Line : 5 ,
2464
+ },
2465
+ blockCtx {"http" , "upstream" },
2466
+ false ,
2467
+ },
2468
+ // The directive only found in source2 and satisfies the bitmask in it
2469
+ "DirectiveFoundOnlyInSource2_pass" : {
2470
+ & Directive {
2471
+ Directive : "test_dir2" ,
2472
+ Args : []string {"arg1" , "arg2" },
2473
+ Line : 5 ,
2474
+ },
2475
+ blockCtx {"http" , "upstream" },
2476
+ false ,
2477
+ },
2478
+ // The directive only found in source2 but not satisfies the bitmask in it
2479
+ "DirectiveFoundOnlyInsource2_fail" : {
2480
+ & Directive {
2481
+ Directive : "test_dir2" ,
2482
+ Args : []string {"arg1" },
2483
+ Line : 5 ,
2484
+ },
2485
+ blockCtx {"http" , "upstream" },
2486
+ true ,
2487
+ },
2488
+ // The directive found in both sources,
2489
+ // but only satisfies bitmasks in source1 it should still pass validation
2490
+ "DirectiveFoundInBothSources_pass_case1" : {
2491
+ & Directive {
2492
+ Directive : "common_dir" ,
2493
+ Args : []string {"arg1" },
2494
+ Line : 5 ,
2495
+ },
2496
+ blockCtx {"http" , "upstream" },
2497
+ false ,
2498
+ },
2499
+ // The directive found in both Sources,
2500
+ // but only satisfies bitmasks in source2 it should still pass validation
2501
+ "DirectiveFoundInBothSources_pass_case2" : {
2502
+ & Directive {
2503
+ Directive : "common_dir" ,
2504
+ Args : []string {"arg1" , "arg2" },
2505
+ Line : 5 ,
2506
+ },
2507
+ blockCtx {"http" , "upstream" },
2508
+ false ,
2509
+ },
2510
+ // The directive found in both sources,
2511
+ // but doesn't satisfy bitmask in any of them
2512
+ "DirectiveFoundInBothSources_fail" : {
2513
+ & Directive {
2514
+ Directive : "common_dir" ,
2515
+ Args : []string {"arg1" , "arg2" , "arg3" },
2516
+ Line : 5 ,
2517
+ },
2518
+ blockCtx {"http" , "upstream" },
2519
+ true ,
2520
+ },
2521
+ // The directive not found in any source
2522
+ "DirectiveNotFoundInAnySource_fail" : {
2523
+ & Directive {
2524
+ Directive : "no_exist" ,
2525
+ Args : []string {},
2526
+ Line : 5 ,
2527
+ },
2528
+ blockCtx {"http" , "location" },
2529
+ true ,
2530
+ },
2531
+ }
2532
+
2533
+ for name , tc := range testcases {
2534
+ tc := tc
2535
+ t .Run (name , func (t * testing.T ) {
2536
+ t .Parallel ()
2537
+ err := analyze ("nginx.conf" , tc .stmt , ";" , tc .ctx , & ParseOptions {
2538
+ DirectiveSources : []MatchFunc {testSource1 , testSource2 },
2539
+ ErrorOnUnknownDirectives : true ,
2540
+ })
2541
+
2542
+ if ! tc .wantErr && err != nil {
2543
+ t .Fatal (err )
2544
+ }
2545
+
2546
+ if tc .wantErr && err == nil {
2547
+ t .Fatal ("expected error, got nil" )
2548
+ }
2549
+ })
2550
+ }
2551
+ }
0 commit comments