diff --git a/.circleci/config.yml b/.circleci/config.yml index 48717dff..ef7ffe09 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -41,7 +41,7 @@ parameters: default: "gcr.io/gcr-for-testing/golang:1.24.9" arangodbImage: type: string - default: "gcr.io/gcr-for-testing/arangodb/enterprise-preview:latest" + default: "public.ecr.aws/b0b8h2r4/enterprise-preview:2025-12-01-devel-d759089-amd64" alpineImage: type: string default: "gcr.io/gcr-for-testing/alpine:3.21" diff --git a/test/asyncjob_test.go b/test/asyncjob_test.go index 43d67b9e..18370290 100644 --- a/test/asyncjob_test.go +++ b/test/asyncjob_test.go @@ -101,6 +101,9 @@ func TestAsyncJobListPending(t *testing.T) { EnsureVersion(t, ctx, c).CheckVersion(MinimumVersion("3.11.1")) skipResilientSingle(t) + // for disabling v8 tests + skipBelowVersion(c, "4.0", t) + db := ensureDatabase(ctx, c, databaseName("db", "async"), nil, t) defer func() { err := db.Remove(ctx) @@ -254,6 +257,9 @@ func TestAsyncJobDelete(t *testing.T) { }) t.Run("delete pending job", func(t *testing.T) { + // for disabling v8 tests + skipBelowVersion(c, "4.0", t) + idTransaction := runLongRequest(t, ctxAsync, db, 10, col.Name()) require.NotEmpty(t, idTransaction) @@ -275,6 +281,9 @@ func TestAsyncJobDelete(t *testing.T) { }) t.Run("delete expired jobs", func(t *testing.T) { + // for disabling v8 tests + skipBelowVersion(c, "4.0", t) + idTransaction := runLongRequest(t, ctxAsync, db, 10, col.Name()) require.NotEmpty(t, idTransaction) diff --git a/test/database_transaction_test.go b/test/database_transaction_test.go index 431ee4e9..54a23070 100644 --- a/test/database_transaction_test.go +++ b/test/database_transaction_test.go @@ -33,7 +33,9 @@ import ( func TestDatabaseTransaction(t *testing.T) { c := createClient(t, nil) - skipBelowVersion(c, "3.2", t) + // for disabling v8 tests + skipBelowVersion(c, "4.0", t) + db := ensureDatabase(nil, c, "transaction_test", nil, t) defer func() { err := db.Remove(nil) diff --git a/v2/tests/asyncjob_test.go b/v2/tests/asyncjob_test.go index f8ecfe26..226da7d5 100644 --- a/v2/tests/asyncjob_test.go +++ b/v2/tests/asyncjob_test.go @@ -111,6 +111,8 @@ func TestAsyncJobListPending(t *testing.T) { skipBelowVersion(client, ctx, "3.11.1", t) skipResilientSingleMode(t) + requireV8Enabled(client, ctx, t) + ctxAsync := connection.WithAsync(context.Background()) idTransaction := runLongRequest(t, ctxAsync, db, 2, col.Name()) @@ -254,6 +256,7 @@ func TestAsyncJobDelete(t *testing.T) { }) t.Run("delete pending job", func(t *testing.T) { + requireV8Enabled(client, ctx, t) idTransaction := runLongRequest(t, ctxAsync, db, 10, col.Name()) require.NotEmpty(t, idTransaction) @@ -275,6 +278,7 @@ func TestAsyncJobDelete(t *testing.T) { }) t.Run("delete expired jobs", func(t *testing.T) { + requireV8Enabled(client, ctx, t) idTransaction := runLongRequest(t, ctxAsync, db, 10, col.Name()) require.NotEmpty(t, idTransaction) diff --git a/v2/tests/database_query_test.go b/v2/tests/database_query_test.go index d5d34470..f7667466 100644 --- a/v2/tests/database_query_test.go +++ b/v2/tests/database_query_test.go @@ -1271,6 +1271,7 @@ func Test_UserDefinedFunctions(t *testing.T) { Wrap(t, func(t *testing.T, client arangodb.Client) { WithDatabase(t, client, nil, func(db arangodb.Database) { withContextT(t, defaultTestTimeout, func(ctx context.Context, tb testing.TB) { + requireV8Enabled(client, ctx, tb) // Define UDF details namespace := "myfunctions::temperature::" + StringWithCharset(16, charset) functionName := namespace + "::celsiustofahrenheit" diff --git a/v2/tests/database_transactionsjs_test.go b/v2/tests/database_transactionsjs_test.go index 9d9b19ff..ed112702 100644 --- a/v2/tests/database_transactionsjs_test.go +++ b/v2/tests/database_transactionsjs_test.go @@ -34,7 +34,7 @@ func Test_DatabaseTransactionsJS(t *testing.T) { Wrap(t, func(t *testing.T, client arangodb.Client) { WithDatabase(t, client, nil, func(db arangodb.Database) { WithCollectionV2(t, db, nil, func(col arangodb.Collection) { - + requireV8Enabled(client, context.Background(), t) t.Run("Transaction ReturnValue", func(t *testing.T) { withContextT(t, defaultTestTimeout, func(ctx context.Context, t testing.TB) { txJSOptions := arangodb.TransactionJSOptions{ diff --git a/v2/tests/foxx_test.go b/v2/tests/foxx_test.go index b7431e75..26cbb766 100644 --- a/v2/tests/foxx_test.go +++ b/v2/tests/foxx_test.go @@ -36,6 +36,7 @@ func Test_FoxxItzpapalotlService(t *testing.T) { Wrap(t, func(t *testing.T, client arangodb.Client) { WithDatabase(t, client, nil, func(db arangodb.Database) { withContextT(t, defaultTestTimeout, func(ctx context.Context, tb testing.TB) { + requireV8Enabled(client, ctx, tb) if os.Getenv("TEST_CONNECTION") == "vst" { skipBelowVersion(client, ctx, "3.6", t) } @@ -298,6 +299,7 @@ func Test_ListInstalledFoxxServices(t *testing.T) { Wrap(t, func(t *testing.T, client arangodb.Client) { WithDatabase(t, client, nil, func(db arangodb.Database) { withContextT(t, defaultTestTimeout, func(ctx context.Context, tb testing.TB) { + requireV8Enabled(client, ctx, tb) services, err := client.ListInstalledFoxxServices(ctx, db.Name(), nil) require.NoError(t, err) require.NotEmpty(t, services) @@ -325,6 +327,7 @@ func Test_GetInstalledFoxxService(t *testing.T) { Wrap(t, func(t *testing.T, client arangodb.Client) { WithDatabase(t, client, nil, func(db arangodb.Database) { withContextT(t, defaultTestTimeout, func(ctx context.Context, tb testing.TB) { + requireV8Enabled(client, ctx, tb) mount := "/_api/foxx" serviceDetails, err := client.GetInstalledFoxxService(ctx, db.Name(), &mount) require.NoError(t, err) diff --git a/v2/tests/tasks_test.go b/v2/tests/tasks_test.go index fce10bea..a52e65de 100644 --- a/v2/tests/tasks_test.go +++ b/v2/tests/tasks_test.go @@ -53,69 +53,73 @@ type TaskParams struct { func Test_CreateNewTask(t *testing.T) { Wrap(t, func(t *testing.T, client arangodb.Client) { - dbName := "_system" - testCases := map[string]*arangodb.TaskOptions{ - "taskWithParams": { - Name: utils.NewType("taskWithParams"), - Command: utils.NewType("(function(params) { require('@arangodb').print(params); })(params)"), - Period: utils.NewType(int64(2)), - Params: map[string]interface{}{ - "test": "hello", - }, - }, - "taskWithoutParams": { - Name: utils.NewType("taskWithoutParams"), - Command: utils.NewType("(function() { require('@arangodb').print('Hello'); })()"), - Period: utils.NewType(int64(2)), - }, - } - - for name, options := range testCases { + WithDatabase(t, client, nil, func(db arangodb.Database) { withContextT(t, defaultTestTimeout, func(ctx context.Context, tb testing.TB) { - createdTask, err := client.CreateTask(ctx, dbName, *options) - require.NoError(t, err) - require.NotNil(t, createdTask) - require.Equal(t, name, *createdTask.Name()) - t.Logf("Params: %v", options.Params) - // Proper params comparison - // Check parameters - if options.Params != nil { - var params map[string]interface{} - err = createdTask.Params(¶ms) - - if err != nil { - t.Logf("WARNING: Could not fetch task params (unsupported feature?): %v", err) - } else if len(params) == 0 { - t.Logf("WARNING: Task params exist but returned empty (ArangoDB limitation?)") - } else { - // Only check if params are actually returned - require.Equal(t, options.Params, params) - } + requireV8Enabled(client, ctx, tb) + testCases := map[string]*arangodb.TaskOptions{ + "taskWithParams": { + Name: utils.NewType("taskWithParams"), + Command: utils.NewType("(function(params) { require('@arangodb').print(params); })(params)"), + Period: utils.NewType(int64(2)), + Params: map[string]interface{}{ + "test": "hello", + }, + }, + "taskWithoutParams": { + Name: utils.NewType("taskWithoutParams"), + Command: utils.NewType("(function() { require('@arangodb').print('Hello'); })()"), + Period: utils.NewType(int64(2)), + }, } - taskInfo, err := client.Task(ctx, dbName, *createdTask.ID()) - require.NoError(t, err) - require.NotNil(t, taskInfo) - require.Equal(t, name, *taskInfo.Name()) - - tasks, err := client.Tasks(ctx, dbName) - require.NoError(t, err) - require.NotNil(t, tasks) - require.Greater(t, len(tasks), 0, "Expected at least one task to be present") - t.Logf("Found tasks: %v", tasks) - if len(tasks) > 0 && tasks[0].ID() != nil { - t.Logf("Task Id to be removed: %s\n", *tasks[0].ID()) - } else { - t.Logf("Task Id to be removed: ") - } - if id := createdTask.ID(); id != nil { - require.NoError(t, client.RemoveTask(ctx, dbName, *id)) - t.Logf("Task %s removed successfully", *id) - } else { - t.Logf("Task ID is nil") + for name, options := range testCases { + withContextT(t, defaultTestTimeout, func(ctx context.Context, tb testing.TB) { + createdTask, err := client.CreateTask(ctx, db.Name(), *options) + require.NoError(t, err) + require.NotNil(t, createdTask) + require.Equal(t, name, *createdTask.Name()) + t.Logf("Params: %v", options.Params) + // Proper params comparison + // Check parameters + if options.Params != nil { + var params map[string]interface{} + err = createdTask.Params(¶ms) + + if err != nil { + t.Logf("WARNING: Could not fetch task params (unsupported feature?): %v", err) + } else if len(params) == 0 { + t.Logf("WARNING: Task params exist but returned empty (ArangoDB limitation?)") + } else { + // Only check if params are actually returned + require.Equal(t, options.Params, params) + } + } + + taskInfo, err := client.Task(ctx, db.Name(), *createdTask.ID()) + require.NoError(t, err) + require.NotNil(t, taskInfo) + require.Equal(t, name, *taskInfo.Name()) + + tasks, err := client.Tasks(ctx, db.Name()) + require.NoError(t, err) + require.NotNil(t, tasks) + require.Greater(t, len(tasks), 0, "Expected at least one task to be present") + t.Logf("Found tasks: %v", tasks) + if len(tasks) > 0 && tasks[0].ID() != nil { + t.Logf("Task Id to be removed: %s\n", *tasks[0].ID()) + } else { + t.Logf("Task Id to be removed: ") + } + if id := createdTask.ID(); id != nil { + require.NoError(t, client.RemoveTask(ctx, db.Name(), *id)) + t.Logf("Task %s removed successfully", *id) + } else { + t.Logf("Task ID is nil") + } + }) } }) - } + }) }, WrapOptions{ Parallel: utils.NewType(false), }) @@ -123,29 +127,32 @@ func Test_CreateNewTask(t *testing.T) { func Test_ValidationsForCreateNewTask(t *testing.T) { Wrap(t, func(t *testing.T, client arangodb.Client) { - dbName := "_system" - testCases := map[string]*arangodb.TaskOptions{ - "taskWithoutCommand": { - Name: utils.NewType("taskWithoutCommand"), - Period: utils.NewType(int64(2)), - }, - "taskWithoutPeriod": nil, - } - - for name, options := range testCases { + WithDatabase(t, client, nil, func(db arangodb.Database) { withContextT(t, defaultTestTimeout, func(ctx context.Context, tb testing.TB) { - var err error - if options == nil { - _, err = client.CreateTask(ctx, dbName, arangodb.TaskOptions{}) - } else { - _, err = client.CreateTask(ctx, dbName, *options) + requireV8Enabled(client, ctx, tb) + testCases := map[string]*arangodb.TaskOptions{ + "taskWithoutCommand": { + Name: utils.NewType("taskWithoutCommand"), + Period: utils.NewType(int64(2)), + }, + "taskWithoutPeriod": nil, } - require.Error(t, err) - t.Logf("Expected error for task '%s': %v", name, err) + for name, options := range testCases { + withContextT(t, defaultTestTimeout, func(ctx context.Context, tb testing.TB) { + var err error + if options == nil { + _, err = client.CreateTask(ctx, db.Name(), arangodb.TaskOptions{}) + } else { + _, err = client.CreateTask(ctx, db.Name(), *options) + } + + require.Error(t, err) + t.Logf("Expected error for task '%s': %v", name, err) + }) + } }) - } - + }) }, WrapOptions{ Parallel: utils.NewType(false), }) @@ -153,36 +160,38 @@ func Test_ValidationsForCreateNewTask(t *testing.T) { func Test_TaskCreationWithId(t *testing.T) { Wrap(t, func(t *testing.T, client arangodb.Client) { - withContextT(t, defaultTestTimeout, func(ctx context.Context, tb testing.TB) { - dbName := "_system" - taskID := "test-task-id" + StringWithCharset(16, charset) - options := &arangodb.TaskOptions{ - ID: &taskID, // Optional if CreateTaskWithID sets it, but safe to keep - Name: utils.NewType("TestTaskWithID"), - Command: utils.NewType("console.log('This is a test task with ID');"), - Period: utils.NewType(int64(5)), - } - - // Create the task with explicit ID - task, err := client.CreateTaskWithID(ctx, dbName, taskID, *options) - require.NoError(t, err, "Expected task creation to succeed") - require.NotNil(t, task, "Expected task to be non-nil") - require.Equal(t, taskID, *task.ID(), "Task ID mismatch") - require.Equal(t, *options.Name, *task.Name(), "Task Name mismatch") - - // Retrieve and validate - retrievedTask, err := client.Task(ctx, dbName, taskID) - require.NoError(t, err, "Expected task retrieval to succeed") - require.NotNil(t, retrievedTask, "Expected retrieved task to be non-nil") - require.Equal(t, taskID, *retrievedTask.ID(), "Retrieved task ID mismatch") - require.Equal(t, *options.Name, *retrievedTask.Name(), "Retrieved task Name mismatch") - - _, err = client.CreateTaskWithID(ctx, dbName, taskID, *options) - require.Error(t, err, "Creating a duplicate task should fail") - - // Clean up - err = client.RemoveTask(ctx, dbName, taskID) - require.NoError(t, err, "Expected task removal to succeed") + WithDatabase(t, client, nil, func(db arangodb.Database) { + withContextT(t, defaultTestTimeout, func(ctx context.Context, tb testing.TB) { + requireV8Enabled(client, ctx, tb) + taskID := "test-task-id" + StringWithCharset(16, charset) + options := &arangodb.TaskOptions{ + ID: &taskID, // Optional if CreateTaskWithID sets it, but safe to keep + Name: utils.NewType("TestTaskWithID"), + Command: utils.NewType("console.log('This is a test task with ID');"), + Period: utils.NewType(int64(5)), + } + + // Create the task with explicit ID + task, err := client.CreateTaskWithID(ctx, db.Name(), taskID, *options) + require.NoError(t, err, "Expected task creation to succeed") + require.NotNil(t, task, "Expected task to be non-nil") + require.Equal(t, taskID, *task.ID(), "Task ID mismatch") + require.Equal(t, *options.Name, *task.Name(), "Task Name mismatch") + + // Retrieve and validate + retrievedTask, err := client.Task(ctx, db.Name(), taskID) + require.NoError(t, err, "Expected task retrieval to succeed") + require.NotNil(t, retrievedTask, "Expected retrieved task to be non-nil") + require.Equal(t, taskID, *retrievedTask.ID(), "Retrieved task ID mismatch") + require.Equal(t, *options.Name, *retrievedTask.Name(), "Retrieved task Name mismatch") + + _, err = client.CreateTaskWithID(ctx, db.Name(), taskID, *options) + require.Error(t, err, "Creating a duplicate task should fail") + + // Clean up + err = client.RemoveTask(ctx, db.Name(), taskID) + require.NoError(t, err, "Expected task removal to succeed") + }) }) }) } diff --git a/v2/tests/util_test.go b/v2/tests/util_test.go index 3450f3ee..4b8756fa 100644 --- a/v2/tests/util_test.go +++ b/v2/tests/util_test.go @@ -29,6 +29,7 @@ import ( "github.com/stretchr/testify/require" "github.com/arangodb/go-driver/v2/arangodb" + "github.com/arangodb/go-driver/v2/utils" ) func getTestMode() string { @@ -136,3 +137,26 @@ func skipVersionNotInRange(c arangodb.Client, ctx context.Context, minVersion, m } return x } + +// requireV8Enabled skips the test if V8 is disabled in the ArangoDB server. +// V8 is required for features like tasks, UDFs, Foxx, JS transactions, and simple queries. +// This function checks the v8-version field in the version details. +// If v8-version is "none", V8 is disabled and the test will be skipped. +func requireV8Enabled(c arangodb.Client, ctx context.Context, t testing.TB) { + versionInfo, err := c.VersionWithOptions(ctx, &arangodb.GetVersionOptions{ + Details: utils.NewType(true), + }) + if err != nil { + t.Fatalf("Failed to get version info with details: %s", err) + } + + // Check if v8-version exists in Details and if it's "none" + if versionInfo.Details != nil { + if v8Version, ok := versionInfo.Details["v8-version"]; ok { + if v8VersionStr, ok := v8Version.(string); ok && v8VersionStr == "none" { + t.Skip("Skipping test: V8 is disabled in this ArangoDB server (v8-version: none). " + + "This test requires V8 enabled.") + } + } + } +}