We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Test failure when using tox
This is because tox use sqlite and has no user set

```
======================================================================
ERROR: test_map_upgrade (modoboa.admin.tests.test_mapfiles.MapFilesTestCase)
Check that map content is used.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/gawel/bear/modoboa/.tox/py27/lib/python2.7/site-packages/modoboa/admin/tests/test_mapfiles.py", line 45, in test_map_upgrade
    self.assertEqual(mapcontent["user"], dbsettings["USER"])
KeyError: 'user'

----------------------------------------------------------------------
Ran 178 tests in 44.553s
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `modoboa/core/management/commands/generate_postfix_maps.py`
Content:
```
1 """Management command to generate/update postfix map files."""
2 
3 import copy
4 import hashlib
5 import os
6 import sys
7 
8 from django.conf import settings
9 from django.core.management.base import BaseCommand
10 from django.template import Context, Template
11 from django.utils import timezone
12 
13 import dj_database_url
14 
15 from ... import signals
16 from ... import utils
17 
18 MAP_FILE_TEMPLATE = """# This file was generated on {{ date }} by running:
19 # {{ commandline }}
20 # DO NOT EDIT!
21 """
22 
23 
24 class Command(BaseCommand):
25     """Command class."""
26 
27     help = "Generate/update postfix map files."
28 
29     def add_arguments(self, parser):
30         """Add extra arguments."""
31         parser.add_argument(
32             "--dburl", help="Custom database url")
33         parser.add_argument(
34             "--destdir", default=".",
35             help="Directory where files will be created")
36         parser.add_argument(
37             "--force-overwrite", action="store_true", default=False,
38             help="Force overwrite of existing map files")
39 
40     def __load_checksums(self, destdir):
41         """Load existing checksums if possible."""
42         self.__checksums_file = os.path.join(
43             destdir, "modoboa-postfix-maps.chk")
44         self.__checksums = {}
45         if not os.path.exists(self.__checksums_file):
46             return
47         with open(self.__checksums_file) as fp:
48             for line in fp:
49                 fname, dbtype, checksum = line.split(":")
50                 self.__checksums[fname.strip()] = {
51                     "dbtype": dbtype, "checksum": checksum.strip()
52                 }
53 
54     def __register_map_files(self):
55         """Load specified applications."""
56         responses = signals.register_postfix_maps.send(sender=self.__class__)
57         mapfiles = []
58         for response in responses:
59             mapfiles += response[1]
60         return mapfiles
61 
62     def __check_file(self, path):
63         """Check if map file has been modified."""
64         fname = os.path.basename(path)
65         condition = (
66             not self.__checksums or
67             fname not in self.__checksums)
68         if condition:
69             return True
70         with open(path) as fp:
71             checksum = hashlib.md5(fp.read()).hexdigest()
72         return checksum == self.__checksums[fname]["checksum"]
73 
74     def get_template(self, dbtype):
75         """Return map file template."""
76         tplcontent = MAP_FILE_TEMPLATE
77         if dbtype == "sqlite":
78             tplcontent += """dbpath = {{ dbname }}
79 query = {{ query|safe }}
80 """
81         else:
82             tplcontent += """user = {{ dbuser }}
83 password = {{ dbpass }}
84 dbname = {{ dbname }}
85 hosts = {{ dbhost }}
86 query = {{ query|safe }}
87 """
88         return Template(tplcontent)
89 
90     def get_template_context(self, options):
91         """Build the context used to render templates."""
92         dburl = options.get("dburl")
93         db_settings = (
94             dj_database_url.config(default=dburl)
95             if dburl else settings.DATABASES["default"])
96         if "sqlite" in db_settings["ENGINE"]:
97             dbtype = "sqlite"
98         elif "psycopg2" in db_settings["ENGINE"]:
99             dbtype = "postgres"
100         else:
101             dbtype = "mysql"
102         commandline = "{} {}".format(
103             os.path.basename(sys.argv[0]), " ".join(sys.argv[1:]))
104         context = {
105             "date": timezone.now(),
106             "commandline": commandline,
107             "dbtype": dbtype,
108             "dbuser": db_settings["USER"],
109             "dbpass": db_settings["PASSWORD"],
110             "dbname": db_settings["NAME"],
111             "dbhost": db_settings.get("HOST", "127.0.0.1"),
112         }
113         return context
114 
115     def __render_map_file(
116             self, mapobject, destdir, context, force_overwrite=False):
117         """Render a map file."""
118         fullpath = os.path.join(destdir, mapobject.filename)
119         if os.path.exists(fullpath) and not force_overwrite:
120             if not self.__check_file(fullpath):
121                 print(
122                     "Cannot upgrade '{}' map because it has been modified."
123                     .format(mapobject.filename))
124                 return self.__checksums[mapobject.filename]
125             mapcontent = utils.parse_map_file(fullpath)
126             context = copy.deepcopy(context)
127             context["dbtype"] = self.__checksums[mapobject.filename]["dbtype"]
128             context["dbuser"] = mapcontent["user"]
129             context["dbpass"] = mapcontent["password"]
130             context["dbname"] = mapcontent["dbname"]
131             context["dbhost"] = mapcontent["hosts"]
132         content = self.get_template(context["dbtype"]).render(
133             Context(
134                 dict(context.items(),
135                      query=getattr(mapobject, context["dbtype"]))
136             )
137         )
138         fullpath = os.path.join(destdir, mapobject.filename)
139         with open(fullpath, "w") as fp:
140             fp.write(content)
141         return hashlib.md5(content).hexdigest()
142 
143     def handle(self, *args, **options):
144         """Command entry point."""
145         mapfiles = self.__register_map_files()
146         destdir = os.path.realpath(options["destdir"])
147         try:
148             os.mkdir(destdir)
149         except OSError:
150             pass
151         self.__load_checksums(destdir)
152         context = self.get_template_context(options)
153         checksums = {}
154         for mapobject in mapfiles:
155             checksum = self.__render_map_file(
156                 mapobject, destdir, context,
157                 force_overwrite=options["force_overwrite"])
158             checksums[mapobject.filename] = checksum
159         with open(self.__checksums_file, "w") as fp:
160             for fname, checksum in checksums.items():
161                 fp.write("{}:{}:{}\n".format(
162                     fname, context["dbtype"], checksum))
163
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/modoboa/core/management/commands/generate_postfix_maps.py b/modoboa/core/management/commands/generate_postfix_maps.py
--- a/modoboa/core/management/commands/generate_postfix_maps.py
+++ b/modoboa/core/management/commands/generate_postfix_maps.py
@@ -125,10 +125,13 @@
             mapcontent = utils.parse_map_file(fullpath)
             context = copy.deepcopy(context)
             context["dbtype"] = self.__checksums[mapobject.filename]["dbtype"]
