mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 11:08:10 +00:00
add regeneration intent log (#26354)
This commit is contained in:
@@ -1175,6 +1175,32 @@ func (c *Core) setupActivityLogLocked(ctx context.Context, wg *sync.WaitGroup) e
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *ActivityLog) createRegenerationIntentLog(ctx context.Context, now time.Time) (*ActivityIntentLog, error) {
|
||||||
|
intentLog := &ActivityIntentLog{}
|
||||||
|
segments, err := a.availableLogs(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error fetching available logs: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, segment := range segments {
|
||||||
|
if timeutil.IsCurrentMonth(segment, now) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
intentLog.PreviousMonth = segment.Unix()
|
||||||
|
if i > 0 {
|
||||||
|
intentLog.NextMonth = segments[i-1].Unix()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if intentLog.NextMonth == 0 || intentLog.PreviousMonth == 0 {
|
||||||
|
return nil, fmt.Errorf("insufficient data to create a regeneration intent log")
|
||||||
|
}
|
||||||
|
|
||||||
|
return intentLog, nil
|
||||||
|
}
|
||||||
|
|
||||||
// stopActivityLogLocked removes the ActivityLog from Core
|
// stopActivityLogLocked removes the ActivityLog from Core
|
||||||
// and frees any resources.
|
// and frees any resources.
|
||||||
// this function should be called with activityLogLock
|
// this function should be called with activityLogLock
|
||||||
|
|||||||
@@ -662,6 +662,102 @@ func TestActivityLog_availableLogs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestActivityLog_createRegenerationIntentLog tests that we can correctly create a regeneration intent log given the segments in storage
|
||||||
|
func TestActivityLog_createRegenerationIntentLog(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
times []time.Time
|
||||||
|
expectedLog *ActivityIntentLog
|
||||||
|
expectedError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"no segments",
|
||||||
|
[]time.Time{},
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"one segment",
|
||||||
|
[]time.Time{
|
||||||
|
time.Date(2024, 4, 4, 10, 54, 12, 0, time.UTC),
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"most recent segment is 3 months ago",
|
||||||
|
[]time.Time{
|
||||||
|
time.Date(2024, 1, 4, 10, 54, 12, 0, time.UTC),
|
||||||
|
time.Date(2024, 1, 3, 10, 54, 12, 0, time.UTC),
|
||||||
|
},
|
||||||
|
&ActivityIntentLog{NextMonth: 1704365652, PreviousMonth: 1704279252},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lots of segments",
|
||||||
|
[]time.Time{
|
||||||
|
// two this month
|
||||||
|
time.Date(2024, 4, 4, 10, 54, 12, 0, time.UTC),
|
||||||
|
time.Date(2024, 4, 6, 10, 54, 12, 0, time.UTC),
|
||||||
|
// three last month
|
||||||
|
time.Date(2024, 3, 3, 10, 54, 12, 0, time.UTC),
|
||||||
|
time.Date(2024, 3, 6, 10, 54, 12, 0, time.UTC),
|
||||||
|
time.Date(2024, 3, 14, 10, 54, 12, 0, time.UTC),
|
||||||
|
// two the month before that
|
||||||
|
time.Date(2024, 2, 10, 10, 54, 12, 0, time.UTC),
|
||||||
|
time.Date(2024, 2, 17, 10, 54, 12, 0, time.UTC),
|
||||||
|
},
|
||||||
|
&ActivityIntentLog{NextMonth: 1712228052, PreviousMonth: 1710413652},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
core, _, _ := TestCoreUnsealed(t)
|
||||||
|
a := core.activityLog
|
||||||
|
now := time.Date(2024, 4, 10, 10, 54, 12, 0, time.UTC)
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
deletePaths := make([]string, 0)
|
||||||
|
|
||||||
|
// insert the times we're given
|
||||||
|
paths := make([]string, 0, len(tc.times))
|
||||||
|
for _, tm := range tc.times {
|
||||||
|
paths = append(paths, fmt.Sprintf("entity/%d/1", tm.Unix()))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, subPath := range paths {
|
||||||
|
fullPath := ActivityLogPrefix + subPath
|
||||||
|
WriteToStorage(t, core, fullPath, []byte("test"))
|
||||||
|
deletePaths = append(deletePaths, fullPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// regenerate the log
|
||||||
|
intentLog, err := a.createRegenerationIntentLog(context.Background(), now)
|
||||||
|
if tc.expectedError && err == nil {
|
||||||
|
t.Fatal("expected an error and got none")
|
||||||
|
}
|
||||||
|
if !tc.expectedError && err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify it's what we expect
|
||||||
|
if diff := deep.Equal(intentLog, tc.expectedLog); len(diff) != 0 {
|
||||||
|
t.Errorf("got=%v, expected=%v, diff=%v", intentLog, tc.expectedLog, diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete everything we wrote so the next test starts fresh
|
||||||
|
for _, p := range deletePaths {
|
||||||
|
err := core.barrier.Delete(ctx, p)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestActivityLog_MultipleFragmentsAndSegments adds 4000 clients to a fragment
|
// TestActivityLog_MultipleFragmentsAndSegments adds 4000 clients to a fragment
|
||||||
// and saves it and reads it. The test then adds 4000 more clients and calls
|
// and saves it and reads it. The test then adds 4000 more clients and calls
|
||||||
// receivedFragment with 200 more entities. The current segment is saved to
|
// receivedFragment with 200 more entities. The current segment is saved to
|
||||||
|
|||||||
Reference in New Issue
Block a user