Add error return to fake IPTables
For negative testing we need to be able to setup the fake IPTables
implementation to return errors. Added the capability to the append and
delete rule APIs.
@@ -18,6 +18,7 @@ limitations under the License.
package fake
import (
+ "errors"
"strings"
"sync"
@@ -29,6 +30,8 @@ type IPTables struct {
sync.Mutex
chainRules map[string]stringset.Interface
tableChains map[string]stringset.Interface
+ failOnAppendRuleMatchers []interface{}
+ failOnDeleteRuleMatchers []interface{}
}
func New() *IPTables {
@@ -41,24 +44,26 @@ func New() *IPTables {
}
func (i *IPTables) Append(table, chain string, rulespec ...string) error {
- i.addRule(table, chain, rulespec...)
- return nil
+ return i.addRule(table, chain, rulespec...)
}
func (i *IPTables) AppendUnique(table, chain string, rulespec ...string) error {
- i.addRule(table, chain, rulespec...)
- return nil
+ return i.addRule(table, chain, rulespec...)
}
func (i *IPTables) Insert(table, chain string, pos int, rulespec ...string) error {
- i.addRule(table, chain, rulespec...)
- return nil
+ return i.addRule(table, chain, rulespec...)
}
func (i *IPTables) Delete(table, chain string, rulespec ...string) error {
i.Lock()
defer i.Unlock()
+ err := matchRuleForError(&i.failOnDeleteRuleMatchers, rulespec...)
+ if err != nil {
+ return err
+ }
+
ruleSet := i.chainRules[table+"/"+chain]
if ruleSet != nil {
ruleSet.Remove(strings.Join(rulespec, " "))
@@ -67,10 +72,15 @@ func (i *IPTables) Delete(table, chain string, rulespec ...string) error {
return nil
}
-func (i *IPTables) addRule(table, chain string, rulespec ...string) {
+func (i *IPTables) addRule(table, chain string, rulespec ...string) error {
i.Lock()
defer i.Unlock()
+ err := matchRuleForError(&i.failOnAppendRuleMatchers, rulespec...)
+ if err != nil {
+ return err
+ }
+
ruleSet := i.chainRules[table+"/"+chain]
if ruleSet == nil {
ruleSet = stringset.New()
@@ -78,6 +88,22 @@ func (i *IPTables) addRule(table, chain string, rulespec ...string) {
}
ruleSet.Add(strings.Join(rulespec, " "))
+
+ return nil
+}
+
+func matchRuleForError(matchers *[]interface{}, rulespec ...string) error {
+ for i, m := range *matchers {
+ matches, err := ContainElement(m).Match([]string{strings.Join(rulespec, " ")})
+ Expect(err).To(Succeed())
+
+ if matches {
+ *matchers = (*matchers)[i+1:]
+ return errors.New("mock IP table rule error")
+ }
+ }
+
+ return nil
}
func (i *IPTables) List(table, chain string) ([]string, error) {
@@ -165,3 +191,17 @@ func (i *IPTables) AwaitNoRule(table, chain string, stringOrMatcher interface{})
return i.listRules(table, chain)
}, 5).ShouldNot(ContainElement(stringOrMatcher), "Rules for IP table %q, chain %q", table, chain)
}
+
+func (i *IPTables) AddFailOnAppendRuleMatcher(stringOrMatcher interface{}) {
+ i.Lock()
+ defer i.Unlock()
+
+ i.failOnAppendRuleMatchers = append(i.failOnAppendRuleMatchers, stringOrMatcher)
+}
+
+func (i *IPTables) AddFailOnDeleteRuleMatcher(stringOrMatcher interface{}) {
+ i.Lock()
+ defer i.Unlock()
+
+ i.failOnDeleteRuleMatchers = append(i.failOnDeleteRuleMatchers, stringOrMatcher)
+}
