blob: 51b53cfc14a41d8963d5559e663896e27b92fcd6 [file] [log] [blame]
// Copyright 2022 The LUCI 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 runs
import (
"context"
"time"
"cloud.google.com/go/spanner"
"go.chromium.org/luci/server/span"
"go.chromium.org/luci/analysis/internal/testutil"
)
const testProject = "myproject"
// RunBuilder provides methods to build a reclustering run
// for testing.
type RunBuilder struct {
run *ReclusteringRun
progressSet bool
}
// NewRun starts building a new Run, for testing.
func NewRun(uniqifier int) *RunBuilder {
run := &ReclusteringRun{
Project: testProject,
AttemptTimestamp: time.Date(2010, time.January, 1, 1, 0, 0, uniqifier, time.UTC),
AlgorithmsVersion: int64(uniqifier + 1),
ConfigVersion: time.Date(2011, time.January, 1, 1, 0, 0, uniqifier, time.UTC),
RulesVersion: time.Date(2012, time.January, 1, 1, 0, 0, uniqifier, time.UTC),
ShardCount: int64(uniqifier + 1),
ShardsReported: int64(uniqifier / 2),
Progress: int64(uniqifier) * 500,
}
return &RunBuilder{
run: run,
}
}
// WithProject specifies the project to use on the run.
func (b *RunBuilder) WithProject(project string) *RunBuilder {
b.run.Project = project
return b
}
// WithAttemptTimestamp specifies the attempt timestamp to use on the run.
func (b *RunBuilder) WithAttemptTimestamp(attemptTimestamp time.Time) *RunBuilder {
b.run.AttemptTimestamp = attemptTimestamp
return b
}
// WithRulesVersion specifies the rules version to use on the run.
func (b *RunBuilder) WithRulesVersion(value time.Time) *RunBuilder {
b.run.RulesVersion = value
return b
}
// WithRulesVersion specifies the config version to use on the run.
func (b *RunBuilder) WithConfigVersion(value time.Time) *RunBuilder {
b.run.ConfigVersion = value
return b
}
// WithAlgorithmsVersion specifies the algorithms version to use on the run.
func (b *RunBuilder) WithAlgorithmsVersion(value int64) *RunBuilder {
b.run.AlgorithmsVersion = value
return b
}
// WithShardCount specifies the number of shards to use on the run.
func (b *RunBuilder) WithShardCount(count int64) *RunBuilder {
if b.progressSet {
panic("Call WithShardCount before setting progress")
}
b.run.ShardCount = count
b.run.Progress = count * 500
return b
}
// WithNoProgress sets that no shards reported and no progress has been made.
func (b *RunBuilder) WithNoReportedProgress() *RunBuilder {
b.run.ShardsReported = 0
b.run.Progress = 0
b.progressSet = true
return b
}
// WithReportedProgress sets that all shards have reported, and some progress
// has been made. (progress is a value out of 1000 that is scaled to the
// number of shards).
func (b *RunBuilder) WithReportedProgress(progress int) *RunBuilder {
b.run.ShardsReported = b.run.ShardCount
b.run.Progress = b.run.ShardCount * int64(progress)
b.progressSet = true
return b
}
// WithCompletedProgress sets that all shards have reported, and the run
// has completed.
func (b *RunBuilder) WithCompletedProgress() *RunBuilder {
b.run.ShardsReported = b.run.ShardCount
b.run.Progress = b.run.ShardCount * 1000
b.progressSet = true
return b
}
func (b *RunBuilder) Build() *ReclusteringRun {
return b.run
}
// SetRunsForTesting replaces the set of stored runs to match the given set.
func SetRunsForTesting(ctx context.Context, rs []*ReclusteringRun) error {
testutil.MustApply(ctx,
spanner.Delete("ReclusteringRuns", spanner.AllKeys()))
// Insert some ReclusteringRuns.
_, err := span.ReadWriteTransaction(ctx, func(ctx context.Context) error {
for _, r := range rs {
if err := Create(ctx, r); err != nil {
return err
}
}
return nil
})
return err
}