mirror of
https://github.com/zrepl/zrepl.git
synced 2024-11-25 18:04:58 +01:00
235 lines
5.4 KiB
Go
235 lines
5.4 KiB
Go
|
package endpoint
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"math"
|
||
|
"runtime/debug"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/stretchr/testify/assert"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
|
||
|
"github.com/zrepl/zrepl/zfs"
|
||
|
)
|
||
|
|
||
|
func TestCreateTXGRange(t *testing.T) {
|
||
|
|
||
|
type testCaseExpectation struct {
|
||
|
input uint64
|
||
|
expect bool
|
||
|
}
|
||
|
type testCase struct {
|
||
|
name string
|
||
|
config *CreateTXGRange
|
||
|
configAllowZeroCreateTXG bool
|
||
|
expectInvalid bool
|
||
|
expectString string
|
||
|
expect []testCaseExpectation
|
||
|
}
|
||
|
|
||
|
tcs := []testCase{
|
||
|
{
|
||
|
name: "unbounded",
|
||
|
expectInvalid: false,
|
||
|
config: &CreateTXGRange{
|
||
|
Since: nil,
|
||
|
Until: nil,
|
||
|
},
|
||
|
expectString: "~,~",
|
||
|
expect: []testCaseExpectation{
|
||
|
{0, true},
|
||
|
{math.MaxUint64, true},
|
||
|
{1, true},
|
||
|
{math.MaxUint64 - 1, true},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "wrong order obvious",
|
||
|
expectInvalid: true,
|
||
|
config: &CreateTXGRange{
|
||
|
Since: &CreateTXGRangeBound{23, &zfs.NilBool{B: true}},
|
||
|
Until: &CreateTXGRangeBound{20, &zfs.NilBool{B: true}},
|
||
|
},
|
||
|
expectString: "[23,20]",
|
||
|
},
|
||
|
{
|
||
|
name: "wrong order edge-case could also be empty",
|
||
|
expectInvalid: true,
|
||
|
config: &CreateTXGRange{
|
||
|
Since: &CreateTXGRangeBound{23, &zfs.NilBool{B: false}},
|
||
|
Until: &CreateTXGRangeBound{22, &zfs.NilBool{B: true}},
|
||
|
},
|
||
|
expectString: "(23,22]",
|
||
|
},
|
||
|
{
|
||
|
name: "empty",
|
||
|
expectInvalid: true,
|
||
|
config: &CreateTXGRange{
|
||
|
Since: &CreateTXGRangeBound{2, &zfs.NilBool{B: false}},
|
||
|
Until: &CreateTXGRangeBound{2, &zfs.NilBool{B: false}},
|
||
|
},
|
||
|
expectString: "(2,2)",
|
||
|
},
|
||
|
{
|
||
|
name: "inclusive-since-exclusive-until",
|
||
|
expectInvalid: false,
|
||
|
config: &CreateTXGRange{
|
||
|
Since: &CreateTXGRangeBound{2, &zfs.NilBool{B: true}},
|
||
|
Until: &CreateTXGRangeBound{5, &zfs.NilBool{B: false}},
|
||
|
},
|
||
|
expectString: "[2,5)",
|
||
|
expect: []testCaseExpectation{
|
||
|
{0, false},
|
||
|
{1, false},
|
||
|
{2, true},
|
||
|
{3, true},
|
||
|
{4, true},
|
||
|
{5, false},
|
||
|
{6, false},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "exclusive-since-inclusive-until",
|
||
|
expectInvalid: false,
|
||
|
config: &CreateTXGRange{
|
||
|
Since: &CreateTXGRangeBound{2, &zfs.NilBool{B: false}},
|
||
|
Until: &CreateTXGRangeBound{5, &zfs.NilBool{B: true}},
|
||
|
},
|
||
|
expectString: "(2,5]",
|
||
|
expect: []testCaseExpectation{
|
||
|
{0, false},
|
||
|
{1, false},
|
||
|
{2, false},
|
||
|
{3, true},
|
||
|
{4, true},
|
||
|
{5, true},
|
||
|
{6, false},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "zero-createtxg-not-allowed-because-likely-programmer-error",
|
||
|
expectInvalid: true,
|
||
|
config: &CreateTXGRange{
|
||
|
Since: nil,
|
||
|
Until: &CreateTXGRangeBound{0, &zfs.NilBool{B: true}},
|
||
|
},
|
||
|
expectString: "~,0]",
|
||
|
},
|
||
|
{
|
||
|
name: "half-open-no-until",
|
||
|
expectInvalid: false,
|
||
|
config: &CreateTXGRange{
|
||
|
Since: &CreateTXGRangeBound{2, &zfs.NilBool{B: false}},
|
||
|
Until: nil,
|
||
|
},
|
||
|
expectString: "(2,~",
|
||
|
expect: []testCaseExpectation{
|
||
|
{0, false},
|
||
|
{1, false},
|
||
|
{2, false},
|
||
|
{3, true},
|
||
|
{4, true},
|
||
|
{5, true},
|
||
|
{6, true},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "half-open-no-since",
|
||
|
expectInvalid: false,
|
||
|
config: &CreateTXGRange{
|
||
|
Since: nil,
|
||
|
Until: &CreateTXGRangeBound{4, &zfs.NilBool{B: true}},
|
||
|
},
|
||
|
expectString: "~,4]",
|
||
|
expect: []testCaseExpectation{
|
||
|
{0, true},
|
||
|
{1, true},
|
||
|
{2, true},
|
||
|
{3, true},
|
||
|
{4, true},
|
||
|
{5, false},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "edgeSince",
|
||
|
expectInvalid: false,
|
||
|
config: &CreateTXGRange{
|
||
|
Since: &CreateTXGRangeBound{math.MaxUint64, &zfs.NilBool{B: true}},
|
||
|
Until: nil,
|
||
|
},
|
||
|
expectString: "[18446744073709551615,~",
|
||
|
expect: []testCaseExpectation{
|
||
|
{math.MaxUint64, true},
|
||
|
{math.MaxUint64 - 1, false},
|
||
|
{0, false},
|
||
|
{1, false},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "edgeSinceNegative",
|
||
|
expectInvalid: true,
|
||
|
config: &CreateTXGRange{
|
||
|
Since: &CreateTXGRangeBound{math.MaxUint64, &zfs.NilBool{B: false}},
|
||
|
Until: nil,
|
||
|
},
|
||
|
expectString: "(18446744073709551615,~",
|
||
|
},
|
||
|
{
|
||
|
name: "edgeUntil",
|
||
|
expectInvalid: false,
|
||
|
config: &CreateTXGRange{
|
||
|
Until: &CreateTXGRangeBound{0, &zfs.NilBool{B: true}},
|
||
|
},
|
||
|
configAllowZeroCreateTXG: true,
|
||
|
expectString: "~,0]",
|
||
|
expect: []testCaseExpectation{
|
||
|
{0, true},
|
||
|
{math.MaxUint64, false},
|
||
|
{1, false},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "edgeUntilNegative",
|
||
|
expectInvalid: true,
|
||
|
configAllowZeroCreateTXG: true,
|
||
|
config: &CreateTXGRange{
|
||
|
Until: &CreateTXGRangeBound{0, &zfs.NilBool{B: false}},
|
||
|
},
|
||
|
expectString: "~,0)",
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for _, tc := range tcs {
|
||
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
require.True(t, tc.expectInvalid != (len(tc.expect) > 0), "invalid test config: must either expect invalid or have expectations: %s", tc.name)
|
||
|
require.NotEmpty(t, tc.expectString)
|
||
|
assert.Equal(t, tc.expectString, tc.config.String())
|
||
|
|
||
|
save := createTXGRangeBoundAllowCreateTXG0
|
||
|
createTXGRangeBoundAllowCreateTXG0 = tc.configAllowZeroCreateTXG
|
||
|
defer func() {
|
||
|
createTXGRangeBoundAllowCreateTXG0 = save
|
||
|
}()
|
||
|
|
||
|
if tc.expectInvalid {
|
||
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
assert.Error(t, tc.config.Validate())
|
||
|
})
|
||
|
} else {
|
||
|
for i, e := range tc.expect {
|
||
|
t.Run(fmt.Sprint(i), func(t *testing.T) {
|
||
|
defer func() {
|
||
|
v := recover()
|
||
|
if v != nil {
|
||
|
t.Fatalf("should not panic: %T %v\n%s", v, v, debug.Stack())
|
||
|
}
|
||
|
}()
|
||
|
assert.Equal(t, e.expect, tc.config.Contains(e.input))
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
}
|