Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ on:
env:
GOPATH: /opt/go
PATH: /opt/go/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin
GO_VER: 1.21.9
GO_VER: 1.25.10

jobs:
unit-tests:
Expand Down
4 changes: 1 addition & 3 deletions ci/install-tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,4 @@ set -euo pipefail

cd "$(dirname "$0")/tools"
export GO111MODULE=on
go install -tags tools golang.org/x/lint/golint
go install -tags tools golang.org/x/tools/cmd/goimports
go install -tags tools mvdan.cc/gofumpt
go install tool
4 changes: 2 additions & 2 deletions ci/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ fi

## Formatting
echo "running gofumpt..."
gofumpt_output="$(gofumpt -l -s "${go_files[@]}")"
gofumpt_output="$(gofumpt -l "${go_files[@]}")"
if [ -n "$gofumpt_output" ]; then
echo "The following files contain gofumpt errors:"
echo "$gofumpt_output"
echo "Please run 'gofumpt -s -w' for these files."
echo "Please run 'gofumpt -w' for these files."
exit 1
fi

Expand Down
18 changes: 14 additions & 4 deletions ci/tools/go.mod
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
module tools

go 1.14
go 1.25.10

tool (
golang.org/x/lint/golint
golang.org/x/tools/cmd/goimports
mvdan.cc/gofumpt
)

require (
golang.org/x/lint v0.0.0-20200302205851-738671d3881b
golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c
mvdan.cc/gofumpt v0.1.0
golang.org/x/lint v0.0.0-20241112194109-818c5a804067 // indirect
golang.org/x/mod v0.36.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/sys v0.44.0 // indirect
golang.org/x/telemetry v0.0.0-20260508192327-42602be52be6 // indirect
golang.org/x/tools v0.45.0 // indirect
mvdan.cc/gofumpt v0.10.0 // indirect
)
59 changes: 24 additions & 35 deletions ci/tools/go.sum
Original file line number Diff line number Diff line change
@@ -1,46 +1,35 @@
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0=
github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/go-quicktest/qt v1.102.0 h1:HSQxCeh5YZH3EL3W39ixjtyaEhcWSXQHtHnMBzSs474=
github.com/go-quicktest/qt v1.102.0/go.mod h1:p4lGIVX+8Wa6ZPNDvqcxq36XpUDLh42FLetFU7odllI=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20241112194109-818c5a804067 h1:adDmSQyFTCiv19j015EGKJBoaa7ElV0Q1Wovb/4G7NA=
golang.org/x/lint v0.0.0-20241112194109-818c5a804067/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/telemetry v0.0.0-20260508192327-42602be52be6 h1:HjU6IWBiAgRIdAJ9/y1rwCn+UELEmwV+VsTLzj/W4sE=
golang.org/x/telemetry v0.0.0-20260508192327-42602be52be6/go.mod h1:Eqhaxk/wZsWEH8CRxLwj6xzEJbz7k1EFGqx7nyCoabE=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c h1:dS09fXwOFF9cXBnIzZexIuUBj95U1NyQjkEhkgidDow=
golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
mvdan.cc/gofumpt v0.1.0 h1:hsVv+Y9UsZ/mFZTxJZuHVI6shSQCtzZ11h1JEFPAZLw=
mvdan.cc/gofumpt v0.1.0/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48=
mvdan.cc/gofumpt v0.10.0 h1:yGGpRS2pBN2OQIi7b21IXknJna7faPkFaVfHLrN6Euo=
mvdan.cc/gofumpt v0.10.0/go.mod h1:sU2ElXHzOEmvoPqfutYG7uunlueR4K2T1JFml40SzP4=
14 changes: 0 additions & 14 deletions ci/tools/tools.go

This file was deleted.

6 changes: 3 additions & 3 deletions configtx/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ func TestNewApplicationGroupFailure(t *testing.T) {
Type: SignaturePolicyType,
}
},
expectedErr: "invalid signature policy rule: 'ANYY Readers': Cannot transition " +
"token types from VARIABLE [ANYY] to VARIABLE [Readers]",
expectedErr: "invalid signature policy rule: 'ANYY Readers': unexpected token Identifier(\"Readers\") " +
"(1:6)\n | ANYY Readers\n | .....^",
},
{
testName: "When ImplicitMetaPolicy type is unknown policy type",
Expand All @@ -200,7 +200,7 @@ func TestNewApplicationGroupFailure(t *testing.T) {
tt.applicationMod(&application)

configGrp, err := newApplicationGroupTemplate(application)
gt.Expect(err).To(MatchError(tt.expectedErr))
gt.Expect(err).To(MatchError(ContainSubstring(tt.expectedErr)))
gt.Expect(configGrp).To(BeNil())
})
}
Expand Down
4 changes: 2 additions & 2 deletions configtx/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ func TestNewCreateChannelTxFailure(t *testing.T) {
},
channelID: "testchannel",
err: errors.New("creating default config template: failed to create application group: " +
"invalid signature policy rule: 'ANYY Readers': Cannot transition " +
"token types from VARIABLE [ANYY] to VARIABLE [Readers]"),
"invalid signature policy rule: 'ANYY Readers': unexpected token Identifier(\"Readers\") " +
"(1:6)\n | ANYY Readers\n | .....^"),
},
{
testName: "When creating the default config template with an unknown policy type fails",
Expand Down
6 changes: 4 additions & 2 deletions configtx/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ func Example_policies() {
configtx.Policy{
Type: configtx.ImplicitMetaPolicyType,
Rule: "MAJORITY Endorsement",
})
},
)
if err != nil {
panic(err)
}
Expand All @@ -247,7 +248,8 @@ func Example_policies() {
configtx.Policy{
Type: configtx.ImplicitMetaPolicyType,
Rule: "MAJORITY Endorsement",
})
},
)
if err != nil {
panic(err)
}
Expand Down
58 changes: 29 additions & 29 deletions configtx/internal/policydsl/policyparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"strconv"
"strings"

