Skip to content

Commit

Permalink
Merge branch '3.6-dev' into 3.7-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
Valentyn Kahamlyk authored and Valentyn Kahamlyk committed Dec 6, 2023
2 parents 1b64fac + bf19ce9 commit 0756e12
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
=== TinkerPop 3.6.7 (NOT OFFICIALLY RELEASED YET)
* Improved error message from `JavaTranslator` by including exception source.
* Added tests for error handling for GLV's if tx.commit() is called remotely for graphs without transactions support.
[[release-3-6-6]]
=== TinkerPop 3.6.6 (November 20, 2023)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,5 +271,25 @@ public async Task ShouldSupportFurtherTraversalsAfterOneWasCancelled()

Assert.True(await g.V().Promise(t => t.HasNext(), CancellationToken.None));
}

[Fact]
public async Task ShouldThrowExceptionOnCommitWhenGraphNotSupportTx()
{
var connection = _connectionFactory.CreateRemoteConnection();
var g = AnonymousTraversalSource.Traversal().WithRemote(connection);
var tx = g.Tx();
var exception = await Assert.ThrowsAsync<ResponseException>(async () => await tx.CommitAsync());
Assert.Equal("ServerError: Graph does not support transactions", exception.Message);
}

[Fact]
public async Task ShouldThrowExceptionOnRollbackWhenGraphNotSupportTx()
{
var connection = _connectionFactory.CreateRemoteConnection();
var g = AnonymousTraversalSource.Traversal().WithRemote(connection);
var tx = g.Tx();
var exception = await Assert.ThrowsAsync<ResponseException>(async () => await tx.RollbackAsync());
Assert.Equal("ServerError: Graph does not support transactions", exception.Message);
}
}
}
44 changes: 44 additions & 0 deletions gremlin-go/driver/traversal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package gremlingo
import (
"crypto/tls"
"reflect"
"strings"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -351,6 +352,49 @@ func TestTraversal(t *testing.T) {
assert.Equal(t, int32(0), getCount(t, g))
})

t.Run("Test commit if no transaction started", func(t *testing.T) {
skipTestsIfNotEnabled(t, integrationTestSuiteName, testTransactionEnable)
// Start a traversal.
g := newWithOptionsConnection(t)

// Create transactions
tx := g.Tx()

// try to commit
err := tx.Commit()
assert.Equal(t, "E1103: cannot commit a transaction that is not started", err.Error())
})

t.Run("Test rollback if no transaction started", func(t *testing.T) {
skipTestsIfNotEnabled(t, integrationTestSuiteName, testTransactionEnable)
// Start a traversal.
g := newWithOptionsConnection(t)

// Create transactions
tx := g.Tx()

// try to rollback
err := tx.Rollback()
assert.Equal(t, "E1102: cannot rollback a transaction that is not started", err.Error())
})

t.Run("Test commit if no transaction support for Graph", func(t *testing.T) {
skipTestsIfNotEnabled(t, integrationTestSuiteName, testTransactionEnable)
// Start a traversal.
g := newWithOptionsConnection(t)

// Create transactions
tx := g.Tx()

_, err := tx.Begin()
assert.Nil(t, err)

// try to commit
err = tx.Commit()
assert.True(t, strings.HasPrefix(err.Error(),
"E0502: error in read loop, error message '{code:244 message:Graph does not support transactions"))
})

