1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
==> Starting check()...
/usr/bin/pytest 
============================================================== test session starts ===============================================================
platform linux -- Python 3.11.5, pytest-7.4.2, pluggy-1.3.0
rootdir: /home/.../aurman/backintime/src/backintime-1.4.0/common
plugins: pyfakefs-5.2.4
collected 359 items                                                                                                                              

test/test_applicationinstance.py ...................                                                                                       [  5%]
test/test_argparser.py .....................                                                                                               [ 11%]
test/test_backintime.py .Fs                                                                                                                [ 11%]
test/test_backup.py ...............                                                                                                        [ 16%]
test/test_config.py ...........                                                                                                            [ 19%]
test/test_configfile.py ......................................................                                                             [ 34%]
test/test_diagnostics.py .....                                                                                                             [ 35%]
test/test_encfstools.py .                                                                                                                  [ 35%]
test/test_restore.py .........ss                                                                                                           [ 38%]
test/test_sid.py ...........................................                                                                               [ 50%]
test/test_snapshotlog.py ..........                                                                                                        [ 53%]
test/test_snapshots.py ..................................................ssss                                                              [ 68%]
test/test_sshtools.py sssssssssssssssssssssss...ssssss                                                                                     [ 77%]
test/test_takeSnapshot.py .........sssssssss                                                                                               [ 82%]
test/test_tools.py ..............................................................                                                          [100%]Clearing the cache


==================================================================== FAILURES ====================================================================
________________________________________________ TestBackInTime.test_local_snapshot_is_successful ________________________________________________

self = <test.test_backintime.TestBackInTime testMethod=test_local_snapshot_is_successful>

        def test_local_snapshot_is_successful(self):
            """From BIT initialization through snapshot
    
            From BIT initialization all the way through successful snapshot on a
            local mount. test one of the highest level interfaces a user could
            work with - the command line ensures that argument parsing,
            functionality, and output all work as expected is NOT intended to
            replace individual method tests, which are incredibly useful as well.
    
            Development notes (by Buhtz):
            Multiple tests do compare return codes and output on stdout. The
            intention might be an integration tests. But the asserts not qualified
            to answer the important questions and observe the intended behaviour.
            Heavy refactoring is needed. But because of the "level" of that tests
            it won't happen in the near future.
            """
    
            # ensure that we see full diffs of assert output if there are any
            self.maxDiff = None
    
            # create pristine source directory with single file
            subprocess.getoutput("chmod -R a+rwx /tmp/test && rm -rf /tmp/test")
            os.mkdir('/tmp/test')
    
            with open('/tmp/test/testfile', 'w') as f:
                f.write('some data')
    
            # create pristine snapshot directory
            subprocess.getoutput(
                "chmod -R a+rwx /tmp/snapshots && rm -rf /tmp/snapshots")
            os.mkdir('/tmp/snapshots')
    
            # remove restored directory
            subprocess.getoutput("rm -rf /tmp/restored")
    
            # install proper destination filesystem structure and verify output
            proc = subprocess.Popen(["./backintime",
                                     "--config",
                                     "test/config",
                                     "--share-path",
                                     self.sharePath,
                                     "check-config",
                                     # do not overwrite users crontab
                                     "--no-crontab"],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
    
            output, error = proc.communicate()
            msg = 'Returncode: {}\nstderr: {}\nstdout: {}' \
                  .format(proc.returncode, error.decode(), output.decode())
    
            self.assertEqual(proc.returncode, 0, msg)
    
            self.assertRegex(output.decode(), re.compile(r'''
    Back In Time
    Version: \d+.\d+.\d+.*
    
    Back In Time comes with ABSOLUTELY NO WARRANTY.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `backintime --license' for details.
    
    (INFO: Update to config version \d+
    )?
     \+--------------------------------\+
     |  Check/prepare snapshot path   |
     \+--------------------------------\+
    Check/prepare snapshot path: done
    
     \+--------------------------------\+
     |          Check config          |
     \+--------------------------------\+
    Check config: done
    
    Config .*test/config profile 'Main profile' is fine.''', re.MULTILINE))
    
            # execute backup and verify output
            proc = subprocess.Popen(["./backintime",
                                     "--config", "test/config",
                                     "--share-path", self.sharePath,
                                     "backup"],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            output, error = proc.communicate()
            msg = 'Returncode: {}\nstderr: {}\nstdout: {}' \
                  .format(proc.returncode, error.decode(), output.decode())
            self.assertEqual(proc.returncode, 0, msg)
    
            self.assertRegex(output.decode(), re.compile(r'''
    Back In Time
    Version: \d+.\d+.\d+.*
    
    Back In Time comes with ABSOLUTELY NO WARRANTY.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `backintime --license' for details.
    ''', re.MULTILINE))
    
            # Workaround until refactoring was done (Buhtz, Feb.'23)
            # The log output completely goes to stderr.
            # Note: DBus warnings at the begin and end are already ignored by the
            #       regex but if the BiT serviceHelper.py DBus daemon is not
            #       installed at all the warnings also occur in the middle of below
            #       expected INFO log lines so they are removed by filtering here.
            #       The same goes with Gtk warnings.
    
            line_beginnings_to_exclude = [
                "WARNING: Failed to connect to Udev serviceHelper",
                "WARNING: D-Bus message:",
                "WARNING: Udev-based profiles cannot be changed or checked",
                "WARNING: Inhibit Suspend failed",
                "Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway"
            ]
    
            line_contains_to_exclude = [
                "Gtk-WARNING",
                "qt.qpa.plugin: Could not find the Qt platform plugin"
            ]
    
            # remove lines via startswith()
            filtered_log_output = filter(
                lambda line: not any([
                    line.startswith(ex) for ex in line_beginnings_to_exclude]),
                error.decode().split('\n')
            )
    
            # remove lines via __contains__()
            filtered_log_output = filter(
                lambda line: not any([
                    ex in line for ex in line_contains_to_exclude]),
                filtered_log_output
            )
    
            # remove empty lines
            filtered_log_output = filter(
                lambda line: line,
                filtered_log_output
            )
    
            filtered_log_output = '\n'.join(filtered_log_output)
    
>           self.assertRegex(filtered_log_output, re.compile(r'''INFO: Lock
    INFO: Take a new snapshot. Profile: 1 Main profile
    INFO: Call rsync to take the snapshot
    INFO: Save config file
    INFO: Save permissions
    INFO: Create info file
    INFO: Unlock''', re.MULTILINE))
E   AssertionError: Regex didn't match: 'INFO: Lock\nINFO: Take a new snapshot. Profile: 1 Main profile\nINFO: Call rsync to take the snapshot\nINFO: Save config file\nINFO: Save permissions\nINFO: Create info file\nINFO: Unlock' not found in 'INFO: Lock\nINFO: Take a new snapshot. Profile: 1 Main profile\nINFO: Call rsync to take the snapshot\nINFO: Save config file\nINFO: Save permissions\nINFO: Create info file\nWARNING: PyQt was not able to install a translator for language code "C". Deactivate translation and falling back to the source language (English).\nINFO: Unlock'

test/test_backintime.py:178: AssertionError