~singpolyma/biboumi

64f341ee80b0d53f0a6e128a1ccc38205361c3bb — louiz’ 6 years ago bd625aa
e2etests: Use charybdis and update the scenarios accordingly
2 files changed, 58 insertions(+), 307 deletions(-)

M tests/end_to_end/__main__.py
D tests/end_to_end/mammond.conf
M tests/end_to_end/__main__.py => tests/end_to_end/__main__.py +58 -38
@@ 165,6 165,7 @@ class ProcessRunner:
    def __del__(self):
        self.stop()


class BiboumiRunner(ProcessRunner):
    def __init__(self, name, with_valgrind):
        super().__init__()


@@ 183,7 184,7 @@ class BiboumiRunner(ProcessRunner):
class IrcServerRunner(ProcessRunner):
    def __init__(self):
        super().__init__()
        self.create = asyncio.create_subprocess_exec("/home/louiz/sources/charybdis/ircd/charybdis", "-foreground",
        self.create = asyncio.create_subprocess_exec("charybdis", "-foreground",
                                                     stderr=asyncio.subprocess.PIPE)




@@ 271,7 272,7 @@ common_replacements = {

def handshake_sequence():
    return (partial(expect_stanza, "//handshake"),
                      partial(send_stanza, "<handshake xmlns='jabber:component:accept'/>"))
            partial(send_stanza, "<handshake xmlns='jabber:component:accept'/>"))


def connection_sequence(irc_host, jid):


@@ 282,32 283,47 @@ def connection_sequence(irc_host, jid):
    partial(expect_stanza,
          xpath % ('Connecting to %s:6697 (encrypted)' % irc_host)),
    partial(expect_stanza,
          xpath % ('Connection failed: Connection refused')),
            xpath % 'Connection failed: Connection refused'),
    partial(expect_stanza,
          xpath % ('Connecting to %s:6670 (encrypted)' % irc_host)),
    partial(expect_stanza,
          xpath % ('Connection failed: Connection refused')),
            xpath % 'Connection failed: Connection refused'),
    partial(expect_stanza,
          xpath % ('Connecting to %s:6667 (not encrypted)' % irc_host)),
    partial(expect_stanza,
          xpath % ('Connected to IRC server.')),
            xpath % 'Connected to IRC server.'),
    # These two messages can be receive in any order
    partial(expect_stanza,
          xpath % ('%s: *** Looking up your hostname...' % irc_host)),
          xpath_re % (r'^%s: \*\*\* (Checking Ident|Looking up your hostname...)$' % irc_host)),
    partial(expect_stanza,
          xpath % ('%s: *** Checking Ident' % irc_host)),
          xpath_re % (r'^%s: \*\*\* (Checking Ident|Looking up your hostname...)$' % irc_host)),
    # These three messages can be received in any order
    partial(expect_stanza,
          xpath_re % (r'^%s: (\*\*\* Found your hostname: .*|NAK multi-prefix |\*\*\* No Ident response)$' % irc_host)),
          xpath_re % (r'^%s: (\*\*\* Found your hostname: .*|ACK multi-prefix|\*\*\* No Ident response)$' % irc_host)),
    partial(expect_stanza,
          xpath_re % (r'^%s: (\*\*\* Found your hostname: .*|NAK multi-prefix |\*\*\* No Ident response)$' % irc_host)),
          xpath_re % (r'^%s: (\*\*\* Found your hostname: .*|ACK multi-prefix|\*\*\* No Ident response)$' % irc_host)),
    partial(expect_stanza,
          xpath_re % (r'^%s: (\*\*\* Found your hostname: .*|NAK multi-prefix |\*\*\* No Ident response)$' % irc_host)),
          xpath_re % (r'^%s: (\*\*\* Found your hostname: .*|ACK multi-prefix|\*\*\* No Ident response)$' % irc_host)),
    partial(expect_stanza,
          xpath_re % (r'^%s: Your host is .*$' % irc_host)),
    partial(expect_stanza,
          xpath_re % (r'^%s: This server was started at .*$' % irc_host)),
          xpath_re % (r'^%s: This server was created .*$' % irc_host)),
    partial(expect_stanza,
          xpath_re % (r'^%s: There are \d+ users and \d+ invisible on \d+ servers$' % irc_host)),
    partial(expect_stanza,
          xpath_re % (r'^%s: \d+ channels formed$' % irc_host), optional=True),
    partial(expect_stanza,
          xpath_re % (r'^%s: I have \d+ clients and \d+ servers$' % irc_host)),
    partial(expect_stanza,
          xpath_re % (r'^%s: \d+ \d+ Current local users \d+, max \d+$' % irc_host)),
    partial(expect_stanza,
          xpath_re % (r'^%s: \d+ \d+ Current global users \d+, max \d+$' % irc_host)),
    partial(expect_stanza,
          xpath_re % (r'^%s: Highest connection count: \d+ \(\d+ clients\) \(\d+ connections received\)$' % irc_host)),
    partial(expect_stanza,
            xpath % "- This is charybdis MOTD you might replace it, but if not your friends will\n- laugh at you.\n"),
    partial(expect_stanza,
          xpath % ("- Default MOTD\n")),
            xpath_re % r'^User mode for \w+ is \[\+i\]$'),
    )




