Skip to content

Commit f1d0eb4

Browse files
committed
Add a unit test for utiliptables.New()
1 parent 9c98d29 commit f1d0eb4

File tree

1 file changed

+158
-28
lines changed

1 file changed

+158
-28
lines changed

pkg/util/iptables/iptables_test.go

Lines changed: 158 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,44 +42,174 @@ func getLockPaths() (string, string) {
4242
return lock14x, lock16x
4343
}
4444

45-
func testIPTablesVersionCmds(t *testing.T, protocol Protocol) {
46-
version := " v1.4.22"
47-
iptablesCmd := iptablesCommand(protocol)
48-
iptablesRestoreCmd := iptablesRestoreCommand(protocol)
45+
type testCommand struct {
46+
command string
47+
action fakeexec.FakeAction
48+
}
4949

50-
fcmd := fakeexec.FakeCmd{
51-
CombinedOutputScript: []fakeexec.FakeAction{
52-
// iptables version response (for runner instantiation)
53-
func() ([]byte, []byte, error) { return []byte(iptablesCmd + version), nil, nil },
54-
// iptables-restore version response (for runner instantiation)
55-
func() ([]byte, []byte, error) { return []byte(iptablesRestoreCmd + version), nil, nil },
56-
},
57-
}
50+
// Creates a FakeExec that expects exactly commands to be run (and will fail otherwise).
51+
func fakeExecForCommands(commands []testCommand) *fakeexec.FakeExec {
5852
fexec := &fakeexec.FakeExec{
59-
CommandScript: []fakeexec.FakeCommandAction{
60-
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
61-
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
62-
},
53+
CommandScript: make([]fakeexec.FakeCommandAction, len(commands)),
54+
ExactOrder: true,
6355
}
64-
_ = newInternal(fexec, protocol, "", "")
56+
for i := range commands {
57+
fcmd := fakeexec.FakeCmd{
58+
CombinedOutputScript: []fakeexec.FakeAction{commands[i].action},
59+
}
60+
argv := strings.Fields(commands[i].command)
61+
fexec.CommandScript[i] = func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, argv[0], argv[1:]...) }
62+
}
63+
return fexec
64+
}
65+
66+
func TestFakeExecForCommands(t *testing.T) {
67+
var panicresult interface{}
68+
defer func() {
69+
panicresult = recover()
70+
}()
6571

66-
// Check that proper iptables version command was used during runner instantiation
67-
if !sets.New(fcmd.CombinedOutputLog[0]...).HasAll(iptablesCmd, "--version") {
68-
t.Errorf("%s runner instantiate: Expected cmd '%s --version', Got '%s'", protocol, iptablesCmd, fcmd.CombinedOutputLog[0])
72+
fake1 := fakeExecForCommands([]testCommand{{
73+
command: "foo bar baz",
74+
action: func() ([]byte, []byte, error) { return []byte("output"), nil, nil },
75+
}})
76+
cmd := fake1.Command("foo", "bar", "baz")
77+
out, err := cmd.CombinedOutput()
78+
if string(out) != "output" {
79+
t.Errorf("fake1: wrong output: expected %q, got %q", "output", out)
80+
}
81+
if err != nil {
82+
t.Errorf("fake1: expected no error, got %v", err)
83+
}
84+
if panicresult != nil {
85+
t.Errorf("fake1: expected no panic, got %q", panicresult)
6986
}
7087

71-
// Check that proper iptables restore version command was used during runner instantiation
72-
if !sets.New(fcmd.CombinedOutputLog[1]...).HasAll(iptablesRestoreCmd, "--version") {
73-
t.Errorf("%s runner instantiate: Expected cmd '%s --version', Got '%s'", protocol, iptablesRestoreCmd, fcmd.CombinedOutputLog[1])
88+
fake2 := fakeExecForCommands([]testCommand{{
89+
command: "foo bar baz",
90+
action: func() ([]byte, []byte, error) { return []byte("output"), nil, nil },
91+
}})
92+
_ = fake2.Command("foo", "baz")
93+
if panicresult == nil {
94+
t.Errorf("fake2: expected panic from FakeExec, got none")
7495
}
7596
}
7697

77-
func TestIPTablesVersionCmdsIPv4(t *testing.T) {
78-
testIPTablesVersionCmds(t, ProtocolIPv4)
79-
}
98+
func TestNew(t *testing.T) {
99+
testCases := []struct {
100+
name string
101+
commands []testCommand
102+
expected *runner
103+
}{
104+
{
105+
name: "ancient",
106+
commands: []testCommand{
107+
{
108+
command: "iptables --version",
109+
action: func() ([]byte, []byte, error) { return []byte("iptables v1.4.0"), nil, nil },
110+
},
111+
{
112+
// iptables-restore version check: ignores --version and just no-ops
113+
command: "iptables-restore --version",
114+
action: func() ([]byte, []byte, error) { return nil, nil, nil },
115+
},
116+
},
117+
expected: &runner{
118+
hasCheck: false,
119+
hasRandomFully: false,
120+
waitFlag: nil,
121+
restoreWaitFlag: nil,
122+
},
123+
},
124+
{
125+
name: "RHEL/CentOS 7",
126+
commands: []testCommand{
127+
{
128+
command: "iptables --version",
129+
action: func() ([]byte, []byte, error) { return []byte("iptables v1.4.21"), nil, nil },
130+
},
131+
{
132+
command: "iptables-restore --version",
133+
action: func() ([]byte, []byte, error) { return []byte("iptables-restore v1.4.21"), nil, nil },
134+
},
135+
},
136+
expected: &runner{
137+
hasCheck: true,
138+
hasRandomFully: false,
139+
waitFlag: []string{"-w"},
140+
restoreWaitFlag: []string{"-w"},
141+
},
142+
},
143+
{
144+
name: "1.6",
145+
commands: []testCommand{
146+
{
147+
command: "iptables --version",
148+
action: func() ([]byte, []byte, error) { return []byte("iptables v1.6.2"), nil, nil },
149+
},
150+
},
151+
expected: &runner{
152+
hasCheck: true,
153+
hasRandomFully: true,
154+
waitFlag: []string{"-w", "5", "-W", "100000"},
155+
restoreWaitFlag: []string{"-w", "5", "-W", "100000"},
156+
},
157+
},
158+
{
159+
name: "1.8",
160+
commands: []testCommand{
161+
{
162+
command: "iptables --version",
163+
action: func() ([]byte, []byte, error) { return []byte("iptables v1.8.11"), nil, nil },
164+
},
165+
},
166+
expected: &runner{
167+
hasCheck: true,
168+
hasRandomFully: true,
169+
waitFlag: []string{"-w", "5", "-W", "100000"},
170+
restoreWaitFlag: []string{"-w", "5", "-W", "100000"},
171+
},
172+
},
173+
{
174+
name: "no iptables",
175+
commands: []testCommand{
176+
{
177+
command: "iptables --version",
178+
action: func() ([]byte, []byte, error) { return nil, nil, fmt.Errorf("no such file or directory") },
179+
},
180+
{
181+
command: "iptables-restore --version",
182+
action: func() ([]byte, []byte, error) { return nil, nil, fmt.Errorf("no such file or directory") },
183+
},
184+
},
185+
expected: &runner{
186+
hasCheck: true,
187+
hasRandomFully: false,
188+
waitFlag: nil,
189+
restoreWaitFlag: nil,
190+
},
191+
},
192+
}
193+
194+
for _, tc := range testCases {
195+
t.Run(tc.name, func(t *testing.T) {
196+
fexec := fakeExecForCommands(tc.commands)
197+
runner := newInternal(fexec, ProtocolIPv4, "", "").(*runner)
80198

81-
func TestIPTablesVersionCmdsIPv6(t *testing.T) {
82-
testIPTablesVersionCmds(t, ProtocolIPv6)
199+
if runner.hasCheck != tc.expected.hasCheck {
200+
t.Errorf("Expected hasCheck=%v, got %v", tc.expected.hasCheck, runner.hasCheck)
201+
}
202+
if runner.hasRandomFully != tc.expected.hasRandomFully {
203+
t.Errorf("Expected hasRandomFully=%v, got %v", tc.expected.hasRandomFully, runner.hasRandomFully)
204+
}
205+
if !reflect.DeepEqual(runner.waitFlag, tc.expected.waitFlag) {
206+
t.Errorf("Expected waitFlag=%v, got %v", tc.expected.waitFlag, runner.waitFlag)
207+
}
208+
if !reflect.DeepEqual(runner.restoreWaitFlag, tc.expected.restoreWaitFlag) {
209+
t.Errorf("Expected restoreWaitFlag=%v, got %v", tc.expected.restoreWaitFlag, runner.restoreWaitFlag)
210+
}
211+
})
212+
}
83213
}
84214

85215
func testEnsureChain(t *testing.T, protocol Protocol) {

0 commit comments

Comments
 (0)