This is an automated email from the ASF dual-hosted git repository.

spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new 3e18838  feat: enhance the verification of the configuration (#5171)
3e18838 is described below

commit 3e188389e39369ecae248a47f6b829e0c08e7ae7
Author: nic-chen <[email protected]>
AuthorDate: Fri Oct 8 08:51:10 2021 +0800

    feat: enhance the verification of the configuration (#5171)
---
 apisix/cli/ops.lua             | 41 +++++++++++++++++++++++++++++++++++++
 docs/en/latest/how-to-build.md |  9 +++++++++
 docs/zh/latest/how-to-build.md |  9 +++++++++
 t/cli/test_validate_config.sh  | 46 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 105 insertions(+)

diff --git a/apisix/cli/ops.lua b/apisix/cli/ops.lua
index e179522..750f5b1 100644
--- a/apisix/cli/ops.lua
+++ b/apisix/cli/ops.lua
@@ -34,6 +34,7 @@ local tostring = tostring
 local tonumber = tonumber
 local io_open = io.open
 local execute = os.execute
+local os_rename = os.rename
 local table_insert = table.insert
 local getenv = os.getenv
 local max = math.max
@@ -891,6 +892,43 @@ local function cleanup()
 end
 
 
+local function test(env, backup_ngx_conf)
+    -- backup nginx.conf
+    local ngx_conf_path = env.apisix_home .. "/conf/nginx.conf"
+    local ngx_conf_exist = util.is_file_exist(ngx_conf_path)
+    if ngx_conf_exist then
+        local ok, err = os_rename(ngx_conf_path, ngx_conf_path .. ".bak")
+        if not ok then
+            util.die("failed to backup nginx.conf, error: ", err)
+        end
+    end
+
+    -- reinit nginx.conf
+    init(env)
+
+    local test_cmd = env.openresty_args .. [[ -t -q ]]
+    local test_ret = execute((test_cmd))
+
+    -- restore nginx.conf
+    if ngx_conf_exist then
+        local ok, err = os_rename(ngx_conf_path .. ".bak", ngx_conf_path)
+        if not ok then
+            util.die("failed to restore original nginx.conf, error: ", err)
+        end
+    end
+
+    -- When success,
+    -- On linux, os.execute returns 0,
+    -- On macos, os.execute returns 3 values: true, exit, 0, and we need the 
first.
+    if (test_ret == 0 or test_ret == true) then
+        print("configuration test is successful")
+        return
+    end
+
+    util.die("configuration test failed")
+end
+
+
 local function quit(env)
     cleanup()
 
@@ -908,6 +946,8 @@ end
 
 
 local function restart(env)
+  -- test configuration
+  test(env)
   stop(env)
   start(env)
 end
@@ -943,6 +983,7 @@ local action = {
     quit = quit,
     restart = restart,
     reload = reload,
+    test = test,
 }
 
 
diff --git a/docs/en/latest/how-to-build.md b/docs/en/latest/how-to-build.md
index 09c5d7c..22b3ba9 100644
--- a/docs/en/latest/how-to-build.md
+++ b/docs/en/latest/how-to-build.md
@@ -93,6 +93,15 @@ Run the following command to initialize the NGINX 
configuration file and etcd.
 apisix init
 ```
 
+### Test configuration file
+
+Run the following command to test the configuration file. APISIX will generate 
`nginx.conf` from `config.yaml` and check whether the syntax of `nginx.conf` is 
correct.
+
+```shell
+# generate `nginx.conf` from `config.yaml` and test it
+apisix test
+```
+
 ### Start Apache APISIX
 
 Run the following command to start Apache APISIX.
diff --git a/docs/zh/latest/how-to-build.md b/docs/zh/latest/how-to-build.md
index 7bbbb76..c419591 100644
--- a/docs/zh/latest/how-to-build.md
+++ b/docs/zh/latest/how-to-build.md
@@ -93,6 +93,15 @@ sudo yum install -y 
https://github.com/apache/apisix/releases/download/2.10.0/ap
 apisix init
 ```
 
+### 测试配置文件
+
+运行以下命令测试配置文件。 APISIX 将根据 `config.yaml` 生成 `nginx.conf` ,并检查 `nginx.conf` 
的语法是否正确。
+
+```shell
+# generate `nginx.conf` from `config.yaml` and test it
+apisix test
+```
+
 ### 启动 Apache APISIX
 
 运行以下命令启动 Apache APISIX。
diff --git a/t/cli/test_validate_config.sh b/t/cli/test_validate_config.sh
index 96f6bf2..c2c7b69 100755
--- a/t/cli/test_validate_config.sh
+++ b/t/cli/test_validate_config.sh
@@ -89,3 +89,49 @@ fi
 git checkout conf/config-default.yaml
 
 echo "passed: allow configuring node_listen as a number in the default config"
+
+# apisix test
+git checkout conf/config.yaml
+
+out=$(./bin/apisix test 2>&1 || true)
+if ! echo "$out" | grep "configuration test is successful"; then
+    echo "failed: configuration test should be successful"
+    exit 1
+fi
+
+echo "pass: apisix test"
+
+./bin/apisix start
+sleep 1 # wait for apisix starts
+
+# set invalid configuration
+echo '
+nginx_config:
+    main_configuration_snippet: |
+        notexist on;
+' > conf/config.yaml
+
+# apisix restart
+out=$(./bin/apisix restart 2>&1 || true)
+if ! (echo "$out" | grep "\[emerg\] unknown directive \"notexist\"") && ! 
(echo "$out" | grep "APISIX is running"); then
+    echo "failed: should restart failed when configuration invalid"
+    exit 1
+fi
+
+echo "passed: apisix restart"
+
+# apisix test - failure scenario
+out=$(./bin/apisix test 2>&1 || true)
+if ! echo "$out" | grep "configuration test failed"; then
+    echo "failed: should test failed when configuration invalid"
+    exit 1
+fi
+
+# apisix test failure should not affect apisix stop
+out=$(./bin/apisix stop 2>&1 || true)
+if echo "$out" | grep "\[emerg\] unknown directive \"notexist\""; then
+    echo "failed: `apisix test` failure should not affect `apisix stop`"
+    exit 1
+fi
+
+echo "passed: apisix test(failure scenario)"

Reply via email to