go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/auth_service/impl/model/graph/subgraph_test.go (about)

     1  // Copyright 2021 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package graph
    16  
    17  import (
    18  	"testing"
    19  
    20  	. "github.com/smartystreets/goconvey/convey"
    21  )
    22  
    23  func TestSubgraphOperations(t *testing.T) {
    24  	t.Parallel()
    25  
    26  	Convey("Testing addNode", t, func() {
    27  		subgraph := &Subgraph{
    28  			Nodes:     []*SubgraphNode{},
    29  			nodesToID: map[NodeKey]int32{},
    30  		}
    31  
    32  		Convey("Testing adding group.", func() {
    33  			testGroup := "test-group"
    34  			nodeID, placed := subgraph.addNode(Group, testGroup)
    35  			So(nodeID, ShouldEqual, 0)
    36  			So(placed, ShouldBeTrue)
    37  		})
    38  
    39  		Convey("Testing adding user.", func() {
    40  			testUser := "user:m1@example.com"
    41  			nodeID, placed := subgraph.addNode(Identity, testUser)
    42  			So(nodeID, ShouldEqual, 0)
    43  			So(placed, ShouldBeTrue)
    44  		})
    45  
    46  		Convey("Testing adding glob.", func() {
    47  			testGlob := "user:*@example.com"
    48  			nodeID, placed := subgraph.addNode(Glob, testGlob)
    49  			So(nodeID, ShouldEqual, 0)
    50  			So(placed, ShouldBeTrue)
    51  		})
    52  
    53  		Convey("Testing adding same node.", func() {
    54  			testGroup := "test-group"
    55  			nodeID, placed := subgraph.addNode(Group, testGroup)
    56  			So(nodeID, ShouldEqual, 0)
    57  			So(placed, ShouldBeTrue)
    58  			nodeID, placed = subgraph.addNode(Group, testGroup)
    59  			So(nodeID, ShouldEqual, 0)
    60  			So(placed, ShouldBeFalse)
    61  		})
    62  
    63  		Convey("Testing key for nodesToID.", func() {
    64  			testGroup := "test-group"
    65  			testGlob := "user:*@example.com"
    66  			testUser := "user:m1@example.com"
    67  			subgraph.addNode(Group, testGroup)
    68  			subgraph.addNode(Glob, testGlob)
    69  			subgraph.addNode(Identity, testUser)
    70  
    71  			expectedNodeMap := map[NodeKey]int32{
    72  				{Group, testGroup}:   0,
    73  				{Glob, testGlob}:     1,
    74  				{Identity, testUser}: 2,
    75  			}
    76  
    77  			So(subgraph.nodesToID, ShouldResemble, expectedNodeMap)
    78  		})
    79  
    80  	})
    81  
    82  	Convey("Testing addEdge", t, func() {
    83  		testGlob := "user:*@example.com"
    84  		testGroup0 := "test-group-0"
    85  		testUser := "user:m1@example.com"
    86  		testGroup1 := "test-group-1"
    87  		testGroup2 := "test-group-2"
    88  
    89  		subgraph := &Subgraph{
    90  			Nodes: []*SubgraphNode{
    91  				{
    92  					NodeKey: NodeKey{
    93  						Kind:  Glob,
    94  						Value: testGlob,
    95  					},
    96  				},
    97  				{
    98  					NodeKey: NodeKey{
    99  						Kind:  Group,
   100  						Value: testGroup0,
   101  					},
   102  				},
   103  				{
   104  					NodeKey: NodeKey{
   105  						Kind:  Identity,
   106  						Value: testUser,
   107  					},
   108  				},
   109  				{
   110  					NodeKey: NodeKey{
   111  						Kind:  Group,
   112  						Value: testGroup1,
   113  					},
   114  				},
   115  				{
   116  					NodeKey: NodeKey{
   117  						Kind:  Group,
   118  						Value: testGroup2,
   119  					},
   120  				},
   121  			},
   122  		}
   123  
   124  		Convey("Testing basic edge adding.", func() {
   125  			subgraph.addEdge(0, 1)
   126  			subgraph.addEdge(2, 1)
   127  
   128  			expectedSubgraph := &Subgraph{
   129  				Nodes: []*SubgraphNode{
   130  					{ // 0
   131  						NodeKey: NodeKey{
   132  							Kind:  Glob,
   133  							Value: testGlob,
   134  						},
   135  						IncludedBy: []int32{1},
   136  					},
   137  					{ // 1
   138  						NodeKey: NodeKey{
   139  							Kind:  Group,
   140  							Value: testGroup0,
   141  						},
   142  					},
   143  					{ // 2
   144  						NodeKey: NodeKey{
   145  							Kind:  Identity,
   146  							Value: testUser,
   147  						},
   148  						IncludedBy: []int32{1},
   149  					},
   150  					{ // 3
   151  						NodeKey: NodeKey{
   152  							Kind:  Group,
   153  							Value: testGroup1,
   154  						},
   155  					},
   156  					{ // 4
   157  						NodeKey: NodeKey{
   158  							Kind:  Group,
   159  							Value: testGroup2,
   160  						},
   161  					},
   162  				},
   163  			}
   164  			So(subgraph.Nodes, ShouldResemble, expectedSubgraph.Nodes)
   165  		})
   166  
   167  		// Make sure that the order that of the edges stays consistent and is predictable.
   168  		Convey("Testing stability.", func() {
   169  			subgraph.addEdge(0, 4)
   170  			subgraph.addEdge(0, 2)
   171  			subgraph.addEdge(0, 3)
   172  			subgraph.addEdge(2, 4)
   173  			subgraph.addEdge(2, 3)
   174  			subgraph.addEdge(2, 0)
   175  			subgraph.addEdge(2, 1)
   176  			expectedSubgraph := &Subgraph{
   177  				Nodes: []*SubgraphNode{
   178  					{ // 0
   179  						NodeKey: NodeKey{
   180  							Kind:  Glob,
   181  							Value: testGlob,
   182  						},
   183  						IncludedBy: []int32{2, 3, 4},
   184  					},
   185  					{ // 1
   186  						NodeKey: NodeKey{
   187  							Kind:  Group,
   188  							Value: testGroup0,
   189  						},
   190  					},
   191  					{ // 2
   192  						NodeKey: NodeKey{
   193  							Kind:  Identity,
   194  							Value: testUser,
   195  						},
   196  						IncludedBy: []int32{0, 1, 3, 4},
   197  					},
   198  					{ // 3
   199  						NodeKey: NodeKey{
   200  							Kind:  Group,
   201  							Value: testGroup1,
   202  						},
   203  					},
   204  					{ // 4
   205  						NodeKey: NodeKey{
   206  							Kind:  Group,
   207  							Value: testGroup2,
   208  						},
   209  					},
   210  				},
   211  			}
   212  			So(subgraph.Nodes, ShouldResemble, expectedSubgraph.Nodes)
   213  		})
   214  	})
   215  }