@@ 336,7 352,9 @@ if __name__ == '__main__':
                             "<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
                     connection_sequence("irc.localhost", '{jid_one}/{resource_one}'),
                     partial(expect_stanza,
                             ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='none'][@role='participant']",
                             "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
                     partial(expect_stanza,
                             ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
                             "/presence/muc_user:x/muc_user:status[@code='110']")
                             ),
                     partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),


@@ 349,7 367,9 @@ if __name__ == '__main__':
                             "<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
                     connection_sequence("irc.localhost", '{jid_one}/{resource_one}'),
                     partial(expect_stanza,
                             ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~nick@localhost'][@role='participant']",
                             "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
                     partial(expect_stanza,
                             ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='~nick@localhost'][@role='moderator']",
                             "/presence/muc_user:x/muc_user:status[@code='110']")
                             ),
                     partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),


@@ 363,8 383,7 @@ if __name__ == '__main__':
                             ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']",)),
                     # The other user presence
                     partial(expect_stanza,
                             ("/presence[@to='{jid_second}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~nick@localhost'][@role='participant']")
                             ),
                             "/presence[@to='{jid_second}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~nick@localhost'][@role='participant']"),
                     # Our own presence
                     partial(expect_stanza,
                             ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']",


@@ 380,33 399,34 @@ if __name__ == '__main__':
                             "<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
                     connection_sequence("irc.localhost", '{jid_one}/{resource_one}'),
                     partial(expect_stanza,
                             ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~nick@localhost'][@role='participant']",
                              "/presence/muc_user:x/muc_user:status[@code='110']")
                             "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
                     partial(expect_stanza,
                             ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='~nick@localhost'][@role='moderator']",
                             "/presence/muc_user:x/muc_user:status[@code='110']")
                             ),
                     partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),

                     # First user sets the topic
                     partial(send_stanza,
                             "<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' type='groupchat'><subject>TOPIC\nTEST</subject></message>"),
                     partial(expect_stanza, "/message[@from='#foo%{irc_server_one}/{nick_one}'][@type='groupchat'][@to='{jid_one}/{resource_one}']/subject[text()='TOPIC\nTEST']"),

                     # # Second user joins
                     # partial(send_stanza,
                     #         "<presence from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}' />"),
                     # connection_sequence("irc.localhost", '{jid_two}/{resource_one}'),
                     # # Our presence, sent to the other user
                     # partial(expect_stanza,
                     #         ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']",)),
                     # # The other user presence
                     # partial(expect_stanza,
                     #         ("/presence[@to='{jid_second}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~nick@localhost'][@role='participant']")
                     #         ),
                     # # Our own presence
                     # partial(expect_stanza,
                     #         ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']",
                     #          "/presence/muc_user:x/muc_user:status[@code='110']")
                     #         ),
                     # partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),
                             "<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><subject>TOPIC TEST</subject></message>"),
                     partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat'][@to='{jid_one}/{resource_one}']/subject[text()='TOPIC TEST']"),

                     # Second user joins
                     partial(send_stanza,
                             "<presence from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}' />"),
                     connection_sequence("irc.localhost", '{jid_two}/{resource_one}'),
                     # Our presence, sent to the other user
                     partial(expect_stanza,
                             ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']",)),
                     # The other user presence
                     partial(expect_stanza,
                             "/presence[@to='{jid_second}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='~nick@localhost'][@role='moderator']"),
                     # Our own presence
                     partial(expect_stanza,
                             ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']",
                              "/presence/muc_user:x/muc_user:status[@code='110']")
                             ),
                     partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[text()='TOPIC TEST']"),
                 ]),
    )


