diff --git a/src/server/testsuite/lyskomd.0/gen-19.py b/src/server/testsuite/lyskomd.0/gen-19.py new file mode 100644 index 0000000000000000000000000000000000000000..e76e2d191938dcd39cfafde6db65162e3eab10dc --- /dev/null +++ b/src/server/testsuite/lyskomd.0/gen-19.py @@ -0,0 +1,528 @@ +# Test suite for lyskomd. +# Copyright (C) 2000 Lysator Academic Computer Association. +# +# This file is part of the LysKOM server. +# +# LysKOM is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 1, or (at your option) +# any later version. +# +# LysKOM is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with LysKOM; see the file COPYING. If not, write to +# Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, +# or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, +# MA 02139, USA. +# +# Please mail bug reports to bug-lyskom@lysator.liu.se. + +# Generate a test script that tests permissions of recpt, cc-recpt and +# bcc-recpt, and that proper asynchronous messages are sent. This +# tests combinations of active and passive memberships. + +import string + +# Set EXTENDED to 1 to emit tests for lots of misc-into combinations, +# which takes a very long time to test (approx. 5 minutes on a 600 MHz Athlon). +EXTENDED = 1 + +# Set DEBUG to 1 to emit extra "get-time" calls, which slows the test down +# approximately 5%, but makes it easier to track down errors. +DEBUG = 1 + +# The database that this test sets up, before any texts are created, +# looks like this: +# +# Persons: +# 6 "Person 6" Member of 6. +# 7 "Person 7" Creator of 10, 11, 12. Member of 10, 11, 12. +# Passive member of 13, 14, 15. +# 8 "Person 8" Member of 8, 13, 14, 15. +# Passive member of 10, 11, 12. +# 9 "Person 9" Creator of 13, 14, 15. Member of 9. +# +# Conferences: +# 10 "conf 10" +# 11 "conf 11" rd-prot +# 12 "conf 12" rd-prot, secret +# 13 "conf 13" +# 14 "conf 14" rd-prot +# 15 "conf 15" rd-prot, secret + +class factory: + def __init__(self, bcc_trigg, bcc_visible, bcc_author_visible, + other_trigg, other_visible, rd): + self.__bcc_trigg = bcc_trigg + self.__bcc_visible = bcc_trigg + bcc_visible + self.__bcc_author_visible = (bcc_trigg + bcc_visible + + bcc_author_visible) + self.__other_trigg = bcc_trigg + other_trigg + self.__other_visible = bcc_trigg + other_trigg + other_visible + for n in bcc_visible: + if n not in self.__other_visible: + self.__other_visible.append(n) + self.__readable = bcc_trigg + other_trigg + rd + + def create(self, author, misc, conf, loc, + rec_time = None, sent_by = None, sent_at = None): + if misc == 15: + trigg = self.__bcc_trigg + visib = self.__bcc_visible + author_visib = self.__bcc_author_visible + else: + trigg = self.__other_trigg + visib = self.__other_visible + author_visib = self.__other_visible + return misc_group(misc, conf, loc, trigg, visib, author_visib, + self.__readable, rec_time, sent_by, sent_at, author) + + +def a_list_pattern(lst): + if len(lst) == 0: + return "0 \\\\\\*" + else: + return "%d { %s }" % (len(lst), string.join(lst, " ")) + +def a_list_rq(lst): + return "%d { %s }" % (len(lst), string.join(lst, " ")) + +class sequence_allocator: + def __init__(self, start): + self.curr = start + + def next(self): + self.curr = self.curr + 1 + return self.curr + +class misc_group: + def __init__(self, misc, conf, loc, trigg, visib, visib_by_author, + readable, rec_time, sent_by, sent_at, author): + self.__misc = misc + self.__conf = conf + self.__loc = loc + self.__trigg = trigg + self.__visib = visib + self.__visib_by_author = visib_by_author + self.__readable = readable + self.__rec_time = rec_time + self.__sent_by = sent_by + self.__sent_at = sent_at + self.__author = author + + def visible(self, viewer): + return (viewer in self.__visib + or (viewer == self.__author + and viewer in self.__visib_by_author)) + + def miscs(self, viewer): + if not self.visible(viewer): + return [] + res = ["%d %d" % (self.__misc, self.__conf), + "6 %d" % self.__loc] + if self.__rec_time != None: + res.append("7 $any_time") + if self.__sent_by != None: + res.append("8 %d" % self.__sent_by) + if self.__sent_at != None: + res.append("9 $any_time") + return res + + def async(self, viewer, text_no): + if not self.visible(viewer): + return None + return "%d %d %d" % (text_no, self.__conf, self.__misc) + + def trigger(self, viewer): + return viewer in self.__trigg + + def readable(self, viewer): + return viewer in self.__readable + + def recipient(self): + return self.__conf + + def recipient_type(self): + return self.__misc + + +class text_stat: + tno = sequence_allocator(0) + + def __init__(self, author): + self.__author = author + self.__misc_groups = [] + self.__text_no = self.tno.next() + + def add_misc_group(self, misc_grp): + assert isinstance(misc_grp, misc_group) + self.__misc_groups.append(misc_grp) + + def author(self): + return self.__author + + def misc_groups(self): + return self.__misc_groups[:] + + def text_no(self): + return self.__text_no + + def remove_misc_group(self, removed): + self.__misc_groups.remove(removed) + +# (creat, rcpt): bcc-trigg, bcc-vis, bcc-author-vis, other-trigg, other-vis, rd +obj = { + (6, 6): factory([6], [], [7, 8, 9], [], [7, 8, 9], []), + (6, 7): factory([], [6, 7], [8, 9], [], [8, 9], [7]), + (6, 8): factory([8], [6], [7, 9], [], [7, 9], []), + (6, 9): factory([9], [6], [7, 8], [], [7, 8], []), + (6, 10): factory([7], [6, 8, 9], [], [], [8], [6, 8, 9]), + (6, 11): factory([7], [6, 8], [9], [], [8, 9], [8]), + (6, 12): factory([7], [6, 8], [], [], [8, 9], [8]), + (6, 13): factory([8], [6, 7, 9], [], [], [7], [6, 7, 9]), + (6, 14): factory([8], [6, 7, 9], [], [], [7], [7, 9]), + (6, 15): factory([8], [6, 7, 9], [], [], [7], [7, 9]), + + (7, 6): factory([6], [7], [8, 9], [], [8, 9], []), + (7, 7): factory([], [7], [6, 8, 9], [], [6, 8, 9], [7]), + (7, 8): factory([8], [7], [6, 9], [], [6, 7, 9], []), + (7, 9): factory([9], [7], [6, 8], [], [6, 7, 8], []), + (7, 10): factory([7], [6, 8, 9], [], [], [8], [6, 8, 9]), + (7, 11): factory([7], [8], [6, 9], [], [6, 8, 9], [8]), + (7, 12): factory([7], [8], [], [], [8], [8]), + (7, 13): factory([8], [6, 7, 9], [], [], [7], [6, 7, 9]), + (7, 14): factory([8], [7, 9], [6], [], [6, 7], [7, 9]), + (7, 15): factory([8], [7, 9], [], [], [7], [7, 9]), + + (8, 6): factory([6], [8], [7, 9], [], [7, 9], []), + (8, 7): factory([], [7, 8], [6, 9], [], [6, 9], [7]), + (8, 8): factory([8], [], [6, 7, 9], [], [6, 7, 9], []), + (8, 9): factory([9], [8], [6, 7], [], [6, 7], []), + (8, 10): factory([7], [6, 8, 9], [], [], [8], [6, 8, 9]), + (8, 11): factory([7], [8], [6, 9], [], [6, 8, 9], [8]), + (8, 12): factory([7], [8], [], [], [8], [7]), + (8, 13): factory([8], [6, 7, 9], [], [], [7], [6, 7, 9]), + (8, 14): factory([8], [7, 9], [6], [], [6, 7], [7, 9]), + (8, 15): factory([8], [7, 9], [], [], [7], [7, 9]), + + (9, 6): factory([6], [9], [7, 8], [], [7, 8], []), + (9, 7): factory([], [7, 9], [6, 8], [], [6, 8], [7]), + (9, 8): factory([8], [9], [6, 7], [], [6, 7], []), + (9, 9): factory([9], [], [6, 7, 8], [], [6, 7, 8], []), + (9, 10): factory([7], [6, 8, 9], [], [], [8], [6, 8, 9]), + (9, 11): factory([7], [8, 9], [6], [], [6, 8], [8]), + (9, 12): factory([7], [8, 9], [], [], [8], [8]), + (9, 13): factory([8], [6, 7, 9], [], [], [7], [6, 7, 9]), + (9, 14): factory([8], [7, 9], [6], [], [6, 7], [7, 9]), + (9, 15): factory([8], [7, 9], [], [], [7], [7, 9]), + + } + +class loc_no_allocator: + def __init__(self): + self.__prev = {} + + def alloc(self, conf): + res = self.__prev.get(conf, 0) + 1 + self.__prev[conf] = res + return res + +locno = loc_no_allocator() + +def talk_to(person): + global active_person + + if active_person != person: + print "# talk to Person %d" % person + print "talk_to client %d" % (person - 6) + active_person = person + +active_person = None + +ref = sequence_allocator(999) + +def create(author, recipients): + print + txt = text_stat(author) + crea = [] + for (m, r) in recipients: + txt.add_misc_group(obj[(author, r)].create(author, m, r, + locno.alloc(r))) + crea.append("%d %d" % (m, r)) + talk_to(author) + cs = ref.next() + print "# Creating text %d by %d" % (txt.text_no(), txt.author()) + print "send \"%d 86 [holl \"text %d\"] %s 0 { }\\n\"" % ( + cs, txt.text_no(), a_list_rq(crea)) + new_text(txt) + talk_to(author) + print "simple_expect \"=%d %d\"" % (cs, txt.text_no()) + verify_text_stat(txt) + return txt + +def add_misc(adder, txt, misc_type, rcpt): + sent_by = None + if adder != txt.author(): + sent_by = adder + misc = obj[(adder, rcpt)].create(txt.author(), misc_type, rcpt, + locno.alloc(rcpt), + sent_at = 1, sent_by = sent_by) + talk_to(adder) + cs = ref.next() + print "# Adding recipient to text %d; adder %d" % (txt.text_no(), adder) + print "send \"%d 30 %d %d %d\\n\"" % (cs, txt.text_no(), rcpt, misc_type) + new_recipient(adder, txt, misc) + talk_to(adder) + print "simple_expect \"=%d\"" % cs + txt.add_misc_group(misc) + +def verify_text_stat(txt): + for p in PERSONS: + talk_to(p) + print "send \"%d 90 %d\\n\"" % (ref.next(), txt.text_no()) + visib = p == txt.author() + pattern = [] + for m in txt.misc_groups(): + pattern = pattern + m.miscs(p) + if m.readable(p): + visib = 1 + if visib: + print "simple_expect \"=%d $any_time " \ + "%d 0 %d 0 %s 0 \\\\\\*\"" % ( + ref.curr, txt.author(), len("text %d" % txt.text_no()), + a_list_pattern(pattern)) + else: + print "simple_expect \"%%%d 14 %d\"" % (ref.curr, txt.text_no()) + +PERSONS = range(6, 10) + +def new_text(txt): + for viewer in PERSONS: + sent = 0 + pattern = [] + for m in txt.misc_groups(): + if m.trigger(viewer): + sent = 1 + pattern = pattern + m.miscs(viewer) + if sent: + talk_to(viewer) + print "simple_expect \":18 15 %d $any_time " \ + "%d 0 %d 0 %s 0 \\\\\\*\"" % ( + txt.text_no(), txt.author(), len("text %d" % txt.text_no()), + a_list_pattern(pattern)) + elif txt.author() != viewer and DEBUG: + talk_to(viewer) + print "send \"%d 35\\n\"" % ref.next() + print "simple_expect \"=%d $any_time\"" % ref.curr + +def new_recipient(author, txt, misc): + for viewer in PERSONS: + sent = 0 + for m in txt.misc_groups() + [misc]: + if m.trigger(viewer): + sent = 1 + async = misc.async(viewer, txt.text_no()) + if sent and async != None: + talk_to(viewer) + print "simple_expect \":3 16 %s\"" % async + elif author != viewer and DEBUG: + talk_to(viewer) + print "send \"%d 35\\n\"" % ref.next() + print "simple_expect \"=%d $any_time\"" % ref.curr + +def delete(deleter, txt): + nr = ref.next() + talk_to(deleter) + print "# Deleting text %d; deleter %d" % (txt.text_no(), deleter) + print "send \"%d 29 %d\\n\"" % (nr, txt.text_no()) + deleted_text(deleter, txt) + talk_to(deleter) + print "simple_expect \"=%d\"" % nr + +def deleted_text(deleter, txt): + for viewer in PERSONS: + sent = 0 + pattern = [] + for m in txt.misc_groups(): + if m.trigger(viewer): + sent = 1 + pattern = pattern + m.miscs(viewer) + if sent: + talk_to(viewer) + print "simple_expect \":18 14 %d $any_time " \ + "%d 0 %d 0 %s 0 \\\\\\*\"" % ( + txt.text_no(), txt.author(), len("text %d" % txt.text_no()), + a_list_pattern(pattern)) + elif deleter != viewer and DEBUG: + talk_to(viewer) + print "send \"%d 35\\n\"" % ref.next() + print "simple_expect \"=%d $any_time\"" % ref.curr + + +def remove_misc(remover, txt, recip): + for removed in txt.misc_groups(): + if removed.recipient() == recip: + break + else: + raise 'no-such-recipient' + nr = ref.next() + talk_to(remover) + print "# Removing recipient from text %d; remover %d" % ( + txt.text_no(), remover) + print "send \"%d 31 %d %d\\n\"" % (nr, txt.text_no(), recip) + sub_recipient(remover, txt, recip, removed.recipient_type()) + talk_to(remover) + print "simple_expect \"=%d\"" % nr + txt.remove_misc_group(removed) + +def sub_recipient(remover, txt, recip, misc_type): + for viewer in PERSONS: + sent = 0 + for m in txt.misc_groups(): + if m.trigger(viewer): + sent = 1 + if sent: + talk_to(viewer) + print "simple_expect \":3 17 %d %d %s\"" % ( + txt.text_no(), recip, misc_type) + elif remover != viewer and DEBUG: + talk_to(viewer) + print "send \"%d 35\\n\"" % ref.next() + print "simple_expect \"=%d $any_time\"" % ref.curr + +def setup(): + print "lyskomd_start" + for p in PERSONS: + print "client_start %d" % (p - 6) + talk_to(p) + print "send \"A3Hfoo\\n\"" + print "simple_expect \"LysKOM\" \"connected %d\"" % p + print "send \"%d 80 4 { 14 15 16 17 }\\n\"" % ref.next() + print "simple_expect \"=%d\"" % ref.curr + print "send \"%d 89 [holl \"Person %d\"] [holl \"foo\"] " \ + "00000000 0 { }\\n\"" % (ref.next(), p) + print "simple_expect \"=%d %d\"" % (ref.curr, p) + print "send \"%d 62 %d [holl \"foo\"] 0\\n\"" % (ref.next(), p) + print "simple_expect \"=%d\"" % ref.curr + for (creator, conf, conf_type) in [ + (7, 10, "0000"), + (7, 11, "1000"), + (7, 12, "1010"), + (9, 13, "0000"), + (9, 14, "1000"), + (9, 15, "1010"), + ]: + + talk_to(creator) + print "send \"%d 88 [holl \"conf %d\"] %s 0 { }\\n\"" % ( + ref.next(), conf, conf_type) + print "simple_expect \"=%d %d\"" % (ref.curr, conf) + talk_to(7) + for conf in [10, 11, 12]: + for (reader, mtype) in [(7, "00000000"), + (8, "01000000")]: + print "send \"%d 100 %d %d 100 3 %s\\n\"" % ( + ref.next(), conf, reader, mtype) + print "simple_expect \"=%d\"" % ref.curr + talk_to(9) + for conf in [13, 14, 15]: + for (reader, mtype) in [(7, "01000000"), + (8, "00000000")]: + print "send \"%d 100 %d %d 100 6 %s\\n\"" % ( + ref.next(), conf, reader, mtype) + print "simple_expect \"=%d\"" % ref.curr + talk_to(7) + print "send \"%d 15 7 7\\n\"" % ref.next() + print "simple_expect \"=%d\"" % ref.curr + +def disco(): + for p in PERSONS[:-1]: + talk_to(p) + print "send \"%d 55 0\\n\"" % ref.next() + print "simple_expect \"=%d\"" % ref.curr + print "client_death %d" % (p - 6) + talk_to(PERSONS[-1]) + print "send \"%d 62 5 [holl \"gazonk\"] 1\\n\"" % ref.next() + print "simple_expect \"=%d\"" % ref.curr + print "send \"%d 42 255\\n\"" % ref.next() + print "simple_expect \"=%d\"" % ref.curr + print "send \"%d 44 0\\n\"" % ref.next() + print "simple_expect \"=%d\"" % ref.curr + print "client_death %d" % (PERSONS[-1] - 6) + print "lyskomd_death" + +def simple_create_delete(): + print "send_user \"testing simple create+delete\\n\"" + for author in [6, 7, 8, 9]: + if EXTENDED: + print "send_user \"...author %d (be patient)\\n\"" % author + for misc_type in [0, 1, 15]: + for rcpt in [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: + if author in [6, 9] and rcpt in [12, 15]: + continue + txt = create(author, [(misc_type, rcpt)]) + delete(author, txt) + if not EXTENDED: + continue + for second_misc_type in [0, 1, 15]: + for second_rcpt in [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: + if rcpt == second_rcpt: + continue + if author in [6, 9] and second_rcpt in [12, 15]: + continue + txt = create(author, [ + (misc_type, rcpt), + (second_misc_type, second_rcpt)]) + delete(author, txt) + +def simple_create_add_delete(): + print "send_user \"testing simple create+add+delete\\n\"" + + for author in [6, 7, 8, 9]: + if EXTENDED: + print "send_user \"...author %d (be patient)\\n\"" % author + for misc_type in [0, 1, 15]: + for rcpt in [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: + if author in [6, 9] and rcpt in [12, 15]: + continue + txt = create(author, []) + add_misc(author, txt, misc_type, rcpt) + verify_text_stat(txt) + delete(author, txt) + if not EXTENDED: + continue + for second_misc_type in [0, 1, 15]: + for second_rcpt in [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: + if rcpt == second_rcpt: + continue + if author in [6, 9] and second_rcpt in [12, 15]: + continue + txt = create(author, []) + add_misc(author, txt, misc_type, rcpt) + verify_text_stat(txt) + add_misc(author, txt, second_misc_type, second_rcpt) + verify_text_stat(txt) + delete(author, txt) + +def special_cases(): + print "send_user \"testing some special cases\\n\"" + + txt = create(7, [(0, 10)]) + add_misc(6, txt, 15, 8) + verify_text_stat(txt) + remove_misc(7, txt, 10) + verify_text_stat(txt) + delete(7, txt) + +def generate_test(): + setup() + simple_create_delete() + simple_create_add_delete() + special_cases() + disco() + +generate_test()