"github.com/Knetic/govaluate"
"github.com/expr-lang/expr"
cb "github.com/hyperledger/fabric-protos-go-apiv2/common"
mb "github.com/hyperledger/fabric-protos-go-apiv2/msp"
"google.golang.org/protobuf/proto"
Expand Down Expand Up @@ -138,6 +138,8 @@ func firstPass(args ...interface{}) (interface{}, error) {
case float32:
case float64:
toret += strconv.Itoa(int(t))
case int:
toret += strconv.Itoa(t)
default:
return nil, fmt.Errorf("unexpected type %s", reflect.TypeOf(arg))
}
Expand Down Expand Up @@ -167,6 +169,8 @@ func secondPass(args ...interface{}) (interface{}, error) {
switch arg := args[1].(type) {
case float64:
t = int(arg)
case int:
t = arg
default:
return nil, fmt.Errorf("unrecognized type, expected a number, got %s", reflect.TypeOf(args[1]))
}
Expand Down Expand Up @@ -277,24 +281,23 @@ func newContext() *context {
// the required role
func FromString(policy string) (*cb.SignaturePolicyEnvelope, error) {
// first we translate the and/or business into outof gates
intermediate, err := govaluate.NewEvaluableExpressionWithFunctions(
policy, map[string]govaluate.ExpressionFunction{
GateAnd: and,
strings.ToLower(GateAnd): and,
strings.ToUpper(GateAnd): and,
GateOr: or,
strings.ToLower(GateOr): or,
strings.ToUpper(GateOr): or,
GateOutOf: outof,
strings.ToLower(GateOutOf): outof,
strings.ToUpper(GateOutOf): outof,
},
)
env := map[string]interface{}{
GateAnd: and,
strings.ToLower(GateAnd): and,
strings.ToUpper(GateAnd): and,
GateOr: or,
strings.ToLower(GateOr): or,
strings.ToUpper(GateOr): or,
GateOutOf: outof,
strings.ToLower(GateOutOf): outof,
strings.ToUpper(GateOutOf): outof,
}
intermediate, err := expr.Compile(policy, expr.Env(env))
if err != nil {
return nil, err
}

intermediateRes, err := intermediate.Evaluate(map[string]interface{}{})
intermediateRes, err := expr.Run(intermediate, env)
if err != nil {
// attempt to produce a meaningful error
if regexErr.MatchString(err.Error()) {
Expand All @@ -318,15 +321,14 @@ func FromString(policy string) (*cb.SignaturePolicyEnvelope, error) {
// to user-implemented functions other than via arguments.
// We need this argument because we need a global place where
// we put the identities that the policy requires
exp, err := govaluate.NewEvaluableExpressionWithFunctions(
resStr,
map[string]govaluate.ExpressionFunction{"outof": firstPass},
)
env = map[string]interface{}{
"outof": firstPass,
}
exp, err := expr.Compile(resStr, expr.Env(env))
if err != nil {
return nil, err
}

res, err := exp.Evaluate(map[string]interface{}{})
res, err := expr.Run(exp, env)
if err != nil {
// attempt to produce a meaningful error
if regexErr.MatchString(err.Error()) {
Expand All @@ -345,18 +347,16 @@ func FromString(policy string) (*cb.SignaturePolicyEnvelope, error) {
}

ctx := newContext()
parameters := make(map[string]interface{}, 1)
parameters["ID"] = ctx

exp, err = govaluate.NewEvaluableExpressionWithFunctions(
resStr,
map[string]govaluate.ExpressionFunction{"outof": secondPass},
)
env = map[string]interface{}{
"outof": secondPass,
"ID": ctx,
}
exp, err = expr.Compile(resStr, expr.Env(env))
if err != nil {
return nil, err
}

res, err = exp.Evaluate(parameters)
res, err = expr.Run(exp, env)
if err != nil {
// attempt to produce a meaningful error
if regexErr.MatchString(err.Error()) {
Expand Down
25 changes: 12 additions & 13 deletions configtx/internal/policydsl/policyparser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ import (
"github.com/hyperledger/fabric-config/configtx/internal/policydsl"
cb "github.com/hyperledger/fabric-protos-go-apiv2/common"
mb "github.com/hyperledger/fabric-protos-go-apiv2/msp"
"google.golang.org/protobuf/proto"

. "github.com/onsi/gomega"
"google.golang.org/protobuf/proto"
)

func TestOutOf1(t *testing.T) {
Expand Down Expand Up @@ -257,13 +256,13 @@ func TestBadStringsNoPanic(t *testing.T) {
gt := NewGomegaWithT(t)

_, err := policydsl.FromString("OR('A.member', Bmember)") // error after 1st Evaluate()
gt.Expect(err).To(MatchError("unrecognized token 'Bmember' in policy string"))
gt.Expect(err).To(MatchError(ContainSubstring("unknown name Bmember")))

_, err = policydsl.FromString("OR('A.member', 'Bmember')") // error after 2nd Evalute()
gt.Expect(err).To(MatchError("unrecognized token 'Bmember' in policy string"))
gt.Expect(err).To(MatchError(ContainSubstring("unknown name Bmember")))

_, err = policydsl.FromString(`OR('A.member', '\'Bmember\'')`) // error after 3rd Evalute()
gt.Expect(err).To(MatchError("unrecognized token 'Bmember' in policy string"))
gt.Expect(err).To(MatchError(ContainSubstring("unknown name Bmember")))
}

func TestNodeOUs(t *testing.T) {
Expand Down Expand Up @@ -339,7 +338,7 @@ func TestOutOfErrorCase(t *testing.T) {
{
testName: "1st NewEvaluableExpressionWithFunctions() returns an error",
policyString: "",
expectedErr: "Unexpected end of expression",
expectedErr: "unexpected token EOF",
},
{
testName: "outof() if len(args)<2",
Expand All @@ -354,7 +353,7 @@ func TestOutOfErrorCase(t *testing.T) {
{
testName: "oufof() switch default. 2nd arg is not string.",
policyString: "OutOf(1, 2)",
expectedErr: "unexpected type float64",
expectedErr: "unexpected type int",
},
{
testName: "firstPass() switch default",
Expand All @@ -369,17 +368,17 @@ func TestOutOfErrorCase(t *testing.T) {
{
testName: "secondPass() switch args[1].(type) default",
policyString: `OutOf(1, '\'1\'')`,
expectedErr: "unrecognized type, expected a principal or a policy, got float64",
expectedErr: "unrecognized type, expected a principal or a policy, got int",
},
{
testName: "2nd NewEvaluateExpressionWithFunction() returns an error",
policyString: `''`,
expectedErr: "Unexpected end of expression",
expectedErr: "unexpected token EOF",
},
{
testName: "3rd NewEvaluateExpressionWithFunction() returns an error",
policyString: `'\'\''`,
expectedErr: "Unexpected end of expression",
expectedErr: "unexpected token EOF",
},
}

Expand All @@ -389,7 +388,7 @@ func TestOutOfErrorCase(t *testing.T) {

p, err := policydsl.FromString(tt.policyString)
gt.Expect(p).To(BeNil())
gt.Expect(err).To(MatchError(tt.expectedErr))
gt.Expect(err).To(MatchError(ContainSubstring(tt.expectedErr)))
})
}
}
Expand Down Expand Up @@ -435,7 +434,7 @@ func TestSecondPassBoundaryCheck(t *testing.T) {
// Prohibit t<0
p0, err0 := policydsl.FromString("OutOf(-1, 'A.member', 'B.member')")
gt.Expect(p0).To(BeNil())
gt.Expect(err0).To(MatchError("invalid t-out-of-n predicate, t -1, n 2"))
gt.Expect(err0).To(MatchError(ContainSubstring("invalid t-out-of-n predicate, t -1, n 2")))

// Permit t==0 : always satisfied policy
// There is no clear usecase of t=0, but somebody may already use it, so we don't treat as an error.
Expand Down Expand Up @@ -472,7 +471,7 @@ func TestSecondPassBoundaryCheck(t *testing.T) {
// Prohibit t>n + 1
p3, err3 := policydsl.FromString("OutOf(4, 'A.member', 'B.member')")
gt.Expect(p3).To(BeNil())
gt.Expect(err3).To(MatchError("invalid t-out-of-n predicate, t 4, n 2"))
gt.Expect(err3).To(MatchError(ContainSubstring("invalid t-out-of-n predicate, t 4, n 2")))
}

// protoMarshalOrPanic serializes a protobuf message and panics if this
Expand Down
Loading
Loading