D tests/end_to_end/mammond.conf => tests/end_to_end/mammond.conf +0 -269
@@ 1,269 0,0 @@
# The server object defines the server information parameters.
server:
  # name - the server name
  name: "irc.localhost"

  # description - the description of the server on the network
  description: "Test server for biboumi"

  # network - the NETWORK= name in 005 for rfc1459 clients
  network: "irc.localhost"

  # recvq_len - the maximum number of lines that can be in a client's recvq
  recvq_len: 20

  # motd - the motd content (will later be file)
  motd:
  - "Default MOTD"


# The clients object defines client parameters
clients:
  # ping_frequency - client ping frequency
  ping_frequency:
    minutes: 1

  # ping_timeout - ping timeout length
  ping_timeout:
    minutes: 2


# The data object defines the data store parameters
data:

  ## JSON should only be considered for testing
  # format - data store type
  format: "json"

  # filename - data store filename
  filename: ".mammon.data.json"

  # save_frequency - save the database every this amount of time
  save_frequency:
    minutes: 5


# The listeners object is a list of listeners.
listeners:
- {"host": "0.0.0.0", "port": 6667, "ssl": false, "certfile": "~/workspace/biboumi/cert.pem", "keyfile": "~/workspace/biboumi/key.pem", }


# The logs section is a list of logs.
logs:
- {
     # path - the path of the logfile
     "path": "mammond.log",

     # level - the log level of the file
     "level": "debug"
  }


# Limits define maximum lengths for various commands and objects
# to remove a limit, simply comment it out
limits:
  # user - maximum length of usernames
  user: 10

  # nick - maximum length of nicknames
  nick: 50

  # channel - maximum length of channel names
  channel: 200

  # topic - maximum length of channel topics
  topic: 400

  # line - maximum length of lines in and out
  line: 2048


# The register object defines registration information
register:

  # verify_timeout - length of time a user has to verify their newly-created
  # account before it can be re-registered
  verify_timeout:
    days: 5

  # enabled_callbacks - callbacks that we allow
  enabled_callbacks:
    # - mailto
    # - none  # no verification required, will instantly register successfully

  # callbacks - types and details for various callback methods
  callbacks:

    # mailto - email using sendmail
    mailto:
      # from - address our messages get sent from
      from: mammon@example.com

      # sendmail - location of the sendmail binary
      sendmail: /usr/sbin/sendmail

      # verify_message_subject - subject of the verify message
      verify_message_subject: "{network_name} Account Registration"

      # verify_message - message sent to users to verify their account
      verify_message: |
        Hi,

        You have requested to register the account {account}.

        Your verification code is {auth_code}

        Please type "/quote REG VERIFY {account} {auth_code}" to complete registration

        Thank you,
        {network_name}
