Update config code

Add vland section (port)
Improve unit tests

Change-Id: Ia6f169c8d51a36ba02b1e9ab4101b31de1585a13
diff --git a/config/config.py b/config/config.py
index fda34d8..08d78f8 100644
--- a/config/config.py
+++ b/config/config.py
@@ -31,16 +31,22 @@
 
 from errors import CriticalError, InputError, ConfigError
 
+class DaemonConfigClass:
+    """ Simple container for stuff to make for nicer syntax """
+
+    def __repr__(self):
+        return "<DaemonConfig: port: %s>" % (self.port)
+
 class DBConfigClass:
     """ Simple container for stuff to make for nicer syntax """
 
     def __repr__(self):
-        return "<DBConfig: server: %s, port: %s, dbname: %s, username: %s, password: %s" % (self.server, self.port, self.dbname, self.username, self.password)
+        return "<DBConfig: server: %s, port: %s, dbname: %s, username: %s, password: %s>" % (self.server, self.port, self.dbname, self.username, self.password)
 
 class SwitchConfigClass:
     """ Simple container for stuff to make for nicer syntax """
     def __repr__(self):
-        return "<SwitchConfig: name: %s, section: %s, driver: %s, username: %s, password: %s, enable_password: %s" % (self.name, self.section, self.driver, self.username, self.password, self.enable_password)
+        return "<SwitchConfig: name: %s, section: %s, driver: %s, username: %s, password: %s, enable_password: %s>" % (self.name, self.section, self.driver, self.username, self.password, self.enable_password)
 
 class VlanConfig:
     """VLANd config class"""
@@ -62,12 +68,20 @@
 
         # Parse out the config file
         # Must have a [database] section
+        # May have a [vland] section
         # May have a [logging] section
         # May have multiple [switch 'foo'] sections
         if not config.has_section('database'):
             raise ConfigError('No database configuration section found')
 
+        # No DB-specific defaults to set
         self.database = DBConfigClass()
+
+        # Set default port number
+        self.vland = DaemonConfigClass()
+        self.vland.port = 3080
+
+        # No switch-specific defaults to set
         self.switches = {}
 
         sw_regex = re.compile('(switch)\ (.*)', flags=re.I)
@@ -75,33 +89,56 @@
             if section == 'database':
                 try:
                     self.database.server = config.get(section, 'server')
+                except ConfigParser.NoOptionError:
+                    pass
                 except:
                     raise ConfigError('Invalid database configuration (server)')
 
                 try:
-                    self.database.port = config.get(section, 'port')
+                    port = config.get(section, 'port')
+                    if port is not None:
+                        self.database.port = config.getint(section, 'port')
+                except ConfigParser.NoOptionError:
+                    pass
                 except:
                     raise ConfigError('Invalid database configuration (port)')
 
                 try:
                     self.database.dbname = config.get(section, 'dbname')
+                except ConfigParser.NoOptionError:
+                    pass
                 except:
                     raise ConfigError('Invalid database configuration (dbname)')
 
                 try:
                     self.database.username = config.get(section, 'username')
+                except ConfigParser.NoOptionError:
+                    pass
                 except:
                     raise ConfigError('Invalid database configuration (username)')
 
                 try:
                     self.database.password = config.get(section, 'password')
+                except ConfigParser.NoOptionError:
+                    pass
                 except:
                     raise ConfigError('Invalid database configuration (password)')
-                # Others are optional, but these are not
+
+                # Other database config options are optional, but these are not
                 if self.database.dbname is None or self.database.username is None:
                     raise ConfigError('Database configuration section incomplete')
+
             elif section == 'logging':
                 pass # Fill this in later...
+
+            elif section == 'vland':
+                try:
+                    self.vland.port = config.getint(section, 'port')
+                except ConfigParser.NoOptionError:
+                    pass
+                except:
+                    raise ConfigError('Invalid vland configuration (port)')
+
             else:
                 match = sw_regex.match(section)
                 if match:
@@ -127,6 +164,7 @@
 if __name__ == '__main__':
     config = VlanConfig(filenames=('./vland.cfg',))
     print config.database
+    print config.vland
     for switch in config.switches:
         print config.switches[switch]