blob: cb48d8ff02c13c9853bccf5326098edb5ad1d63e [file]
// Copyright 2022 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package verify
import (
"fmt"
"os"
"strings"
)
const envVerify = "ETCD_VERIFY"
type VerificationType string
const (
envVerifyValueAll VerificationType = "all"
envVerifyValueAssert VerificationType = "assert"
)
func getEnvVerify() string {
return strings.ToLower(os.Getenv(envVerify))
}
func IsVerificationEnabled(verification VerificationType) bool {
env := getEnvVerify()
return env == string(envVerifyValueAll) || env == strings.ToLower(string(verification))
}
// EnableVerifications sets `envVerify` and returns a function that
// can be used to bring the original settings.
func EnableVerifications(verification VerificationType) func() {
previousEnv := getEnvVerify()
os.Setenv(envVerify, string(verification))
return func() {
os.Setenv(envVerify, previousEnv)
}
}
// EnableAllVerifications enables verification and returns a function
// that can be used to bring the original settings.
func EnableAllVerifications() func() {
return EnableVerifications(envVerifyValueAll)
}
// DisableVerifications unsets `envVerify` and returns a function that
// can be used to bring the original settings.
func DisableVerifications() func() {
previousEnv := getEnvVerify()
os.Unsetenv(envVerify)
return func() {
os.Setenv(envVerify, previousEnv)
}
}
// Verify performs verification if the assertions are enabled.
// In the default setup running in tests and skipped in the production code.
func Verify(msg string, f VerifyFunc) {
if IsVerificationEnabled(envVerifyValueAssert) {
ok, details := f()
verifier(ok, msg, details)
}
}
type VerifyFunc func() (condition bool, details map[string]any)
func verifier(condition bool, msg string, details map[string]any) {
if !condition {
panic(fmt.Sprintf("%s. details: %v.", msg, details))
}
}
// Assert will panic with a given formatted message if the given condition is false.
func Assert(condition bool, msg string, v ...any) {
if !condition {
panic(fmt.Sprintf("assertion failed: "+msg, v...))
}
}