# Roles define the capabilities an oper may have, as well as role-specific
# metadata.

  # mammon capability names:
  #   oper:local_kill    allows /KILLing local users
  #   oper:global_kill   allows /KILLing local and remote users
  #   oper:routing       allows remote SQUIT and CONNECT
  #   oper:kline         allows KLINE and DLINE
  #   oper:unkline       allows UNKLINE and UNDLINE
  #   oper:remote_ban    allows remote klines
  #   oper:rehash        allows REHASH of server config
  #   oper:die           allows DIE and RESTART

roles:
  # name - the name of the privilege set
  "local_op":
    # capabilities - a list of qualified capability names
    capabilities:
      - oper:local_kill
      - oper:kline
      - oper:unkline
      - metadata:set_local

    # metakeys_get - metadata keys this role can view
    metakeys_get:
      # - spammer_probability

    # title - metadata identifying the specific role
    title: "IRC Operator"

  # name - the name of the privilege set
  "global_op":
    # extends - inherets this role's capabilities
    extends: "local_op"

    # capabilities - a list of qualified capability names
    capabilities:
      - oper:global_kill
      - oper:remote_ban
      - metadata:set_global

    # title - metadata identifying the specific role
    title: "IRC Operator"

  # name - the name of the privilege set
  "network_admin":
    # capabilities - a list of qualified capability names
    capabilities:
      - oper:global_kill
      - oper:routing

    # title - metadata identifying the specific role
    title: "Network Administrator"

  # name - the name of the privilege set
  "server_admin":
    # extends - inherets this role's capabilities
    extends: "local_op"

    # capabilities - a list of qualified capability names
    capabilities:
      - oper:rehash
      - oper:die

    # title - metadata identifying the specific role
    title: "Server Administrator"

  # example metadata-specific roles
  # name - the name of the privilege set
  "spam_detection_bot":
    # capabilities - a list of qualified capability names
    capabilities:
      - metadata:set_global

    # metakeys_access - metadata keys this role can view and set
    metakeys_access:
      - spammer_probability

    # title - metadata identifying the specific role
    title: "Spam Detection Bot"


# Metadata defines the metadata users are allowed to set for themselves
metadata:
  # limit - max number of metadata each target is allowed to have
  #   comment out to remove limit
  limit: 20

  # whitelist - if defined, a list of lowercase keys that are checked when users set data
  whitelist:
    - avatar
    - info
    - source
    - url
    - version

  # restricted_keys - keys that unprived users cannot see / edit, and require a
  #   special entry in a ROLE to see / edit
  restricted_keys:
    - away
    # - spammer_probability


# Monitor defines the monitoring users are allowed to do on other users
monitor:
  # limit - max number of 'monitors' each target is allowed to have
  #   comment out to remove limit
  limit: 20


# Operator credentials allow a user to transition from a typical user role
# to a privileged role.
opers:
  # name - the name of the operator
  "nobody":
    # password - the plaintext oper password
    # password: "nothing"

    # hostmask - if defined, the hostmask the oper must connect from
    hostmask: "*@localhost"

    # role - the role that the credentials allow transition to
    role: "local_op"

  # name - the name of the operator
  "somebody":
    # password - the hashed oper password
    # created by:  mammond --mkpasswd
    password: "$6$rounds=100000$KkEHFBhWHV3BHCCS$YuOdlikJHdeIv2YpwvyLAtYCslDlsnUUnrfeKJiBh4SeVhkSU6pQqHWWDjr6lnalkkf1KLDD1wgSQH5AObILQ1"

    # hash - the hashing algorithm to use
    hash: "sha512_crypt"

    # hostmask - if defined, the hostmask the oper must connect from
    hostmask: "somebody!*@localhost"

    # role - the role that the credentials allow transition to
    role: "local_op"


# The extensions section is a list of extension modules to load.
extensions:
- mammon.ext.rfc1459.42
- mammon.ext.rfc1459.ident
- mammon.ext.ircv3.account_notify
- mammon.ext.ircv3.server_time
- mammon.ext.ircv3.echo_message
- mammon.ext.ircv3.register
- mammon.ext.ircv3.sasl
- mammon.ext.misc.nopost
\ No newline at end of file