t.Run("Test WithOptions.Tokens WithOptions.None", func(t *testing.T) {
skipTestsIfNotEnabled(t, integrationTestSuiteName, getEnvOrDefaultBool("RUN_INTEGRATION_WITH_ALIAS_TESTS", true))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,22 @@ class Transaction {
* @returns {Promise}
*/
commit() {
return this._sessionBasedConnection.commit().then(() => this.close());
if (!this._sessionBasedConnection) {
throw new Error('Cannot commit a transaction that is not started');
}

return this._sessionBasedConnection.commit().finally(() => this.close());
}

/**
* @returns {Promise}
*/
rollback() {
return this._sessionBasedConnection.rollback().then(() => this.close());
if (!this._sessionBasedConnection) {
throw new Error('Cannot rollback a transaction that is not started');
}

return this._sessionBasedConnection.rollback().finally(() => this.close());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,32 @@ describe('Traversal', function () {
}, (err) => assert.fail("tanked: " + err));
});
});
describe("should handle tx errors if graph not support tx", function() {
it('should throw exception on commit if graph not support tx', async function() {
const g = traversal().withRemote(connection);
const tx = g.tx();
const gtx = tx.begin();
const result = await g.V().count().next();
assert.strictEqual(6, result.value);
try {
await tx.commit();
assert.fail("should throw error");
} catch (err) {
assert.strictEqual("Server error: Graph does not support transactions (500)", err.message);
}
});
it('should throw exception on rollback if graph not support tx', async function() {
const g = traversal().withRemote(connection);
const tx = g.tx();
tx.begin();
try {
await tx.rollback();
assert.fail("should throw error");
} catch (err) {
assert.strictEqual("Server error: Graph does not support transactions (500)", err.message);
}
});
});
describe('support remote transactions - commit', function() {
before(function () {
txConnection = helper.getConnection('gtx');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,29 @@ describe('Traversal', function () {
});
});

describe('not opened transactions', function() {
it('should not allow commit for not opened transactions', async function() {
const g = anon.traversal().withRemote(new MockRemoteConnection());
const tx = g.tx();
try {
await tx.commit();
assert.fail("should throw error");
} catch (err) {
assert.strictEqual('Cannot commit a transaction that is not started', err.message);
}
});
it('should not allow rollback for not opened transactions', async function() {
const g = anon.traversal().withRemote(new MockRemoteConnection());
const tx = g.tx();
try {
await tx.rollback();
assert.fail("should throw error");
} catch (err) {
assert.strictEqual('Cannot rollback a transaction that is not started', err.message);
}
});
});

describe('tx#begin()', function() {
it("should not allow a transaction to begin more than once", function() {
const g = anon.traversal().withRemote(new MockRemoteConnection());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1751,7 +1751,7 @@ def begin(self):
def rollback(self):
with self.__mutex:
# Verify transaction is open, close session and return result of transaction's rollback.
self.__verify_transaction_state(True, "Cannot commit a transaction that is not started.")
self.__verify_transaction_state(True, "Cannot rollback a transaction that is not started.")
return self.__close_session(self._session_based_connection.rollback())

# Commits the current transaction.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,37 @@ def test_close_sessions(self, remote_transaction_connection):
# after closing transaction we should remove spawned_session
assert 0 == len(remote_transaction_connection._DriverRemoteConnection__spawned_sessions)

def test_tx_on_graph_without_tx_support(self, remote_connection):
g = traversal().withRemote(remote_connection)
tx = g.tx()
try:
# tx is just a session, so no exception here
gtx = tx.begin()
# read operation is ok for sessioned connection
assert 6 == gtx.V().count().next()
tx.commit().all().result()
assert False
except GremlinServerError as ex:
assert "500: Graph does not support transactions" == str(ex)

def test_tx_commit_on_graph_without_tx_support(self, remote_connection):
g = traversal().withRemote(remote_connection)
tx = g.tx()
try:
tx.commit()
assert False
except Exception as ex:
assert "Cannot commit a transaction that is not started." == str(ex)

def test_tx_rollback_on_graph_without_tx_support(self, remote_connection):
g = traversal().withRemote(remote_connection)
tx = g.tx()
try:
tx.rollback()
assert False
except Exception as ex:
assert "Cannot rollback a transaction that is not started." == str(ex)

def test_clone(self, remote_connection):
g = traversal().withRemote(remote_connection)
t = g.V().both()
Expand Down

0 comments on commit 0756e12

Please sign in to comment.