Test release wiring by its effective behavior
This commit is contained in:
@@ -7,6 +7,8 @@ import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
@@ -19,10 +21,13 @@ if [[ ${RELEASEKIT_BOOTSTRAP_STATUS:-0} != 0 ]]; then
|
||||
fi
|
||||
output=
|
||||
while (($#)); do
|
||||
if [[ $1 == -o ]]; then
|
||||
case $1 in
|
||||
-o)
|
||||
shift
|
||||
output=${1:?missing output path}
|
||||
fi
|
||||
;;
|
||||
-o=*) output=${1#-o=} ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
[[ -n $output ]]
|
||||
@@ -36,8 +41,8 @@ chmod +x "$output"
|
||||
`
|
||||
|
||||
func TestReleaseWrapperForwardsNativeArgumentsAndStatus(t *testing.T) {
|
||||
for _, toolStatus := range []string{"0", "3"} {
|
||||
t.Run("status "+toolStatus, func(t *testing.T) {
|
||||
for _, toolStatus := range []int{0, 3} {
|
||||
t.Run("status "+strconv.Itoa(toolStatus), func(t *testing.T) {
|
||||
layout := newReleaseTestLayout(t)
|
||||
args := []string{"publish", "v4.2.0", "argument with spaces"}
|
||||
cmd := exec.Command("bash", append([]string{layout.wrapper}, args...)...)
|
||||
@@ -45,11 +50,11 @@ func TestReleaseWrapperForwardsNativeArgumentsAndStatus(t *testing.T) {
|
||||
cmd.Env = layout.environment(map[string]string{
|
||||
"RELEASEKIT_ARGS_LOG": layout.argsLog,
|
||||
"RELEASEKIT_BUILD_LOG": layout.buildLog,
|
||||
"RELEASEKIT_TOOL_STATUS": toolStatus,
|
||||
"RELEASEKIT_TOOL_STATUS": strconv.Itoa(toolStatus),
|
||||
})
|
||||
output, err := cmd.CombinedOutput()
|
||||
if got := commandStatus(err); got != toolStatusInt(toolStatus) {
|
||||
t.Fatalf("exit=%d, want %s; output=%q, error=%v", got, toolStatus, output, err)
|
||||
if got := commandStatus(err); got != toolStatus {
|
||||
t.Fatalf("exit=%d, want %d; output=%q, error=%v", got, toolStatus, output, err)
|
||||
}
|
||||
if len(output) != 0 {
|
||||
t.Fatalf("unexpected output: %q", output)
|
||||
@@ -63,11 +68,11 @@ func TestReleaseWrapperForwardsNativeArgumentsAndStatus(t *testing.T) {
|
||||
t.Fatalf("build environment=%q", buildInvocation[1:3])
|
||||
}
|
||||
buildArgs := buildInvocation[3:]
|
||||
if buildArgs[0] != "build" || !containsArgument(buildArgs, "-mod=readonly") || !containsArgument(buildArgs, "gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit") {
|
||||
if buildArgs[0] != "build" || !slices.Contains(buildArgs, "-mod=readonly") || !slices.Contains(buildArgs, "gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit") {
|
||||
t.Fatalf("unexpected build arguments: %q", buildArgs)
|
||||
}
|
||||
if !hasAdjacentArguments(buildArgs, "-o", "./bin/releasekit") {
|
||||
t.Fatalf("build output was not selected: %q", buildArgs)
|
||||
if info, err := os.Stat(filepath.Join(layout.repo, "bin", "releasekit")); err != nil || !info.Mode().IsRegular() {
|
||||
t.Fatalf("ReleaseKit executable was not built in bin: %v", err)
|
||||
}
|
||||
|
||||
toolInvocation := readNULArguments(t, layout.argsLog)
|
||||
@@ -106,9 +111,6 @@ func TestReleaseKitProfileDeclaresProductAndDeliverySettings(t *testing.T) {
|
||||
if err := json.Unmarshal(data, &raw); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, exists := raw["checks"]; exists {
|
||||
t.Fatal("profile must not define additional checks")
|
||||
}
|
||||
var deliveryFields map[string]json.RawMessage
|
||||
if err := json.Unmarshal(raw["delivery"], &deliveryFields); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -117,8 +119,9 @@ func TestReleaseKitProfileDeclaresProductAndDeliverySettings(t *testing.T) {
|
||||
t.Fatal("profile must not contain a credential value")
|
||||
}
|
||||
var profile struct {
|
||||
Product string `json:"product"`
|
||||
Remote string `json:"remote"`
|
||||
Product string `json:"product"`
|
||||
Remote string `json:"remote"`
|
||||
Checks []json.RawMessage `json:"checks"`
|
||||
Build struct {
|
||||
MainPackage string `json:"main_package"`
|
||||
BinaryName string `json:"binary_name"`
|
||||
@@ -134,6 +137,9 @@ func TestReleaseKitProfileDeclaresProductAndDeliverySettings(t *testing.T) {
|
||||
if err := json.Unmarshal(data, &profile); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(profile.Checks) != 0 {
|
||||
t.Fatal("profile must not define additional checks")
|
||||
}
|
||||
if profile.Product != "Audita" || profile.Remote != "origin" {
|
||||
t.Fatalf("product=%q remote=%q", profile.Product, profile.Remote)
|
||||
}
|
||||
@@ -211,7 +217,7 @@ func (layout releaseTestLayout) environment(values map[string]string) []string {
|
||||
filtered := make([]string, 0, len(os.Environ())+len(values)+1)
|
||||
for _, value := range os.Environ() {
|
||||
key, _, _ := strings.Cut(value, "=")
|
||||
if key == "PATH" || hasKey(values, key) {
|
||||
if _, overridden := values[key]; key == "PATH" || overridden {
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, value)
|
||||
@@ -253,31 +259,6 @@ func commandStatus(err error) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
func toolStatusInt(value string) int {
|
||||
if value == "3" {
|
||||
return 3
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func containsArgument(args []string, want string) bool {
|
||||
for _, arg := range args {
|
||||
if arg == want {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func hasAdjacentArguments(args []string, first, second string) bool {
|
||||
for i := 0; i+1 < len(args); i++ {
|
||||
if args[i] == first && args[i+1] == second {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func sameMembers(got, want []string) bool {
|
||||
gotSet := make(map[string]struct{}, len(got))
|
||||
for _, value := range got {
|
||||
@@ -289,8 +270,3 @@ func sameMembers(got, want []string) bool {
|
||||
}
|
||||
return maps.Equal(gotSet, wantSet)
|
||||
}
|
||||
|
||||
func hasKey(values map[string]string, key string) bool {
|
||||
_, exists := values[key]
|
||||
return exists
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user