Skip to content

Commit

Permalink
Merge pull request #1724 from josephschorr/e2e-flakes
Browse files Browse the repository at this point in the history
HLC Parsing fixes
  • Loading branch information
josephschorr authored Jan 30, 2024
2 parents 3edd286 + 349eb20 commit 395f2c9
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 18 deletions.
10 changes: 8 additions & 2 deletions e2e/newenemy/newenemy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ func checkDataNoNewEnemy(ctx context.Context, t testing.TB, slowNodeID int, crdb
Updates: []*v1.RelationshipUpdate{blockusers[i]},
})
require.NoError(t, err)
t.Log("r1 token: ", r1.WrittenAt.Token)

// sleeping in between the writes seems to let cockroach clear out
// pending transactions in the background and has a better chance
Expand All @@ -373,6 +374,13 @@ func checkDataNoNewEnemy(ctx context.Context, t testing.TB, slowNodeID int, crdb
Updates: []*v1.RelationshipUpdate{allowlists[i]},
})
require.NoError(t, err)
t.Log("r2 token: ", r2.WrittenAt.Token)

z1, _ := zedtoken.DecodeRevision(r1.WrittenAt, revisions.CommonDecoder{Kind: revisions.HybridLogicalClock})
z2, _ := zedtoken.DecodeRevision(r2.WrittenAt, revisions.CommonDecoder{Kind: revisions.HybridLogicalClock})

t.Log("z1 revision: ", z1)
t.Log("z2 revision: ", z2)

