Merge ~teknoraver/snappy-hwe-snaps/+git/captive-redirect:master into ~snappy-hwe-team/snappy-hwe-snaps/+git/captive-redirect:master

Proposed by Matteo Croce
Status: Merged
Approved by: Matteo Croce
Approved revision: 48ec1db781397020d8f5d6f464bd474553f08d75
Merged at revision: a10ecc6ddb9439708da44f861325df1c8ce11518
Proposed branch: ~teknoraver/snappy-hwe-snaps/+git/captive-redirect:master
Merge into: ~snappy-hwe-team/snappy-hwe-snaps/+git/captive-redirect:master
Diff against target: 591 lines (+452/-7)
14 files modified
README.md (+4/-0)
cmd/config/main.go (+23/-7)
cmd/config/main_test.go (+119/-0)
parts/plugins/x-go.py (+44/-0)
run-tests.sh (+80/-0)
snap/hooks/configure (+24/-0)
snapcraft.yaml (+22/-0)
spread.yaml (+50/-0)
tests/lib/prepare-all.sh (+26/-0)
tests/lib/prepare-each.sh (+15/-0)
tests/lib/restore-each.sh (+3/-0)
tests/main/disable/task.yaml (+8/-0)
tests/main/enable-all/task.yaml (+16/-0)
tests/main/enable-some/task.yaml (+18/-0)
Reviewer Review Type Date Requested Status
Jim Hodapp (community) Approve
Simon Fels Approve
System Enablement Bot continuous-integration Approve
Review via email: mp+315937@code.launchpad.net

Description of the change

Add configure hook

To post a comment you must log in.
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Simon Fels (morphis) wrote :

Needs tests and left a comment inline.

review: Needs Fixing
Revision history for this message
Simon Fels (morphis) :
Revision history for this message
Matteo Croce (teknoraver) :
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Jim Hodapp (jhodapp) :
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Simon Fels (morphis) :
review: Needs Fixing
Revision history for this message
Simon Fels (morphis) wrote :

Still missing spread tests.

Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Jim Hodapp (jhodapp) wrote :

The tests look good, some changes needed...see inline below.

review: Needs Fixing
Revision history for this message
Jim Hodapp (jhodapp) wrote :

I'd also like to see a test that verifies that traffic makes it from the external interface(s) and gets redirected to the portal destination.

Revision history for this message
Simon Fels (morphis) :
review: Needs Fixing
Revision history for this message
Matteo Croce (teknoraver) :
Revision history for this message
Matteo Croce (teknoraver) wrote :

> I'd also like to see a test that verifies that traffic makes it from the
> external interface(s) and gets redirected to the portal destination.

That would involve a second VM with the the virtual ethernet bridged to the tested one

Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Simon Fels (morphis) wrote :

I would like to see still a spread test covering the real functionality of this snap using some kind of network namespace + veth combination but considering we want to get the first part of this finally done approving this now.

review: Approve
Revision history for this message
Jim Hodapp (jhodapp) wrote :

