Rego testing: как проверить "не отрицать"?
Я изучаю возможность тестирования своих политик Rego, используя opa test
начиная с этого тривиального правила:
deny["Must be allowed"] {
input.allowed == "no"
}
Я могу успешно проверить это в случае, когда это отрицается:
test_denied_example {
deny with input as {"allowed":"no"}
}
Однако, когда я пытаюсь протестировать его в случае, когда это должно быть разрешено, например:
test_allowed_example {
not deny with input as {"allowed":"yes"}
}
Я получаю сообщение об ошибке:
data.example.test_allowed_example: FAIL (330.534µs)
Enter data.example.test_allowed_example = _
| Enter data.example.test_allowed_example
| | Fail not data.example.deny with input as {"allowed": "yes"}
| Fail data.example.test_allowed_example = _
Я не могу разобрать это сообщение об ошибке, за исключением того, что знаю, что test_allowed_example
был проваленным тестом.
Как правильно проверить случаи, когда ввод разрешен (не запрещен)?
1 ответ
TL; DR; вы можете сказать любое из этих слов:
count(deny) == 0 with input as {"allowed":"yes"}
deny == set() with input as {"allowed":"yes"}
not deny["Must be allowed"] with input as {"allowed":"yes"}
Последний проверяет, не содержит ли набор конкретного сообщения. Это хорошая идея, если у вас несколькоdeny
правила внутри одного пакета.
В not deny with input as ...
заявление терпит неудачу, потому что not
ключевое слово только инвертирует неопределенные / ложные утверждения (делая их истинными). В этом случае,deny
относится к набору значений. Набор может быть пустым, но он никогда не может быть неопределенным / ложным.
В OPA/Rego все правила - это просто операторы IF-THEN, которые присваивают значения переменным. Если часть "ЕСЛИ" - это логика в теле правила. Часть "THEN" - это назначение в заголовке правила. Есть два типа операторов IF-THEN (также известных как правила):
- Полные правила, например,
deny = true { input.allowed == "no" }
- Частичные правила, например,
deny[msg] { input.allowed == "no" }
Полные правила присваивают переменной ЕДИНОЕ значение. Если вы опустите значение, по умолчанию будет установлено значение true (например,deny = true { ... }
а также deny { ... }
означают то же самое.) Когда часть правила "ЕСЛИ" истинна / удовлетворена, переменной присваивается значение. Когда часть правила "ЕСЛИ" неверна / не выполняется, переменная не определена. Это немного отличается отfalse
но в большинстве случаев это не важно.
Частичные правила присваивают переменной НЕСКОЛЬКО значений. Другими словами, они определяют НАБОР значений. Когда часть правила "ЕСЛИ" истинна / удовлетворена, значение, определенное в заголовке правила, добавляется к набору, в противном случае значение НЕ добавляется. Если в набор не добавляются никакие значения, он все равно определен - он просто пуст.
Это описано во введении: https://www.openpolicyagent.org/docs/latest/
Дополнительные примеры и информацию о правилах см. На https://www.openpolicyagent.org/docs/latest/policy-language/.