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