WIP ACLTree tests
This commit is contained in:
parent
8372abb4e1
commit
b07a137fb9
@ -1,231 +0,0 @@
|
||||
package acltree
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/aclchanges/pb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/testutils/threadbuilder"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/thread"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type ACLContext struct {
|
||||
Tree *Tree
|
||||
ACLState *ACLState
|
||||
}
|
||||
|
||||
func createTreeFromThread(t thread.Thread, fromStart bool) (*Tree, error) {
|
||||
treeBuilder := newTreeBuilder(t, keys.NewEd25519Decoder())
|
||||
treeBuilder.Init()
|
||||
return treeBuilder.Build(fromStart)
|
||||
}
|
||||
|
||||
func createACLStateFromThread(
|
||||
t thread.Thread,
|
||||
identity string,
|
||||
key keys.EncryptionPrivKey,
|
||||
decoder keys.SigningPubKeyDecoder,
|
||||
fromStart bool) (*ACLContext, error) {
|
||||
tree, err := createTreeFromThread(t, fromStart)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
accountData := &account.AccountData{
|
||||
Identity: identity,
|
||||
EncKey: key,
|
||||
}
|
||||
|
||||
aclTreeBuilder := newACLTreeBuilder(t, decoder)
|
||||
aclTreeBuilder.Init()
|
||||
aclTree, err := aclTreeBuilder.Build()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !fromStart {
|
||||
snapshotValidator := newSnapshotValidator(decoder, accountData)
|
||||
snapshotValidator.Init(aclTree)
|
||||
valid, err := snapshotValidator.ValidateSnapshot(tree.root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !valid {
|
||||
// TODO: think about what to do if the snapshot is invalid - should we rebuild the Tree without it
|
||||
return createACLStateFromThread(t, identity, key, decoder, true)
|
||||
}
|
||||
}
|
||||
|
||||
aclBuilder := newACLStateBuilder(decoder, accountData)
|
||||
err = aclBuilder.Init(tree)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aclState, err := aclBuilder.Build()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ACLContext{
|
||||
Tree: tree,
|
||||
ACLState: aclState,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func TestACLStateBuilder_UserJoinBuild(t *testing.T) {
|
||||
thread, err := threadbuilder.NewThreadBuilderFromFile("threadbuilder/userjoinexample.yml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
keychain := thread.GetKeychain()
|
||||
ctx, err := createACLStateFromThread(
|
||||
thread,
|
||||
keychain.GetIdentity("A"),
|
||||
keychain.EncryptionKeys["A"],
|
||||
keys.NewEd25519Decoder(),
|
||||
false)
|
||||
if err != nil {
|
||||
t.Fatalf("should Build acl ACLState without err: %v", err)
|
||||
}
|
||||
aclState := ctx.ACLState
|
||||
//fmt.Println(ctx.Tree.Graph())
|
||||
aId := keychain.GeneratedIdentities["A"]
|
||||
bId := keychain.GeneratedIdentities["B"]
|
||||
cId := keychain.GeneratedIdentities["C"]
|
||||
|
||||
assert.Equal(t, aclState.identity, aId)
|
||||
assert.Equal(t, aclState.userStates[aId].Permissions, pb.ACLChange_Admin)
|
||||
assert.Equal(t, aclState.userStates[bId].Permissions, pb.ACLChange_Writer)
|
||||
assert.Equal(t, aclState.userStates[cId].Permissions, pb.ACLChange_Reader)
|
||||
|
||||
var changeIds []string
|
||||
ctx.Tree.Iterate(ctx.Tree.root.Id, func(c *Change) (isContinue bool) {
|
||||
changeIds = append(changeIds, c.Id)
|
||||
return true
|
||||
})
|
||||
assert.Equal(t, changeIds, []string{"A.1.1", "A.1.2", "B.1.1", "B.1.2"})
|
||||
}
|
||||
|
||||
func TestACLStateBuilder_UserRemoveBuild(t *testing.T) {
|
||||
thread, err := threadbuilder.NewThreadBuilderFromFile("threadbuilder/userremoveexample.yml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
keychain := thread.GetKeychain()
|
||||
ctx, err := createACLStateFromThread(
|
||||
thread,
|
||||
keychain.GetIdentity("A"),
|
||||
keychain.EncryptionKeys["A"],
|
||||
keys.NewEd25519Decoder(),
|
||||
false)
|
||||
if err != nil {
|
||||
t.Fatalf("should Build acl ACLState without err: %v", err)
|
||||
}
|
||||
aclState := ctx.ACLState
|
||||
//fmt.Println(ctx.Tree.Graph())
|
||||
aId := keychain.GeneratedIdentities["A"]
|
||||
|
||||
assert.Equal(t, aclState.identity, aId)
|
||||
assert.Equal(t, aclState.userStates[aId].Permissions, pb.ACLChange_Admin)
|
||||
|
||||
var changeIds []string
|
||||
ctx.Tree.Iterate(ctx.Tree.root.Id, func(c *Change) (isContinue bool) {
|
||||
changeIds = append(changeIds, c.Id)
|
||||
return true
|
||||
})
|
||||
assert.Equal(t, changeIds, []string{"A.1.1", "A.1.2", "B.1.1", "A.1.3", "A.1.4"})
|
||||
}
|
||||
|
||||
func TestACLStateBuilder_UserRemoveBeforeBuild(t *testing.T) {
|
||||
thread, err := threadbuilder.NewThreadBuilderFromFile("threadbuilder/userremovebeforeexample.yml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
keychain := thread.GetKeychain()
|
||||
ctx, err := createACLStateFromThread(
|
||||
thread,
|
||||
keychain.GetIdentity("A"),
|
||||
keychain.EncryptionKeys["A"],
|
||||
keys.NewEd25519Decoder(),
|
||||
false)
|
||||
if err != nil {
|
||||
t.Fatalf("should Build acl ACLState without err: %v", err)
|
||||
}
|
||||
aclState := ctx.ACLState
|
||||
//fmt.Println(ctx.Tree.Graph())
|
||||
for _, s := range []string{"A", "C", "E"} {
|
||||
assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, pb.ACLChange_Admin)
|
||||
}
|
||||
assert.Equal(t, aclState.identity, keychain.GetIdentity("A"))
|
||||
assert.Nil(t, aclState.userStates[keychain.GetIdentity("B")])
|
||||
|
||||
var changeIds []string
|
||||
ctx.Tree.Iterate(ctx.Tree.root.Id, func(c *Change) (isContinue bool) {
|
||||
changeIds = append(changeIds, c.Id)
|
||||
return true
|
||||
})
|
||||
assert.Equal(t, changeIds, []string{"A.1.1", "B.1.1", "A.1.2", "A.1.3"})
|
||||
}
|
||||
|
||||
func TestACLStateBuilder_InvalidSnapshotBuild(t *testing.T) {
|
||||
thread, err := threadbuilder.NewThreadBuilderFromFile("threadbuilder/invalidsnapshotexample.yml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
keychain := thread.GetKeychain()
|
||||
ctx, err := createACLStateFromThread(
|
||||
thread,
|
||||
keychain.GetIdentity("A"),
|
||||
keychain.EncryptionKeys["A"],
|
||||
keys.NewEd25519Decoder(),
|
||||
false)
|
||||
if err != nil {
|
||||
t.Fatalf("should Build acl ACLState without err: %v", err)
|
||||
}
|
||||
aclState := ctx.ACLState
|
||||
//fmt.Println(ctx.Tree.Graph())
|
||||
for _, s := range []string{"A", "B", "C", "D", "E", "F"} {
|
||||
assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, pb.ACLChange_Admin)
|
||||
}
|
||||
assert.Equal(t, aclState.identity, keychain.GetIdentity("A"))
|
||||
|
||||
var changeIds []string
|
||||
ctx.Tree.Iterate(ctx.Tree.root.Id, func(c *Change) (isContinue bool) {
|
||||
changeIds = append(changeIds, c.Id)
|
||||
return true
|
||||
})
|
||||
assert.Equal(t, []string{"A.1.1", "B.1.1", "A.1.2", "A.1.3", "B.1.2"}, changeIds)
|
||||
}
|
||||
|
||||
func TestACLStateBuilder_ValidSnapshotBuild(t *testing.T) {
|
||||
thread, err := threadbuilder.NewThreadBuilderFromFile("threadbuilder/validsnapshotexample.yml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
keychain := thread.GetKeychain()
|
||||
ctx, err := createACLStateFromThread(
|
||||
thread,
|
||||
keychain.GetIdentity("A"),
|
||||
keychain.EncryptionKeys["A"],
|
||||
keys.NewEd25519Decoder(),
|
||||
false)
|
||||
if err != nil {
|
||||
t.Fatalf("should Build acl ACLState without err: %v", err)
|
||||
}
|
||||
aclState := ctx.ACLState
|
||||
//fmt.Println(ctx.Tree.Graph())
|
||||
for _, s := range []string{"A", "B", "C", "D", "E", "F"} {
|
||||
assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, pb.ACLChange_Admin)
|
||||
}
|
||||
assert.Equal(t, aclState.identity, keychain.GetIdentity("A"))
|
||||
|
||||
var changeIds []string
|
||||
ctx.Tree.Iterate(ctx.Tree.root.Id, func(c *Change) (isContinue bool) {
|
||||
changeIds = append(changeIds, c.Id)
|
||||
return true
|
||||
})
|
||||
assert.Equal(t, []string{"A.1.2", "A.1.3", "B.1.2"}, changeIds)
|
||||
}
|
||||
166
acltree/acltree_test.go
Normal file
166
acltree/acltree_test.go
Normal file
@ -0,0 +1,166 @@
|
||||
package acltree
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/aclchanges/pb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/testutils/threadbuilder"
|
||||
)
|
||||
|
||||
func TestACLTree_UserJoinBuild(t *testing.T) {
|
||||
thr, err := threadbuilder.NewThreadBuilderFromFile("threadbuilder/userjoinexample.yml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
keychain := thr.GetKeychain()
|
||||
accountData := &account.AccountData{
|
||||
Identity: keychain.GetIdentity("A"),
|
||||
SignKey: keychain.SigningKeys["A"],
|
||||
EncKey: keychain.EncryptionKeys["A"],
|
||||
}
|
||||
tree, err := BuildACLTree(thr, accountData)
|
||||
if err != nil {
|
||||
t.Fatalf("should Build acl ACLState without err: %v", err)
|
||||
}
|
||||
aclState := tree.ACLState()
|
||||
//fmt.Println(ctx.Tree.Graph())
|
||||
aId := keychain.GeneratedIdentities["A"]
|
||||
bId := keychain.GeneratedIdentities["B"]
|
||||
cId := keychain.GeneratedIdentities["C"]
|
||||
|
||||
assert.Equal(t, aclState.identity, aId)
|
||||
assert.Equal(t, aclState.userStates[aId].Permissions, pb.ACLChange_Admin)
|
||||
assert.Equal(t, aclState.userStates[bId].Permissions, pb.ACLChange_Writer)
|
||||
assert.Equal(t, aclState.userStates[cId].Permissions, pb.ACLChange_Reader)
|
||||
|
||||
var changeIds []string
|
||||
tree.Iterate(func(c *Change) (isContinue bool) {
|
||||
changeIds = append(changeIds, c.Id)
|
||||
return true
|
||||
})
|
||||
assert.Equal(t, changeIds, []string{"A.1.1", "A.1.2", "B.1.1", "B.1.2"})
|
||||
}
|
||||
|
||||
func TestACLTree_UserRemoveBuild(t *testing.T) {
|
||||
thr, err := threadbuilder.NewThreadBuilderFromFile("threadbuilder/userremoveexample.yml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
keychain := thr.GetKeychain()
|
||||
accountData := &account.AccountData{
|
||||
Identity: keychain.GetIdentity("A"),
|
||||
SignKey: keychain.SigningKeys["A"],
|
||||
EncKey: keychain.EncryptionKeys["A"],
|
||||
}
|
||||
tree, err := BuildACLTree(thr, accountData)
|
||||
if err != nil {
|
||||
t.Fatalf("should Build acl ACLState without err: %v", err)
|
||||
}
|
||||
aclState := tree.ACLState()
|
||||
//fmt.Println(ctx.Tree.Graph())
|
||||
aId := keychain.GeneratedIdentities["A"]
|
||||
|
||||
assert.Equal(t, aclState.identity, aId)
|
||||
assert.Equal(t, aclState.userStates[aId].Permissions, pb.ACLChange_Admin)
|
||||
|
||||
var changeIds []string
|
||||
tree.Iterate(func(c *Change) (isContinue bool) {
|
||||
changeIds = append(changeIds, c.Id)
|
||||
return true
|
||||
})
|
||||
assert.Equal(t, changeIds, []string{"A.1.1", "A.1.2", "B.1.1", "A.1.3", "A.1.4"})
|
||||
}
|
||||
|
||||
func TestACLTree_UserRemoveBeforeBuild(t *testing.T) {
|
||||
thr, err := threadbuilder.NewThreadBuilderFromFile("threadbuilder/userremovebeforeexample.yml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
keychain := thr.GetKeychain()
|
||||
accountData := &account.AccountData{
|
||||
Identity: keychain.GetIdentity("A"),
|
||||
SignKey: keychain.SigningKeys["A"],
|
||||
EncKey: keychain.EncryptionKeys["A"],
|
||||
}
|
||||
tree, err := BuildACLTree(thr, accountData)
|
||||
if err != nil {
|
||||
t.Fatalf("should Build acl ACLState without err: %v", err)
|
||||
}
|
||||
aclState := tree.ACLState()
|
||||
//fmt.Println(ctx.Tree.Graph())
|
||||
for _, s := range []string{"A", "C", "E"} {
|
||||
assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, pb.ACLChange_Admin)
|
||||
}
|
||||
assert.Equal(t, aclState.identity, keychain.GetIdentity("A"))
|
||||
assert.Nil(t, aclState.userStates[keychain.GetIdentity("B")])
|
||||
|
||||
var changeIds []string
|
||||
tree.Iterate(func(c *Change) (isContinue bool) {
|
||||
changeIds = append(changeIds, c.Id)
|
||||
return true
|
||||
})
|
||||
assert.Equal(t, changeIds, []string{"A.1.1", "B.1.1", "A.1.2", "A.1.3"})
|
||||
}
|
||||
|
||||
func TestACLTree_InvalidSnapshotBuild(t *testing.T) {
|
||||
thr, err := threadbuilder.NewThreadBuilderFromFile("threadbuilder/invalidsnapshotexample.yml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
keychain := thr.GetKeychain()
|
||||
accountData := &account.AccountData{
|
||||
Identity: keychain.GetIdentity("A"),
|
||||
SignKey: keychain.SigningKeys["A"],
|
||||
EncKey: keychain.EncryptionKeys["A"],
|
||||
}
|
||||
tree, err := BuildACLTree(thr, accountData)
|
||||
if err != nil {
|
||||
t.Fatalf("should Build acl ACLState without err: %v", err)
|
||||
}
|
||||
aclState := tree.ACLState()
|
||||
//fmt.Println(ctx.Tree.Graph())
|
||||
for _, s := range []string{"A", "B", "C", "D", "E", "F"} {
|
||||
assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, pb.ACLChange_Admin)
|
||||
}
|
||||
assert.Equal(t, aclState.identity, keychain.GetIdentity("A"))
|
||||
|
||||
var changeIds []string
|
||||
tree.Iterate(func(c *Change) (isContinue bool) {
|
||||
changeIds = append(changeIds, c.Id)
|
||||
return true
|
||||
})
|
||||
assert.Equal(t, []string{"A.1.1", "B.1.1", "A.1.2", "A.1.3", "B.1.2"}, changeIds)
|
||||
}
|
||||
|
||||
func TestACLTree_ValidSnapshotBuild(t *testing.T) {
|
||||
thr, err := threadbuilder.NewThreadBuilderFromFile("threadbuilder/validsnapshotexample.yml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
keychain := thr.GetKeychain()
|
||||
accountData := &account.AccountData{
|
||||
Identity: keychain.GetIdentity("A"),
|
||||
SignKey: keychain.SigningKeys["A"],
|
||||
EncKey: keychain.EncryptionKeys["A"],
|
||||
}
|
||||
tree, err := BuildACLTree(thr, accountData)
|
||||
if err != nil {
|
||||
t.Fatalf("should Build acl ACLState without err: %v", err)
|
||||
}
|
||||
aclState := tree.ACLState()
|
||||
//fmt.Println(ctx.Tree.Graph())
|
||||
for _, s := range []string{"A", "B", "C", "D", "E", "F"} {
|
||||
assert.Equal(t, aclState.userStates[keychain.GetIdentity(s)].Permissions, pb.ACLChange_Admin)
|
||||
}
|
||||
assert.Equal(t, aclState.identity, keychain.GetIdentity("A"))
|
||||
|
||||
var changeIds []string
|
||||
tree.Iterate(func(c *Change) (isContinue bool) {
|
||||
changeIds = append(changeIds, c.Id)
|
||||
return true
|
||||
})
|
||||
assert.Equal(t, []string{"A.1.2", "A.1.3", "B.1.2"}, changeIds)
|
||||
}
|
||||
@ -1,5 +1,11 @@
|
||||
package acltree
|
||||
|
||||
//func createTreeFromThread(t thread.Thread, fromStart bool) (*Tree, error) {
|
||||
// treeBuilder := newTreeBuilder(t, keys.NewEd25519Decoder())
|
||||
// treeBuilder.Init()
|
||||
// return treeBuilder.Build(fromStart)
|
||||
//}
|
||||
//
|
||||
//func TestACLTreeBuilder_UserJoinCorrectHeadsAndLen(t *testing.T) {
|
||||
// thread, err := threadbuilder.NewThreadBuilderFromFile("threadbuilder/userjoinexample.yml")
|
||||
// if err != nil {
|
||||
|
||||
@ -117,7 +117,7 @@ graph:
|
||||
baseSnapshot: A.1.2
|
||||
aclHeads: [A.1.2]
|
||||
treeHeads: [A.1.2]
|
||||
maybeHeads:
|
||||
orphans:
|
||||
- A.1.3
|
||||
- B.1.2
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/aclchanges"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
@ -31,7 +32,7 @@ type ThreadBuilder struct {
|
||||
allChanges map[string]*threadChange
|
||||
updatedChanges map[string]*threadChange
|
||||
heads []string
|
||||
maybeHeads []string
|
||||
orphans []string
|
||||
keychain *Keychain
|
||||
}
|
||||
|
||||
@ -109,8 +110,8 @@ func (t *ThreadBuilder) AddRawChange(change *thread.RawChange) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *ThreadBuilder) AddOrphans(head string) {
|
||||
t.maybeHeads = append(t.maybeHeads, head)
|
||||
func (t *ThreadBuilder) AddOrphans(orphans ...string) {
|
||||
t.orphans = append(t.orphans, orphans...)
|
||||
}
|
||||
|
||||
func (t *ThreadBuilder) AddChange(change aclchanges.Change) error {
|
||||
@ -141,12 +142,7 @@ func (t *ThreadBuilder) AddChange(change aclchanges.Change) error {
|
||||
}
|
||||
|
||||
func (t *ThreadBuilder) Orphans() []string {
|
||||
return t.maybeHeads
|
||||
}
|
||||
|
||||
func (t *ThreadBuilder) SetPossibleHeads(heads []string) {
|
||||
// we should copy here instead of just setting the value
|
||||
t.maybeHeads = heads
|
||||
return t.orphans
|
||||
}
|
||||
|
||||
func (t *ThreadBuilder) SetHeads(heads []string) {
|
||||
@ -154,6 +150,10 @@ func (t *ThreadBuilder) SetHeads(heads []string) {
|
||||
t.heads = heads
|
||||
}
|
||||
|
||||
func (t *ThreadBuilder) RemoveOrphans(orphans ...string) {
|
||||
t.orphans = slice.Difference(t.orphans, orphans)
|
||||
}
|
||||
|
||||
func (t *ThreadBuilder) GetChange(ctx context.Context, recordID string) (*thread.RawChange, error) {
|
||||
return t.getChange(recordID, t.allChanges), nil
|
||||
}
|
||||
@ -214,7 +214,7 @@ func (t *ThreadBuilder) Parse(thread *YMLThread) {
|
||||
}
|
||||
|
||||
t.parseGraph(thread)
|
||||
t.parseHeads(thread)
|
||||
t.parseOrphans(thread)
|
||||
}
|
||||
|
||||
func (t *ThreadBuilder) parseChange(ch *Change) *threadChange {
|
||||
@ -469,8 +469,8 @@ func (t *ThreadBuilder) convertPermission(perm string) pb.ACLChangeUserPermissio
|
||||
|
||||
func (t *ThreadBuilder) traverseFromHeads(f func(t *threadChange) error) error {
|
||||
uniqMap := map[string]struct{}{}
|
||||
stack := make([]string, len(t.maybeHeads), 10)
|
||||
copy(stack, t.maybeHeads)
|
||||
stack := make([]string, len(t.orphans), 10)
|
||||
copy(stack, t.orphans)
|
||||
for len(stack) > 0 {
|
||||
id := stack[len(stack)-1]
|
||||
stack = stack[:len(stack)-1]
|
||||
@ -507,7 +507,6 @@ func (t *ThreadBuilder) parseGraph(thread *YMLThread) {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *ThreadBuilder) parseHeads(thread *YMLThread) {
|
||||
t.heads = thread.Heads
|
||||
t.maybeHeads = thread.MaybeHeads
|
||||
func (t *ThreadBuilder) parseOrphans(thread *YMLThread) {
|
||||
t.orphans = thread.Orphans
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ graph:
|
||||
baseSnapshot: A.1.1
|
||||
aclHeads: [B.1.1]
|
||||
treeHeads: [B.1.1]
|
||||
maybeHeads:
|
||||
orphans:
|
||||
- "A.1.3"
|
||||
updatedChanges:
|
||||
- id: B.1.3
|
||||
|
||||
@ -101,7 +101,7 @@ graph:
|
||||
baseSnapshot: A.1.1
|
||||
aclHeads: [B.1.1]
|
||||
treeHeads: [B.1.1]
|
||||
maybeHeads:
|
||||
orphans:
|
||||
- "A.1.3"
|
||||
updatedChanges:
|
||||
- id: B.1.3
|
||||
|
||||
@ -101,6 +101,6 @@ graph:
|
||||
baseSnapshot: A.1.1
|
||||
aclHeads: [A.1.2]
|
||||
treeHeads: [A.1.2]
|
||||
maybeHeads:
|
||||
orphans:
|
||||
- "A.1.3"
|
||||
- "B.1.2"
|
||||
|
||||
@ -101,6 +101,6 @@ graph:
|
||||
aclSnapshot: A.1.1
|
||||
aclHeads: [A.1.3]
|
||||
treeHeads: [A.1.3]
|
||||
maybeHeads:
|
||||
orphans:
|
||||
- "A.1.4"
|
||||
- "B.1.2"
|
||||
|
||||
@ -124,7 +124,7 @@ graph:
|
||||
baseSnapshot: A.1.2
|
||||
aclHeads: [A.1.2]
|
||||
treeHeads: [A.1.2]
|
||||
maybeHeads:
|
||||
orphans:
|
||||
- "A.1.3"
|
||||
- "B.1.2"
|
||||
|
||||
|
||||
@ -100,6 +100,6 @@ type YMLThread struct {
|
||||
Graph []*GraphNode `yaml:"graph"`
|
||||
UpdatedGraph []*GraphNode `yaml:"updatedGraph"`
|
||||
|
||||
Heads []string `yaml:"heads"`
|
||||
MaybeHeads []string `yaml:"maybeHeads"`
|
||||
Heads []string `yaml:"heads"`
|
||||
Orphans []string `yaml:"orphans"`
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user