github.com/ravendb/ravendb-go-client@v0.0.0-20240229102137-4474ee7aa0fa/tests/changes_test.go (about)

     1  package tests
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	ravendb "github.com/ravendb/ravendb-go-client"
     8  	"github.com/stretchr/testify/assert"
     9  )
    10  
    11  func changesTestSingleDocumentChangesCommon(t *testing.T, store *ravendb.DocumentStore) {
    12  
    13  	changes := store.Changes("")
    14  	err := changes.EnsureConnectedNow()
    15  	assert.NoError(t, err)
    16  
    17  	var cancel ravendb.CancelFunc
    18  	{
    19  		chDone := make(chan struct{})
    20  		n := 0
    21  		cb := func(documentChange *ravendb.DocumentChange) {
    22  			if n == 0 {
    23  				assert.NotNil(t, documentChange)
    24  				assert.Equal(t, documentChange.ID, "users/1")
    25  				assert.Equal(t, documentChange.Type, ravendb.DocumentChangePut)
    26  				chDone <- struct{}{}
    27  			} else {
    28  				assert.Fail(t, "got too many (%d) changes")
    29  			}
    30  			n++
    31  		}
    32  		cancel, err = changes.ForDocument("users/1", cb)
    33  		assert.NoError(t, err)
    34  
    35  		{
    36  			session := openSessionMust(t, store)
    37  			user := &User{}
    38  			err = session.StoreWithID(user, "users/1")
    39  			assert.NoError(t, err)
    40  			err = session.SaveChanges()
    41  			assert.NoError(t, err)
    42  		}
    43  
    44  		select {
    45  		case <-chDone:
    46  			// got a result
    47  		case <-time.After(_reasonableWaitTime):
    48  			assert.Fail(t, "timed out waiting for changesList to close")
    49  		}
    50  		cancel()
    51  	}
    52  
    53  	// at this point we should be unsubscribed from changes on 'users/1'
    54  	{
    55  		changesList := make(chan *ravendb.DocumentChange, 1)
    56  		session := openSessionMust(t, store)
    57  		user := &User{}
    58  		user.setName("another name")
    59  		err = session.StoreWithID(user, "users/1")
    60  		assert.NoError(t, err)
    61  		err = session.SaveChanges()
    62  		assert.NoError(t, err)
    63  
    64  		select {
    65  		case v := <-changesList:
    66  			assert.Nil(t, v, "got too many changes")
    67  		case <-time.After(time.Second * 1):
    68  			// ok, no changes
    69  			assert.True(t, true)
    70  		}
    71  	}
    72  
    73  	changes.Close()
    74  }
    75  
    76  func changesTestSingleDocumentChanges(t *testing.T, driver *RavenTestDriver) {
    77  	store := driver.getDocumentStoreMust(t)
    78  	defer store.Close()
    79  	changesTestSingleDocumentChangesCommon(t, store)
    80  }
    81  
    82  func changesTestChangesWithHttps(t *testing.T, driver *RavenTestDriver) {
    83  	if isWindows() {
    84  		return
    85  	}
    86  	store := driver.getSecuredDocumentStoreMust(t)
    87  	defer store.Close()
    88  	changesTestSingleDocumentChangesCommon(t, store)
    89  }
    90  
    91  func changesTestAllDocumentsChanges(t *testing.T, driver *RavenTestDriver) {
    92  
    93  	var err error
    94  	store := driver.getDocumentStoreMust(t)
    95  	defer store.Close()
    96  
    97  	{
    98  		changes := store.Changes("")
    99  		err = changes.EnsureConnectedNow()
   100  		assert.NoError(t, err)
   101  
   102  		{
   103  			changesList := make(chan *ravendb.DocumentChange, 1)
   104  			var unregister ravendb.CancelFunc
   105  			cb := func(change *ravendb.DocumentChange) {
   106  				changesList <- change
   107  			}
   108  			unregister, err = changes.ForAllDocuments(cb)
   109  			assert.NoError(t, err)
   110  
   111  			{
   112  				session := openSessionMust(t, store)
   113  				user := &User{}
   114  				err = session.StoreWithID(user, "users/1")
   115  				assert.NoError(t, err)
   116  				err = session.SaveChanges()
   117  				assert.NoError(t, err)
   118  			}
   119  
   120  			select {
   121  			case documentChange := <-changesList:
   122  				assert.NotNil(t, documentChange)
   123  				assert.Equal(t, documentChange.ID, "users/1")
   124  				assert.Equal(t, documentChange.Type, ravendb.DocumentChangePut)
   125  
   126  			case <-time.After(time.Second * 2):
   127  				assert.Fail(t, "timed out waiting for changes")
   128  			}
   129  
   130  			select {
   131  			case <-changesList:
   132  				assert.Fail(t, "got too many changes")
   133  			case <-time.After(time.Second * 1):
   134  				// ok, no changes
   135  				assert.True(t, true)
   136  			}
   137  
   138  			unregister()
   139  		}
   140  
   141  		// at this point we should be unsubscribed from changes on 'users/1'
   142  
   143  		{
   144  			changesList := make(chan *ravendb.DocumentChange, 1)
   145  			session := openSessionMust(t, store)
   146  			user := &User{}
   147  			user.setName("another name")
   148  			err = session.StoreWithID(user, "users/1")
   149  			assert.NoError(t, err)
   150  			err = session.SaveChanges()
   151  			assert.NoError(t, err)
   152  
   153  			select {
   154  			case v := <-changesList:
   155  				assert.Nil(t, v, "got too many changes")
   156  			case <-time.After(time.Second * 1):
   157  				// ok, no changes
   158  				assert.True(t, true)
   159  			}
   160  		}
   161  
   162  		changes.Close()
   163  		changes.Close() // call twice to make sure we're robust
   164  	}
   165  }
   166  
   167  // Note: UsersByName is the same as makeUsersByNameIndex in query_test.go
   168  
   169  func changesTestSingleIndexChanges(t *testing.T, driver *RavenTestDriver) {
   170  	var err error
   171  	store := driver.getDocumentStoreMust(t)
   172  	defer store.Close()
   173  
   174  	index := makeUsersByNameIndex()
   175  	err = store.ExecuteIndex(index, "")
   176  	assert.NoError(t, err)
   177  
   178  	var cancel ravendb.CancelFunc
   179  
   180  	{
   181  		changesList := make(chan *ravendb.IndexChange, 1)
   182  		changes := store.Changes("")
   183  		err = changes.EnsureConnectedNow()
   184  		assert.NoError(t, err)
   185  
   186  		{
   187  			cb := func(change *ravendb.IndexChange) {
   188  				changesList <- change
   189  			}
   190  			cancel, err = changes.ForIndex(index.IndexName, cb)
   191  			assert.NoError(t, err)
   192  
   193  			time.Sleep(500 * time.Millisecond)
   194  			operation, err := ravendb.NewSetIndexesPriorityOperation(index.IndexName, ravendb.IndexPriorityLow)
   195  			assert.NoError(t, err)
   196  			err = store.Maintenance().Send(operation)
   197  			assert.NoError(t, err)
   198  
   199  			select {
   200  			case indexChange := <-changesList:
   201  				assert.Equal(t, indexChange.Name, index.IndexName)
   202  			case <-time.After(time.Second * 2):
   203  				assert.Fail(t, "timed out waiting for changes")
   204  			}
   205  
   206  			cancel()
   207  		}
   208  
   209  		changes.Close()
   210  	}
   211  }
   212  
   213  func changesTestAllIndexChanges(t *testing.T, driver *RavenTestDriver) {
   214  	var err error
   215  	store := driver.getDocumentStoreMust(t)
   216  	defer store.Close()
   217  
   218  	index := makeUsersByNameIndex()
   219  	err = store.ExecuteIndex(index, "")
   220  	assert.NoError(t, err)
   221  
   222  	var cancel ravendb.CancelFunc
   223  
   224  	{
   225  		changesList := make(chan *ravendb.IndexChange, 1)
   226  		changes := store.Changes("")
   227  		err = changes.EnsureConnectedNow()
   228  		assert.NoError(t, err)
   229  
   230  		{
   231  			cb := func(change *ravendb.IndexChange) {
   232  				changesList <- change
   233  			}
   234  			cancel, err = changes.ForAllIndexes(cb)
   235  			assert.NoError(t, err)
   236  
   237  			time.Sleep(500 * time.Millisecond)
   238  			operation, err := ravendb.NewSetIndexesPriorityOperation(index.IndexName, ravendb.IndexPriorityLow)
   239  			assert.NoError(t, err)
   240  			err = store.Maintenance().Send(operation)
   241  			assert.NoError(t, err)
   242  
   243  			select {
   244  			case indexChange := <-changesList:
   245  				assert.Equal(t, indexChange.Name, index.IndexName)
   246  			case <-time.After(time.Second * 2):
   247  				assert.Fail(t, "timed out waiting for changes")
   248  			}
   249  			cancel()
   250  		}
   251  
   252  		changes.Close()
   253  	}
   254  }
   255  
   256  func changesTestCanCanNotificationAboutDocumentsStartingWiths(t *testing.T, driver *RavenTestDriver) {
   257  	var err error
   258  	store := driver.getDocumentStoreMust(t)
   259  	defer store.Close()
   260  
   261  	var cancel ravendb.CancelFunc
   262  	{
   263  		changesList := make(chan *ravendb.DocumentChange, 1)
   264  		changes := store.Changes("")
   265  		err = changes.EnsureConnectedNow()
   266  		assert.NoError(t, err)
   267  
   268  		{
   269  			cb := func(change *ravendb.DocumentChange) {
   270  				changesList <- change
   271  			}
   272  			cancel, err = changes.ForDocumentsStartingWith("users/", cb)
   273  			assert.NoError(t, err)
   274  
   275  			{
   276  				session := openSessionMust(t, store)
   277  				err = session.StoreWithID(&User{}, "users/1")
   278  				assert.NoError(t, err)
   279  				err = session.SaveChanges()
   280  				assert.NoError(t, err)
   281  
   282  				session.Close()
   283  			}
   284  
   285  			{
   286  				session := openSessionMust(t, store)
   287  				err = session.StoreWithID(&User{}, "differentDocumentPrefix/1")
   288  				assert.NoError(t, err)
   289  				err = session.SaveChanges()
   290  				assert.NoError(t, err)
   291  
   292  				session.Close()
   293  			}
   294  
   295  			{
   296  				session := openSessionMust(t, store)
   297  				err = session.StoreWithID(&User{}, "users/2")
   298  				assert.NoError(t, err)
   299  				err = session.SaveChanges()
   300  				assert.NoError(t, err)
   301  
   302  				session.Close()
   303  			}
   304  
   305  			select {
   306  			case documentChange := <-changesList:
   307  				assert.Equal(t, documentChange.ID, "users/1")
   308  			case <-time.After(time.Second * 2):
   309  				assert.Fail(t, "timed out waiting for changes")
   310  			}
   311  
   312  			select {
   313  			case documentChange := <-changesList:
   314  				assert.Equal(t, documentChange.ID, "users/2")
   315  			case <-time.After(time.Second * 2):
   316  				assert.Fail(t, "timed out waiting for changes")
   317  			}
   318  
   319  			cancel()
   320  		}
   321  
   322  		changes.Close()
   323  	}
   324  }
   325  
   326  func changesTestCanCanNotificationAboutDocumentsFromCollection(t *testing.T, driver *RavenTestDriver) {
   327  	var err error
   328  	store := driver.getDocumentStoreMust(t)
   329  	defer store.Close()
   330  
   331  	var cancel ravendb.CancelFunc
   332  	{
   333  		changesList := make(chan *ravendb.DocumentChange, 1)
   334  		changes := store.Changes("")
   335  		err = changes.EnsureConnectedNow()
   336  		assert.NoError(t, err)
   337  
   338  		{
   339  			cb := func(change *ravendb.DocumentChange) {
   340  				changesList <- change
   341  			}
   342  			cancel, err = changes.ForDocumentsInCollection("users", cb)
   343  			assert.NoError(t, err)
   344  
   345  			{
   346  				session := openSessionMust(t, store)
   347  				err = session.StoreWithID(&User{}, "users/1")
   348  				assert.NoError(t, err)
   349  				err = session.SaveChanges()
   350  				assert.NoError(t, err)
   351  
   352  				session.Close()
   353  			}
   354  
   355  			{
   356  				session := openSessionMust(t, store)
   357  				err = session.StoreWithID(&Order{}, "orders/1")
   358  				assert.NoError(t, err)
   359  				err = session.SaveChanges()
   360  				assert.NoError(t, err)
   361  
   362  				session.Close()
   363  			}
   364  
   365  			{
   366  				session := openSessionMust(t, store)
   367  				err = session.StoreWithID(&User{}, "users/2")
   368  				assert.NoError(t, err)
   369  				err = session.SaveChanges()
   370  				assert.NoError(t, err)
   371  
   372  				session.Close()
   373  			}
   374  
   375  			select {
   376  			case documentChange := <-changesList:
   377  				assert.Equal(t, documentChange.ID, "users/1")
   378  			case <-time.After(time.Second * 2):
   379  				assert.Fail(t, "timed out waiting for changes")
   380  			}
   381  
   382  			select {
   383  			case documentChange := <-changesList:
   384  				assert.Equal(t, documentChange.ID, "users/2")
   385  			case <-time.After(time.Second * 2):
   386  				assert.Fail(t, "timed out waiting for changes")
   387  			}
   388  
   389  			cancel()
   390  		}
   391  	}
   392  }
   393  
   394  func changesTestNotificationOnWrongDatabaseShouldNotCrashServer(t *testing.T, driver *RavenTestDriver) {
   395  	var err error
   396  	store := driver.getDocumentStoreMust(t)
   397  	defer store.Close()
   398  
   399  	closer := disableLogFailedRequests()
   400  	defer closer()
   401  
   402  	changes := store.Changes("no_such_db")
   403  	err = changes.EnsureConnectedNow()
   404  	assert.NotNil(t, err)
   405  	_, ok := err.(*ravendb.DatabaseDoesNotExistError)
   406  	assert.True(t, ok)
   407  
   408  	op := ravendb.NewGetStatisticsOperation("")
   409  	err = store.Maintenance().Send(op)
   410  	assert.NoError(t, err)
   411  }
   412  
   413  func TestChanges(t *testing.T) {
   414  	driver := createTestDriver(t)
   415  	destroy := func() { destroyDriver(t, driver) }
   416  	defer recoverTest(t, destroy)
   417  
   418  	// follows execution order of java tests
   419  	changesTestAllDocumentsChanges(t, driver)
   420  	changesTestSingleDocumentChanges(t, driver)
   421  	changesTestChangesWithHttps(t, driver)
   422  	changesTestSingleIndexChanges(t, driver)
   423  	changesTestNotificationOnWrongDatabaseShouldNotCrashServer(t, driver)
   424  	changesTestAllIndexChanges(t, driver)
   425  
   426  	// TODO: order different than Java's
   427  	changesTestCanCanNotificationAboutDocumentsStartingWiths(t, driver)
   428  	changesTestCanCanNotificationAboutDocumentsFromCollection(t, driver)
   429  }