canHas, err := spicedb[1].Client().V1().Permissions().CheckPermission(context.Background(), &v1.CheckPermissionRequest{
Consistency: &v1.Consistency{Requirement: &v1.Consistency_AtExactSnapshot{AtExactSnapshot: r2.WrittenAt}},
Expand All @@ -396,8 +404,6 @@ func checkDataNoNewEnemy(ctx context.Context, t testing.TB, slowNodeID int, crdb
ns2AllowlistLeader := getLeaderNodeForNamespace(ctx, crdb[2].Conn(), allowlists[i].Relationship.Subject.Object.ObjectType)

r1leader, r2leader := getLeaderNode(ctx, crdb[2].Conn(), blockusers[i].Relationship), getLeaderNode(ctx, crdb[2].Conn(), allowlists[i].Relationship)
z1, _ := zedtoken.DecodeRevision(r1.WrittenAt, revisions.CommonDecoder{Kind: revisions.HybridLogicalClock})
z2, _ := zedtoken.DecodeRevision(r2.WrittenAt, revisions.CommonDecoder{Kind: revisions.HybridLogicalClock})
t.Log(sleep, z1, z2, z1.GreaterThan(z2), r1leader, r2leader, ns1BlocklistLeader, ns1UserLeader, ns2ResourceLeader, ns2AllowlistLeader)

if z1.GreaterThan(z2) {
Expand Down
2 changes: 1 addition & 1 deletion internal/datastore/crdb/crdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ func readCRDBNow(ctx context.Context, reader pgxcommon.DBFuncQuerier) (datastore
return datastore.NoRevision, fmt.Errorf("unable to read timestamp: %w", err)
}

return revisions.NewForHLC(hlcNow), nil
return revisions.NewForHLC(hlcNow)
}

func readClusterTTLNanos(ctx context.Context, conn pgxcommon.DBFuncQuerier) (int64, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/datastore/crdb/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,5 @@ func updateCounter(ctx context.Context, tx pgx.Tx, change int64) (datastore.Revi
return datastore.NoRevision, fmt.Errorf("unable to executed upsert counter query: %w", err)
}

return revisions.NewForHLC(timestamp), nil
return revisions.NewForHLC(timestamp)
}
21 changes: 13 additions & 8 deletions internal/datastore/revisions/hlcrevision.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,14 @@ func parseHLCRevisionString(revisionStr string) (datastore.Revision, error) {
return datastore.NoRevision, fmt.Errorf("invalid revision string: %q", revisionStr)
}

logicalclock, err := strconv.ParseInt(pieces[1], 10, 32)
if err != nil {
return datastore.NoRevision, fmt.Errorf("invalid revision string: %q", revisionStr)
if len(pieces[1]) > logicalClockLength {
return datastore.NoRevision, spiceerrors.MustBugf("invalid revision string due to unexpected logical clock size (%d): %q", len(pieces[1]), revisionStr)
}

if len(pieces[1]) != logicalClockLength {
return datastore.NoRevision, spiceerrors.MustBugf("invalid revision string due to unexpected logical clock size (%d): %q", len(pieces[1]), revisionStr)
paddedLogicalClockStr := pieces[1] + strings.Repeat("0", logicalClockLength-len(pieces[1]))
logicalclock, err := strconv.ParseInt(paddedLogicalClockStr, 10, 32)
if err != nil {
return datastore.NoRevision, fmt.Errorf("invalid revision string: %q", revisionStr)
}

return HLCRevision{timestamp, uint32(logicalclock) + logicalClockOffset}, nil
Expand All @@ -73,9 +74,13 @@ func HLCRevisionFromString(revisionStr string) (HLCRevision, error) {
}

// NewForHLC creates a new revision for the given hybrid logical clock.
func NewForHLC(decimal decimal.Decimal) HLCRevision {
rev, _ := HLCRevisionFromString(decimal.String())
return rev
func NewForHLC(decimal decimal.Decimal) (HLCRevision, error) {
rev, err := HLCRevisionFromString(decimal.String())
if err != nil {
return zeroHLC, fmt.Errorf("invalid HLC decimal: %v (%s) => %w", decimal, decimal.String(), err)
}

return rev, nil
}

// NewHLCForTime creates a new revision for the given time.
Expand Down
20 changes: 19 additions & 1 deletion internal/datastore/revisions/hlcrevision_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ func TestNewForHLC(t *testing.T) {
"-1",
"1.0000000023",
"1703283409994227985.0000000004",
"1703283409994227985.0000000040",
"1703283409994227985.0010000000",
}

for _, tc := range tcs {
t.Run(tc, func(t *testing.T) {
d, err := decimal.NewFromString(tc)
require.NoError(t, err)

rev := NewForHLC(d)
rev, err := NewForHLC(d)
require.NoError(t, err)
require.Equal(t, tc, rev.String())
})
}
Expand All @@ -40,6 +43,7 @@ func TestTimestampNanoSec(t *testing.T) {
"1.0000000023": 1,
"9223372036854775807.0000000002": 9223372036854775807,
"1703283409994227985.0000000004": 1703283409994227985,
"1703283409994227985.0000000040": 1703283409994227985,
}

for tc, nano := range tcs {
Expand All @@ -62,6 +66,11 @@ func TestInexactFloat64(t *testing.T) {
"1.0000000023": 1.0000000023,
"9223372036854775807.0000000002": 9223372036854775807.0000000002,
"1703283409994227985.0000000004": 1703283409994227985.0000000004,
"1703283409994227985.0000000040": 1703283409994227985.000000004,
"1703283409994227985.000000004": 1703283409994227985.000000004,
"1703283409994227985.0010": 1703283409994227985.001,
"1703283409994227985.0010000000": 1703283409994227985.001,
"1703283409994227985.001": 1703283409994227985.001,
}

for tc, floatValue := range tcs {
Expand Down Expand Up @@ -116,6 +125,15 @@ func TestHLCKeyEquals(t *testing.T) {
{
"1703283409994227985.0000000005", "1703283409994227985.0000000005", true,
},
{
"1703283409994227985.0000000050", "1703283409994227985.0000000050", true,
},
{
"1703283409994227985.0000000050", "1703283409994227985.0000000005", false,
},
{
"1703283409994227985.000000005", "1703283409994227985.0000000050", true,
},
}

for _, tc := range tcs {
Expand Down
22 changes: 17 additions & 5 deletions pkg/zedtoken/zedtoken_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,16 @@ var hlcDecodeTests = []struct {
expectError bool
}{
{
format: "V1 ZedToken",
token: "CAIaFQoTMTYyMTUzODE4OTAyODkyODAwMA==",
expectedRevision: revisions.NewForHLC(decimal.NewFromInt(1621538189028928000)),
expectError: false,
format: "V1 ZedToken",
token: "CAIaFQoTMTYyMTUzODE4OTAyODkyODAwMA==",
expectedRevision: func() datastore.Revision {
r, err := revisions.NewForHLC(decimal.NewFromInt(1621538189028928000))
if err != nil {
panic(err)
}
return r
}(),
expectError: false,
},
{
format: "V1 ZedToken",
Expand All @@ -179,7 +185,13 @@ var hlcDecodeTests = []struct {
if err != nil {
panic(err)
}
return revisions.NewForHLC(v)

r, err := revisions.NewForHLC(v)
if err != nil {
panic(err)
}

return r
})(),
expectError: false,
},
Expand Down

0 comments on commit 395f2c9

Please sign in to comment.