Agree with Simon's comment, approving.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/README.md b/README.md
2index 16ce364..69d3bcc 100644
3--- a/README.md
4+++ b/README.md
5@@ -19,6 +19,10 @@ You can set multiple configuration options with the config command:
6 ```
7 $ captive-portal.config set active=true port=8080 interfaces=eth1
8 ```
9+The configuration options are:
10+active=(true,false) activates or deactivates the redirect
11+port=(1-65535) port to redirect to
12+interfaces=... comma separated value of interface to redirect from, if empty redirects from all
13 ## Development
14
15 ```
16diff --git a/cmd/config/main.go b/cmd/config/main.go
17index 1c1fd2a..535bc02 100644
18--- a/cmd/config/main.go
19+++ b/cmd/config/main.go
20@@ -28,7 +28,7 @@ import (
21 "github.com/jessevdk/go-flags"
22 )
23
24-var configFile = filepath.Join(os.Getenv("SNAP_DATA"), "config.json")
25+var configFile = filepath.Join(os.Getenv("SNAP_COMMON"), "config.json")
26
27 type config struct {
28 Active bool `json:"active"`
29@@ -72,11 +72,14 @@ func (c *config) saveConfig(path string) error {
30
31 // Convenience function which basically does 'iptables -t nat ...'
32 // to add rules to the nat table
33-func addRule(args ...string) error {
34+func run(args ...string) error {
35 cmd := exec.Command("iptables", append([]string{"-t", "nat"}, args...)...)
36 return cmd.Run()
37 }
38
39+// Override run with a logging function in tests
40+var addRule = run
41+
42 func clearRules() {
43 // Flush our custom 'captive' chain and delete it
44 addRule("-D", "PREROUTING", "-j", "captive")
45@@ -134,9 +137,9 @@ func applyRules() error {
46 type statusCommand struct{}
47
48 func (cmd *statusCommand) Execute(args []string) error {
49- println("active:", cfg.Active)
50- println("port:", cfg.Port)
51- println("interfaces:", strings.Join(cfg.Interfaces, ", "))
52+ fmt.Println("active:", cfg.Active)
53+ fmt.Println("port:", cfg.Port)
54+ fmt.Println("interfaces:", strings.Join(cfg.Interfaces, ", "))
55
56 return nil
57 }
58@@ -157,9 +160,22 @@ func (cmd *setCommand) Execute(args []string) error {
59
60 switch value := arg[i+1:]; arg[:i] {
61 case "active":
62- cfg.Active = value == "true"
63+ switch value {
64+ case "true":
65+ cfg.Active = true
66+ case "false":
67+ cfg.Active = false
68+ default:
69+ return fmt.Errorf("Invalid active status %s", value)
70+ }
71 case "port":
72- port, _ := strconv.ParseUint(value, 0, 16)
73+ port, err := strconv.ParseUint(value, 0, 16)
74+ if err != nil {
75+ return err
76+ }
77+ if port == 0 {
78+ return fmt.Errorf("Port can't be 0")
79+ }
80 cfg.Port = uint16(port)
81 case "interfaces":
82 if len(value) > 0 {
83diff --git a/cmd/config/main_test.go b/cmd/config/main_test.go
84new file mode 100644
85index 0000000..dc7a1c1
86--- /dev/null
87+++ b/cmd/config/main_test.go
88@@ -0,0 +1,119 @@
89+//
90+// Copyright (C) 2017 Canonical Ltd
91+//
92+// This program is free software: you can redistribute it and/or modify
93+// it under the terms of the GNU General Public License version 3 as
94+// published by the Free Software Foundation.
95+//
96+// This program is distributed in the hope that it will be useful,
97+// but WITHOUT ANY WARRANTY; without even the implied warranty of
98+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
99+// GNU General Public License for more details.
100+//
101+// You should have received a copy of the GNU General Public License
102+// along with this program. If not, see <http://www.gnu.org/licenses/>.
103+
104+package main
105+
106+import (
107+ "os"
108+ "testing"
109+
110+ "gopkg.in/check.v1"
111+)
112+
113+const (
114+ configPath = "/tmp/cr-config.json"
115+ argsfile = "iptables.args"
116+)
117+
118+// gopkg.in/check.v1 stuff
119+func Test(t *testing.T) { check.TestingT(t) }
120+
121+type ClientSuite struct{}
122+
123+var _ = check.Suite(&ClientSuite{})
124+
125+func (s *ClientSuite) TestConfig(c *check.C) {
126+
127+ // Prepare two configuration structures
128+ cfg1 := config{
129+ Active: true,
130+ Port: 8080,
131+ Interfaces: []string{"eth2", "tun1"},
132+ }
133+ var cfg2 config
134+
135+ c.Assert(cfg1.saveConfig(configPath), check.IsNil)
136+ defer os.Remove(configPath)
137+ c.Assert(cfg2.loadConfig(configPath), check.IsNil)
138+
139+ c.Assert(cfg1, check.DeepEquals, cfg2)
140+}
141+
142+var iptablesArgs [][]string
143+
144+func testRun(args ...string) error {
145+ iptablesArgs = append(iptablesArgs, args)
146+ return nil
147+}
148+
149+func (s *ClientSuite) TestClear(c *check.C) {
150+ // Mock iptables calls
151+ iptablesArgs = [][]string{}
152+ addRule = testRun
153+
154+ clearRules()
155+
156+ c.Assert(iptablesArgs, check.DeepEquals, [][]string{
157+ {"-D", "PREROUTING", "-j", "captive"},
158+ {"-F", "captive"},
159+ {"-X", "captive"},
160+ })
161+}
162+
163+func (s *ClientSuite) TestApplyAll(c *check.C) {
164+ // Mock iptables calls
165+ iptablesArgs = [][]string{}
166+ addRule = testRun
167+
168+ cfg = config{
169+ Active: true,
170+ Port: 54239,
171+ }
172+
173+ applyRules()
174+
175+ c.Assert(iptablesArgs, check.DeepEquals, [][]string{
176+ {"-D", "PREROUTING", "-j", "captive"},
177+ {"-F", "captive"},
178+ {"-X", "captive"},
179+ {"-N", "captive"},
180+ {"-I", "PREROUTING", "-j", "captive"},
181+ {"-A", "captive", "-p", "tcp", "-m", "multiport", "--dport", "80,443", "-j", "REDIRECT", "--to-ports", "54239"},
182+ })
183+}
184+
185+func (s *ClientSuite) TestApplySome(c *check.C) {
186+ // Mock iptables calls
187+ iptablesArgs = [][]string{}
188+ addRule = testRun
189+
190+ cfg = config{
191+ Active: true,
192+ Port: 1234,
193+ Interfaces: []string{"eth4", "ppp2"},
194+ }
195+
196+ applyRules()
197+
198+ c.Assert(iptablesArgs, check.DeepEquals, [][]string{
199+ {"-D", "PREROUTING", "-j", "captive"},
200+ {"-F", "captive"},
201+ {"-X", "captive"},
202+ {"-N", "captive"},
203+ {"-I", "PREROUTING", "-j", "captive"},
204+ {"-A", "captive", "-i", "eth4", "-p", "tcp", "-m", "multiport", "--dport", "80,443", "-j", "REDIRECT", "--to-ports", "1234"},
205+ {"-A", "captive", "-i", "ppp2", "-p", "tcp", "-m", "multiport", "--dport", "80,443", "-j", "REDIRECT", "--to-ports", "1234"},
206+ })
207+}
208diff --git a/parts/plugins/x-go.py b/parts/plugins/x-go.py
209new file mode 100644
210index 0000000..2211de7
211--- /dev/null
212+++ b/parts/plugins/x-go.py
213@@ -0,0 +1,44 @@
214+# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
215+#
216+# Copyright (C) 2015, 2016 Canonical Ltd
217+#
218+# This program is free software: you can redistribute it and/or modify
219+# it under the terms of the GNU General Public License version 3 as
220+# published by the Free Software Foundation.
221+#
222+# This program is distributed in the hope that it will be useful,
223+# but WITHOUT ANY WARRANTY; without even the implied warranty of
224+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
225+# GNU General Public License for more details.
226+#
227+# You should have received a copy of the GNU General Public License
228+# along with this program. If not, see <http://www.gnu.org/licenses/>.
229+
230+import os
231+
232+import snapcraft
233+import snapcraft.plugins.go
234+
235+DEBIAN_GOCODE_SRC_PATH = "/usr/share/gocode/src"
236+
237+class GoPlugin(snapcraft.plugins.go.GoPlugin):
238+ def pull(self):
239+ # Skip the pull step from GoPlugin here as it would repeat 90% of what
240+ # we're doing here and will only conflict.
241+ snapcraft.BasePlugin.pull(self)
242+ os.makedirs(self._gopath_src, exist_ok=True)
243+
244+ if self.options.source:
245+ go_package = self._get_local_go_package()
246+ go_package_path = os.path.join(self._gopath_src, go_package)
247+ if os.path.islink(go_package_path):
248+ os.unlink(go_package_path)
249+ os.makedirs(os.path.dirname(go_package_path), exist_ok=True)
250+ os.symlink(self.sourcedir, go_package_path)
251+ # We can't just add the gocode directory to GOPATH as go
252+ # doesn't like this. Instead we're symlinking the necessary
253+ # subdirectories from the gocode directory into our already
254+ # existing GOPATH.
255+ for dir in os.listdir(DEBIAN_GOCODE_SRC_PATH):
256+ os.symlink(os.path.join(DEBIAN_GOCODE_SRC_PATH, dir),
257+ os.path.join(self._gopath_src, dir))
258diff --git a/run-tests.sh b/run-tests.sh
259new file mode 100755
260index 0000000..92910b5
261--- /dev/null
262+++ b/run-tests.sh
263@@ -0,0 +1,80 @@
264+#!/bin/sh
265+#
266+# Copyright (C) 2016 Canonical Ltd
267+#
268+# This program is free software: you can redistribute it and/or modify
269+# it under the terms of the GNU General Public License version 3 as
270+# published by the Free Software Foundation.
271+#
272+# This program is distributed in the hope that it will be useful,
273+# but WITHOUT ANY WARRANTY; without even the implied warranty of
274+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
275+# GNU General Public License for more details.
276+#
277+# You should have received a copy of the GNU General Public License
278+# along with this program. If not, see <http://www.gnu.org/licenses/>.
279+
280+set -e
281+
282+TESTS_EXTRAS_URL="https://git.launchpad.net/~snappy-hwe-team/snappy-hwe-snaps/+git/tests-extras"
283+TESTS_EXTRAS_PATH=".tests-extras"
284+
285+# Display help.
286+# This has to be in sync with the tests-extras/test-runner.sh script
287+# functionalities as the parameters to this one are passed directly there
288+show_help() {
289+ exec cat <<'EOF'
290+Usage: run-tests.sh [OPTIONS]
291+
292+This is fetch & forget script and what it does is to fetch the
293+tests-extras repository and execute the run-tests.sh script from
294+there passing arguments as-is.
295+
296+optional arguments:
297+ --help Show this help message and exit
298+ --channel Select another channel to build the base image from (default: stable)
299+ --snap Extra snap to install
300+ --debug Enable verbose debugging output
301+ --test-from-channel Pull network-manager snap from the specified channel instead of building it from source
302+ --force-new-image Force generating a new image used for testing
303+EOF
304+}
305+
306+# Clone the tests-extras repository
307+clone_tests_extras() {
308+ echo "INFO: Fetching tests-extras scripts into $TESTS_EXTRAS_PATH ..."
309+ git clone -b master $TESTS_EXTRAS_URL $TESTS_EXTRAS_PATH >/dev/null 2>&1
310+ if [ $? -ne 0 ]; then
311+ echo "ERROR: Failed to fetch the $TESTS_EXTRAS_URL repo, exiting.."
312+ exit 1
313+ fi
314+}
315+
316+# Make sure the already cloned tests-extras repository is in a known and update
317+# state before it is going to be used.
318+restore_and_update_tests_extras() {
319+ echo "INFO: Restoring and updating $TESTS_EXTRAS_PATH"
320+ cd $TESTS_EXTRAS_PATH && git reset --hard && git clean -dfx && git pull
321+ cd -
322+}
323+
324+# ==============================================================================
325+# This is fetch & forget script and what it does is to fetch the tests-extras
326+# repo and execute the run-tests.sh script from there passing arguments as-is.
327+#
328+# The tests-extras repository ends up checked out in the snap tree but as a
329+# hidden directory which is re-used since then.
330+
331+# Display help w/o fetching anything
332+if [ "$1" = "--help" ]; then
333+ show_help
334+fi
335+
336+if [ -d "$TESTS_EXTRAS_PATH" ]; then
337+ restore_and_update_tests_extras
338+else
339+ clone_tests_extras
340+fi
341+
342+echo "INFO: Executing tests runner"
343+cd $TESTS_EXTRAS_PATH && ./tests-runner.sh "$@"
344diff --git a/snap/hooks/configure b/snap/hooks/configure
345new file mode 100755
346index 0000000..249f367
347--- /dev/null
348+++ b/snap/hooks/configure
349@@ -0,0 +1,24 @@
350+#!/bin/sh
351+
352+# Copyright (C) 2017 Canonical Ltd
353+#
354+# This program is free software: you can redistribute it and/or modify
355+# it under the terms of the GNU General Public License version 3 as
356+# published by the Free Software Foundation.
357+#
358+# This program is distributed in the hope that it will be useful,
359+# but WITHOUT ANY WARRANTY; without even the implied warranty of
360+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
361+# GNU General Public License for more details.
362+#
363+# You should have received a copy of the GNU General Public License
364+# along with this program. If not, see <http://www.gnu.org/licenses/>.
365+
366+active=$(snapctl get active)
367+port=$(snapctl get port)
368+interfaces=$(snapctl get interfaces)
369+
370+# Exit after fresh installation
371+[ -z "$active$port$interfaces" ] && exit 0
372+
373+exec $SNAP/bin/config set active="$active" port="$port" interfaces="$interfaces"
374diff --git a/snapcraft.yaml b/snapcraft.yaml
375index 1bb3f5f..7e030be 100644
376--- a/snapcraft.yaml
377+++ b/snapcraft.yaml
378@@ -1,3 +1,18 @@
379+#
380+# Copyright (C) 2017 Canonical Ltd
381+#
382+# This program is free software: you can redistribute it and/or modify
383+# it under the terms of the GNU General Public License version 3 as
384+# published by the Free Software Foundation.
385+#
386+# This program is distributed in the hope that it will be useful,
387+# but WITHOUT ANY WARRANTY; without even the implied warranty of
388+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
389+# GNU General Public License for more details.
390+#
391+# You should have received a copy of the GNU General Public License
392+# along with this program. If not, see <http://www.gnu.org/licenses/>.
393+
394 name: captive-redirect
395 version: 1
396 confinement: strict
397@@ -14,9 +29,16 @@ apps:
398 plugs:
399 - firewall-control
400
401+hooks:
402+ configure:
403+ plugs:
404+ - firewall-control
405+
406 parts:
407 config:
408 plugin: go
409 source: cmd/config
410 snap:
411 - bin
412+ build-packages:
413+ - golang-go-flags-dev
414diff --git a/spread.yaml b/spread.yaml
415new file mode 100644
416index 0000000..3eefa0a
417--- /dev/null
418+++ b/spread.yaml
419@@ -0,0 +1,50 @@
420+#
421+# Copyright (C) 2017 Canonical Ltd
422+#
423+# This program is free software: you can redistribute it and/or modify
424+# it under the terms of the GNU General Public License version 3 as
425+# published by the Free Software Foundation.
426+#
427+# This program is distributed in the hope that it will be useful,
428+# but WITHOUT ANY WARRANTY; without even the implied warranty of
429+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
430+# GNU General Public License for more details.
431+#
432+# You should have received a copy of the GNU General Public License
433+# along with this program. If not, see <http://www.gnu.org/licenses/>.
434+
435+
436+project: captive-redirect
437+
438+environment:
439+ PROJECT_PATH: /home/captive-redirect
440+ TESTSLIB: $PROJECT_PATH/tests/lib
441+ SNAP_NAME: captive-redirect
442+ # Allow the host to pass the channel to use for the test rim
443+ SNAP_CHANNEL: $(HOST:echo $SNAP_CHANNEL)
444+
445+backends:
446+ qemu:
447+ systems:
448+ - ubuntu-core-16:
449+ username: test
450+ password: test
451+
452+# Put this somewhere where we have read-write access
453+path: /home/captive-redirect
454+
455+exclude:
456+ - .git
457+
458+prepare: |
459+ . $TESTSLIB/prepare-all.sh
460+
461+suites:
462+ tests/main/:
463+ summary: Full-system tests for the captive-redirect snap
464+ systems:
465+ - ubuntu-core-16
466+ prepare-each: |
467+ . $TESTSLIB/prepare-each.sh
468+ restore-each: |
469+ . $TESTSLIB/restore-each.sh
470diff --git a/tests/lib/prepare-all.sh b/tests/lib/prepare-all.sh
471new file mode 100755
472index 0000000..d47845f
473--- /dev/null
474+++ b/tests/lib/prepare-all.sh
475@@ -0,0 +1,26 @@
476+#!/bin/sh
477+
478+rm -f /home/captive-redirect/captive-redirect_*.snap
479+
480+# Setup classic snap and build the captive-redirect snap in there
481+snap install --devmode --beta classic
482+cat <<-EOF > /home/test/build-snap.sh
483+#!/bin/sh
484+set -ex
485+apt update
486+apt install -y snapcraft git
487+cd /home/captive-redirect/
488+snapcraft clean
489+snapcraft
490+EOF
491+chmod +x /home/test/build-snap.sh
492+sudo classic /home/test/build-snap.sh
493+snap remove classic
494+
495+# Make sure we have a snap binary
496+test -e /home/captive-redirect/captive-redirect_*.snap
497+
498+# Snapshot of the current snapd state for a later restore
499+systemctl stop snapd.service snapd.socket
500+tar czf $SPREAD_PATH/snapd-state.tar.gz /var/lib/snapd
501+systemctl start snapd.socket
502diff --git a/tests/lib/prepare-each.sh b/tests/lib/prepare-each.sh
503new file mode 100755
504index 0000000..d983cef
505--- /dev/null
506+++ b/tests/lib/prepare-each.sh
507@@ -0,0 +1,15 @@
508+#!/bin/sh
509+
510+# Restore snapd state from backup
511+systemctl stop snapd.service snapd.socket
512+rm -rf /var/lib/snapd/*
513+tar xzf $SPREAD_PATH/snapd-state.tar.gz -C /
514+rm -rf /root/.snap
515+systemctl start snapd.socket
516+
517+# Clean iptables
518+iptables -t nat -F
519+iptables -t nat -X
520+
521+snap install --dangerous /home/captive-redirect/captive-redirect_*.snap
522+snap connect captive-redirect:firewall-control core
523diff --git a/tests/lib/restore-each.sh b/tests/lib/restore-each.sh
524new file mode 100755
525index 0000000..aa8f65c
526--- /dev/null
527+++ b/tests/lib/restore-each.sh
528@@ -0,0 +1,3 @@
529+#!/bin/sh
530+
531+snap remove captive-redirect
532diff --git a/tests/main/disable/task.yaml b/tests/main/disable/task.yaml
533new file mode 100644
534index 0000000..ababdb0
535--- /dev/null
536+++ b/tests/main/disable/task.yaml
537@@ -0,0 +1,8 @@
538+summary: Verify that the redirect can be disabled
539+
540+execute: |
541+ # Snap is installed, check that it's disabled
542+ captive-redirect.config status |grep 'active: false'
543+
544+ # Check that we have no iptables rules
545+ ! iptables-save |grep -- -j
546diff --git a/tests/main/enable-all/task.yaml b/tests/main/enable-all/task.yaml
547new file mode 100644
548index 0000000..4745acb
549--- /dev/null
550+++ b/tests/main/enable-all/task.yaml
551@@ -0,0 +1,16 @@
552+summary: Verify that the redirect can be enabled on all interfaces
553+
554+execute: |
555+ # Enable the redirect on all interfaces
556+ captive-redirect.config set active=true port=9000
557+
558+ captive-redirect.config status |grep 'active: true'
559+ captive-redirect.config status |grep 'port: 9000'
560+ captive-redirect.config status |grep 'interfaces: $'
561+
562+ # Check that we have the iptables rules
563+ ipt=/tmp/rules.$$
564+ iptables-save >$ipt
565+
566+ grep -- '-A PREROUTING -j captive' $ipt
567+ grep -- '-A captive -p tcp -m multiport --dports 80,443 -j REDIRECT --to-ports 9000' $ipt
568diff --git a/tests/main/enable-some/task.yaml b/tests/main/enable-some/task.yaml
569new file mode 100644
570index 0000000..5bf13f6
571--- /dev/null
572+++ b/tests/main/enable-some/task.yaml
573@@ -0,0 +1,18 @@
574+summary: Verify that the redirect can be enabled selectively on configured interfaces
575+
576+execute: |
577+ # Enable the redirect on the configured interfaces
578+ captive-redirect.config set active=true port=7689 interfaces=eth4,tun2
579+
580+ captive-redirect.config status |grep 'active: true'
581+ captive-redirect.config status |grep 'port: 7689'
582+ captive-redirect.config status |grep 'interfaces: .*eth4'
583+ captive-redirect.config status |grep 'interfaces: .*tun2'
584+
585+ # Check that we have the iptables rules
586+ ipt=/tmp/rules.$$
587+ iptables-save >$ipt
588+
589+ grep -- '-A PREROUTING -j captive' $ipt
590+ grep -- '-A captive -i eth4 -p tcp -m multiport --dports 80,443 -j REDIRECT --to-ports 7689' $ipt
591+ grep -- '-A captive -i tun2 -p tcp -m multiport --dports 80,443 -j REDIRECT --to-ports 7689' $ipt

Subscribers

People subscribed via source and target branches

to all changes: