github.com/ethereum-optimism/optimism@v1.7.2/op-node/flags/flags_test.go (about)

     1  package flags
     2  
     3  import (
     4  	"slices"
     5  	"strings"
     6  	"testing"
     7  
     8  	opservice "github.com/ethereum-optimism/optimism/op-service"
     9  
    10  	"github.com/stretchr/testify/require"
    11  	"github.com/urfave/cli/v2"
    12  )
    13  
    14  // TestOptionalFlagsDontSetRequired asserts that all flags deemed optional set
    15  // the Required field to false.
    16  func TestOptionalFlagsDontSetRequired(t *testing.T) {
    17  	for _, flag := range optionalFlags {
    18  		reqFlag, ok := flag.(cli.RequiredFlag)
    19  		require.True(t, ok)
    20  		require.False(t, reqFlag.IsRequired())
    21  	}
    22  }
    23  
    24  // TestUniqueFlags asserts that all flag names are unique, to avoid accidental conflicts between the many flags.
    25  func TestUniqueFlags(t *testing.T) {
    26  	seenCLI := make(map[string]struct{})
    27  	for _, flag := range Flags {
    28  		for _, name := range flag.Names() {
    29  			if _, ok := seenCLI[name]; ok {
    30  				t.Errorf("duplicate flag %s", name)
    31  				continue
    32  			}
    33  			seenCLI[name] = struct{}{}
    34  		}
    35  	}
    36  }
    37  
    38  // TestBetaFlags test that all flags starting with "beta." have "BETA_" in the env var, and vice versa.
    39  func TestBetaFlags(t *testing.T) {
    40  	for _, flag := range Flags {
    41  		envFlag, ok := flag.(interface {
    42  			GetEnvVars() []string
    43  		})
    44  		if !ok || len(envFlag.GetEnvVars()) == 0 { // skip flags without env-var support
    45  			continue
    46  		}
    47  		name := flag.Names()[0]
    48  		envName := envFlag.GetEnvVars()[0]
    49  		if strings.HasPrefix(name, "beta.") {
    50  			require.Contains(t, envName, "BETA_", "%q flag must contain BETA in env var to match \"beta.\" flag name", name)
    51  		}
    52  		if strings.Contains(envName, "BETA_") {
    53  			require.True(t, strings.HasPrefix(name, "beta."), "%q flag must start with \"beta.\" in flag name to match \"BETA_\" env var", name)
    54  		}
    55  	}
    56  }
    57  
    58  func TestDeprecatedFlagsAreHidden(t *testing.T) {
    59  	for _, flag := range DeprecatedFlags {
    60  		flag := flag
    61  		flagName := flag.Names()[0]
    62  
    63  		t.Run(flagName, func(t *testing.T) {
    64  
    65  			visibleFlag, ok := flag.(interface {
    66  				IsVisible() bool
    67  			})
    68  			require.True(t, ok, "Need to case the flag to the correct format")
    69  			require.False(t, visibleFlag.IsVisible())
    70  		})
    71  	}
    72  }
    73  
    74  func TestHasEnvVar(t *testing.T) {
    75  	for _, flag := range Flags {
    76  		flag := flag
    77  		flagName := flag.Names()[0]
    78  
    79  		t.Run(flagName, func(t *testing.T) {
    80  			if flagName == PeerScoringName || flagName == PeerScoreBandsName || flagName == TopicScoringName {
    81  				t.Skipf("Skipping flag %v which is known to have no env vars", flagName)
    82  			}
    83  			envFlagGetter, ok := flag.(interface {
    84  				GetEnvVars() []string
    85  			})
    86  			envFlags := envFlagGetter.GetEnvVars()
    87  			require.True(t, ok, "must be able to cast the flag to an EnvVar interface")
    88  			require.Equal(t, 1, len(envFlags), "flags should have exactly one env var")
    89  		})
    90  	}
    91  }
    92  
    93  func TestEnvVarFormat(t *testing.T) {
    94  	for _, flag := range Flags {
    95  		flag := flag
    96  		flagName := flag.Names()[0]
    97  
    98  		skippedFlags := []string{
    99  			L1NodeAddr.Name,
   100  			L2EngineAddr.Name,
   101  			L2EngineJWTSecret.Name,
   102  			L1TrustRPC.Name,
   103  			L1RPCProviderKind.Name,
   104  			SnapshotLog.Name,
   105  			BackupL2UnsafeSyncRPC.Name,
   106  			BackupL2UnsafeSyncRPCTrustRPC.Name,
   107  			"p2p.scoring",
   108  			"p2p.ban.peers",
   109  			"p2p.ban.threshold",
   110  			"p2p.ban.duration",
   111  			"p2p.listen.tcp",
   112  			"p2p.listen.udp",
   113  			"p2p.useragent",
   114  			"p2p.gossip.mesh.lo",
   115  			"p2p.gossip.mesh.floodpublish",
   116  			"l2.engine-sync",
   117  		}
   118  
   119  		t.Run(flagName, func(t *testing.T) {
   120  			if slices.Contains(skippedFlags, flagName) {
   121  				t.Skipf("Skipping flag %v which is known to not have a standard flag name <-> env var conversion", flagName)
   122  			}
   123  			if flagName == PeerScoringName || flagName == PeerScoreBandsName || flagName == TopicScoringName {
   124  				t.Skipf("Skipping flag %v which is known to have no env vars", flagName)
   125  			}
   126  			envFlagGetter, ok := flag.(interface {
   127  				GetEnvVars() []string
   128  			})
   129  			envFlags := envFlagGetter.GetEnvVars()
   130  			require.True(t, ok, "must be able to cast the flag to an EnvVar interface")
   131  			require.Equal(t, 1, len(envFlags), "flags should have exactly one env var")
   132  			expectedEnvVar := opservice.FlagNameToEnvVarName(flagName, "OP_NODE")
   133  			require.Equal(t, expectedEnvVar, envFlags[0])
   134  		})
   135  	}
   136  }