require 'common/configuration' require 'fileutils' require 'minitest/unit' require 'pg' class MailshearsTest < MiniTest::Unit::TestCase # This is that class that most (if not all) of our test cases will # inherit. It provides the automatic setup and teardown of the # filesystem and database that the test cases will exercise. def configuration() # Return the test config object. return Configuration.new('test/mailshears.test.conf.yml') end def maildir_exists(dir) # Check if the given mail directory of the form "example.com/user" # exists. cfg = configuration() return File.directory?("#{cfg.dovecot_mail_root()}/#{dir}") end def connect_superuser() # Connect to the database (specified in the test configuration) as # the superuser. Your local configuration is expected to be such # that this "just works." db_host = 'localhost' db_port = 5432 db_opts = nil db_tty = nil db_name = 'postgres' db_user = 'postgres' db_pass = nil connection = PGconn.connect(db_host, db_port, db_opts, db_tty, db_name, db_user, db_pass) return connection end def setup # Connect to the database specified in the test configutation as # the super user. Then, run all of the SQL scripts contained in # test/sql. These scripts create the tables for the plugins listed # in the test configuration, and then create some sample data. # # Here is the full list of what gets created. Every test case # inheriting from this class can expect this schema and data to # exist. The filesystem entries are located beneath mail_root from # the configuration file. # # == Filesystem == # # * example.com/alice # * example.com/booger # * example.com/jeremy # * example.net/adam # # == Databases == # # 1. agendav_test # # +------------------------------+ # | prefs | # +--------------------+---------+ # | username | options | # +--------------------+---------+ # | adam@example.net | herp | # +--------------------+---------+ # | booger@example.com | herp | # +------------------ +---------+ # # # +---------------------------------------------------------+ # | shared | # +-----+--------------------+----------+-------------------+ # | sid | user_from | calendar | user_which | # +-----+--------------------+----------+-------------------+ # | 1 | adam@example.net | derp | beth@example.net | # +-----+--------------------+----------+-------------------+ # | 2 | booger@example.com | derp | carol@example.net | # +-----+--------------------+----------+-------------------+ # # # 2. davical_test # # +--------------------------------------------------------+ # | usr | # +---------+--------+----------------+--------------------+ # | user_no | active | joined | username | # +---------+--------+----------------+--------------------+ # | 17 | t | 2014-01-04 ... | alice@example.com | # +---------+--------+----------------+--------------------+ # | 18 | t | 2014-01-04 ... | booger@example.com | # +---------+--------+----------------+--------------------+ # # # +-----------------------------------------+ # | usr_setting | # +---------+--------------+----------------+ # | user_no | setting_name | setting_value | # +---------+--------------+----------------+ # | 17 | dumb setting | its dumb value | # +---------+--------------+----------------+ # | 18 | dumb setting | its dumb value | # +---------+--------------+----------------+ # # # 3. postfixadmin_test # # +-------------+ # | domain | # +-------------+ # | domain | # +-------------+ # | ALL | # +-------------+ # | example.com | # +-------------+ # | example.net | # +-------------+ # # # +----------------------------------------------+ # | mailbox | # +-------------------+-------------+------------+ # | username | domain | local_part | # +-------------------+-------------+------------+ # | alice@example.com | example.com | alice | # +-------------------+-------------+------------+ # | bob@example.com | example.com | bob | # +-------------------+-------------+------------+ # | adam@example.net | example.net | adam | # +-------------------+-------------+------------+ # | beth@example.net | example.net | beth | # +-------------------+-------------+------------+ # | carol@example.net | example.net | carol | # +-------------------+-------------+------------+ # # # +------------------------------------------------------+ # | alias | # +-------------------+-------------------+--------------+ # | address | goto | domain | # +-------------------+-------------------+--------------+ # | alice@example.com | alice@example.com | example.com | # +-------------------+-------------------+--------------+ # | bob@example.com | bob@example.com | example.com | # +-------------------+-------------------+--------------+ # | adam@example.net | adam@example.net | example.net | # +-------------------+-------------------+--------------+ # | beth@example.net | beth@example.net | example.net | # +-------------------+-------------------+--------------+ # | carol@example.net | carol@example.net | example.net | # +-------------------+-------------------+--------------+ # # # +---------------------------------+ # | domain_admins | # +-------------------+-------------+ # | username | domain | # +-------------------+-------------+ # | admin@example.com | example.com | # +-------------------+-------------+ # | admin@example.com | example.net | # +-------------------+-------------+ # # 4. roundcube_test # # # +---------+--------------------+ # | user_id | username | # +---------+--------------------+ # | 1 | alice@example.com | # +---------+--------------------+ # | 2 | booger@example.com | # +---------+--------------------+ # | 3 | adam@example.net | # +---------+--------------------+ # First make sure we get rid of everything so we don't get random # failures from databases and directories that already exist. teardown() cfg = configuration() # First create the "mail directories". FileUtils.mkdir_p("#{cfg.dovecot_mail_root()}/example.com/alice") FileUtils.mkdir_p("#{cfg.dovecot_mail_root()}/example.com/booger") FileUtils.mkdir_p("#{cfg.dovecot_mail_root()}/example.com/jeremy") FileUtils.mkdir_p("#{cfg.dovecot_mail_root()}/example.net/adam") # Now the databases and their content. connection = connect_superuser() cfg.plugins.each do |plugin| plugin_dbname = cfg.send("#{plugin}_dbname") next if plugin_dbname.nil? # Skip the dovecot plugin query = "CREATE DATABASE #{plugin_dbname};" connection.query(query) plugin_dbhost = cfg.send("#{plugin}_dbhost") plugin_dbport = cfg.send("#{plugin}_dbport") plugin_dbopts = cfg.send("#{plugin}_dbopts") plugin_dbtty = cfg.send("#{plugin}_dbtty") plugin_dbuser = cfg.send("#{plugin}_dbuser") plugin_dbpass = cfg.send("#{plugin}_dbpass") plugin_conn = PGconn.connect(plugin_dbhost, plugin_dbport, plugin_dbopts, plugin_dbtty, plugin_dbname, plugin_dbuser, plugin_dbpass) sql = File.open("test/sql/#{plugin}.sql").read() plugin_conn.query(sql) sql = File.open("test/sql/#{plugin}-fixtures.sql").read() plugin_conn.query(sql) plugin_conn.close() end connection.close() end def teardown # Drop all of the databases that were created in setup(). cfg = configuration() connection = connect_superuser() # Don't emit notices about missing tables. Why this happens when I # explicitly say IF EXISTS is beyond me. connection.set_notice_processor{} cfg.plugins.each do |plugin| plugin_dbname = cfg.send("#{plugin}_dbname") next if plugin_dbname.nil? # Skip the dovecot plugin query = "DROP DATABASE IF EXISTS #{plugin_dbname};" connection.query(query) end connection.close() # Get rid of the maildirs. FileUtils.rm_rf(cfg.dovecot_mail_root()) end end