From 1b407e076593b9e6957c140fbb36224a80a65374 Mon Sep 17 00:00:00 2001
From: milogreg <oldesoot@gmail.com>
Date: Sun, 8 Dec 2024 16:40:45 -0800
Subject: [PATCH] Add bats tests for config file generation

---
 .../bats/helper/query-server-common.bash      |  12 +-
 .../sql-server-config-file-generation.bats    | 142 ++++++++++++++++++
 2 files changed, 151 insertions(+), 3 deletions(-)
 create mode 100644 integration-tests/bats/sql-server-config-file-generation.bats

diff --git a/integration-tests/bats/helper/query-server-common.bash b/integration-tests/bats/helper/query-server-common.bash
index 456be9d53ea..cf9e05aef89 100644
--- a/integration-tests/bats/helper/query-server-common.bash
+++ b/integration-tests/bats/helper/query-server-common.bash
@@ -60,12 +60,18 @@ start_sql_server() {
 # arguments to dolt-sql-server (excluding --port, which is defined in
 # this func)
 start_sql_server_with_args() {
-    DEFAULT_DB=""
     PORT=$( definePORT )
+    start_sql_server_with_args_no_port "$@" --port=$PORT
+}
+
+# behaves like start_sql_server_with_args, but doesn't define --port.
+# caller must set variable PORT to proper value before calling.
+start_sql_server_with_args_no_port() {
+    DEFAULT_DB=""
     if [ "$IS_WINDOWS" == true ]; then
-      dolt sql-server "$@" --port=$PORT &
+      dolt sql-server "$@" &
     else
-      dolt sql-server "$@" --port=$PORT --socket "dolt.$PORT.sock" &
+      dolt sql-server "$@" --socket "dolt.$PORT.sock" &
     fi
     SERVER_PID=$!
     wait_for_connection $PORT 8500
diff --git a/integration-tests/bats/sql-server-config-file-generation.bats b/integration-tests/bats/sql-server-config-file-generation.bats
new file mode 100644
index 00000000000..63daf9e0ad9
--- /dev/null
+++ b/integration-tests/bats/sql-server-config-file-generation.bats
@@ -0,0 +1,142 @@
+#!/usr/bin/env bats
+load "$BATS_TEST_DIRNAME/helper/common.bash"
+load "$BATS_TEST_DIRNAME/helper/query-server-common.bash"
+
+CONFIG_FILE_NAME=config.yaml
+
+DATABASE_DIRS=(
+    .
+    mydir
+    nest1/nest2/nest3
+)
+
+setup() {
+    setup_common
+}
+
+teardown() {
+    stop_sql_server
+    teardown_common
+}
+
+@test "sql-server-config-file-generation: config file is generated if one doesn't exist" {
+    for data_dir in "${DATABASE_DIRS[@]}"; do
+        if [[ "$data_dir" != "." ]]; then
+            mkdir -p "$data_dir"
+        fi
+
+        start_sql_server_with_args --data-dir "$data_dir" --host 0.0.0.0 --user dolt
+
+        [[ -f "$data_dir/$CONFIG_FILE_NAME" ]] || false
+
+        rm "$data_dir/$CONFIG_FILE_NAME"
+        stop_sql_server
+    done
+}
+
+@test "sql-server-config-file-generation: config file isn't generated if one already exists" {
+    for data_dir in "${DATABASE_DIRS[@]}"; do
+        if [[ "$data_dir" != "." ]]; then
+            mkdir -p "$data_dir"
+        fi
+
+        echo "Don't overwrite me!" >"$data_dir/$CONFIG_FILE_NAME"
+
+        start_sql_server_with_args --data-dir "$data_dir" --host 0.0.0.0 --user dolt
+
+        run cat "$data_dir/$CONFIG_FILE_NAME"
+        [ $status -eq 0 ]
+        [[ "$output" =~ "Don't overwrite me!" ]] || false
+
+        rm "$data_dir/$CONFIG_FILE_NAME"
+        stop_sql_server
+    done
+}
+
+@test "sql-server-config-file-generation: config file isn't generated if a config is specified in args" {
+    for data_dir in "${DATABASE_DIRS[@]}"; do
+        if [[ "$data_dir" != "." ]]; then
+            mkdir -p "$data_dir"
+        fi
+
+        NOT_CONFIG_FILE_NAME="not-$CONFIG_FILE_NAME"
+        PORT=$(definePORT)
+
+        cat >"$data_dir/$NOT_CONFIG_FILE_NAME" <<EOF
+user:
+  name: dolt
+
+listener:
+  host: 0.0.0.0
+  port: $PORT
+
+data_dir: $data_dir
+
+# Don't overwrite me!
+EOF
+
+        start_sql_server_with_args_no_port --config "$data_dir/$NOT_CONFIG_FILE_NAME"
+
+        [[ ! -f "$data_dir/$CONFIG_FILE_NAME" ]] || false
+
+        run cat "$data_dir/$NOT_CONFIG_FILE_NAME"
+        [ $status -eq 0 ]
+        [[ "$output" =~ "Don't overwrite me!" ]] || false
+
+        rm "$data_dir/$NOT_CONFIG_FILE_NAME"
+        stop_sql_server
+    done
+}
+
+@test "sql-server-config-file-generation: generated config file has fields set to arg-provided values" {
+    start_sql_server_with_args \
+        --readonly \
+        --no-auto-commit \
+        --persistence-behavior ignore \
+        --max-connections 77 \
+        --timeout 7777777 \
+        --allow-cleartext-passwords true \
+        --host 0.0.0.0 \
+        --user dolt
+
+    run cat "$CONFIG_FILE_NAME"
+    [ $status -eq 0 ]
+    [[ "$output" =~ "read_only: true" ]] || false
+    [[ "$output" =~ "autocommit: false" ]] || false
+    [[ "$output" =~ "persistence_behavior: ignore" ]] || false
+    [[ "$output" =~ "max_connections: 77" ]] || false
+    [[ "$output" =~ "read_timeout_millis: 7777777" ]] || false
+    [[ "$output" =~ "write_timeout_millis: 7777777" ]] || false
+    [[ "$output" =~ "allow_cleartext_passwords: true" ]] || false
+}
+
+@test "sql-server-config-file-generation: generated config file has unset fields set to default values" {
+    start_sql_server_with_args \
+        --max-connections 77 \
+        --timeout 7777777 \
+        --host 0.0.0.0 \
+        --user dolt
+
+    run cat "$CONFIG_FILE_NAME"
+    [ $status -eq 0 ]
+
+    # not default (set by args)
+    [[ "$output" =~ "max_connections: 77" ]] || false
+    [[ "$output" =~ "read_timeout_millis: 7777777" ]] || false
+    [[ "$output" =~ "write_timeout_millis: 7777777" ]] || false
+
+    # default (not set by args)
+    [[ "$output" =~ "read_only: false" ]] || false
+    [[ "$output" =~ "autocommit: true" ]] || false
+    [[ "$output" =~ "persistence_behavior: load" ]] || false
+    [[ "$output" =~ "allow_cleartext_passwords: false" ]] || false
+}
+
+@test "sql-server-config-file-generation: generated config file has placeholders for unset fields with no default values" {
+    start_sql_server
+
+    run cat "$CONFIG_FILE_NAME"
+    [ $status -eq 0 ]
+    [[ "$output" =~ "# tls_key:" ]] || false
+    [[ "$output" =~ "# tls_cert:" ]] || false
+}