github.com/cs3org/reva/v2@v2.27.7/pkg/storage/utils/indexer/indexer_test.go (about)

     1  // Copyright 2018-2022 CERN
     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  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  package indexer
    20  
    21  import (
    22  	"context"
    23  	"os"
    24  	"path"
    25  	"testing"
    26  
    27  	_ "github.com/cs3org/reva/v2/pkg/storage/utils/indexer/index"
    28  	"github.com/cs3org/reva/v2/pkg/storage/utils/indexer/option"
    29  	. "github.com/cs3org/reva/v2/pkg/storage/utils/indexer/test"
    30  	"github.com/cs3org/reva/v2/pkg/storage/utils/metadata"
    31  	"github.com/stretchr/testify/assert"
    32  )
    33  
    34  func TestIndexer_Disk_FindByWithUniqueIndex(t *testing.T) {
    35  	dataDir, err := WriteIndexTestData(Data, "ID", "")
    36  	assert.NoError(t, err)
    37  	indexer := createDiskIndexer(dataDir)
    38  
    39  	err = indexer.AddIndex(&User{}, option.IndexByField("UserName"), "ID", "users", "unique", nil, false)
    40  	assert.NoError(t, err)
    41  
    42  	u := &User{ID: "abcdefg-123", UserName: "mikey", Email: "mikey@example.com"}
    43  	_, err = indexer.Add(u)
    44  	assert.NoError(t, err)
    45  
    46  	res, err := indexer.FindBy(User{}, NewField("UserName", "mikey"))
    47  	assert.NoError(t, err)
    48  	t.Log(res)
    49  
    50  	_ = os.RemoveAll(dataDir)
    51  }
    52  
    53  func TestIndexer_Disk_AddWithUniqueIndex(t *testing.T) {
    54  	dataDir, err := WriteIndexTestData(Data, "ID", "")
    55  	assert.NoError(t, err)
    56  	indexer := createDiskIndexer(dataDir)
    57  
    58  	err = indexer.AddIndex(&User{}, option.IndexByField("UserName"), "ID", "users", "unique", nil, false)
    59  	assert.NoError(t, err)
    60  
    61  	u := &User{ID: "abcdefg-123", UserName: "mikey", Email: "mikey@example.com"}
    62  	_, err = indexer.Add(u)
    63  	assert.NoError(t, err)
    64  
    65  	_ = os.RemoveAll(dataDir)
    66  }
    67  
    68  func TestIndexer_Disk_AddWithNonUniqueIndex(t *testing.T) {
    69  	dataDir, err := WriteIndexTestData(Data, "ID", "")
    70  	assert.NoError(t, err)
    71  	indexer := createDiskIndexer(dataDir)
    72  
    73  	err = indexer.AddIndex(&Pet{}, option.IndexByField("Kind"), "ID", "pets", "non_unique", nil, false)
    74  	assert.NoError(t, err)
    75  
    76  	pet1 := Pet{ID: "goefe-789", Kind: "Hog", Color: "Green", Name: "Dicky"}
    77  	pet2 := Pet{ID: "xadaf-189", Kind: "Hog", Color: "Green", Name: "Ricky"}
    78  
    79  	_, err = indexer.Add(pet1)
    80  	assert.NoError(t, err)
    81  
    82  	_, err = indexer.Add(pet2)
    83  	assert.NoError(t, err)
    84  
    85  	res, err := indexer.FindBy(Pet{}, NewField("Kind", "Hog"))
    86  	assert.NoError(t, err)
    87  
    88  	t.Log(res)
    89  
    90  	_ = os.RemoveAll(dataDir)
    91  }
    92  
    93  func TestIndexer_Disk_AddWithAutoincrementIndex(t *testing.T) {
    94  	dataDir, err := WriteIndexTestData(Data, "ID", "")
    95  	assert.NoError(t, err)
    96  	indexer := createDiskIndexer(dataDir)
    97  
    98  	err = indexer.AddIndex(&User{}, option.IndexByField("UID"), "ID", "users", "autoincrement", &option.Bound{Lower: 5}, false)
    99  	assert.NoError(t, err)
   100  
   101  	res1, err := indexer.Add(Data["users"][0])
   102  	assert.NoError(t, err)
   103  	assert.Equal(t, "UID", res1[0].Field)
   104  	assert.Equal(t, "5", path.Base(res1[0].Value))
   105  
   106  	res2, err := indexer.Add(Data["users"][1])
   107  	assert.NoError(t, err)
   108  	assert.Equal(t, "UID", res2[0].Field)
   109  	assert.Equal(t, "6", path.Base(res2[0].Value))
   110  
   111  	resFindBy, err := indexer.FindBy(User{}, NewField("UID", "6"))
   112  	assert.NoError(t, err)
   113  	assert.Equal(t, "hijklmn-456", resFindBy[0])
   114  	t.Log(resFindBy)
   115  
   116  	_ = os.RemoveAll(dataDir)
   117  }
   118  
   119  func TestIndexer_Disk_DeleteWithNonUniqueIndex(t *testing.T) {
   120  	dataDir, err := WriteIndexTestData(Data, "ID", "")
   121  	assert.NoError(t, err)
   122  	indexer := createDiskIndexer(dataDir)
   123  
   124  	err = indexer.AddIndex(&Pet{}, option.IndexByField("Kind"), "ID", "pets", "non_unique", nil, false)
   125  	assert.NoError(t, err)
   126  
   127  	pet1 := Pet{ID: "goefe-789", Kind: "Hog", Color: "Green", Name: "Dicky"}
   128  	pet2 := Pet{ID: "xadaf-189", Kind: "Hog", Color: "Green", Name: "Ricky"}
   129  
   130  	_, err = indexer.Add(pet1)
   131  	assert.NoError(t, err)
   132  
   133  	_, err = indexer.Add(pet2)
   134  	assert.NoError(t, err)
   135  
   136  	err = indexer.Delete(pet2)
   137  	assert.NoError(t, err)
   138  
   139  	_ = os.RemoveAll(dataDir)
   140  }
   141  
   142  func TestIndexer_Disk_SearchWithNonUniqueIndex(t *testing.T) {
   143  	dataDir, err := WriteIndexTestData(Data, "ID", "")
   144  	assert.NoError(t, err)
   145  	indexer := createDiskIndexer(dataDir)
   146  
   147  	err = indexer.AddIndex(&Pet{}, option.IndexByField("Name"), "ID", "pets", "non_unique", nil, false)
   148  	assert.NoError(t, err)
   149  
   150  	pet1 := Pet{ID: "goefe-789", Kind: "Hog", Color: "Green", Name: "Dicky"}
   151  	pet2 := Pet{ID: "xadaf-189", Kind: "Hog", Color: "Green", Name: "Ricky"}
   152  
   153  	_, err = indexer.Add(pet1)
   154  	assert.NoError(t, err)
   155  
   156  	_, err = indexer.Add(pet2)
   157  	assert.NoError(t, err)
   158  
   159  	res, err := indexer.FindByPartial(pet2, "Name", "*ky")
   160  	assert.NoError(t, err)
   161  
   162  	t.Log(res)
   163  	_ = os.RemoveAll(dataDir)
   164  }
   165  
   166  func TestIndexer_Disk_UpdateWithUniqueIndex(t *testing.T) {
   167  	dataDir, err := WriteIndexTestData(Data, "ID", "")
   168  	assert.NoError(t, err)
   169  	indexer := createDiskIndexer(dataDir)
   170  
   171  	err = indexer.AddIndex(&User{}, option.IndexByField("UserName"), "ID", "users", "unique", nil, false)
   172  	assert.NoError(t, err)
   173  
   174  	err = indexer.AddIndex(&User{}, option.IndexByField("Email"), "ID", "users", "unique", nil, false)
   175  	assert.NoError(t, err)
   176  
   177  	user1 := &User{ID: "abcdefg-123", UserName: "mikey", Email: "mikey@example.com"}
   178  	user2 := &User{ID: "hijklmn-456", UserName: "frank", Email: "frank@example.com"}
   179  
   180  	_, err = indexer.Add(user1)
   181  	assert.NoError(t, err)
   182  
   183  	_, err = indexer.Add(user2)
   184  	assert.NoError(t, err)
   185  
   186  	err = indexer.Update(user1, &User{
   187  		ID:       "abcdefg-123",
   188  		UserName: "mikey-new",
   189  		Email:    "mikey@example.com",
   190  	})
   191  	assert.NoError(t, err)
   192  	v, err1 := indexer.FindBy(&User{}, NewField("UserName", "mikey-new"))
   193  	assert.NoError(t, err1)
   194  	assert.Len(t, v, 1)
   195  	v, err2 := indexer.FindBy(&User{}, NewField("UserName", "mikey"))
   196  	assert.NoError(t, err2)
   197  	assert.Len(t, v, 0)
   198  
   199  	err1 = indexer.Update(&User{
   200  		ID:       "abcdefg-123",
   201  		UserName: "mikey-new",
   202  		Email:    "mikey@example.com",
   203  	}, &User{
   204  		ID:       "abcdefg-123",
   205  		UserName: "mikey-newest",
   206  		Email:    "mikey-new@example.com",
   207  	})
   208  	assert.NoError(t, err1)
   209  	fbUserName, err2 := indexer.FindBy(&User{}, NewField("UserName", "mikey-newest"))
   210  	assert.NoError(t, err2)
   211  	assert.Len(t, fbUserName, 1)
   212  	fbEmail, err3 := indexer.FindBy(&User{}, NewField("Email", "mikey-new@example.com"))
   213  	assert.NoError(t, err3)
   214  	assert.Len(t, fbEmail, 1)
   215  
   216  	_ = os.RemoveAll(dataDir)
   217  }
   218  
   219  func TestIndexer_Disk_UpdateWithNonUniqueIndex(t *testing.T) {
   220  	dataDir, err := WriteIndexTestData(Data, "ID", "")
   221  	assert.NoError(t, err)
   222  	indexer := createDiskIndexer(dataDir)
   223  
   224  	err = indexer.AddIndex(&Pet{}, option.IndexByField("Name"), "ID", "pets", "non_unique", nil, false)
   225  	assert.NoError(t, err)
   226  
   227  	pet1 := Pet{ID: "goefe-789", Kind: "Hog", Color: "Green", Name: "Dicky"}
   228  	pet2 := Pet{ID: "xadaf-189", Kind: "Hog", Color: "Green", Name: "Ricky"}
   229  
   230  	_, err = indexer.Add(pet1)
   231  	assert.NoError(t, err)
   232  
   233  	_, err = indexer.Add(pet2)
   234  	assert.NoError(t, err)
   235  
   236  	_ = os.RemoveAll(dataDir)
   237  }
   238  
   239  func TestQueryDiskImpl(t *testing.T) {
   240  	dataDir, err := WriteIndexTestData(Data, "ID", "")
   241  	assert.NoError(t, err)
   242  	indexer := createDiskIndexer(dataDir)
   243  	ctx := context.Background()
   244  
   245  	err = indexer.AddIndex(&Account{}, option.IndexByField("OnPremisesSamAccountName"), "ID", "accounts", "non_unique", nil, false)
   246  	assert.NoError(t, err)
   247  
   248  	err = indexer.AddIndex(&Account{}, option.IndexByField("Mail"), "ID", "accounts", "non_unique", nil, false)
   249  	assert.NoError(t, err)
   250  
   251  	err = indexer.AddIndex(&Account{}, option.IndexByField("ID"), "ID", "accounts", "non_unique", nil, false)
   252  	assert.NoError(t, err)
   253  
   254  	acc := Account{
   255  		ID:                       "ba5b6e54-e29d-4b2b-8cc4-0a0b958140d2",
   256  		Mail:                     "spooky@skeletons.org",
   257  		OnPremisesSamAccountName: "MrDootDoot",
   258  	}
   259  
   260  	_, err = indexer.Add(acc)
   261  	assert.NoError(t, err)
   262  
   263  	r, err := indexer.Query(ctx, &Account{}, "on_premises_sam_account_name eq 'MrDootDoot'") // this query will match both pets.
   264  	assert.NoError(t, err)
   265  	assert.Equal(t, []string{"ba5b6e54-e29d-4b2b-8cc4-0a0b958140d2"}, r)
   266  
   267  	r, err = indexer.Query(ctx, &Account{}, "mail eq 'spooky@skeletons.org'") // this query will match both pets.
   268  	assert.NoError(t, err)
   269  	assert.Equal(t, []string{"ba5b6e54-e29d-4b2b-8cc4-0a0b958140d2"}, r)
   270  
   271  	r, err = indexer.Query(ctx, &Account{}, "on_premises_sam_account_name eq 'MrDootDoot' or mail eq 'spooky@skeletons.org'") // this query will match both pets.
   272  	assert.NoError(t, err)
   273  	assert.Equal(t, []string{"ba5b6e54-e29d-4b2b-8cc4-0a0b958140d2"}, r)
   274  
   275  	r, err = indexer.Query(ctx, &Account{}, "startswith(on_premises_sam_account_name,'MrDoo')") // this query will match both pets.
   276  	assert.NoError(t, err)
   277  	assert.Equal(t, []string{"ba5b6e54-e29d-4b2b-8cc4-0a0b958140d2"}, r)
   278  
   279  	r, err = indexer.Query(ctx, &Account{}, "id eq 'ba5b6e54-e29d-4b2b-8cc4-0a0b958140d2' or on_premises_sam_account_name eq 'MrDootDoot'") // this query will match both pets.
   280  	assert.NoError(t, err)
   281  	assert.Equal(t, []string{"ba5b6e54-e29d-4b2b-8cc4-0a0b958140d2"}, r)
   282  
   283  	_ = os.RemoveAll(dataDir)
   284  }
   285  
   286  func createDiskIndexer(dataDir string) *StorageIndexer {
   287  	storage, err := metadata.NewDiskStorage(dataDir)
   288  	if err != nil {
   289  		return nil
   290  	}
   291  
   292  	return CreateIndexer(storage).(*StorageIndexer)
   293  }