diff --git a/test/env.bats b/test/env.bats index 81da2d52f982b0d1f3f7b6004337bf892f342db4..82cdc71ee1b0bb024a4691cd6ee5402685c164de 100644 --- a/test/env.bats +++ b/test/env.bats @@ -18,5 +18,14 @@ load test_helper @test "Check dial timeout" { run timeout 1 ${SOAR_BIN} -test-dsn "1.1.1.1" -check-config + echo "$output" [ $status -eq 124 ] } + +# 12. 带数据库连接时黑名单功能是否正常 +# soar 的日志和黑名单的相对路径都相对于 soar 的二进制文件路径说的 +@test "Check Soar With Mysql Connect Blacklist" { + run ${SOAR_BIN_ENV} -blacklist ../etc/soar.blacklist -query "show processlist;" + [ $status -eq 0 ] + [ -z ${output} ] +} diff --git a/test/fixture/test_Check_-2dreport-2dtype_rewrite_-2drewrite-2drules_mergealter.golden b/test/fixture/test_Check_-2dreport-2dtype_rewrite_-2drewrite-2drules_mergealter.golden deleted file mode 100644 index 702c6827ffc2801683ed15f2a091d4405e256781..0000000000000000000000000000000000000000 --- a/test/fixture/test_Check_-2dreport-2dtype_rewrite_-2drewrite-2drules_mergealter.golden +++ /dev/null @@ -1,79 +0,0 @@ -ALTER TABLE `address` add index idx_city_id(city_id) ; -ALTER TABLE `inventory` add index `idx_store_film` (`store_id`,`film_id`), add index `idx_store_film` (`store_id`,`film_id`),add index `idx_store_film` (`store_id`,`film_id`),add index `idx_store_film` (`store_id`,`film_id`) ; -ALTER TABLE `tb` alter column id drop default ; -DELETE a1, a2 FROM city AS a1 INNER JOIN country AS a2 WHERE a1.country_id=a2.country_id -DELETE city, country FROM city INNER JOIN country using (country_id) WHERE city.city_id = 1 -DELETE city FROM city LEFT JOIN country ON city.country_id = country.country_id WHERE country.country IS NULL -DELETE FROM a1, a2 USING city AS a1 INNER JOIN country AS a2 WHERE a1.country_id=a2.country_id -DELETE FROM film WHERE length > 100 -INSERT INTO city (country_id) SELECT 10 FROM DUAL -INSERT INTO city (country_id) SELECT country_id FROM country -INSERT INTO city (country_id) VALUES (1),(2),(3) -REPLACE INTO city (country_id) SELECT 10 FROM DUAL -REPLACE INTO city (country_id) SELECT country_id FROM country -REPLACE INTO city (country_id) VALUES (1),(2),(3) -SELECT a.address, a.postal_code FROM sakila.address a WHERE a.city_id IN (SELECT c.city_id FROM sakila.city c) -SELECT a.country_id, a.last_update FROM city a STRAIGHT_JOIN country b ON a.country_id=b.country_id -SELECT city FROM( SELECT city_id FROM city WHERE city = "A Corua (La Corua)" ORDER BY last_update DESC LIMIT 50, 10) I JOIN city ON (I.city_id = city.city_id) JOIN country ON (country.country_id = city.country_id) ORDER BY city DESC -SELECT country_id, last_update FROM city NATURAL JOIN country -SELECT country_id, last_update FROM city NATURAL LEFT JOIN country -SELECT country_id, last_update FROM city NATURAL RIGHT JOIN country -SELECT DATE_FORMAT(t.last_update, '%Y-%m-%d'), COUNT(DISTINCT (t.city)) FROM city t WHERE t.last_update > '2018-10-22 00:00:00' AND t.city LIKE '%Chrome%' AND t.city = 'eip' GROUP BY DATE_FORMAT(t.last_update, '%Y-%m-%d') ORDER BY DATE_FORMAT(t.last_update, '%Y-%m-%d') -SELECT description FROM film WHERE description IN('NEWS','asd') GROUP BY description -SELECT film_id FROM film ORDER BY release_year LIMIT 10 -SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM film ) film ) film ) film ) film ) film ) film ) film ) film ) film ) film ) film ) film ) film ) film ) film ) film -SELECT first_name,last_name,email FROM customer STRAIGHT_JOIN address ON customer.address_id=address.address_id -SELECT * FROM address GROUP BY address,district -SELECT * FROM city a INNER JOIN country b ON a.country_id=b.country_id -SELECT * FROM city a LEFT JOIN country b ON a.country_id=b.country_id -SELECT * FROM city a LEFT JOIN country b ON a.country_id=b.country_id UNION SELECT * FROM city a RIGHT JOIN country b ON a.country_id=b.country_id -SELECT * FROM city a LEFT JOIN country b ON a.country_id=b.country_id WHERE b.last_update IS NULL -SELECT * FROM city a RIGHT JOIN country b ON a.country_id=b.country_id -SELECT * FROM city a RIGHT JOIN country b ON a.country_id=b.country_id WHERE a.last_update IS NULL -SELECT * FROM city a RIGHT JOIN country b ON a.country_id=b.country_id WHERE a.last_update IS NULL UNION SELECT * FROM city a LEFT JOIN country b ON a.country_id=b.country_id WHERE b.last_update IS NULL -SELECT * FROM city i left JOIN country o ON i.city_id=o.country_id union SELECT * FROM city i right JOIN country o ON i.city_id=o.country_id -SELECT * FROM city i left JOIN country o ON i.city_id=o.country_id WHERE o.country_id is null union SELECT * FROM city i right JOIN country o ON i.city_id=o.country_id WHERE i.city_id is null -SELECT * FROM customer WHERE address_id in (224,510) ORDER BY last_name -SELECT * FROM film HAVING title = 'abc' -SELECT * FROM film ORDER BY release_year LIMIT 10 -SELECT * FROM film WHERE date(last_update)='2006-02-15' -SELECT * FROM film WHERE language_id = (SELECT language_id FROM language LIMIT 1) -SELECT * FROM film WHERE length > 100 and language_id < 10 -SELECT * FROM film WHERE length > 100 and language_id < 10 and title = 'xyz' -SELECT * FROM film WHERE length > 100 and title = 'ALABAMA DEVIL' -SELECT * FROM film WHERE length = 100 and title = 'xyz' ORDER BY release_year -SELECT * FROM film WHERE length > 100 and title = 'xyz' ORDER BY release_year -SELECT * FROM film WHERE length < 100 ORDER BY length LIMIT 10 -SELECT * FROM film WHERE length > 100 ORDER BY length LIMIT 10 -SELECT * FROM film WHERE length > 100 ORDER BY release_year -SELECT * FROM film WHERE length = 114 and title = 'ALABAMA DEVIL' -SELECT * FROM film WHERE length = 123 ORDER BY release_year ASC, language_id DESC -SELECT * FROM film WHERE length = 123 ORDER BY release_year LIMIT 10 -SELECT * FROM film WHERE length = 86 -SELECT * FROM film WHERE length BETWEEN 60 AND 84 -SELECT * FROM film WHERE length IS NULL -SELECT * FROM film WHERE release_year = 2016 AND length != 1 ORDER BY title -SELECT * FROM film WHERE title IS NOT NULL -SELECT * FROM film WHERE title LIKE 'AIR%' -SELECT * FROM sakila.film WHERE length >= 60 -SELECT * FROM (SELECT * FROM actor WHERE last_update='2006-02-15 04:34:33' and last_name='CHASE') t WHERE last_update='2006-02-15 04:34:33' and last_name='CHASE' GROUP BY first_name -select * from tb where data >= '' -SELECT ID,name FROM (SELECT address FROM customer_list WHERE SID=1 order by phone limit 50,10) a JOIN customer_list l ON (a.address=l.address) JOIN city c ON (c.city=l.city) order by phone desc -SELECT language_id FROM film WHERE length = 123 GROUP BY release_year ORDER BY language_id -SELECT last_update FROM film GROUP BY date(last_update) -SELECT last_update FROM film order by date(last_update) -SELECT release_year FROM film WHERE length = 123 GROUP BY release_year ORDER BY release_year -SELECT release_year FROM film WHERE length = 123 GROUP BY release_year ORDER BY release_year LIMIT 10 -SELECT release_year, language_id, sum(length) FROM film GROUP BY release_year, language_id -SELECT release_year, sum(film_id) FROM film GROUP BY release_year -SELECT release_year, sum(length) FROM film WHERE length = 123 AND language_id = 1 GROUP BY release_year -SELECT release_year, sum(length) FROM film WHERE length >= 123 GROUP BY release_year -SELECT release_year, sum(length) FROM film WHERE length = 123 GROUP BY release_year,(length+language_id) -SELECT title FROM film WHERE ABS(language_id) = 3 GROUP BY title -SELECT title FROM film WHERE language_id > 5 AND length > 70 -SELECT title FROM film WHERE release_year = 1995 -SELECT title, replacement_cost FROM film WHERE language_id = 5 AND length = 70 -UPDATE city, country SET city.city = 'Abha', city.last_update = '2006-02-15 04:45:25', country.country = 'Afghanistan' WHERE city.country_id = country.country_id AND city.city_id=10 -UPDATE city INNER JOIN country ON city.country_id = country.country_id INNER JOIN address ON city.city_id = address.city_id SET city.city = 'Abha', city.last_update = '2006-02-15 04:45:25', country.country = 'Afghanistan' WHERE city.city_id=10 -UPDATE city INNER JOIN country USING(country_id) SET city.city = 'Abha', city.last_update = '2006-02-15 04:45:25', country.country = 'Afghanistan' WHERE city.city_id=10 -UPDATE film SET length = 10 WHERE language_id = 20 diff --git a/test/fixture/test_Check_Max_Join_Table_Count_Default.golden b/test/fixture/test_Check_Max_Join_Table_Count_Default.golden new file mode 100644 index 0000000000000000000000000000000000000000..1a3dd3857acacb0ea9fed1fa32970abb561c2050 --- /dev/null +++ b/test/fixture/test_Check_Max_Join_Table_Count_Default.golden @@ -0,0 +1,22 @@ +# Query: E813EA038141E9CE + +★ ★ ★ ★ ☆ 80分 + +```sql + +SELECT + a +FROM + b + JOIN c + JOIN d +``` + +## 最外层 SELECT 未指定 WHERE 条件 + +* **Item:** CLA.001 + +* **Severity:** L4 + +* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。 + diff --git a/test/fixture/test_Check_Max_Join_Table_Count_Overflow.golden b/test/fixture/test_Check_Max_Join_Table_Count_Overflow.golden new file mode 100644 index 0000000000000000000000000000000000000000..b2feb33784532cd1455d5e99cf1c2f93ba93477d --- /dev/null +++ b/test/fixture/test_Check_Max_Join_Table_Count_Overflow.golden @@ -0,0 +1,30 @@ +# Query: E813EA038141E9CE + +★ ★ ★ ☆ ☆ 70分 + +```sql + +SELECT + a +FROM + b + JOIN c + JOIN d +``` + +## 最外层 SELECT 未指定 WHERE 条件 + +* **Item:** CLA.001 + +* **Severity:** L4 + +* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。 + +## 减少 JOIN 的数量 + +* **Item:** JOI.005 + +* **Severity:** L2 + +* **Content:** 太多的 JOIN 是复杂的裹脚布式查询的症状。考虑将复杂查询分解成许多简单的查询,并减少 JOIN 的数量。 + diff --git a/test/fixture/test_Check_Soar_SQL_Rewrite_Mergealter_.golden b/test/fixture/test_Check_Soar_SQL_Rewrite_Mergealter_.golden index fd5900e7aa0392280a176a3ec7da21801c3f973f..e450f5df88859ae02f939b3a6a676de66ada9f8b 100644 --- a/test/fixture/test_Check_Soar_SQL_Rewrite_Mergealter_.golden +++ b/test/fixture/test_Check_Soar_SQL_Rewrite_Mergealter_.golden @@ -1 +1,79 @@ -ALTER TABLE `t2` DROP COLUMN c, DROP COLUMN d ; +ALTER TABLE `address` add index idx_city_id(city_id) ; +ALTER TABLE `inventory` add index `idx_store_film` (`store_id`,`film_id`), add index `idx_store_film` (`store_id`,`film_id`),add index `idx_store_film` (`store_id`,`film_id`),add index `idx_store_film` (`store_id`,`film_id`) ; +ALTER TABLE `tb` alter column id drop default ; +DELETE a1, a2 FROM city AS a1 INNER JOIN country AS a2 WHERE a1.country_id=a2.country_id +DELETE city, country FROM city INNER JOIN country using (country_id) WHERE city.city_id = 1 +DELETE city FROM city LEFT JOIN country ON city.country_id = country.country_id WHERE country.country IS NULL +DELETE FROM a1, a2 USING city AS a1 INNER JOIN country AS a2 WHERE a1.country_id=a2.country_id +DELETE FROM film WHERE length > 100 +INSERT INTO city (country_id) SELECT 10 FROM DUAL +INSERT INTO city (country_id) SELECT country_id FROM country +INSERT INTO city (country_id) VALUES (1),(2),(3) +REPLACE INTO city (country_id) SELECT 10 FROM DUAL +REPLACE INTO city (country_id) SELECT country_id FROM country +REPLACE INTO city (country_id) VALUES (1),(2),(3) +SELECT DATE_FORMAT(t.last_update, '%Y-%m-%d'), COUNT(DISTINCT (t.city)) FROM city t WHERE t.last_update > '2018-10-22 00:00:00' AND t.city LIKE '%Chrome%' AND t.city = 'eip' GROUP BY DATE_FORMAT(t.last_update, '%Y-%m-%d') ORDER BY DATE_FORMAT(t.last_update, '%Y-%m-%d') +SELECT * FROM address GROUP BY address,district +SELECT * FROM city a INNER JOIN country b ON a.country_id=b.country_id +SELECT * FROM city a LEFT JOIN country b ON a.country_id=b.country_id +SELECT * FROM city a LEFT JOIN country b ON a.country_id=b.country_id UNION SELECT * FROM city a RIGHT JOIN country b ON a.country_id=b.country_id +SELECT * FROM city a LEFT JOIN country b ON a.country_id=b.country_id WHERE b.last_update IS NULL +SELECT * FROM city a RIGHT JOIN country b ON a.country_id=b.country_id +SELECT * FROM city a RIGHT JOIN country b ON a.country_id=b.country_id WHERE a.last_update IS NULL +SELECT * FROM city a RIGHT JOIN country b ON a.country_id=b.country_id WHERE a.last_update IS NULL UNION SELECT * FROM city a LEFT JOIN country b ON a.country_id=b.country_id WHERE b.last_update IS NULL +SELECT * FROM city i left JOIN country o ON i.city_id=o.country_id union SELECT * FROM city i right JOIN country o ON i.city_id=o.country_id +SELECT * FROM city i left JOIN country o ON i.city_id=o.country_id WHERE o.country_id is null union SELECT * FROM city i right JOIN country o ON i.city_id=o.country_id WHERE i.city_id is null +SELECT * FROM customer WHERE address_id in (224,510) ORDER BY last_name +SELECT * FROM film HAVING title = 'abc' +SELECT * FROM film ORDER BY release_year LIMIT 10 +SELECT * FROM film WHERE date(last_update)='2006-02-15' +SELECT * FROM film WHERE language_id = (SELECT language_id FROM language LIMIT 1) +SELECT * FROM film WHERE length > 100 and language_id < 10 +SELECT * FROM film WHERE length > 100 and language_id < 10 and title = 'xyz' +SELECT * FROM film WHERE length > 100 and title = 'ALABAMA DEVIL' +SELECT * FROM film WHERE length = 100 and title = 'xyz' ORDER BY release_year +SELECT * FROM film WHERE length > 100 and title = 'xyz' ORDER BY release_year +SELECT * FROM film WHERE length < 100 ORDER BY length LIMIT 10 +SELECT * FROM film WHERE length > 100 ORDER BY length LIMIT 10 +SELECT * FROM film WHERE length > 100 ORDER BY release_year +SELECT * FROM film WHERE length = 114 and title = 'ALABAMA DEVIL' +SELECT * FROM film WHERE length = 123 ORDER BY release_year ASC, language_id DESC +SELECT * FROM film WHERE length = 123 ORDER BY release_year LIMIT 10 +SELECT * FROM film WHERE length = 86 +SELECT * FROM film WHERE length BETWEEN 60 AND 84 +SELECT * FROM film WHERE length IS NULL +SELECT * FROM film WHERE release_year = 2016 AND length != 1 ORDER BY title +SELECT * FROM film WHERE title IS NOT NULL +SELECT * FROM film WHERE title LIKE 'AIR%' +SELECT * FROM sakila.film WHERE length >= 60 +SELECT * FROM (SELECT * FROM actor WHERE last_update='2006-02-15 04:34:33' and last_name='CHASE') t WHERE last_update='2006-02-15 04:34:33' and last_name='CHASE' GROUP BY first_name +select * from tb where data >= '' +SELECT a.address, a.postal_code FROM sakila.address a WHERE a.city_id IN (SELECT c.city_id FROM sakila.city c) +SELECT a.country_id, a.last_update FROM city a STRAIGHT_JOIN country b ON a.country_id=b.country_id +SELECT city FROM( SELECT city_id FROM city WHERE city = "A Corua (La Corua)" ORDER BY last_update DESC LIMIT 50, 10) I JOIN city ON (I.city_id = city.city_id) JOIN country ON (country.country_id = city.country_id) ORDER BY city DESC +SELECT country_id, last_update FROM city NATURAL JOIN country +SELECT country_id, last_update FROM city NATURAL LEFT JOIN country +SELECT country_id, last_update FROM city NATURAL RIGHT JOIN country +SELECT description FROM film WHERE description IN('NEWS','asd') GROUP BY description +SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM ( SELECT film_id FROM film ) film ) film ) film ) film ) film ) film ) film ) film ) film ) film ) film ) film ) film ) film ) film ) film +SELECT film_id FROM film ORDER BY release_year LIMIT 10 +SELECT first_name,last_name,email FROM customer STRAIGHT_JOIN address ON customer.address_id=address.address_id +SELECT ID,name FROM (SELECT address FROM customer_list WHERE SID=1 order by phone limit 50,10) a JOIN customer_list l ON (a.address=l.address) JOIN city c ON (c.city=l.city) order by phone desc +SELECT language_id FROM film WHERE length = 123 GROUP BY release_year ORDER BY language_id +SELECT last_update FROM film GROUP BY date(last_update) +SELECT last_update FROM film order by date(last_update) +SELECT release_year FROM film WHERE length = 123 GROUP BY release_year ORDER BY release_year +SELECT release_year FROM film WHERE length = 123 GROUP BY release_year ORDER BY release_year LIMIT 10 +SELECT release_year, language_id, sum(length) FROM film GROUP BY release_year, language_id +SELECT release_year, sum(film_id) FROM film GROUP BY release_year +SELECT release_year, sum(length) FROM film WHERE length = 123 AND language_id = 1 GROUP BY release_year +SELECT release_year, sum(length) FROM film WHERE length >= 123 GROUP BY release_year +SELECT release_year, sum(length) FROM film WHERE length = 123 GROUP BY release_year,(length+language_id) +SELECT title FROM film WHERE ABS(language_id) = 3 GROUP BY title +SELECT title FROM film WHERE language_id > 5 AND length > 70 +SELECT title FROM film WHERE release_year = 1995 +SELECT title, replacement_cost FROM film WHERE language_id = 5 AND length = 70 +UPDATE city, country SET city.city = 'Abha', city.last_update = '2006-02-15 04:45:25', country.country = 'Afghanistan' WHERE city.country_id = country.country_id AND city.city_id=10 +UPDATE city INNER JOIN country ON city.country_id = country.country_id INNER JOIN address ON city.city_id = address.city_id SET city.city = 'Abha', city.last_update = '2006-02-15 04:45:25', country.country = 'Afghanistan' WHERE city.city_id=10 +UPDATE city INNER JOIN country USING(country_id) SET city.city = 'Abha', city.last_update = '2006-02-15 04:45:25', country.country = 'Afghanistan' WHERE city.city_id=10 +UPDATE film SET length = 10 WHERE language_id = 20 diff --git a/test/main.bats b/test/main.bats index 674fcced4b36b1b5f17588aa5627ed14116eeb66..7d7ac51de757d7e1b8e2ac20309e3b8737c3a0a1 100644 --- a/test/main.bats +++ b/test/main.bats @@ -146,9 +146,17 @@ load test_helper [ ${status} -eq 0 ] } -# -@test "Check -report-type rewrite -rewrite-rules mergealter" { - ${SOAR_BIN} -list-test-sqls |${SOAR_BIN} -report-type rewrite -rewrite-rules mergealter | sort > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden +# 20. 单条 SQL 中 JOIN 表的最大数量超过 2 +@test "Check Max Join Table Count Overflow" { + ${SOAR_BIN} -max-join-table-count 2 -query="select a from b join c join d" > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden + run golden_diff + echo "${output}" + [ $status -eq 0 ] +} + +# 21. 单条 SQL 中 JOIN 表未超过时是否正常默认为 5 +@test "Check Max Join Table Count Default" { + ${SOAR_BIN} -query="select a from b join c join d" > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden run golden_diff echo "${output}" [ $status -eq 0 ] diff --git a/test/query.bats b/test/query.bats index ad8abaeac08596853734ae612e58a94926c8775b..6fb734349137ed5f4f61913ddcf9dbd6093f66ae 100644 --- a/test/query.bats +++ b/test/query.bats @@ -124,10 +124,11 @@ load test_helper } # 10. 检查 SQL 改写 mergealter +# Linux macOS sort 排序不一致 https://unix.stackexchange.com/questions/362728/why-does-gnu-sort-sort-differently-on-my-osx-machine-and-linux-machine @test "Check Soar SQL Rewrite Mergealter " { - ${SOAR_BIN} -report-type "rewrite" -rewrite-rules "mergealter" \ - -query "ALTER TABLE t2 DROP COLUMN c;ALTER TABLE t2 DROP COLUMN d;" > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden + ${SOAR_BIN} -list-test-sqls |${SOAR_BIN} -report-type rewrite -rewrite-rules mergealter | sort -bdfi > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden run golden_diff + echo "${output}" [ $status -eq 0 ] } diff --git a/test/test_helper.bash b/test/test_helper.bash index af30e84c59bd67a0563451e47d813c70f24caddf..90c63a0d98fca19d7e7da07201f6f1198a3136c7 100644 --- a/test/test_helper.bash +++ b/test/test_helper.bash @@ -4,6 +4,7 @@ setup() { export SOAR_BIN_ENV="${SOAR_DEV_DIRNAME}/bin/soar -config ${SOAR_DEV_DIRNAME}/etc/soar.yaml" export BATS_TMP_DIRNAME="${BATS_TEST_DIRNAME}/tmp" export BATS_FIXTURE_DIRNAME="${BATS_TEST_DIRNAME}/fixture" + export LC_ALL=C # Linux macOS 下 sort 排序问题 mkdir -p "${BATS_TMP_DIRNAME}" }