Skip to content
This repository was archived by the owner on Feb 12, 2019. It is now read-only.

Test writing

Christine Dodrill edited this page Oct 14, 2017 · 12 revisions

Elemental-IRCd uses TCL for its functional testing suite. All new contributions (even ones from the team) are very much encouraged to have a test to ensure that the changes made are functional.

Tests are very concise and declarative, however there are a few peculiarities that TCL has that are worth pointing out.

An Example Test

begin {example test}

set test_channel #exampletest

client me
client you

me  >> PRIVMSG $test_channel "Hi there [you nick]!"
you << PRIVMSG $test_channel "Hi there [you nick]!"

This creates a test with the description "example test", a test channel (that all related clients will implicitly join) named #exampletest, a couple of clients and then makes sure they can send a message from me to you.

Something that will stand out instantly is the fact that none of the IRC line portions had to be quoted using the standard double quotes ("). This is because TCL commands are somewhat of a hybrid between shell functions and "real" functions like you would see in C or Lua. TCL procedures are actually implemented as a series of arguments being applied against a string denoted by starting with { and ending with }. A side effect of this is that TCL allows bare words as a language primitive, which we heavily take advantage of in tests.

Also in TCL, to make an argument the result of some arbitrary command, you need to wrap it in square brackets ([ and ]). An example:

client oper

puts [oper nick]

# prints the nick of the client referred to by `oper`

Client Functions

Creation

Creating a client is done using the client proc. When a client is declared it will automatically connect to a random server in the array of servers that are available to connect to. The first argument to client is the name of the object that should be used in TCL to refer to it.

Flags

Flag name Meaning
-nick Sets client nickname to an arbitrary value (make sure this is unique across all tests)
-user Sets a client username (ident) to an arbitrary value
-gecos Sets a client gecos (real name) to an arbitrary value
-caps Sets the client IRCv3 capabilities
client god -nick opermcoperface -user floam -gecos Floamtastic
    oper god

Getting the Nickname

The nickname of a client is available by the attribute nick applied to a client instance. An example:

client god

puts [god nick]

# prints the nick of the client referred to by `god`

Operators on Clients

client >>

The >> operator sends an arbitrary line to the IRC daemon taken in as bare words.

client me

me >> PRIVMSG #foo {ha! I can say words!}

client <<

The << operator waits for and blocks a line matching what you specify (with shell-style matching) and will fail if the line hasn't been received in about one and a half seconds. This may seem a bit small but the actual tests run for only a few seconds in total, so it is pretty easy to look at the list of tests as they run and see if one is going to fail. The last argument needs to be specified as a TCL curly-brace quoted string to match an RFC 1459 extended argument.

# Master sends TOPIC to $test_channel to change the state for victim
master >> TOPIC $test_channel {This is a test topic}
# Victim blocks on the topic being the exact same as the one master sent
victim << TOPIC $test_channel {This is a test topic}

client :

The : operator when applied to a client sets that client as the current global implicit client. By default the implicit client is only changed when:

  1. A new client is created
  2. A line is written to a client using the >> operator
  3. The : operator is applied to a client

This is useful for emulating block styles in Python or the like:

# set up m_omode.so
oper :
    # oper up as god for module loading
    oper god
    # load m_omode.so
    >> MODLOAD extensions/m_omode.so

client oper

oper takes the first argument as the oper name to run /OPER against. The two values are as follows:

Name Purpose
god All privileges
oper Limited privileges, only oper:chghost
client god
    oper god

client lowpower
    oper oper

Constants

Most of the numerics are defined as constants in the tests/lib/numerics.tcl file. In most cases the numeric values should Just Work.

victim :
  << TOPIC $test_channel {This is a test topic}
  >> TOPIC $test_channel {No I think this should be the topic}
  << ERR_CHANOPRIVSNEEDED

Clone this wiki locally