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 (также известных как правила):

  1. Полные правила, например,deny = true { input.allowed == "no" }
  2. Частичные правила, например,deny[msg] { input.allowed == "no" }

Полные правила присваивают переменной ЕДИНОЕ значение. Если вы опустите значение, по умолчанию будет установлено значение true (например,deny = true { ... } а также deny { ... }означают то же самое.) Когда часть правила "ЕСЛИ" истинна / удовлетворена, переменной присваивается значение. Когда часть правила "ЕСЛИ" неверна / не выполняется, переменная не определена. Это немного отличается отfalse но в большинстве случаев это не важно.

Частичные правила присваивают переменной НЕСКОЛЬКО значений. Другими словами, они определяют НАБОР значений. Когда часть правила "ЕСЛИ" истинна / удовлетворена, значение, определенное в заголовке правила, добавляется к набору, в противном случае значение НЕ добавляется. Если в набор не добавляются никакие значения, он все равно определен - он просто пуст.

Это описано во введении: https://www.openpolicyagent.org/docs/latest/

Дополнительные примеры и информацию о правилах см. На https://www.openpolicyagent.org/docs/latest/policy-language/.

Другие вопросы по тегам