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

     1  package tests
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  
    11  	ravendb "github.com/ravendb/ravendb-go-client"
    12  )
    13  
    14  func ravendb6292_ifIncludedDocumentIsConflictedItShouldNotThrowConflictException(t *testing.T, driver *RavenTestDriver) {
    15  	driver.customize = func(r *ravendb.DatabaseRecord) {
    16  		conflictSolver := &ravendb.ConflictSolver{
    17  			ResolveToLatest:     false,
    18  			ResolveByCollection: map[string]*ravendb.ScriptResolver{},
    19  		}
    20  		r.ConflictSolverConfig = conflictSolver
    21  	}
    22  	defer func() {
    23  		driver.customize = nil
    24  	}()
    25  
    26  	var err error
    27  	store1 := driver.getDocumentStoreMust(t)
    28  	defer store1.Close()
    29  
    30  	store2 := driver.getDocumentStoreMust(t)
    31  	defer store2.Close()
    32  
    33  	{
    34  		session := openSessionMust(t, store1)
    35  
    36  		address := &Address{
    37  			City: "New York",
    38  		}
    39  		err = session.StoreWithID(address, "addresses/1")
    40  		assert.NoError(t, err)
    41  		err = session.SaveChanges()
    42  		assert.NoError(t, err)
    43  
    44  		session.Close()
    45  	}
    46  
    47  	{
    48  		session := openSessionMust(t, store2)
    49  		address := &Address{
    50  			City: "Torun",
    51  		}
    52  
    53  		err = session.StoreWithID(address, "addresses/1")
    54  		assert.NoError(t, err)
    55  
    56  		user := &User{}
    57  		user.setName("John")
    58  		user.AddressID = "addresses/1"
    59  		err = session.StoreWithID(user, "users/1")
    60  		assert.NoError(t, err)
    61  
    62  		err = session.SaveChanges()
    63  		assert.NoError(t, err)
    64  
    65  		session.Close()
    66  	}
    67  
    68  	err = driver.setupReplication(store1, store2)
    69  	assert.NoError(t, err)
    70  
    71  	var addressTmp *Address
    72  	err = driver.waitForConflict(store2, &addressTmp, "addresses/1")
    73  	if err != nil {
    74  		fmt.Printf("Got unexpected error '%s' of type %T\n", err, err)
    75  	}
    76  	assert.NoError(t, err)
    77  
    78  	{
    79  		session := openSessionMust(t, store2)
    80  
    81  		clazz := reflect.TypeOf(&User{})
    82  		documentQuery := session.Advanced().QueryCollectionForType(clazz)
    83  		documentQuery = documentQuery.Include("addressId")
    84  
    85  		iq, err := documentQuery.GetIndexQuery()
    86  		assert.NoError(t, err)
    87  
    88  		var user *User
    89  		err = documentQuery.First(&user)
    90  		assert.NoError(t, err)
    91  		assert.Equal(t, *user.Name, "John")
    92  
    93  		{
    94  			var addr *Address
    95  			err = session.Load(&addr, user.AddressID)
    96  			assert.Error(t, err)
    97  			_, ok := err.(*ravendb.DocumentConflictError)
    98  			assert.True(t, ok)
    99  		}
   100  
   101  		queryCommand, err := ravendb.NewQueryCommand(ravendb.NewDocumentConventions(), iq, false, false)
   102  		assert.NoError(t, err)
   103  
   104  		err = store2.GetRequestExecutor("").ExecuteCommand(queryCommand, nil)
   105  		assert.NoError(t, err)
   106  
   107  		result := queryCommand.Result
   108  		address := result.Includes["addresses/1"].(map[string]interface{})
   109  
   110  		metadata := address["@metadata"].(map[string]interface{})
   111  		id := metadata["@id"].(string)
   112  		assert.Equal(t, id, "addresses/1")
   113  
   114  		assert.True(t, tryGetConflict(metadata))
   115  	}
   116  }
   117  
   118  func tryGetConflict(metadata map[string]interface{}) bool {
   119  	v, ok := metadata[ravendb.MetadataConflict]
   120  	if !ok {
   121  		return false
   122  	}
   123  	b, ok := v.(bool)
   124  	if !ok {
   125  		return false
   126  	}
   127  	return b
   128  }
   129  
   130  func (d *RavenTestDriver) waitForConflict(store *ravendb.DocumentStore, result interface{}, id string) error {
   131  	sw := time.Now()
   132  	timeout := time.Millisecond * 10090
   133  	for {
   134  		time.Sleep(time.Millisecond * 500)
   135  		dur := time.Since(sw)
   136  		if dur > timeout {
   137  			return nil
   138  		}
   139  		{
   140  			session, err := store.OpenSession("")
   141  			if err != nil {
   142  				return err
   143  			}
   144  			err = session.Load(result, id)
   145  			session.Close()
   146  			if err != nil {
   147  				// Note: in Java the code checks for ConflictException which is a base class
   148  				// for ConcurrencyException and DocumentConflictException
   149  				if _, ok := err.(*ravendb.ConflictError); ok {
   150  					return nil
   151  				}
   152  				if _, ok := err.(*ravendb.ConcurrencyError); ok {
   153  					return nil
   154  				}
   155  				if _, ok := err.(*ravendb.DocumentConflictError); ok {
   156  					return nil
   157  				}
   158  				return err
   159  			}
   160  		}
   161  	}
   162  }
   163  
   164  func TestRavenDB6292(t *testing.T) {
   165  	driver := createTestDriver(t)
   166  	destroy := func() { destroyDriver(t, driver) }
   167  	defer recoverTest(t, destroy)
   168  
   169  	if !enableReplicationTests() {
   170  		fmt.Printf("Skipping TestRavenDB6292 because RAVEN_License env variable is not set\n")
   171  		return
   172  	}
   173  
   174  	// matches Java's order
   175  	ravendb6292_ifIncludedDocumentIsConflictedItShouldNotThrowConflictException(t, driver)
   176  }