-            context["dbuser"] = mapcontent["user"]
-            context["dbpass"] = mapcontent["password"]
-            context["dbname"] = mapcontent["dbname"]
-            context["dbhost"] = mapcontent["hosts"]
+            if context["dbtype"] == "sqlite":
+                context["dbname"] = mapcontent["dbpath"]
+            else:
+                context["dbuser"] = mapcontent["user"]
+                context["dbpass"] = mapcontent["password"]
+                context["dbname"] = mapcontent["dbname"]
+                context["dbhost"] = mapcontent["hosts"]
         content = self.get_template(context["dbtype"]).render(
             Context(
                 dict(context.items(),

{"golden_diff": "diff --git a/modoboa/core/management/commands/generate_postfix_maps.py b/modoboa/core/management/commands/generate_postfix_maps.py\n--- a/modoboa/core/management/commands/generate_postfix_maps.py\n+++ b/modoboa/core/management/commands/generate_postfix_maps.py\n@@ -125,10 +125,13 @@\n             mapcontent = utils.parse_map_file(fullpath)\n             context = copy.deepcopy(context)\n             context[\"dbtype\"] = self.__checksums[mapobject.filename][\"dbtype\"]\n-            context[\"dbuser\"] = mapcontent[\"user\"]\n-            context[\"dbpass\"] = mapcontent[\"password\"]\n-            context[\"dbname\"] = mapcontent[\"dbname\"]\n-            context[\"dbhost\"] = mapcontent[\"hosts\"]\n+            if context[\"dbtype\"] == \"sqlite\":\n+                context[\"dbname\"] = mapcontent[\"dbpath\"]\n+            else:\n+                context[\"dbuser\"] = mapcontent[\"user\"]\n+                context[\"dbpass\"] = mapcontent[\"password\"]\n+                context[\"dbname\"] = mapcontent[\"dbname\"]\n+                context[\"dbhost\"] = mapcontent[\"hosts\"]\n         content = self.get_template(context[\"dbtype\"]).render(\n             Context(\n                 dict(context.items(),\n", "issue": "Test failure when using tox\nThis is because tox use sqlite and has no user set\n\n```\n======================================================================\nERROR: test_map_upgrade (modoboa.admin.tests.test_mapfiles.MapFilesTestCase)\nCheck that map content is used.\n----------------------------------------------------------------------\nTraceback (most recent call last):\n  File \"/home/gawel/bear/modoboa/.tox/py27/lib/python2.7/site-packages/modoboa/admin/tests/test_mapfiles.py\", line 45, in test_map_upgrade\n    self.assertEqual(mapcontent[\"user\"], dbsettings[\"USER\"])\nKeyError: 'user'\n\n----------------------------------------------------------------------\nRan 178 tests in 44.553s\n```\n\n", "before_files": [{"content": "\"\"\"Management command to generate/update postfix map files.\"\"\"\n\nimport copy\nimport hashlib\nimport os\nimport sys\n\nfrom django.conf import settings\nfrom django.core.management.base import BaseCommand\nfrom django.template import Context, Template\nfrom django.utils import timezone\n\nimport dj_database_url\n\nfrom ... import signals\nfrom ... import utils\n\nMAP_FILE_TEMPLATE = \"\"\"# This file was generated on {{ date }} by running:\n# {{ commandline }}\n# DO NOT EDIT!\n\"\"\"\n\n\nclass Command(BaseCommand):\n    \"\"\"Command class.\"\"\"\n\n    help = \"Generate/update postfix map files.\"\n\n    def add_arguments(self, parser):\n        \"\"\"Add extra arguments.\"\"\"\n        parser.add_argument(\n            \"--dburl\", help=\"Custom database url\")\n        parser.add_argument(\n            \"--destdir\", default=\".\",\n            help=\"Directory where files will be created\")\n        parser.add_argument(\n            \"--force-overwrite\", action=\"store_true\", default=False,\n            help=\"Force overwrite of existing map files\")\n\n    def __load_checksums(self, destdir):\n        \"\"\"Load existing checksums if possible.\"\"\"\n        self.__checksums_file = os.path.join(\n            destdir, \"modoboa-postfix-maps.chk\")\n        self.__checksums = {}\n        if not os.path.exists(self.__checksums_file):\n            return\n        with open(self.__checksums_file) as fp:\n            for line in fp:\n                fname, dbtype, checksum = line.split(\":\")\n                self.__checksums[fname.strip()] = {\n                    \"dbtype\": dbtype, \"checksum\": checksum.strip()\n                }\n\n    def __register_map_files(self):\n        \"\"\"Load specified applications.\"\"\"\n        responses = signals.register_postfix_maps.send(sender=self.__class__)\n        mapfiles = []\n        for response in responses:\n            mapfiles += response[1]\n        return mapfiles\n\n    def __check_file(self, path):\n        \"\"\"Check if map file has been modified.\"\"\"\n        fname = os.path.basename(path)\n        condition = (\n            not self.__checksums or\n            fname not in self.__checksums)\n        if condition:\n            return True\n        with open(path) as fp:\n            checksum = hashlib.md5(fp.read()).hexdigest()\n        return checksum == self.__checksums[fname][\"checksum\"]\n\n    def get_template(self, dbtype):\n        \"\"\"Return map file template.\"\"\"\n        tplcontent = MAP_FILE_TEMPLATE\n        if dbtype == \"sqlite\":\n            tplcontent += \"\"\"dbpath = {{ dbname }}\nquery = {{ query|safe }}\n\"\"\"\n        else:\n            tplcontent += \"\"\"user = {{ dbuser }}\npassword = {{ dbpass }}\ndbname = {{ dbname }}\nhosts = {{ dbhost }}\nquery = {{ query|safe }}\n\"\"\"\n        return Template(tplcontent)\n\n    def get_template_context(self, options):\n        \"\"\"Build the context used to render templates.\"\"\"\n        dburl = options.get(\"dburl\")\n        db_settings = (\n            dj_database_url.config(default=dburl)\n            if dburl else settings.DATABASES[\"default\"])\n        if \"sqlite\" in db_settings[\"ENGINE\"]:\n            dbtype = \"sqlite\"\n        elif \"psycopg2\" in db_settings[\"ENGINE\"]:\n            dbtype = \"postgres\"\n        else:\n            dbtype = \"mysql\"\n        commandline = \"{} {}\".format(\n            os.path.basename(sys.argv[0]), \" \".join(sys.argv[1:]))\n        context = {\n            \"date\": timezone.now(),\n            \"commandline\": commandline,\n            \"dbtype\": dbtype,\n            \"dbuser\": db_settings[\"USER\"],\n            \"dbpass\": db_settings[\"PASSWORD\"],\n            \"dbname\": db_settings[\"NAME\"],\n            \"dbhost\": db_settings.get(\"HOST\", \"127.0.0.1\"),\n        }\n        return context\n\n    def __render_map_file(\n            self, mapobject, destdir, context, force_overwrite=False):\n        \"\"\"Render a map file.\"\"\"\n        fullpath = os.path.join(destdir, mapobject.filename)\n        if os.path.exists(fullpath) and not force_overwrite:\n            if not self.__check_file(fullpath):\n                print(\n                    \"Cannot upgrade '{}' map because it has been modified.\"\n                    .format(mapobject.filename))\n                return self.__checksums[mapobject.filename]\n            mapcontent = utils.parse_map_file(fullpath)\n            context = copy.deepcopy(context)\n            context[\"dbtype\"] = self.__checksums[mapobject.filename][\"dbtype\"]\n            context[\"dbuser\"] = mapcontent[\"user\"]\n            context[\"dbpass\"] = mapcontent[\"password\"]\n            context[\"dbname\"] = mapcontent[\"dbname\"]\n            context[\"dbhost\"] = mapcontent[\"hosts\"]\n        content = self.get_template(context[\"dbtype\"]).render(\n            Context(\n                dict(context.items(),\n                     query=getattr(mapobject, context[\"dbtype\"]))\n            )\n        )\n        fullpath = os.path.join(destdir, mapobject.filename)\n        with open(fullpath, \"w\") as fp:\n            fp.write(content)\n        return hashlib.md5(content).hexdigest()\n\n    def handle(self, *args, **options):\n        \"\"\"Command entry point.\"\"\"\n        mapfiles = self.__register_map_files()\n        destdir = os.path.realpath(options[\"destdir\"])\n        try:\n            os.mkdir(destdir)\n        except OSError:\n            pass\n        self.__load_checksums(destdir)\n        context = self.get_template_context(options)\n        checksums = {}\n        for mapobject in mapfiles:\n            checksum = self.__render_map_file(\n                mapobject, destdir, context,\n                force_overwrite=options[\"force_overwrite\"])\n            checksums[mapobject.filename] = checksum\n        with open(self.__checksums_file, \"w\") as fp:\n            for fname, checksum in checksums.items():\n                fp.write(\"{}:{}:{}\\n\".format(\n                    fname, context[\"dbtype\"], checksum))\n", "path": "modoboa/core/management/commands/generate_postfix_maps.py"}], "after_files": [{"content": "\"\"\"Management command to generate/update postfix map files.\"\"\"\n\nimport copy\nimport hashlib\nimport os\nimport sys\n\nfrom django.conf import settings\nfrom django.core.management.base import BaseCommand\nfrom django.template import Context, Template\nfrom django.utils import timezone\n\nimport dj_database_url\n\nfrom ... import signals\nfrom ... import utils\n\nMAP_FILE_TEMPLATE = \"\"\"# This file was generated on {{ date }} by running:\n# {{ commandline }}\n# DO NOT EDIT!\n\"\"\"\n\n\nclass Command(BaseCommand):\n    \"\"\"Command class.\"\"\"\n\n    help = \"Generate/update postfix map files.\"\n\n    def add_arguments(self, parser):\n        \"\"\"Add extra arguments.\"\"\"\n        parser.add_argument(\n            \"--dburl\", help=\"Custom database url\")\n        parser.add_argument(\n            \"--destdir\", default=\".\",\n            help=\"Directory where files will be created\")\n        parser.add_argument(\n            \"--force-overwrite\", action=\"store_true\", default=False,\n            help=\"Force overwrite of existing map files\")\n\n    def __load_checksums(self, destdir):\n        \"\"\"Load existing checksums if possible.\"\"\"\n        self.__checksums_file = os.path.join(\n            destdir, \"modoboa-postfix-maps.chk\")\n        self.__checksums = {}\n        if not os.path.exists(self.__checksums_file):\n            return\n        with open(self.__checksums_file) as fp:\n            for line in fp:\n                fname, dbtype, checksum = line.split(\":\")\n                self.__checksums[fname.strip()] = {\n                    \"dbtype\": dbtype, \"checksum\": checksum.strip()\n                }\n\n    def __register_map_files(self):\n        \"\"\"Load specified applications.\"\"\"\n        responses = signals.register_postfix_maps.send(sender=self.__class__)\n        mapfiles = []\n        for response in responses:\n            mapfiles += response[1]\n        return mapfiles\n\n    def __check_file(self, path):\n        \"\"\"Check if map file has been modified.\"\"\"\n        fname = os.path.basename(path)\n        condition = (\n            not self.__checksums or\n            fname not in self.__checksums)\n        if condition:\n            return True\n        with open(path) as fp:\n            checksum = hashlib.md5(fp.read()).hexdigest()\n        return checksum == self.__checksums[fname][\"checksum\"]\n\n    def get_template(self, dbtype):\n        \"\"\"Return map file template.\"\"\"\n        tplcontent = MAP_FILE_TEMPLATE\n        if dbtype == \"sqlite\":\n            tplcontent += \"\"\"dbpath = {{ dbname }}\nquery = {{ query|safe }}\n\"\"\"\n        else:\n            tplcontent += \"\"\"user = {{ dbuser }}\npassword = {{ dbpass }}\ndbname = {{ dbname }}\nhosts = {{ dbhost }}\nquery = {{ query|safe }}\n\"\"\"\n        return Template(tplcontent)\n\n    def get_template_context(self, options):\n        \"\"\"Build the context used to render templates.\"\"\"\n        dburl = options.get(\"dburl\")\n        db_settings = (\n            dj_database_url.config(default=dburl)\n            if dburl else settings.DATABASES[\"default\"])\n        if \"sqlite\" in db_settings[\"ENGINE\"]:\n            dbtype = \"sqlite\"\n        elif \"psycopg2\" in db_settings[\"ENGINE\"]:\n            dbtype = \"postgres\"\n        else:\n            dbtype = \"mysql\"\n        commandline = \"{} {}\".format(\n            os.path.basename(sys.argv[0]), \" \".join(sys.argv[1:]))\n        context = {\n            \"date\": timezone.now(),\n            \"commandline\": commandline,\n            \"dbtype\": dbtype,\n            \"dbuser\": db_settings[\"USER\"],\n            \"dbpass\": db_settings[\"PASSWORD\"],\n            \"dbname\": db_settings[\"NAME\"],\n            \"dbhost\": db_settings.get(\"HOST\", \"127.0.0.1\"),\n        }\n        return context\n\n    def __render_map_file(\n            self, mapobject, destdir, context, force_overwrite=False):\n        \"\"\"Render a map file.\"\"\"\n        fullpath = os.path.join(destdir, mapobject.filename)\n        if os.path.exists(fullpath) and not force_overwrite:\n            if not self.__check_file(fullpath):\n                print(\n                    \"Cannot upgrade '{}' map because it has been modified.\"\n                    .format(mapobject.filename))\n                return self.__checksums[mapobject.filename]\n            mapcontent = utils.parse_map_file(fullpath)\n            context = copy.deepcopy(context)\n            context[\"dbtype\"] = self.__checksums[mapobject.filename][\"dbtype\"]\n            if context[\"dbtype\"] == \"sqlite\":\n                context[\"dbname\"] = mapcontent[\"dbpath\"]\n            else:\n                context[\"dbuser\"] = mapcontent[\"user\"]\n                context[\"dbpass\"] = mapcontent[\"password\"]\n                context[\"dbname\"] = mapcontent[\"dbname\"]\n                context[\"dbhost\"] = mapcontent[\"hosts\"]\n        content = self.get_template(context[\"dbtype\"]).render(\n            Context(\n                dict(context.items(),\n                     query=getattr(mapobject, context[\"dbtype\"]))\n            )\n        )\n        fullpath = os.path.join(destdir, mapobject.filename)\n        with open(fullpath, \"w\") as fp:\n            fp.write(content)\n        return hashlib.md5(content).hexdigest()\n\n    def handle(self, *args, **options):\n        \"\"\"Command entry point.\"\"\"\n        mapfiles = self.__register_map_files()\n        destdir = os.path.realpath(options[\"destdir\"])\n        try:\n            os.mkdir(destdir)\n        except OSError:\n            pass\n        self.__load_checksums(destdir)\n        context = self.get_template_context(options)\n        checksums = {}\n        for mapobject in mapfiles:\n            checksum = self.__render_map_file(\n                mapobject, destdir, context,\n                force_overwrite=options[\"force_overwrite\"])\n            checksums[mapobject.filename] = checksum\n        with open(self.__checksums_file, \"w\") as fp:\n            for fname, checksum in checksums.items():\n                fp.write(\"{}:{}:{}\\n\".format(\n                    fname, context[\"dbtype\"], checksum))\n", "path": "modoboa/core/management/commands/generate_postfix_maps.py"}]}