Add new graph status in prep for migration
Fault allows us to remove the error tracking from the graph support statuses. This PR is a first step in a small refactor to slim down the status. Following PRs will replace the existing status with the new one.
This commit is contained in:
parent
5593352226
commit
8d52f7655a
25
src/internal/connector/graph/status/operation_string.go
Normal file
25
src/internal/connector/graph/status/operation_string.go
Normal file
@ -0,0 +1,25 @@
|
||||
// Code generated by "stringer -type=Operation"; DO NOT EDIT.
|
||||
|
||||
package status
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[OpUnknown-0]
|
||||
_ = x[Backup-1]
|
||||
_ = x[Restore-2]
|
||||
}
|
||||
|
||||
const _Operation_name = "OpUnknownBackupRestore"
|
||||
|
||||
var _Operation_index = [...]uint8{0, 9, 15, 22}
|
||||
|
||||
func (i Operation) String() string {
|
||||
if i < 0 || i >= Operation(len(_Operation_index)-1) {
|
||||
return "Operation(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _Operation_name[_Operation_index[i]:_Operation_index[i+1]]
|
||||
}
|
||||
104
src/internal/connector/graph/status/status.go
Normal file
104
src/internal/connector/graph/status/status.go
Normal file
@ -0,0 +1,104 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
)
|
||||
|
||||
type Operation int
|
||||
|
||||
//go:generate stringer -type=Operation
|
||||
const (
|
||||
OpUnknown Operation = iota
|
||||
Backup
|
||||
Restore
|
||||
)
|
||||
|
||||
// ConnectorStatus is a data type used to describe the state of the sequence of operations.
|
||||
type ConnectorStatus struct {
|
||||
Metrics Counts
|
||||
|
||||
details string
|
||||
incomplete bool
|
||||
op Operation
|
||||
}
|
||||
|
||||
type Counts struct {
|
||||
Bytes int64
|
||||
Folders, Objects, Successes int
|
||||
}
|
||||
|
||||
func CombineCounts(a, b Counts) Counts {
|
||||
return Counts{
|
||||
Bytes: a.Bytes + b.Bytes,
|
||||
Folders: a.Folders + b.Folders,
|
||||
Objects: a.Objects + b.Objects,
|
||||
Successes: a.Successes + b.Successes,
|
||||
}
|
||||
}
|
||||
|
||||
// Constructor for ConnectorStatus. If the counts do not agree, an error is returned.
|
||||
func New(
|
||||
ctx context.Context,
|
||||
op Operation,
|
||||
cs Counts,
|
||||
details string,
|
||||
incomplete bool,
|
||||
) ConnectorStatus {
|
||||
status := ConnectorStatus{
|
||||
Metrics: cs,
|
||||
details: details,
|
||||
incomplete: incomplete,
|
||||
op: op,
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
|
||||
// Combine aggregates both ConnectorStatus value into a single status.
|
||||
func Combine(one, two ConnectorStatus) ConnectorStatus {
|
||||
if one.op == OpUnknown {
|
||||
return two
|
||||
}
|
||||
|
||||
if two.op == OpUnknown {
|
||||
return one
|
||||
}
|
||||
|
||||
status := ConnectorStatus{
|
||||
Metrics: CombineCounts(one.Metrics, two.Metrics),
|
||||
details: one.details + ", " + two.details,
|
||||
incomplete: one.incomplete || two.incomplete,
|
||||
op: one.op,
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
|
||||
func (cos ConnectorStatus) String() string {
|
||||
var operationStatement string
|
||||
|
||||
switch cos.op {
|
||||
case Backup:
|
||||
operationStatement = "Downloaded from "
|
||||
case Restore:
|
||||
operationStatement = "Restored content to "
|
||||
}
|
||||
|
||||
var incomplete string
|
||||
if cos.incomplete {
|
||||
incomplete = "Incomplete "
|
||||
}
|
||||
|
||||
message := fmt.Sprintf("%sAction: %s performed on %d of %d objects (%s) within %d directories.",
|
||||
incomplete,
|
||||
cos.op.String(),
|
||||
cos.Metrics.Successes,
|
||||
cos.Metrics.Objects,
|
||||
humanize.Bytes(uint64(cos.Metrics.Bytes)),
|
||||
cos.Metrics.Folders)
|
||||
|
||||
return message + " " + operationStatement + cos.details
|
||||
}
|
||||
91
src/internal/connector/graph/status/status_test.go
Normal file
91
src/internal/connector/graph/status/status_test.go
Normal file
@ -0,0 +1,91 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/tester"
|
||||
)
|
||||
|
||||
type StatusUnitSuite struct {
|
||||
tester.Suite
|
||||
}
|
||||
|
||||
func TestGraphConnectorStatus(t *testing.T) {
|
||||
suite.Run(t, &StatusUnitSuite{tester.NewUnitSuite(t)})
|
||||
}
|
||||
|
||||
func (suite *StatusUnitSuite) TestNew() {
|
||||
ctx, flush := tester.NewContext()
|
||||
defer flush()
|
||||
|
||||
result := New(
|
||||
ctx,
|
||||
Backup,
|
||||
Counts{1, 1, 1, 1},
|
||||
"details",
|
||||
true)
|
||||
assert.True(suite.T(), result.incomplete, "status is incomplete")
|
||||
}
|
||||
|
||||
func (suite *StatusUnitSuite) TestMergeStatus() {
|
||||
ctx, flush := tester.NewContext()
|
||||
defer flush()
|
||||
|
||||
table := []struct {
|
||||
name string
|
||||
one ConnectorStatus
|
||||
two ConnectorStatus
|
||||
expectOP Operation
|
||||
expected Counts
|
||||
isIncomplete assert.BoolAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "Test: Status + unknown",
|
||||
one: New(ctx, Backup, Counts{1, 1, 1, 1}, "details", false),
|
||||
two: ConnectorStatus{},
|
||||
expectOP: Backup,
|
||||
expected: Counts{1, 1, 1, 1},
|
||||
isIncomplete: assert.False,
|
||||
},
|
||||
{
|
||||
name: "Test: unknown + Status",
|
||||
one: ConnectorStatus{},
|
||||
two: New(ctx, Backup, Counts{1, 1, 1, 1}, "details", false),
|
||||
expectOP: Backup,
|
||||
expected: Counts{1, 1, 1, 1},
|
||||
isIncomplete: assert.False,
|
||||
},
|
||||
{
|
||||
name: "Test: complete + complete",
|
||||
one: New(ctx, Backup, Counts{1, 1, 3, 0}, "details", false),
|
||||
two: New(ctx, Backup, Counts{3, 3, 3, 0}, "details", false),
|
||||
expectOP: Backup,
|
||||
expected: Counts{4, 4, 6, 0},
|
||||
isIncomplete: assert.False,
|
||||
},
|
||||
{
|
||||
name: "Test: complete + incomplete",
|
||||
one: New(ctx, Restore, Counts{17, 17, 13, 0}, "details", false),
|
||||
two: New(ctx, Restore, Counts{12, 9, 8, 0}, "details", true),
|
||||
expectOP: Restore,
|
||||
expected: Counts{29, 26, 21, 0},
|
||||
isIncomplete: assert.True,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range table {
|
||||
suite.Run(test.name, func() {
|
||||
t := suite.T()
|
||||
result := Combine(test.one, test.two)
|
||||
assert.Equal(t, result.op, test.expectOP)
|
||||
assert.Equal(t, test.expected.Folders, result.Metrics.Folders)
|
||||
assert.Equal(t, test.expected.Objects, result.Metrics.Objects)
|
||||
assert.Equal(t, test.expected.Successes, result.Metrics.Successes)
|
||||
assert.Equal(t, test.expected.Bytes, result.Metrics.Bytes)
|
||||
test.isIncomplete(t, result.incomplete)
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user