[英]Test Cases for Rego Polices
对不起,我的新手问题。 我已经编写了一个 rego 规则来检查 ASV 名称,现在我正在寻找相同的测试用例。 我查看了示例测试用例,但没有成功为我的策略编写(粘贴在下面)。 想知道我怎么能得到下面规则的肯定和失败案例。
asv_list = {"ASVONE","ASVXYZ"}
check_asv := { resources[i]: Reason |
resources:=[resource | data[j] ;
list := {x| x:=asv_list[_]}
not(list[data[j].ASV])
resource:=data[j].Name]
Reason := sprintf("THE ASV - %v being used is not a valid ASV", [data[j].ASV])
}
data = {resource |
doc = input[i];
key_ids := [k | doc[k]; startswith(k, "tag."); k != "tag.#"; endswith(k, ".key")]
resource := {
doc[k] : doc[replace(k, ".key", ".value")] | key_ids[_] == k
}
}
如果您尝试测试check_asv
您的正面和负面测试用例看起来很相似:
check_asv
等于预期值例如:
test_check_asv_positive {
expected := {"r1": "..."}
fake_input := [{"Name": "foo", ...}]
check_asv == expected with input as fake_input
}
不过,在开始为您的规则编写测试之前,我认为您应该澄清您试图表达的逻辑,因为有一些危险信号会跳出来。 我试图分解我在下面的政策中看到的问题。 最后,我写了一些示例测试用例。
首先,只需将 Rego 格式化,使其更易于阅读。 我将您的示例粘贴到一个文件中,添加了一个package
(使其成为有效的 .rego 文件),然后运行opa fmt file.rego
:
asv_list = {"ASVONE", "ASVXYZ"}
check_asv := {resources[i]: Reason |
resources := [resource |
data[j]
list := {x | x := asv_list[_]}
not list[data[j].ASV]
resource := data[j].Name
]
Reason := sprintf("THE ASV - %v being used is not a valid ASV", [data[j].ASV])
}
data = {resource |
doc = input[i]
key_ids := [k |
doc[k]
startswith(k, "tag.")
k != "tag.#"
endswith(k, ".key")
]
resource := {doc[k]: doc[replace(k, ".key", ".value")] |
key_ids[_] == k
}
}
这更容易阅读。
data
我建议不要命名该规则data
。 Rego 中的data
是一个特殊的全局变量,它指的是策略引擎中缓存的状态。 任何来自 OPA 外部或由 OPA 内部规则生成的data
都可以在data
下访问。 定义名为data
的规则是允许的,但它令人困惑。 将data
重命名为域中有意义的名称。 例如,如果这些是虚拟机资源,您可以将它们命名为vm_resources
。 在这种情况下,我没有太多事情要做,所以我将把它重命名为input_docs
因为doc
被用作变量名:
check_asv := {resources[i]: Reason |
resources := [resource |
input_docs[j]
list := {x | x := asv_list[_]}
not list[input_docs[j].ASV]
resource := input_docs[j].Name
]
Reason := sprintf("THE ASV - %v being used is not a valid ASV", [input_docs[j].ASV])
}
input_docs = {resource |
doc = input[i]
key_ids := [k |
doc[k]
startswith(k, "tag.")
k != "tag.#"
endswith(k, ".key")
]
resource := {doc[k]: doc[replace(k, ".key", ".value")] |
key_ids[_] == k
}
}
input_docs
helper 规则(原来叫data
) 乍一看,这条规则做了很多工作,但实际上并非如此。 第一行( doc = input[i]
)只是遍历input
每个元素。 规则的其余部分基于input
每个元素。 第二个表达式key_ids := [...
,从元素计算对象键的数组。 第三个表达式resources := {doc[k]: ...
,通过映射元素构造一个新对象。
第一个表达式不能简化太多,但是,最好使用:=
而不是=
,因为i
没有在其他任何地方被引用,我们只能使用_
。 第一个表达式变为:
doc := input[_]
第二个表达式计算一个键数组,但过滤有点多余: k
不能等于tag.#
AND 以.key
结尾,因此可以删除!=
表达式:
key_ids := [k |
some k
doc[k]
startswith(k, "tag.")
endswith(k, ".key")
]
此时我们可以停止,但值得注意的是规则中的第二个和第三个表达式都只是迭代doc
对象。 这里没有理由使用两个单独的表达式。 为了简化这个规则,我们可以将它们组合起来:
input_docs = {resource |
doc := input[_]
resource := {v: x |
some k
v := doc[k]
startswith(k, "tag.")
endswith(k, ".key")
x := doc[replace(k, ".key", ".value")]
}
}
check_asv
规则现在我们有了一个简化版本的input_docs
规则,它生成了一组映射资源,我们可以专注于check_asv
规则。 check_asv
规则可以简化很多:
i
和j
)应该只有一个。该规则可以简化为以下内容:
check_asv := {name: reason |
r := input_docs[_]
not asv_list[r.ASV]
name := r.Name
reason := sprintf("THE ASV - %v being used is not a valid ASV", [r.ASV])
}
input_docs
两次(实际上这是不正确的。)asv_list
构造一个集合,它已经是一个集合。此时,策略如下所示:
asv_list = {"ASVONE", "ASVXYZ"}
check_asv := {name: reason |
r := input_docs[_]
not asv_list[r.ASV]
name := r.Name
reason := sprintf("THE ASV - %v being used is not a valid ASV", [r.ASV])
}
input_docs = {resource |
doc := input[_]
resource := {v: x |
some k
v := doc[k]
startswith(k, "tag.")
endswith(k, ".key")
x := doc[replace(k, ".key", ".value")]
}
}
为了测试这个策略,我们可以很容易地编写几个测试用例:
test_check_asv_positive {
exp := {
"dog": "THE ASV - ASVBAD being used is not a valid ASV"
}
inp := [
{
"tag.foo.key": "Name",
"tag.foo.value": "dog",
"tag.bar.key": "ASV",
"tag.bar.value": "ASVBAD"
}
]
check_asv == exp with input as inp
}
test_check_asv_positive_multiple_resources {
exp := {
"dog": "THE ASV - ASVBAD being used is not a valid ASV",
"horse": "THE ASV - ASVBAD2 being used is not a valid ASV"
}
inp := [
{
"tag.foo.key": "Name",
"tag.foo.value": "dog",
"tag.bar.key": "ASV",
"tag.bar.value": "ASVBAD"
},
{
"tag.foo.key": "Name",
"tag.foo.value": "horse",
"tag.bar.key": "ASV",
"tag.bar.value": "ASVBAD2"
}
]
check_asv == exp with input as inp
}
test_check_asv_positive_multiple_resources_mixed {
exp := {
"horse": "THE ASV - ASVBAD2 being used is not a valid ASV"
}
inp := [
{
"tag.foo.key": "Name",
"tag.foo.value": "cat",
"tag.bar.key": "ASV",
"tag.bar.value": "ASVONE"
},
{
"tag.foo.key": "Name",
"tag.foo.value": "horse",
"tag.bar.key": "ASV",
"tag.bar.value": "ASVBAD2"
}
]
check_asv == exp with input as inp
}
test_check_asv_negative {
exp := {}
inp := [
{
"tag.foo.key": "Name",
"tag.foo.value": "cat",
"tag.bar.key": "ASV",
"tag.bar.value": "ASVONE"
}
]
check_asv == exp with input as inp
}
这是操场上完整政策的链接: https : //play.openpolicyagent.org/p/6w7aC9xWYH
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.