13 def pytest_report_header():
14 vers = subprocess.run(['notmuch', '--version'], stdout=subprocess.PIPE)
15 which = subprocess.run(['which', 'notmuch'], stdout=subprocess.PIPE)
16 return ['{} ({})'.format(vers.stdout.decode(errors='replace').strip(),
17 which.stdout.decode(errors='replace').strip())]
20 @pytest.fixture(scope='function')
22 """The tmpdir fixture wrapped in pathlib.Path."""
23 return pathlib.Path(str(tmpdir))
28 """Return a function which runs notmuch commands on our test maildir.
30 This uses the notmuch-config file created by the ``maildir``
34 """Run a notmuch comand.
36 This function runs with a timeout error as many notmuch
37 commands may block if multiple processes are trying to open
38 the database in write-mode. It is all too easy to
39 accidentally do this in the unittests.
41 cfg_fname = maildir.path / 'notmuch-config'
42 cmd = ['notmuch'] + list(args)
43 env = os.environ.copy()
44 env['NOTMUCH_CONFIG'] = str(cfg_fname)
45 proc = subprocess.run(cmd,
48 proc.check_returncode()
54 """A basic test interface to a valid maildir directory.
56 This creates a valid maildir and provides a simple mechanism to
57 deliver test emails to it. It also writes a notmuch-config file
58 in the top of the maildir.
66 cfg_fname = tmppath/'notmuch-config'
67 with cfg_fname.open('w') as fp:
68 fp.write(textwrap.dedent("""\
73 primary_email=dst@example.com
78 exclude_tags=deleted;spam;
80 synchronize_flags=true
83 """.format(tmppath=tmppath)))
84 return MailDir(tmppath)
88 """An interface around a correct maildir."""
90 def __init__(self, path):
91 self._path = pathlib.Path(path)
92 self.mailbox = mailbox.Maildir(str(path))
97 """The pathname of the maildir."""
100 def _next_msgid(self):
101 """Return a new unique message ID."""
102 msgid = '{}@{}'.format(self._idcount, socket.getfqdn())
108 body='This is a test mail',
109 to='dst@example.com',
110 frm='src@example.com',
112 new=False, # Move to new dir or cur dir?
113 keywords=None, # List of keywords or labels
114 seen=False, # Seen flag (cur dir only)
115 replied=False, # Replied flag (cur dir only)
116 flagged=False): # Flagged flag (cur dir only)
117 """Deliver a new mail message in the mbox.
119 This does only adds the message to maildir, does not insert it
120 into the notmuch database.
122 :returns: A tuple of (msgid, pathname).
124 msgid = self._next_msgid()
126 msg = email.message.EmailMessage()
127 msg.add_header('Received', 'by MailDir; {}'.format(time.ctime(when)))
128 msg.add_header('Message-ID', '<{}>'.format(msgid))
129 msg.add_header('Date', time.ctime(when))
130 msg.add_header('From', frm)
131 msg.add_header('To', to)
132 msg.add_header('Subject', subject)
136 msg.set_content(body)
137 mdmsg = mailbox.MaildirMessage(msg)
139 mdmsg.set_subdir('cur')
146 boxid = self.mailbox.add(mdmsg)
149 basename += mailbox.Maildir.colon + mdmsg.get_info()
150 msgpath = self.path / mdmsg.get_subdir() / basename
151 return (msgid, msgpath)