Remove access checks in tests under root
[tinc] / test / integration / cmd_import.py
1 #!/usr/bin/env python3
2
3 """Test import/export error conditions."""
4
5 import os
6
7 from testlib import check, cmd, util
8 from testlib.log import log
9 from testlib.const import RUN_ACCESS_CHECKS
10 from testlib.proc import Tinc
11 from testlib.test import Test
12
13 SEPARATOR = f"#{'-' * 63}#"
14
15 MULTI_HOST = f"""
16 Name = node0
17 Address = sun
18 {SEPARATOR}
19 Name = node1
20 Address = moon
21 {SEPARATOR}
22 """.strip()
23
24 MAX_PATH = 255 if os.name == "nt" else os.pathconf("/", "PC_PATH_MAX")
25 LONG_NAME = MAX_PATH * "x"
26
27
28 def init(ctx: Test) -> Tinc:
29     """Initialize a node."""
30
31     node = ctx.node()
32     stdin = f"""
33         init {node}
34         set Port 0
35         set Address localhost
36         set DeviceType dummy
37         set AutoConnect no
38     """
39     node.cmd(stdin=stdin)
40     return node
41
42
43 def test_import(foo: Tinc) -> None:
44     """Run tests for command 'import'."""
45
46     _, err = foo.cmd("import", "foo", code=1)
47     check.is_in("Too many arguments", err)
48
49     _, err = foo.cmd("import", code=1)
50     check.is_in("No host configuration files imported", err)
51
52     for prefix in "fred", "Name fred", "name = fred", "name=fred":
53         log.info("testing prefix '%s'", prefix)
54         _, err = foo.cmd("import", stdin=prefix, code=1)
55         check.is_in("Junk at the beginning", err)
56
57     _, err = foo.cmd("import", stdin="Name = !@#", code=1)
58     check.is_in("Invalid Name in input", err)
59
60     _, err = foo.cmd("import", stdin=f"Name = {LONG_NAME}", code=1)
61     check.is_in("Filename too long", err)
62
63     log.info("make sure no address for imported nodes is present")
64     for node in "node0", "node1":
65         foo.cmd("get", f"{node}.Address", code=1)
66
67     _, err = foo.cmd("import", stdin=MULTI_HOST)
68     check.is_in("Imported 2 host configuration files", err)
69
70     log.info("check imported nodes addresses")
71     check.equals("sun", cmd.get(foo, "node0.Address"))
72     check.equals("moon", cmd.get(foo, "node1.Address"))
73
74     _, err = foo.cmd("import", stdin="Name = node0", code=1)
75     check.is_in("node0 already exists", err)
76
77     if RUN_ACCESS_CHECKS:
78         log.info("import to inaccessible hosts subdirectory")
79         os.chmod(foo.sub("hosts"), 0)
80         _, err = foo.cmd("import", stdin="Name = vinny", code=1)
81         check.is_in("Error creating configuration", err)
82
83
84 def test_export(foo: Tinc) -> None:
85     """Run tests for command 'export'."""
86
87     _, err = foo.cmd("export", "foo", code=1)
88     check.is_in("Too many arguments", err)
89
90     os.remove(foo.sub(f"hosts/{foo}"))
91     _, err = foo.cmd("export", code=1)
92     check.is_in("Could not open configuration", err)
93
94     util.write_text(foo.sub("tinc.conf"), "")
95     _, err = foo.cmd("export", code=1)
96     check.is_in("Could not find Name", err)
97
98     os.remove(foo.sub("tinc.conf"))
99     _, err = foo.cmd("export", code=1)
100     check.is_in("Could not open", err)
101
102
103 def test_exchange(foo: Tinc) -> None:
104     """Run tests for command 'exchange'."""
105
106     log.info("make sure exchange does not import if export fails")
107     util.write_text(foo.sub("tinc.conf"), "")
108     host_foo = "Name = foo\nAddress = 1.1.1.1"
109     _, err = foo.cmd("exchange", stdin=host_foo, code=1)
110     assert "Imported" not in err
111
112
113 def test_exchange_all(foo: Tinc) -> None:
114     """Run tests for command 'exchange'."""
115
116     log.info("make sure exchange-all does not import if export fails")
117     host_bar = foo.sub("hosts/bar")
118     util.write_text(host_bar, "")
119     os.chmod(host_bar, 0)
120     host_foo = "Name = foo\nAddress = 1.1.1.1"
121     _, err = foo.cmd("exchange-all", stdin=host_foo, code=1)
122     assert "Imported" not in err
123
124
125 def test_export_all(foo: Tinc) -> None:
126     """Run tests for command 'export-all'."""
127
128     _, err = foo.cmd("export-all", "foo", code=1)
129     check.is_in("Too many arguments", err)
130
131     host_foo = foo.sub("hosts/foo")
132     util.write_text(host_foo, "Name = foo")
133     os.chmod(host_foo, 0)
134
135     host_bar = foo.sub("hosts/bar")
136     util.write_text(host_bar, "Host = bar\nAddress = 1.1.1.1")
137
138     host_invalid = foo.sub("hosts/xi-Eb-Vx-k3")
139     util.write_text(host_invalid, "Host = invalid")
140
141     out, err = foo.cmd("export-all", code=1)
142     check.is_in("Could not open configuration", err)
143
144     log.info("checking bad node name in export")
145     assert "xi-Eb-Vx-k3" not in out
146
147     for want in "Host = bar", "Address = 1.1.1.1", SEPARATOR:
148         check.is_in(want, out)
149
150     log.info("verify that separators are used on separate lines")
151     lines = out.splitlines()
152     separators = list(filter(lambda line: line == SEPARATOR, lines))
153     if len(separators) != 2:
154         log.info("unexpected number of separators: %s", lines)
155         assert False
156
157     if RUN_ACCESS_CHECKS:
158         os.chmod(foo.sub("hosts"), 0)
159         _, err = foo.cmd("export-all", code=1)
160         check.is_in("Could not open host configuration", err)
161
162
163 with Test("test 'import' command") as context:
164     test_import(init(context))
165
166 with Test("test 'export' command") as context:
167     test_export(init(context))
168
169 with Test("test 'exchange' command") as context:
170     test_exchange(init(context))
171
172 if RUN_ACCESS_CHECKS:
173     with Test("test 'exchange-all' command") as context:
174         test_exchange_all(init(context))
175
176     with Test("test 'export-all' command") as context:
177         test_export_all(init(context))