mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/flagutil: add defaultValue arg to NewArray{Int,Bytes,Duration} functions
The defaultValue is printed in the flag description when passing -help to the app.
This is a follow-up for aef31f201a
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4776
This commit is contained in:
parent
e8bcb17c8a
commit
d7067c46d0
4 changed files with 203 additions and 149 deletions
|
@ -26,12 +26,11 @@ var (
|
||||||
forceVMProto = flagutil.NewArrayBool("remoteWrite.forceVMProto", "Whether to force VictoriaMetrics remote write protocol for sending data "+
|
forceVMProto = flagutil.NewArrayBool("remoteWrite.forceVMProto", "Whether to force VictoriaMetrics remote write protocol for sending data "+
|
||||||
"to the corresponding -remoteWrite.url . See https://docs.victoriametrics.com/vmagent.html#victoriametrics-remote-write-protocol")
|
"to the corresponding -remoteWrite.url . See https://docs.victoriametrics.com/vmagent.html#victoriametrics-remote-write-protocol")
|
||||||
|
|
||||||
rateLimit = flagutil.NewArrayInt("remoteWrite.rateLimit", "Optional rate limit in bytes per second for data sent to the corresponding -remoteWrite.url. "+
|
rateLimit = flagutil.NewArrayInt("remoteWrite.rateLimit", 0, "Optional rate limit in bytes per second for data sent to the corresponding -remoteWrite.url. "+
|
||||||
"By default, the rate limit is disabled. It can be useful for limiting load on remote storage when big amounts of buffered data "+
|
"By default, the rate limit is disabled. It can be useful for limiting load on remote storage when big amounts of buffered data "+
|
||||||
"is sent after temporary unavailability of the remote storage")
|
"is sent after temporary unavailability of the remote storage")
|
||||||
sendTimeout = flagutil.NewArrayDuration("remoteWrite.sendTimeout", "Timeout for sending a single block of data to the corresponding -remoteWrite.url (default "+
|
sendTimeout = flagutil.NewArrayDuration("remoteWrite.sendTimeout", time.Minute, "Timeout for sending a single block of data to the corresponding -remoteWrite.url")
|
||||||
defaultSendTimeout.String()+")")
|
proxyURL = flagutil.NewArrayString("remoteWrite.proxyURL", "Optional proxy URL for writing data to the corresponding -remoteWrite.url. "+
|
||||||
proxyURL = flagutil.NewArrayString("remoteWrite.proxyURL", "Optional proxy URL for writing data to the corresponding -remoteWrite.url. "+
|
|
||||||
"Supported proxies: http, https, socks5. Example: -remoteWrite.proxyURL=socks5://proxy:1234")
|
"Supported proxies: http, https, socks5. Example: -remoteWrite.proxyURL=socks5://proxy:1234")
|
||||||
|
|
||||||
tlsInsecureSkipVerify = flagutil.NewArrayBool("remoteWrite.tlsInsecureSkipVerify", "Whether to skip tls verification when connecting to the corresponding -remoteWrite.url")
|
tlsInsecureSkipVerify = flagutil.NewArrayBool("remoteWrite.tlsInsecureSkipVerify", "Whether to skip tls verification when connecting to the corresponding -remoteWrite.url")
|
||||||
|
@ -73,8 +72,6 @@ var (
|
||||||
awsSecretKey = flagutil.NewArrayString("remoteWrite.aws.secretKey", "Optional AWS SecretKey to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
|
awsSecretKey = flagutil.NewArrayString("remoteWrite.aws.secretKey", "Optional AWS SecretKey to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultSendTimeout = time.Minute
|
|
||||||
|
|
||||||
type client struct {
|
type client struct {
|
||||||
sanitizedURL string
|
sanitizedURL string
|
||||||
remoteWriteURL string
|
remoteWriteURL string
|
||||||
|
@ -137,7 +134,7 @@ func newHTTPClient(argIdx int, remoteWriteURL, sanitizedURL string, fq *persiste
|
||||||
}
|
}
|
||||||
hc := &http.Client{
|
hc := &http.Client{
|
||||||
Transport: tr,
|
Transport: tr,
|
||||||
Timeout: sendTimeout.GetOptionalArgOrDefault(argIdx, defaultSendTimeout),
|
Timeout: sendTimeout.GetOptionalArg(argIdx),
|
||||||
}
|
}
|
||||||
c := &client{
|
c := &client{
|
||||||
sanitizedURL: sanitizedURL,
|
sanitizedURL: sanitizedURL,
|
||||||
|
@ -172,7 +169,7 @@ func newHTTPClient(argIdx int, remoteWriteURL, sanitizedURL string, fq *persiste
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) init(argIdx, concurrency int, sanitizedURL string) {
|
func (c *client) init(argIdx, concurrency int, sanitizedURL string) {
|
||||||
if bytesPerSec := rateLimit.GetOptionalArgOrDefault(argIdx, 0); bytesPerSec > 0 {
|
if bytesPerSec := rateLimit.GetOptionalArg(argIdx); bytesPerSec > 0 {
|
||||||
logger.Infof("applying %d bytes per second rate limit for -remoteWrite.url=%q", bytesPerSec, sanitizedURL)
|
logger.Infof("applying %d bytes per second rate limit for -remoteWrite.url=%q", bytesPerSec, sanitizedURL)
|
||||||
c.rl.perSecondLimit = int64(bytesPerSec)
|
c.rl.perSecondLimit = int64(bytesPerSec)
|
||||||
}
|
}
|
||||||
|
@ -181,7 +178,7 @@ func (c *client) init(argIdx, concurrency int, sanitizedURL string) {
|
||||||
c.bytesSent = metrics.GetOrCreateCounter(fmt.Sprintf(`vmagent_remotewrite_bytes_sent_total{url=%q}`, c.sanitizedURL))
|
c.bytesSent = metrics.GetOrCreateCounter(fmt.Sprintf(`vmagent_remotewrite_bytes_sent_total{url=%q}`, c.sanitizedURL))
|
||||||
c.blocksSent = metrics.GetOrCreateCounter(fmt.Sprintf(`vmagent_remotewrite_blocks_sent_total{url=%q}`, c.sanitizedURL))
|
c.blocksSent = metrics.GetOrCreateCounter(fmt.Sprintf(`vmagent_remotewrite_blocks_sent_total{url=%q}`, c.sanitizedURL))
|
||||||
c.rateLimit = metrics.GetOrCreateGauge(fmt.Sprintf(`vmagent_remotewrite_rate_limit{url=%q}`, c.sanitizedURL), func() float64 {
|
c.rateLimit = metrics.GetOrCreateGauge(fmt.Sprintf(`vmagent_remotewrite_rate_limit{url=%q}`, c.sanitizedURL), func() float64 {
|
||||||
return float64(rateLimit.GetOptionalArgOrDefault(argIdx, 0))
|
return float64(rateLimit.GetOptionalArg(argIdx))
|
||||||
})
|
})
|
||||||
c.requestDuration = metrics.GetOrCreateHistogram(fmt.Sprintf(`vmagent_remotewrite_duration_seconds{url=%q}`, c.sanitizedURL))
|
c.requestDuration = metrics.GetOrCreateHistogram(fmt.Sprintf(`vmagent_remotewrite_duration_seconds{url=%q}`, c.sanitizedURL))
|
||||||
c.requestsOKCount = metrics.GetOrCreateCounter(fmt.Sprintf(`vmagent_remotewrite_requests_total{url=%q, status_code="2XX"}`, c.sanitizedURL))
|
c.requestsOKCount = metrics.GetOrCreateCounter(fmt.Sprintf(`vmagent_remotewrite_requests_total{url=%q, status_code="2XX"}`, c.sanitizedURL))
|
||||||
|
|
|
@ -48,14 +48,15 @@ var (
|
||||||
"isn't enough for sending high volume of collected data to remote storage. Default value is 2 * numberOfAvailableCPUs")
|
"isn't enough for sending high volume of collected data to remote storage. Default value is 2 * numberOfAvailableCPUs")
|
||||||
showRemoteWriteURL = flag.Bool("remoteWrite.showURL", false, "Whether to show -remoteWrite.url in the exported metrics. "+
|
showRemoteWriteURL = flag.Bool("remoteWrite.showURL", false, "Whether to show -remoteWrite.url in the exported metrics. "+
|
||||||
"It is hidden by default, since it can contain sensitive info such as auth key")
|
"It is hidden by default, since it can contain sensitive info such as auth key")
|
||||||
maxPendingBytesPerURL = flagutil.NewArrayBytes("remoteWrite.maxDiskUsagePerURL", "The maximum file-based buffer size in bytes at -remoteWrite.tmpDataPath "+
|
maxPendingBytesPerURL = flagutil.NewArrayBytes("remoteWrite.maxDiskUsagePerURL", 0, "The maximum file-based buffer size in bytes at -remoteWrite.tmpDataPath "+
|
||||||
"for each -remoteWrite.url. When buffer size reaches the configured maximum, then old data is dropped when adding new data to the buffer. "+
|
"for each -remoteWrite.url. When buffer size reaches the configured maximum, then old data is dropped when adding new data to the buffer. "+
|
||||||
"Buffered data is stored in ~500MB chunks. It is recommended to set the value for this flag to a multiple of the block size 500MB. "+
|
"Buffered data is stored in ~500MB chunks. It is recommended to set the value for this flag to a multiple of the block size 500MB. "+
|
||||||
"Disk usage is unlimited if the value is set to 0")
|
"Disk usage is unlimited if the value is set to 0")
|
||||||
significantFigures = flagutil.NewArrayInt("remoteWrite.significantFigures", "The number of significant figures to leave in metric values before writing them "+
|
significantFigures = flagutil.NewArrayInt("remoteWrite.significantFigures", 0, "The number of significant figures to leave in metric values before writing them "+
|
||||||
"to remote storage. See https://en.wikipedia.org/wiki/Significant_figures . Zero value saves all the significant figures. "+
|
"to remote storage. See https://en.wikipedia.org/wiki/Significant_figures . Zero value saves all the significant figures. "+
|
||||||
"This option may be used for improving data compression for the stored metrics. See also -remoteWrite.roundDigits")
|
"This option may be used for improving data compression for the stored metrics. See also -remoteWrite.roundDigits")
|
||||||
roundDigits = flagutil.NewArrayInt("remoteWrite.roundDigits", "Round metric values to this number of decimal digits after the point before writing them to remote storage. "+
|
roundDigits = flagutil.NewArrayInt("remoteWrite.roundDigits", 100, "Round metric values to this number of decimal digits after the point before "+
|
||||||
|
"writing them to remote storage. "+
|
||||||
"Examples: -remoteWrite.roundDigits=2 would round 1.236 to 1.24, while -remoteWrite.roundDigits=-1 would round 126.78 to 130. "+
|
"Examples: -remoteWrite.roundDigits=2 would round 1.236 to 1.24, while -remoteWrite.roundDigits=-1 would round 126.78 to 130. "+
|
||||||
"By default, digits rounding is disabled. Set it to 100 for disabling it for a particular remote storage. "+
|
"By default, digits rounding is disabled. Set it to 100 for disabling it for a particular remote storage. "+
|
||||||
"This option may be used for improving data compression for the stored metrics")
|
"This option may be used for improving data compression for the stored metrics")
|
||||||
|
@ -77,7 +78,7 @@ var (
|
||||||
streamAggrDropInput = flagutil.NewArrayBool("remoteWrite.streamAggr.dropInput", "Whether to drop all the input samples after the aggregation "+
|
streamAggrDropInput = flagutil.NewArrayBool("remoteWrite.streamAggr.dropInput", "Whether to drop all the input samples after the aggregation "+
|
||||||
"with -remoteWrite.streamAggr.config. By default, only aggregates samples are dropped, while the remaining samples "+
|
"with -remoteWrite.streamAggr.config. By default, only aggregates samples are dropped, while the remaining samples "+
|
||||||
"are written to the corresponding -remoteWrite.url . See also -remoteWrite.streamAggr.keepInput and https://docs.victoriametrics.com/stream-aggregation.html")
|
"are written to the corresponding -remoteWrite.url . See also -remoteWrite.streamAggr.keepInput and https://docs.victoriametrics.com/stream-aggregation.html")
|
||||||
streamAggrDedupInterval = flagutil.NewArrayDuration("remoteWrite.streamAggr.dedupInterval", "Input samples are de-duplicated with this interval before being aggregated. "+
|
streamAggrDedupInterval = flagutil.NewArrayDuration("remoteWrite.streamAggr.dedupInterval", 0, "Input samples are de-duplicated with this interval before being aggregated. "+
|
||||||
"Only the last sample per each time series per each interval is aggregated if the interval is greater than zero")
|
"Only the last sample per each time series per each interval is aggregated if the interval is greater than zero")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -565,7 +566,7 @@ func newRemoteWriteCtx(argIdx int, at *auth.Token, remoteWriteURL *url.URL, maxI
|
||||||
pqURL.Fragment = ""
|
pqURL.Fragment = ""
|
||||||
h := xxhash.Sum64([]byte(pqURL.String()))
|
h := xxhash.Sum64([]byte(pqURL.String()))
|
||||||
queuePath := filepath.Join(*tmpDataPath, persistentQueueDirname, fmt.Sprintf("%d_%016X", argIdx+1, h))
|
queuePath := filepath.Join(*tmpDataPath, persistentQueueDirname, fmt.Sprintf("%d_%016X", argIdx+1, h))
|
||||||
maxPendingBytes := maxPendingBytesPerURL.GetOptionalArgOrDefault(argIdx, 0)
|
maxPendingBytes := maxPendingBytesPerURL.GetOptionalArg(argIdx)
|
||||||
if maxPendingBytes != 0 && maxPendingBytes < persistentqueue.DefaultChunkFileSize {
|
if maxPendingBytes != 0 && maxPendingBytes < persistentqueue.DefaultChunkFileSize {
|
||||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4195
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4195
|
||||||
logger.Warnf("rounding the -remoteWrite.maxDiskUsagePerURL=%d to the minimum supported value: %d", maxPendingBytes, persistentqueue.DefaultChunkFileSize)
|
logger.Warnf("rounding the -remoteWrite.maxDiskUsagePerURL=%d to the minimum supported value: %d", maxPendingBytes, persistentqueue.DefaultChunkFileSize)
|
||||||
|
@ -589,8 +590,8 @@ func newRemoteWriteCtx(argIdx int, at *auth.Token, remoteWriteURL *url.URL, maxI
|
||||||
c.init(argIdx, *queues, sanitizedURL)
|
c.init(argIdx, *queues, sanitizedURL)
|
||||||
|
|
||||||
// Initialize pss
|
// Initialize pss
|
||||||
sf := significantFigures.GetOptionalArgOrDefault(argIdx, 0)
|
sf := significantFigures.GetOptionalArg(argIdx)
|
||||||
rd := roundDigits.GetOptionalArgOrDefault(argIdx, 100)
|
rd := roundDigits.GetOptionalArg(argIdx)
|
||||||
pssLen := *queues
|
pssLen := *queues
|
||||||
if n := cgroup.AvailableCPUs(); pssLen > n {
|
if n := cgroup.AvailableCPUs(); pssLen > n {
|
||||||
// There is no sense in running more than availableCPUs concurrent pendingSeries,
|
// There is no sense in running more than availableCPUs concurrent pendingSeries,
|
||||||
|
@ -615,7 +616,7 @@ func newRemoteWriteCtx(argIdx int, at *auth.Token, remoteWriteURL *url.URL, maxI
|
||||||
// Initialize sas
|
// Initialize sas
|
||||||
sasFile := streamAggrConfig.GetOptionalArg(argIdx)
|
sasFile := streamAggrConfig.GetOptionalArg(argIdx)
|
||||||
if sasFile != "" {
|
if sasFile != "" {
|
||||||
dedupInterval := streamAggrDedupInterval.GetOptionalArgOrDefault(argIdx, 0)
|
dedupInterval := streamAggrDedupInterval.GetOptionalArg(argIdx)
|
||||||
sas, err := streamaggr.LoadFromFile(sasFile, rwctx.pushInternal, dedupInterval)
|
sas, err := streamaggr.LoadFromFile(sasFile, rwctx.pushInternal, dedupInterval)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("cannot initialize stream aggregators from -remoteWrite.streamAggr.config=%q: %s", sasFile, err)
|
logger.Fatalf("cannot initialize stream aggregators from -remoteWrite.streamAggr.config=%q: %s", sasFile, err)
|
||||||
|
@ -733,7 +734,7 @@ func (rwctx *remoteWriteCtx) reinitStreamAggr() {
|
||||||
sasFile := streamAggrConfig.GetOptionalArg(rwctx.idx)
|
sasFile := streamAggrConfig.GetOptionalArg(rwctx.idx)
|
||||||
logger.Infof("reloading stream aggregation configs pointed by -remoteWrite.streamAggr.config=%q", sasFile)
|
logger.Infof("reloading stream aggregation configs pointed by -remoteWrite.streamAggr.config=%q", sasFile)
|
||||||
metrics.GetOrCreateCounter(fmt.Sprintf(`vmagent_streamaggr_config_reloads_total{path=%q}`, sasFile)).Inc()
|
metrics.GetOrCreateCounter(fmt.Sprintf(`vmagent_streamaggr_config_reloads_total{path=%q}`, sasFile)).Inc()
|
||||||
dedupInterval := streamAggrDedupInterval.GetOptionalArgOrDefault(rwctx.idx, 0)
|
dedupInterval := streamAggrDedupInterval.GetOptionalArg(rwctx.idx)
|
||||||
sasNew, err := streamaggr.LoadFromFile(sasFile, rwctx.pushInternal, dedupInterval)
|
sasNew, err := streamaggr.LoadFromFile(sasFile, rwctx.pushInternal, dedupInterval)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
metrics.GetOrCreateCounter(fmt.Sprintf(`vmagent_streamaggr_config_reloads_errors_total{path=%q}`, sasFile)).Inc()
|
metrics.GetOrCreateCounter(fmt.Sprintf(`vmagent_streamaggr_config_reloads_errors_total{path=%q}`, sasFile)).Inc()
|
||||||
|
@ -775,7 +776,7 @@ func CheckStreamAggrConfigs() error {
|
||||||
if sasFile == "" {
|
if sasFile == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dedupInterval := streamAggrDedupInterval.GetOptionalArgOrDefault(idx, 0)
|
dedupInterval := streamAggrDedupInterval.GetOptionalArg(idx)
|
||||||
sas, err := streamaggr.LoadFromFile(sasFile, pushNoop, dedupInterval)
|
sas, err := streamaggr.LoadFromFile(sasFile, pushNoop, dedupInterval)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot load -remoteWrite.streamAggr.config=%q: %w", sasFile, err)
|
return fmt.Errorf("cannot load -remoteWrite.streamAggr.config=%q: %w", sasFile, err)
|
||||||
|
|
|
@ -16,12 +16,15 @@ func NewArrayString(name, description string) *ArrayString {
|
||||||
return &a
|
return &a
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewArrayDuration returns new ArrayDuration with the given name and description.
|
// NewArrayDuration returns new ArrayDuration with the given name, defaultValue and description.
|
||||||
func NewArrayDuration(name, description string) *ArrayDuration {
|
func NewArrayDuration(name string, defaultValue time.Duration, description string) *ArrayDuration {
|
||||||
|
description += fmt.Sprintf(" (default %s)", defaultValue)
|
||||||
description += "\nSupports `array` of values separated by comma or specified via multiple flags."
|
description += "\nSupports `array` of values separated by comma or specified via multiple flags."
|
||||||
var a ArrayDuration
|
a := &ArrayDuration{
|
||||||
flag.Var(&a, name, description)
|
defaultValue: defaultValue,
|
||||||
return &a
|
}
|
||||||
|
flag.Var(a, name, description)
|
||||||
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewArrayBool returns new ArrayBool with the given name and description.
|
// NewArrayBool returns new ArrayBool with the given name and description.
|
||||||
|
@ -32,21 +35,27 @@ func NewArrayBool(name, description string) *ArrayBool {
|
||||||
return &a
|
return &a
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewArrayInt returns new ArrayInt with the given name and description.
|
// NewArrayInt returns new ArrayInt with the given name, defaultValue and description.
|
||||||
func NewArrayInt(name, description string) *ArrayInt {
|
func NewArrayInt(name string, defaultValue int, description string) *ArrayInt {
|
||||||
|
description += fmt.Sprintf(" (default %d)", defaultValue)
|
||||||
description += "\nSupports `array` of values separated by comma or specified via multiple flags."
|
description += "\nSupports `array` of values separated by comma or specified via multiple flags."
|
||||||
var a ArrayInt
|
a := &ArrayInt{
|
||||||
flag.Var(&a, name, description)
|
defaultValue: defaultValue,
|
||||||
return &a
|
}
|
||||||
|
flag.Var(a, name, description)
|
||||||
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewArrayBytes returns new ArrayBytes with the given name and description.
|
// NewArrayBytes returns new ArrayBytes with the given name, defaultValue and description.
|
||||||
func NewArrayBytes(name, description string) *ArrayBytes {
|
func NewArrayBytes(name string, defaultValue int64, description string) *ArrayBytes {
|
||||||
description += "\nSupports the following optional suffixes for size values: KB, MB, GB, TB, KiB, MiB, GiB, TiB."
|
description += "\nSupports the following optional suffixes for size values: KB, MB, GB, TB, KiB, MiB, GiB, TiB."
|
||||||
|
description += fmt.Sprintf(" (default %d)", defaultValue)
|
||||||
description += "\nSupports `array` of values separated by comma or specified via multiple flags."
|
description += "\nSupports `array` of values separated by comma or specified via multiple flags."
|
||||||
var a ArrayBytes
|
a := &ArrayBytes{
|
||||||
flag.Var(&a, name, description)
|
defaultValue: defaultValue,
|
||||||
return &a
|
}
|
||||||
|
flag.Var(a, name, description)
|
||||||
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArrayString is a flag that holds an array of strings.
|
// ArrayString is a flag that holds an array of strings.
|
||||||
|
@ -220,11 +229,11 @@ func (a *ArrayBool) IsBoolFlag() bool { return true }
|
||||||
|
|
||||||
// String implements flag.Value interface
|
// String implements flag.Value interface
|
||||||
func (a *ArrayBool) String() string {
|
func (a *ArrayBool) String() string {
|
||||||
formattedBools := make([]string, len(*a))
|
formattedResults := make([]string, len(*a))
|
||||||
for i, v := range *a {
|
for i, v := range *a {
|
||||||
formattedBools[i] = strconv.FormatBool(v)
|
formattedResults[i] = strconv.FormatBool(v)
|
||||||
}
|
}
|
||||||
return strings.Join(formattedBools, ",")
|
return strings.Join(formattedResults, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set implements flag.Value interface
|
// Set implements flag.Value interface
|
||||||
|
@ -255,15 +264,19 @@ func (a *ArrayBool) GetOptionalArg(argIdx int) bool {
|
||||||
// ArrayDuration is a flag that holds an array of time.Duration values.
|
// ArrayDuration is a flag that holds an array of time.Duration values.
|
||||||
//
|
//
|
||||||
// Has the same api as ArrayString.
|
// Has the same api as ArrayString.
|
||||||
type ArrayDuration []time.Duration
|
type ArrayDuration struct {
|
||||||
|
defaultValue time.Duration
|
||||||
|
a []time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
// String implements flag.Value interface
|
// String implements flag.Value interface
|
||||||
func (a *ArrayDuration) String() string {
|
func (a *ArrayDuration) String() string {
|
||||||
formattedBools := make([]string, len(*a))
|
x := a.a
|
||||||
for i, v := range *a {
|
formattedResults := make([]string, len(x))
|
||||||
formattedBools[i] = v.String()
|
for i, v := range x {
|
||||||
|
formattedResults[i] = v.String()
|
||||||
}
|
}
|
||||||
return strings.Join(formattedBools, ",")
|
return strings.Join(formattedResults, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set implements flag.Value interface
|
// Set implements flag.Value interface
|
||||||
|
@ -274,20 +287,19 @@ func (a *ArrayDuration) Set(value string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
*a = append(*a, b)
|
a.a = append(a.a, b)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOptionalArgOrDefault returns optional arg under the given argIdx,
|
// GetOptionalArg returns optional arg under the given argIdx, or default value, if argIdx not found.
|
||||||
// or default value, if argIdx not found.
|
func (a *ArrayDuration) GetOptionalArg(argIdx int) time.Duration {
|
||||||
func (a *ArrayDuration) GetOptionalArgOrDefault(argIdx int, defaultValue time.Duration) time.Duration {
|
x := a.a
|
||||||
x := *a
|
|
||||||
if argIdx >= len(x) {
|
if argIdx >= len(x) {
|
||||||
if len(x) == 1 {
|
if len(x) == 1 {
|
||||||
return x[0]
|
return x[0]
|
||||||
}
|
}
|
||||||
return defaultValue
|
return a.defaultValue
|
||||||
}
|
}
|
||||||
return x[argIdx]
|
return x[argIdx]
|
||||||
}
|
}
|
||||||
|
@ -295,11 +307,14 @@ func (a *ArrayDuration) GetOptionalArgOrDefault(argIdx int, defaultValue time.Du
|
||||||
// ArrayInt is flag that holds an array of ints.
|
// ArrayInt is flag that holds an array of ints.
|
||||||
//
|
//
|
||||||
// Has the same api as ArrayString.
|
// Has the same api as ArrayString.
|
||||||
type ArrayInt []int
|
type ArrayInt struct {
|
||||||
|
defaultValue int
|
||||||
|
a []int
|
||||||
|
}
|
||||||
|
|
||||||
// String implements flag.Value interface
|
// String implements flag.Value interface
|
||||||
func (a *ArrayInt) String() string {
|
func (a *ArrayInt) String() string {
|
||||||
x := *a
|
x := a.a
|
||||||
formattedInts := make([]string, len(x))
|
formattedInts := make([]string, len(x))
|
||||||
for i, v := range x {
|
for i, v := range x {
|
||||||
formattedInts[i] = strconv.Itoa(v)
|
formattedInts[i] = strconv.Itoa(v)
|
||||||
|
@ -315,31 +330,34 @@ func (a *ArrayInt) Set(value string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
*a = append(*a, n)
|
a.a = append(a.a, n)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOptionalArgOrDefault returns optional arg under the given argIdx.
|
// GetOptionalArg returns optional arg under the given argIdx or default value.
|
||||||
func (a *ArrayInt) GetOptionalArgOrDefault(argIdx, defaultValue int) int {
|
func (a *ArrayInt) GetOptionalArg(argIdx int) int {
|
||||||
x := *a
|
x := a.a
|
||||||
if argIdx < len(x) {
|
if argIdx < len(x) {
|
||||||
return x[argIdx]
|
return x[argIdx]
|
||||||
}
|
}
|
||||||
if len(x) == 1 {
|
if len(x) == 1 {
|
||||||
return x[0]
|
return x[0]
|
||||||
}
|
}
|
||||||
return defaultValue
|
return a.defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArrayBytes is flag that holds an array of Bytes.
|
// ArrayBytes is flag that holds an array of Bytes.
|
||||||
//
|
//
|
||||||
// Has the same api as ArrayString.
|
// Has the same api as ArrayString.
|
||||||
type ArrayBytes []*Bytes
|
type ArrayBytes struct {
|
||||||
|
defaultValue int64
|
||||||
|
a []*Bytes
|
||||||
|
}
|
||||||
|
|
||||||
// String implements flag.Value interface
|
// String implements flag.Value interface
|
||||||
func (a *ArrayBytes) String() string {
|
func (a *ArrayBytes) String() string {
|
||||||
x := *a
|
x := a.a
|
||||||
formattedBytes := make([]string, len(x))
|
formattedBytes := make([]string, len(x))
|
||||||
for i, v := range x {
|
for i, v := range x {
|
||||||
formattedBytes[i] = v.String()
|
formattedBytes[i] = v.String()
|
||||||
|
@ -355,19 +373,19 @@ func (a *ArrayBytes) Set(value string) error {
|
||||||
if err := b.Set(v); err != nil {
|
if err := b.Set(v); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
*a = append(*a, &b)
|
a.a = append(a.a, &b)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOptionalArgOrDefault returns optional arg under the given argIdx.
|
// GetOptionalArg returns optional arg under the given argIdx, or default value
|
||||||
func (a *ArrayBytes) GetOptionalArgOrDefault(argIdx int, defaultValue int64) int64 {
|
func (a *ArrayBytes) GetOptionalArg(argIdx int) int64 {
|
||||||
x := *a
|
x := a.a
|
||||||
if argIdx < len(x) {
|
if argIdx < len(x) {
|
||||||
return x[argIdx].N
|
return x[argIdx].N
|
||||||
}
|
}
|
||||||
if len(x) == 1 {
|
if len(x) == 1 {
|
||||||
return x[0].N
|
return x[0].N
|
||||||
}
|
}
|
||||||
return defaultValue
|
return a.defaultValue
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,69 +45,74 @@ func TestArrayString(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayString_Set(t *testing.T) {
|
func TestArrayString_Set(t *testing.T) {
|
||||||
f := func(s string, expectedValues []string) {
|
f := func(s, expectedResult string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayString
|
var a ArrayString
|
||||||
_ = a.Set(s)
|
if err := a.Set(s); err != nil {
|
||||||
if !reflect.DeepEqual([]string(a), expectedValues) {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected values parsed;\ngot\n%q\nwant\n%q", a, expectedValues)
|
}
|
||||||
|
result := a.String()
|
||||||
|
if result != expectedResult {
|
||||||
|
t.Fatalf("unexpected values parsed;\ngot\n%s\nwant\n%s", result, expectedResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Zero args
|
// Zero args
|
||||||
f("", nil)
|
f("", "")
|
||||||
|
|
||||||
// Single arg
|
// Single arg
|
||||||
f(`foo`, []string{`foo`})
|
f(`foo`, `foo`)
|
||||||
f(`fo"o`, []string{`fo"o`})
|
f(`fo"o`, `"fo\"o"`)
|
||||||
f(`fo'o`, []string{`fo'o`})
|
f(`fo'o`, `"fo'o"`)
|
||||||
f(`fo{o`, []string{`fo{o`})
|
f(`fo{o`, `"fo{o"`)
|
||||||
f(`fo[o`, []string{`fo[o`})
|
f(`fo[o`, `"fo[o"`)
|
||||||
f(`fo(o`, []string{`fo(o`})
|
f(`fo(o`, `"fo(o"`)
|
||||||
|
|
||||||
// Single arg with Prometheus label filters
|
// Single arg with Prometheus label filters
|
||||||
f(`foo{bar="baz",x="y"}`, []string{`foo{bar="baz",x="y"}`})
|
f(`foo{bar="baz",x="y"}`, `"foo{bar=\"baz\",x=\"y\"}"`)
|
||||||
f(`foo{bar="ba}z",x="y"}`, []string{`foo{bar="ba}z",x="y"}`})
|
f(`foo{bar="ba}z",x="y"}`, `"foo{bar=\"ba}z\",x=\"y\"}"`)
|
||||||
f(`foo{bar='baz',x="y"}`, []string{`foo{bar='baz',x="y"}`})
|
f(`foo{bar='baz',x="y"}`, `"foo{bar='baz',x=\"y\"}"`)
|
||||||
f(`foo{bar='baz',x='y'}`, []string{`foo{bar='baz',x='y'}`})
|
f(`foo{bar='baz',x='y'}`, `"foo{bar='baz',x='y'}"`)
|
||||||
f(`foo{bar='ba}z',x='y'}`, []string{`foo{bar='ba}z',x='y'}`})
|
f(`foo{bar='ba}z',x='y'}`, `"foo{bar='ba}z',x='y'}"`)
|
||||||
f(`{foo="ba[r",baz='a'}`, []string{`{foo="ba[r",baz='a'}`})
|
f(`{foo="ba[r",baz='a'}`, `"{foo=\"ba[r\",baz='a'}"`)
|
||||||
|
|
||||||
// Single arg with JSON
|
// Single arg with JSON
|
||||||
f(`[1,2,3]`, []string{`[1,2,3]`})
|
f(`[1,2,3]`, `"[1,2,3]"`)
|
||||||
f(`{"foo":"ba,r",baz:x}`, []string{`{"foo":"ba,r",baz:x}`})
|
f(`{"foo":"ba,r",baz:x}`, `"{\"foo\":\"ba,r\",baz:x}"`)
|
||||||
|
|
||||||
// Single quoted arg
|
// Single quoted arg
|
||||||
f(`"foo"`, []string{`foo`})
|
f(`"foo"`, `foo`)
|
||||||
f(`"fo,'o"`, []string{`fo,'o`})
|
f(`"fo,'o"`, `"fo,'o"`)
|
||||||
f(`"f\\o,\'\"o"`, []string{`f\o,\'"o`})
|
f(`"f\\o,\'\"o"`, `"f\\o,\\'\"o"`)
|
||||||
f(`"foo{bar='baz',x='y'}"`, []string{`foo{bar='baz',x='y'}`})
|
f(`"foo{bar='baz',x='y'}"`, `"foo{bar='baz',x='y'}"`)
|
||||||
f(`'foo'`, []string{`foo`})
|
f(`'foo'`, `foo`)
|
||||||
f(`'fo,"o'`, []string{`fo,"o`})
|
f(`'fo,"o'`, `"fo,\"o"`)
|
||||||
f(`'f\\o,\'\"o'`, []string{`f\o,'\"o`})
|
f(`'f\\o,\'\"o'`, `"f\\o,'\\\"o"`)
|
||||||
f(`'foo{bar="baz",x="y"}'`, []string{`foo{bar="baz",x="y"}`})
|
f(`'foo{bar="baz",x="y"}'`, `"foo{bar=\"baz\",x=\"y\"}"`)
|
||||||
|
|
||||||
// Multiple args
|
// Multiple args
|
||||||
f(`foo,bar,baz`, []string{`foo`, `bar`, `baz`})
|
f(`foo,bar,baz`, `foo,bar,baz`)
|
||||||
f(`"foo",'bar',{[(ba'",z"`, []string{`foo`, `bar`, `{[(ba'",z"`})
|
f(`"foo",'bar',{[(ba'",z"`, `foo,bar,"{[(ba'\",z\""`)
|
||||||
f(`foo,b"'ar,"baz,d`, []string{`foo`, `b"'ar,"baz`, `d`})
|
f(`foo,b"'ar,"baz,d`, `foo,"b\"'ar,\"baz",d`)
|
||||||
f(`{foo="b,ar"},baz{x="y",z="d"}`, []string{`{foo="b,ar"}`, `baz{x="y",z="d"}`})
|
f(`{foo="b,ar"},baz{x="y",z="d"}`, `"{foo=\"b,ar\"}","baz{x=\"y\",z=\"d\"}"`)
|
||||||
|
|
||||||
// Empty args
|
// Empty args
|
||||||
f(`""`, []string{``})
|
f(`""`, ``)
|
||||||
f(`''`, []string{``})
|
f(`''`, ``)
|
||||||
f(`,`, []string{``, ``})
|
f(`,`, `,`)
|
||||||
f(`,foo,,ba"r,`, []string{``, `foo`, ``, `ba"r`, ``})
|
f(`,foo,,ba"r,`, `,foo,,"ba\"r",`)
|
||||||
|
|
||||||
// Special chars inside double quotes
|
// Special chars inside double quotes
|
||||||
f(`"foo,b\nar"`, []string{"foo,b\nar"})
|
f(`"foo,b\nar"`, `"foo,b\nar"`)
|
||||||
f(`"foo\x23bar"`, []string{"foo\x23bar"})
|
f(`"foo\x23bar"`, "foo\x23bar")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayString_GetOptionalArg(t *testing.T) {
|
func TestArrayString_GetOptionalArg(t *testing.T) {
|
||||||
f := func(s string, argIdx int, expectedValue string) {
|
f := func(s string, argIdx int, expectedValue string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayString
|
var a ArrayString
|
||||||
_ = a.Set(s)
|
if err := a.Set(s); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
v := a.GetOptionalArg(argIdx)
|
v := a.GetOptionalArg(argIdx)
|
||||||
if v != expectedValue {
|
if v != expectedValue {
|
||||||
t.Fatalf("unexpected value; got %q; want %q", v, expectedValue)
|
t.Fatalf("unexpected value; got %q; want %q", v, expectedValue)
|
||||||
|
@ -126,7 +131,9 @@ func TestArrayString_String(t *testing.T) {
|
||||||
f := func(s string) {
|
f := func(s string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayString
|
var a ArrayString
|
||||||
_ = a.Set(s)
|
if err := a.Set(s); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
result := a.String()
|
result := a.String()
|
||||||
if result != s {
|
if result != s {
|
||||||
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
||||||
|
@ -144,34 +151,42 @@ func TestArrayString_String(t *testing.T) {
|
||||||
|
|
||||||
func TestArrayDuration(t *testing.T) {
|
func TestArrayDuration(t *testing.T) {
|
||||||
expected := ArrayDuration{
|
expected := ArrayDuration{
|
||||||
time.Second * 10,
|
a: []time.Duration{
|
||||||
time.Minute * 5,
|
time.Second * 10,
|
||||||
|
time.Minute * 5,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(expected, fooFlagDuration) {
|
if !reflect.DeepEqual(expected, fooFlagDuration) {
|
||||||
t.Fatalf("unexpected flag values; got\n%s\nwant\n%s", fooFlagDuration, expected)
|
t.Fatalf("unexpected flag values; got\n%s\nwant\n%s", &fooFlagDuration, &expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayDuration_Set(t *testing.T) {
|
func TestArrayDuration_Set(t *testing.T) {
|
||||||
f := func(s string, expectedValues []time.Duration) {
|
f := func(s, expectedResult string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayDuration
|
var a ArrayDuration
|
||||||
_ = a.Set(s)
|
if err := a.Set(s); err != nil {
|
||||||
if !reflect.DeepEqual([]time.Duration(a), expectedValues) {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected values parsed;\ngot\n%q\nwant\n%q", a, expectedValues)
|
}
|
||||||
|
result := a.String()
|
||||||
|
if result != expectedResult {
|
||||||
|
t.Fatalf("unexpected values parsed;\ngot\n%q\nwant\n%q", result, expectedResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("", nil)
|
f("", "")
|
||||||
f(`1m`, []time.Duration{time.Minute})
|
f(`1m`, `1m0s`)
|
||||||
f(`5m,1s,1h`, []time.Duration{time.Minute * 5, time.Second, time.Hour})
|
f(`5m,1s,1h`, `5m0s,1s,1h0m0s`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayDuration_GetOptionalArg(t *testing.T) {
|
func TestArrayDuration_GetOptionalArg(t *testing.T) {
|
||||||
f := func(s string, argIdx int, defaultValue, expectedValue time.Duration) {
|
f := func(s string, argIdx int, defaultValue, expectedValue time.Duration) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayDuration
|
var a ArrayDuration
|
||||||
_ = a.Set(s)
|
a.defaultValue = defaultValue
|
||||||
v := a.GetOptionalArgOrDefault(argIdx, defaultValue)
|
if err := a.Set(s); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
v := a.GetOptionalArg(argIdx)
|
||||||
if v != expectedValue {
|
if v != expectedValue {
|
||||||
t.Fatalf("unexpected value; got %q; want %q", v, expectedValue)
|
t.Fatalf("unexpected value; got %q; want %q", v, expectedValue)
|
||||||
}
|
}
|
||||||
|
@ -186,7 +201,9 @@ func TestArrayDuration_String(t *testing.T) {
|
||||||
f := func(s string) {
|
f := func(s string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayDuration
|
var a ArrayDuration
|
||||||
_ = a.Set(s)
|
if err := a.Set(s); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
result := a.String()
|
result := a.String()
|
||||||
if result != s {
|
if result != s {
|
||||||
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
||||||
|
@ -207,24 +224,29 @@ func TestArrayBool(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayBool_Set(t *testing.T) {
|
func TestArrayBool_Set(t *testing.T) {
|
||||||
f := func(s string, expectedValues []bool) {
|
f := func(s, expectedResult string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayBool
|
var a ArrayBool
|
||||||
_ = a.Set(s)
|
if err := a.Set(s); err != nil {
|
||||||
if !reflect.DeepEqual([]bool(a), expectedValues) {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected values parsed;\ngot\n%v\nwant\n%v", a, expectedValues)
|
}
|
||||||
|
result := a.String()
|
||||||
|
if result != expectedResult {
|
||||||
|
t.Fatalf("unexpected values parsed;\ngot\n%v\nwant\n%v", result, expectedResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("", nil)
|
f("", "")
|
||||||
f(`true`, []bool{true})
|
f(`true`, `true`)
|
||||||
f(`false,True,False`, []bool{false, true, false})
|
f(`false,True,False`, `false,true,false`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayBool_GetOptionalArg(t *testing.T) {
|
func TestArrayBool_GetOptionalArg(t *testing.T) {
|
||||||
f := func(s string, argIdx int, expectedValue bool) {
|
f := func(s string, argIdx int, expectedValue bool) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayBool
|
var a ArrayBool
|
||||||
_ = a.Set(s)
|
if err := a.Set(s); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
v := a.GetOptionalArg(argIdx)
|
v := a.GetOptionalArg(argIdx)
|
||||||
if v != expectedValue {
|
if v != expectedValue {
|
||||||
t.Fatalf("unexpected value; got %v; want %v", v, expectedValue)
|
t.Fatalf("unexpected value; got %v; want %v", v, expectedValue)
|
||||||
|
@ -240,7 +262,9 @@ func TestArrayBool_String(t *testing.T) {
|
||||||
f := func(s string) {
|
f := func(s string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayBool
|
var a ArrayBool
|
||||||
_ = a.Set(s)
|
if err := a.Set(s); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
result := a.String()
|
result := a.String()
|
||||||
if result != s {
|
if result != s {
|
||||||
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
||||||
|
@ -253,32 +277,40 @@ func TestArrayBool_String(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayInt(t *testing.T) {
|
func TestArrayInt(t *testing.T) {
|
||||||
expected := ArrayInt{1, 2, 3}
|
expected := ArrayInt{
|
||||||
|
a: []int{1, 2, 3},
|
||||||
|
}
|
||||||
if !reflect.DeepEqual(expected, fooFlagInt) {
|
if !reflect.DeepEqual(expected, fooFlagInt) {
|
||||||
t.Fatalf("unexpected flag values; got\n%d\nwant\n%d", fooFlagInt, expected)
|
t.Fatalf("unexpected flag values; got\n%d\nwant\n%d", fooFlagInt, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayInt_Set(t *testing.T) {
|
func TestArrayInt_Set(t *testing.T) {
|
||||||
f := func(s string, expectedValues []int) {
|
f := func(s, expectedResult string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayInt
|
var a ArrayInt
|
||||||
_ = a.Set(s)
|
if err := a.Set(s); err != nil {
|
||||||
if !reflect.DeepEqual([]int(a), expectedValues) {
|
t.Fatalf("unexpected error: %s", err)
|
||||||
t.Fatalf("unexpected values parsed;\ngot\n%q\nwant\n%q", a, expectedValues)
|
}
|
||||||
|
result := a.String()
|
||||||
|
if result != expectedResult {
|
||||||
|
t.Fatalf("unexpected values parsed;\ngot\n%q\nwant\n%q", result, expectedResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("", nil)
|
f("", "")
|
||||||
f(`1`, []int{1})
|
f(`1`, `1`)
|
||||||
f(`-2,3,-64`, []int{-2, 3, -64})
|
f(`-2,3,-64`, `-2,3,-64`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayInt_GetOptionalArg(t *testing.T) {
|
func TestArrayInt_GetOptionalArg(t *testing.T) {
|
||||||
f := func(s string, argIdx, defaultValue, expectedValue int) {
|
f := func(s string, argIdx, defaultValue, expectedValue int) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayInt
|
var a ArrayInt
|
||||||
_ = a.Set(s)
|
a.defaultValue = defaultValue
|
||||||
v := a.GetOptionalArgOrDefault(argIdx, defaultValue)
|
if err := a.Set(s); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
v := a.GetOptionalArg(argIdx)
|
||||||
if v != expectedValue {
|
if v != expectedValue {
|
||||||
t.Fatalf("unexpected value; got %d; want %d", v, expectedValue)
|
t.Fatalf("unexpected value; got %d; want %d", v, expectedValue)
|
||||||
}
|
}
|
||||||
|
@ -293,7 +325,9 @@ func TestArrayInt_String(t *testing.T) {
|
||||||
f := func(s string) {
|
f := func(s string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayInt
|
var a ArrayInt
|
||||||
_ = a.Set(s)
|
if err := a.Set(s); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
result := a.String()
|
result := a.String()
|
||||||
if result != s {
|
if result != s {
|
||||||
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
||||||
|
@ -306,8 +340,8 @@ func TestArrayInt_String(t *testing.T) {
|
||||||
|
|
||||||
func TestArrayBytes(t *testing.T) {
|
func TestArrayBytes(t *testing.T) {
|
||||||
expected := []int64{10000000, 23, 10240}
|
expected := []int64{10000000, 23, 10240}
|
||||||
result := make([]int64, len(fooFlagBytes))
|
result := make([]int64, len(fooFlagBytes.a))
|
||||||
for i, b := range fooFlagBytes {
|
for i, b := range fooFlagBytes.a {
|
||||||
result[i] = b.N
|
result[i] = b.N
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(expected, result) {
|
if !reflect.DeepEqual(expected, result) {
|
||||||
|
@ -316,29 +350,31 @@ func TestArrayBytes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayBytes_Set(t *testing.T) {
|
func TestArrayBytes_Set(t *testing.T) {
|
||||||
f := func(s string, expectedValues []int64) {
|
f := func(s, expectedResult string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayBytes
|
var a ArrayBytes
|
||||||
_ = a.Set(s)
|
if err := a.Set(s); err != nil {
|
||||||
values := make([]int64, len(a))
|
t.Fatalf("unexpected error: %s", err)
|
||||||
for i, v := range a {
|
|
||||||
values[i] = v.N
|
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(values, expectedValues) {
|
result := a.String()
|
||||||
t.Fatalf("unexpected values parsed;\ngot\n%d\nwant\n%d", values, expectedValues)
|
if result != expectedResult {
|
||||||
|
t.Fatalf("unexpected values parsed;\ngot\n%s\nwant\n%s", result, expectedResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f("", []int64{})
|
f("", "")
|
||||||
f(`1`, []int64{1})
|
f(`1`, `1`)
|
||||||
f(`-2,3,10kb`, []int64{-2, 3, 10000})
|
f(`-2,3,10kb`, `-2,3,10KB`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayBytes_GetOptionalArg(t *testing.T) {
|
func TestArrayBytes_GetOptionalArg(t *testing.T) {
|
||||||
f := func(s string, argIdx int, defaultValue, expectedValue int64) {
|
f := func(s string, argIdx int, defaultValue, expectedValue int64) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayBytes
|
var a ArrayBytes
|
||||||
_ = a.Set(s)
|
a.defaultValue = defaultValue
|
||||||
v := a.GetOptionalArgOrDefault(argIdx, defaultValue)
|
if err := a.Set(s); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
v := a.GetOptionalArg(argIdx)
|
||||||
if v != expectedValue {
|
if v != expectedValue {
|
||||||
t.Fatalf("unexpected value; got %d; want %d", v, expectedValue)
|
t.Fatalf("unexpected value; got %d; want %d", v, expectedValue)
|
||||||
}
|
}
|
||||||
|
@ -354,7 +390,9 @@ func TestArrayBytes_String(t *testing.T) {
|
||||||
f := func(s string) {
|
f := func(s string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var a ArrayBytes
|
var a ArrayBytes
|
||||||
_ = a.Set(s)
|
if err := a.Set(s); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
result := a.String()
|
result := a.String()
|
||||||
if result != s {
|
if result != s {
|
||||||
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
|
||||||
|
|
Loading…
Reference in a new issue