"Fossies" - the Fresh Open Source Software Archive

Member "roundup-2.0.0/test/test_admin.py" (29 Jun 2020, 31377 Bytes) of package /linux/www/roundup-2.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "test_admin.py": 1.6.1_vs_2.0.0.

    1 #
    2 # Copyright (C) 2007 Stefan Seefeld
    3 # All rights reserved.
    4 # For license terms see the file COPYING.txt.
    5 #
    6 
    7 from __future__ import print_function
    8 import unittest, os, shutil, errno, sys, difflib, cgi, re
    9 
   10 from roundup.admin import AdminTool
   11 
   12 from . import db_test_base
   13 from .test_mysql import skip_mysql
   14 from .test_postgresql import skip_postgresql
   15 
   16 #from roundup import instance
   17 
   18 # https://stackoverflow.com/questions/4219717/how-to-assert-output-with-nosetest-unittest-in-python
   19 # lightly modified
   20 from contextlib import contextmanager
   21 _py3 = sys.version_info[0] > 2
   22 if _py3:
   23     from io import StringIO # py3
   24 else:
   25     from StringIO import StringIO # py2
   26 
   27 @contextmanager
   28 def captured_output():
   29     new_out, new_err = StringIO(), StringIO()
   30     old_out, old_err = sys.stdout, sys.stderr
   31     try:
   32         sys.stdout, sys.stderr = new_out, new_err
   33         yield sys.stdout, sys.stderr
   34     finally:
   35         sys.stdout, sys.stderr = old_out, old_err
   36 
   37 def normalize_file(filename, skiplines = [ None ]):
   38 # https://stackoverflow.com/questions/4710067/using-python-for-deleting-a-specific-line-in-a-file
   39 
   40     with open(filename, "r+") as f:
   41         d = f.readlines()
   42         f.seek(0)
   43         for i in d:
   44             for skip in skiplines:
   45                 if skip not in i:
   46                     f.write(i)
   47         f.truncate()
   48 
   49 class AdminTest(object):
   50 
   51     backend = None
   52 
   53     def setUp(self):
   54         self.dirname = '_test_admin'
   55 
   56     def tearDown(self):
   57         try:
   58             shutil.rmtree(self.dirname)
   59         except OSError as error:
   60             if error.errno not in (errno.ENOENT, errno.ESRCH): raise
   61 
   62     def install_init(self, type="classic",
   63                      settings="mail_domain=example.com," +
   64                      "mail_host=localhost," +
   65                      "tracker_web=http://test/," +
   66                      "rdbms_name=rounduptest," +
   67                      "rdbms_user=rounduptest," +
   68                      "rdbms_password=rounduptest," +
   69                      "rdbms_template=template0"
   70     ):
   71         ''' install tracker with settings for required config.ini settings.
   72         '''
   73 
   74         admin=AdminTool()
   75         admin.force = True  # force it to nuke existing tracker
   76 
   77         # Run under context manager to suppress output of help text.
   78         with captured_output() as (out, err):
   79             sys.argv=['main', '-i', self.dirname, 'install',
   80                       type, self.backend, settings ]
   81             ret = admin.main()
   82         self.assertEqual(ret, 0)
   83 
   84         # nuke any existing database (mysql/postgreql)
   85         # possible method in case admin.force doesn't work
   86         #tracker = instance.open(self.dirname)
   87         #if tracker.exists():
   88         #    tracker.nuke()
   89 
   90         # initialize tracker with initial_data.py. Put password
   91         # on cli so I don't have to respond to prompting.
   92         sys.argv=['main', '-i', self.dirname, 'initialise', 'admin']
   93         admin.force = True  # force it to nuke existing database
   94         ret = admin.main()
   95         self.assertEqual(ret, 0)
   96 
   97 
   98     def testGet(self):
   99         ''' Note the tests will fail if you run this under pdb.
  100             the context managers capture the pdb prompts and this screws
  101             up the stdout strings with (pdb) prefixed to the line.
  102         '''
  103         import sys
  104 
  105         self.install_init()
  106         self.admin=AdminTool()
  107 
  108         with captured_output() as (out, err):
  109             sys.argv=['main', '-i', self.dirname, 'create', 'issue',
  110                       'title="foo bar"', 'assignedto=admin' ]
  111             ret = self.admin.main()
  112 
  113         out = out.getvalue().strip()
  114         print(out)
  115         self.assertEqual(out, '1')
  116 
  117         self.admin=AdminTool()
  118         with captured_output() as (out, err):
  119             sys.argv=['main', '-i', self.dirname, 'create', 'issue',
  120                       'title="bar foo bar"', 'assignedto=anonymous',
  121                       'superseder=1']
  122             ret = self.admin.main()
  123 
  124         self.assertEqual(ret, 0)
  125         out = out.getvalue().strip()
  126         print(out)
  127         self.assertEqual(out, '2')
  128 
  129         self.admin=AdminTool()
  130         with captured_output() as (out, err):
  131             sys.argv=['main', '-i', self.dirname, 'get', 'assignedto',
  132                       'issue2' ]
  133             ret = self.admin.main()
  134 
  135         self.assertEqual(ret, 0)
  136         out = out.getvalue().strip()
  137         err = err.getvalue().strip()
  138         self.assertEqual(out, '2')
  139         self.assertEqual(len(err), 0)
  140 
  141         self.admin=AdminTool()
  142         with captured_output() as (out, err):
  143             sys.argv=['main', '-i', self.dirname, 'get', 'superseder',
  144                       'issue2' ]
  145             ret = self.admin.main()
  146 
  147         self.assertEqual(ret, 0)
  148         out = out.getvalue().strip()
  149         err = err.getvalue().strip()
  150         self.assertEqual(out, "['1']")
  151         self.assertEqual(len(err), 0)
  152 
  153         self.admin=AdminTool()
  154         with captured_output() as (out, err):
  155             sys.argv=['main', '-i', self.dirname, 'get', 'title', 'issue1']
  156             ret = self.admin.main()
  157 
  158         self.assertEqual(ret, 0)
  159         out = out.getvalue().strip()
  160         err = err.getvalue().strip()
  161         self.assertEqual(out, '"foo bar"')  ## why is capture inserting "??
  162         self.assertEqual(len(err), 0)
  163 
  164         self.admin=AdminTool()
  165         with captured_output() as (out, err):
  166             sys.argv=['main', '-i', self.dirname, 'get', 'tile', 'issue1']
  167             ret = self.admin.main()
  168 
  169         expected_err = 'Error: no such issue property "tile"'
  170 
  171         self.assertEqual(ret, 1)
  172         out = out.getvalue().strip()
  173         err = err.getvalue().strip()
  174         self.assertEqual(out.index(expected_err), 0)
  175         self.assertEqual(len(err), 0)
  176 
  177         self.admin=AdminTool()
  178         with captured_output() as (out, err):
  179             sys.argv=['main', '-i', self.dirname, 'get', 'title', 'issue']
  180             ret = self.admin.main()
  181 
  182         expected_err = 'Error: "issue" not a node designator'
  183 
  184         self.assertEqual(ret, 1)
  185         out = out.getvalue().strip()
  186         err = err.getvalue().strip()
  187         self.assertEqual(out.index(expected_err), 0)
  188         self.assertEqual(len(err), 0)
  189 
  190     def testInit(self):
  191         import sys
  192         self.admin=AdminTool()
  193         sys.argv=['main', '-i', self.dirname, 'install', 'classic', self.backend]
  194         ret = self.admin.main()
  195         print(ret)
  196         self.assertTrue(ret == 0)
  197         self.assertTrue(os.path.isfile(self.dirname + "/config.ini"))
  198         self.assertTrue(os.path.isfile(self.dirname + "/schema.py"))
  199 
  200     def testInitWithConfig_ini(self):
  201         import sys
  202         from roundup.configuration import CoreConfig
  203         self.admin=AdminTool()
  204         sys.argv=['main', '-i', self.dirname, 'install', 'classic', self.backend]
  205         # create a config_ini.ini file in classic template
  206         templates=self.admin.listTemplates()
  207         config_ini_content = "[mail]\n# comment\ndebug = SendMail.LOG\n"
  208         config_ini_path = templates['classic']['path'] + '/config_ini.ini'
  209         config_ini_file = open(config_ini_path, "w")
  210         config_ini_file.write(config_ini_content)
  211         config_ini_file.close()
  212 
  213         try:
  214             ret = self.admin.main()
  215         finally:
  216             try:
  217                 # ignore file not found
  218                 os.remove(config_ini_path)
  219             except OSError as e:  # FileNotFound exception under py3
  220                 if e.errno == 2:
  221                     pass
  222                 else:
  223                     raise
  224 
  225         print(ret)
  226         self.assertTrue(ret == 0)
  227         self.assertTrue(os.path.isfile(self.dirname + "/config.ini"))
  228         self.assertTrue(os.path.isfile(self.dirname + "/schema.py"))
  229         config=CoreConfig(self.dirname)
  230         self.assertEqual(config['MAIL_DEBUG'], self.dirname + "/SendMail.LOG")
  231 
  232     def testFind(self):
  233         ''' Note the tests will fail if you run this under pdb.
  234             the context managers capture the pdb prompts and this screws
  235             up the stdout strings with (pdb) prefixed to the line.
  236         '''
  237         import sys
  238 
  239         self.admin=AdminTool()
  240         self.install_init()
  241 
  242         with captured_output() as (out, err):
  243             sys.argv=['main', '-i', self.dirname, 'create', 'issue',
  244                       'title="foo bar"', 'assignedto=admin' ]
  245             ret = self.admin.main()
  246 
  247         out = out.getvalue().strip()
  248         print(out)
  249         self.assertEqual(out, '1')
  250 
  251         self.admin=AdminTool()
  252         with captured_output() as (out, err):
  253             sys.argv=['main', '-i', self.dirname, 'create', 'issue',
  254                       'title="bar foo bar"', 'assignedto=anonymous' ]
  255             ret = self.admin.main()
  256 
  257         out = out.getvalue().strip()
  258         print(out)
  259         self.assertEqual(out, '2')
  260 
  261         self.admin=AdminTool()
  262         with captured_output() as (out, err):
  263             sys.argv=['main', '-i', self.dirname, 'find', 'issue',
  264                       'assignedto=1']
  265             ret = self.admin.main()
  266 
  267         out = out.getvalue().strip()
  268         print(out)
  269         self.assertEqual(out, "['1']")
  270 
  271         # Reopen the db closed by previous filter call
  272         self.admin=AdminTool()
  273         with captured_output() as (out, err):
  274             ''' 1,2 should return all entries that have assignedto
  275                 either admin or anonymous
  276             '''
  277             sys.argv=['main', '-i', self.dirname, 'find', 'issue',
  278                       'assignedto=1,2']
  279             ret = self.admin.main()
  280 
  281         out = out.getvalue().strip()
  282         print(out)
  283         # out can be "['2', '1']" or "['1', '2']"
  284         # so eval to real list so Equal can do a list compare
  285         self.assertEqual(sorted(eval(out)), ['1', '2'])
  286 
  287         # Reopen the db closed by previous filter call
  288         self.admin=AdminTool()
  289         with captured_output() as (out, err):
  290             ''' 1,2 should return all entries that have assignedto
  291                 either admin or anonymous
  292             '''
  293             sys.argv=['main', '-i', self.dirname, 'find', 'issue',
  294                       'assignedto=admin,anonymous']
  295             ret = self.admin.main()
  296 
  297         out = out.getvalue().strip()
  298         print(out)
  299         # out can be "['2', '1']" or "['1', '2']"
  300         # so eval to real list so Equal can do a list compare
  301         self.assertEqual(sorted(eval(out)), ['1', '2'])
  302 
  303     def testGenconfigUpdate(self):
  304         ''' Note the tests will fail if you run this under pdb.
  305             the context managers capture the pdb prompts and this screws
  306             up the stdout strings with (pdb) prefixed to the line.
  307         '''
  308         import sys, filecmp
  309 
  310         self.admin=AdminTool()
  311         self.install_init()
  312 
  313         with captured_output() as (out, err):
  314             sys.argv=['main', '-i', self.dirname, 'genconfig']
  315             ret = self.admin.main()
  316 
  317         out = out.getvalue().strip()
  318         print(out)
  319         expected = "Not enough arguments supplied"
  320         self.assertTrue(expected in out)
  321 
  322         # Reopen the db closed by previous call
  323         self.admin=AdminTool()
  324 
  325         with captured_output() as (out, err):
  326             sys.argv=['main', '-i', self.dirname, 'genconfig',
  327                       self.dirname + "/config2.ini"]
  328             ret = self.admin.main()
  329 
  330         out = out.getvalue().strip()
  331         print(out)
  332         # FIXME get better successful test later.
  333         expected = ""
  334         self.assertTrue(expected in out)
  335         self.assertTrue(os.path.isfile(self.dirname + "/config2.ini"))
  336         # Files aren't the same. Lines need to be removed.
  337         # like user, web, backend etc. Genconfig generates a file
  338         # to be customized.
  339         #self.assertTrue(filecmp.cmp(self.dirname + "/config2.ini",
  340         #                            self.dirname + "/config.ini"))
  341 
  342         # Reopen the db closed by previous call
  343         self.admin=AdminTool()
  344 
  345         with captured_output() as (out, err):
  346             sys.argv=['main', '-i', self.dirname, 'update',
  347                       self.dirname + "/foo2.ini"]
  348             ret = self.admin.main()
  349 
  350         out = out.getvalue().strip()
  351         print(out)
  352         # FIXME get better successful test later.
  353         expected = ""
  354         self.assertTrue(expected in out)
  355         self.assertTrue(os.path.isfile(self.dirname + "/foo2.ini"))
  356 
  357         # Autogenerated date header is different. Remove it
  358         # so filecmp passes.
  359         normalize_file(self.dirname + "/foo2.ini",
  360                        [ '# Autogenerated at' ])
  361         normalize_file(self.dirname + "/config.ini",
  362                        [ '# Autogenerated at' ])
  363 
  364         self.assertTrue(filecmp.cmp(self.dirname + "/config.ini",
  365                                     self.dirname + "/foo2.ini"))
  366 
  367 
  368     def testCliParse(self):
  369         ''' Note the tests will fail if you run this under pdb.
  370             the context managers capture the pdb prompts and this screws
  371             up the stdout strings with (pdb) prefixed to the line.
  372         '''
  373         import sys
  374 
  375         self.admin=AdminTool()
  376         self.install_init()
  377 
  378         # test partial command lookup fin -> calls find
  379 
  380         with captured_output() as (out, err):
  381             ''' assignedto is not a valid property=value, so
  382                 report error.
  383             '''
  384             sys.argv=['main', '-i', self.dirname, 'fin', 'issue',
  385                       'assignedto=1']
  386             ret = self.admin.main()
  387 
  388         out = out.getvalue().strip()
  389         print(out)
  390         expected="[ '1' ]"
  391         self.assertTrue(expected, out)
  392 
  393         # Reopen the db closed by previous call
  394         self.admin=AdminTool()
  395         # test multiple matches
  396         with captured_output() as (out, err):
  397             ''' assignedto is not a valid property=value, so
  398                 report error.
  399             '''
  400             sys.argv=['main', '-i', self.dirname, 'f', 'issue',
  401                       'assignedto']
  402             ret = self.admin.main()
  403 
  404         out = out.getvalue().strip()
  405         print(out)
  406         expected='Multiple commands match "f": filter, find'
  407         self.assertEqual(expected, out)
  408 
  409         # Reopen the db closed by previous call
  410         self.admin=AdminTool()
  411         # test broken command lookup xyzzy is not a valid command
  412         with captured_output() as (out, err):
  413             ''' assignedto is not a valid property=value, so
  414                 report error.
  415             '''
  416             sys.argv=['main', '-i', self.dirname, 'xyzzy', 'issue',
  417                       'assignedto']
  418             ret = self.admin.main()
  419 
  420         out = out.getvalue().strip()
  421         print(out)
  422         expected=('Unknown command "xyzzy" '
  423                   '("help commands" for a list)')
  424         self.assertEqual(expected, out)
  425 
  426         # Reopen the db closed by previous call
  427         self.admin=AdminTool()
  428         # test for keyword=value check
  429         with captured_output() as (out, err):
  430             ''' assignedto is not a valid property=value, so
  431                 report error.
  432             '''
  433             sys.argv=['main', '-i', self.dirname, 'find', 'issue',
  434                       'assignedto']
  435             ret = self.admin.main()
  436 
  437         out = out.getvalue().strip()
  438         print(out)
  439         expected='Error: argument "assignedto" not propname=value'
  440         self.assertTrue(expected in out)
  441 
  442     def testFilter(self):
  443         ''' Note the tests will fail if you run this under pdb.
  444             the context managers capture the pdb prompts and this screws
  445             up the stdout strings with (pdb) prefixed to the line.
  446         '''
  447         import sys
  448 
  449         self.admin=AdminTool()
  450         self.install_init()
  451 
  452         with captured_output() as (out, err):
  453             sys.argv=['main', '-i', self.dirname, 'create', 'issue',
  454                       'title="foo bar"', 'assignedto=admin' ]
  455             ret = self.admin.main()
  456 
  457         out = out.getvalue().strip()
  458         print(out)
  459         self.assertEqual(out, '1')
  460 
  461         self.admin=AdminTool()
  462         with captured_output() as (out, err):
  463             sys.argv=['main', '-i', self.dirname, 'create', 'issue',
  464                       'title="bar foo bar"', 'assignedto=anonymous' ]
  465             ret = self.admin.main()
  466 
  467         out = out.getvalue().strip()
  468         print(out)
  469         self.assertEqual(out, '2')
  470 
  471         
  472         # Reopen the db closed by previous filter call
  473         # test string - one results, one value, substring
  474         self.admin=AdminTool()
  475         with captured_output() as (out, err):
  476             sys.argv=['main', '-i', self.dirname, 'filter', 'user',
  477                       'username=admin']
  478             ret = self.admin.main()
  479 
  480         out = out.getvalue().strip()
  481         print(out)
  482         self.assertEqual(out, "['1']")
  483 
  484         # Reopen the db closed by previous filter call
  485         # test string - two results, two values, substring
  486         self.admin=AdminTool()
  487         with captured_output() as (out, err):
  488             ''' a,n should return all entries that have an a and n
  489                 so admin or anonymous
  490             '''
  491             sys.argv=['main', '-i', self.dirname, 'filter', 'user',
  492                       'username=a,n']
  493             ret = self.admin.main()
  494 
  495         out = out.getvalue().strip()
  496         print(out)
  497         # out can be "['2', '1']" or "['1', '2']"
  498         # so eval to real list so Equal can do a list compare
  499         self.assertEqual(sorted(eval(out)), ['1', '2'])
  500 
  501         # Reopen the db closed by previous filter call
  502         # test string - one result, two values, substring
  503         self.admin=AdminTool()
  504         with captured_output() as (out, err):
  505             ''' a,y should return all entries that have an a and y
  506                 so anonymous
  507             '''
  508             sys.argv=['main', '-i', self.dirname, 'filter', 'user',
  509                       'username=a,y']
  510             ret = self.admin.main()
  511 
  512         out = out.getvalue().strip()
  513         print(out)
  514         self.assertEqual(out, "['2']")
  515 
  516         # Reopen the db closed by previous filter call
  517         # test string - no results
  518         self.admin=AdminTool()
  519         with captured_output() as (out, err):
  520             ''' will return empty set as admin!=anonymous
  521             '''
  522             sys.argv=['main', '-i', self.dirname, 'filter', 'user',
  523                       'username=admin,anonymous']
  524             ret = self.admin.main()
  525 
  526         out = out.getvalue().strip()
  527         print(out)
  528         self.assertEqual(out, "[]")
  529 
  530         # Reopen the db closed by previous filter call
  531         # test link using ids
  532         self.admin=AdminTool()
  533         with captured_output() as (out, err):
  534             sys.argv=['main', '-i', self.dirname, 'filter', 'issue',
  535                       'assignedto=1,2']
  536             ret = self.admin.main()
  537 
  538         out = out.getvalue().strip()
  539         print(out)
  540         self.assertEqual(sorted(eval(out)), ['1', '2'])
  541 
  542         # Reopen the db closed by previous filter call
  543         # test link using names
  544         self.admin=AdminTool()
  545         with captured_output() as (out, err):
  546             ''' will return empty set as admin!=anonymous
  547             '''
  548             sys.argv=['main', '-i', self.dirname, 'filter', 'issue',
  549                       'assignedto=admin,anonymous']
  550             ret = self.admin.main()
  551 
  552         out = out.getvalue().strip()
  553         print(out)
  554         self.assertEqual(sorted(eval(out)), ['1', '2'])
  555 
  556     def disabletestHelpInitopts(self):
  557 
  558         ''' Note the tests will fail if you run this under pdb.
  559             the context managers capture the pdb prompts and this screws
  560             up the stdout strings with (pdb) prefixed to the line.
  561         '''
  562         import sys
  563 
  564         self.install_init()
  565         self.admin=AdminTool()
  566 
  567         with captured_output() as (out, err):
  568             sys.argv=['main', '-i', self.dirname, 'help', 'initopts']
  569             ret = self.admin.main()
  570 
  571         out = out.getvalue().strip()
  572         expected = [
  573         'Templates: minimal, jinja2, classic, responsive, devel',
  574         'Back ends: anydbm, sqlite'
  575         ]
  576         print(out)
  577         self.assertTrue(expected[0] in out)
  578         self.assertTrue("Back ends:" in out)
  579 
  580     def testSet(self):
  581         ''' Note the tests will fail if you run this under pdb.
  582             the context managers capture the pdb prompts and this screws
  583             up the stdout strings with (pdb) prefixed to the line.
  584         '''
  585         import sys
  586 
  587         self.install_init()
  588         self.admin=AdminTool()
  589 
  590         with captured_output() as (out, err):
  591             sys.argv=['main', '-i', self.dirname, 'create', 'issue',
  592                       'title="foo bar"', 'assignedto=admin' ]
  593             ret = self.admin.main()
  594 
  595         out = out.getvalue().strip()
  596         print(out)
  597         self.assertEqual(out, '1')
  598 
  599         self.admin=AdminTool()
  600         with captured_output() as (out, err):
  601             sys.argv=['main', '-i', self.dirname, 'create', 'issue',
  602                       'title="bar foo bar"', 'assignedto=anonymous' ]
  603             ret = self.admin.main()
  604 
  605         out = out.getvalue().strip()
  606         print(out)
  607         self.assertEqual(out, '2')
  608 
  609         self.admin=AdminTool()
  610         with captured_output() as (out, err):
  611             sys.argv=['main', '-i', self.dirname, 'set', 'issue2', 'title="new title"']
  612             ret = self.admin.main()
  613 
  614         out = out.getvalue().strip()
  615         err = err.getvalue().strip()
  616         self.assertEqual(len(out), 0)
  617         self.assertEqual(len(err), 0)
  618 
  619         self.admin=AdminTool()
  620         with captured_output() as (out, err):
  621             sys.argv=['main', '-i', self.dirname, 'set', 'issue2',
  622                       'tile="new title"']
  623             ret = self.admin.main()
  624 
  625         expected_err = "Error: 'tile' is not a property of issue"
  626 
  627         out = out.getvalue().strip()
  628         err = err.getvalue().strip()
  629         self.assertEqual(out.index(expected_err), 0)
  630         self.assertEqual(len(err), 0)
  631 
  632         self.admin=AdminTool()
  633         with captured_output() as (out, err):
  634             sys.argv=['main', '-i', self.dirname, 'set', 'issue2']
  635             ret = self.admin.main()
  636 
  637         expected_err = "Error: Not enough arguments supplied"
  638 
  639         out = out.getvalue().strip()
  640         err = err.getvalue().strip()
  641         self.assertEqual(out.index(expected_err), 0)
  642         self.assertEqual(len(err), 0)
  643 
  644 
  645         self.admin=AdminTool()
  646         with captured_output() as (out, err):
  647             sys.argv=['main', '-i', self.dirname, 'set',
  648                       'issue2,issue1,issue', "status=1" ]
  649             ret = self.admin.main()
  650 
  651         expected_err = 'Error: "issue" not a node designator'
  652 
  653         out = out.getvalue().strip()
  654         err = err.getvalue().strip()
  655         self.assertEqual(out.index(expected_err), 0)
  656         self.assertEqual(len(err), 0)
  657 
  658         self.admin=AdminTool()
  659         with captured_output() as (out, err):
  660             sys.argv=['main', '-i', self.dirname, 'set',
  661                       'issue2,issue1,user2', "status=1" ]
  662             ret = self.admin.main()
  663 
  664         expected_err = "Error: 'status' is not a property of user"
  665 
  666         out = out.getvalue().strip()
  667         err = err.getvalue().strip()
  668         print(out)
  669         print(expected_err)
  670         print(err)
  671         self.assertEqual(out.index(expected_err), 0)
  672         self.assertEqual(len(err), 0)
  673 
  674         self.admin=AdminTool()
  675         with captured_output() as (out, err):
  676             sys.argv=['main', '-i', self.dirname, 'set',
  677                       'issue2,issue1,issue1000', "status=1" ]
  678             ret = self.admin.main()
  679 
  680         expected_err = 'Error: no such issue 1000'
  681 
  682         out = out.getvalue().strip()
  683         err = err.getvalue().strip()
  684         self.assertEqual(out.index(expected_err), 0)
  685         self.assertEqual(len(err), 0)
  686 
  687     def testSetOnClass(self):
  688         ''' Note the tests will fail if you run this under pdb.
  689             the context managers capture the pdb prompts and this screws
  690             up the stdout strings with (pdb) prefixed to the line.
  691         '''
  692         import sys
  693 
  694         self.install_init()
  695 
  696         self.admin=AdminTool()
  697         with captured_output() as (out, err):
  698             sys.argv=['main', '-i', self.dirname, 'create', 'issue',
  699                       'title="foo bar"', 'assignedto=admin' ]
  700             ret = self.admin.main()
  701 
  702         out = out.getvalue().strip()
  703         print(out)
  704         self.assertEqual(out, '1')
  705 
  706         self.admin=AdminTool()
  707         with captured_output() as (out, err):
  708             sys.argv=['main', '-i', self.dirname, 'create', 'issue',
  709                       'title="bar foo bar"', 'assignedto=anonymous' ]
  710             ret = self.admin.main()
  711 
  712         out = out.getvalue().strip()
  713         print(out)
  714         self.assertEqual(out, '2')
  715 
  716         # Run this test in a separate test.
  717         # It can cause a database timeout/resource
  718         # unavailable error for anydbm when run with other tests.
  719         # Not sure why.
  720         # Set assignedto=2 for all issues
  721         ## verify that issue 1 and 2 are assigned to user1 and user2
  722         self.admin=AdminTool()
  723         with captured_output() as (out, err):
  724             sys.argv=['main', '-i', self.dirname, 'table', 'issue',
  725             'assignedto']
  726             ret = self.admin.main()
  727 
  728         expected = "Assignedto\n1         \n2"
  729         out = out.getvalue().strip()
  730         err = err.getvalue().strip()
  731         self.assertEqual(out, expected)
  732         self.assertEqual(len(err), 0)
  733         self.admin=AdminTool()
  734         # do the set
  735         with captured_output() as (out, err):
  736             sys.argv=['main', '-i', self.dirname, 'set', 'issue',
  737             'assignedto=2']
  738             ret = self.admin.main()
  739 
  740         expected_err = ""
  741 
  742         out = out.getvalue().strip()
  743         err = err.getvalue().strip()
  744         self.assertEqual(len(out), 0)
  745         self.assertEqual(len(err), 0)
  746 
  747         ## verify that issue 1 and 2 are assigned to user2 and user2
  748         self.admin=AdminTool()
  749         with captured_output() as (out, err):
  750             sys.argv=['main', '-i', self.dirname, 'table', 'issue',
  751             'assignedto']
  752             ret = self.admin.main()
  753 
  754         expected = "Assignedto\n2         \n2"
  755         out = out.getvalue().strip()
  756         err = err.getvalue().strip()
  757         self.assertEqual(out, expected)
  758         self.assertEqual(len(err), 0)
  759 
  760     def testSpecification(self):
  761         ''' Note the tests will fail if you run this under pdb.
  762             the context managers capture the pdb prompts and this screws
  763             up the stdout strings with (pdb) prefixed to the line.
  764         '''
  765         import sys
  766 
  767         self.install_init()
  768         self.admin=AdminTool()
  769 
  770         spec= [ 'username: <roundup.hyperdb.String> (key property)',
  771                 'alternate_addresses: <roundup.hyperdb.String>',
  772                 'realname: <roundup.hyperdb.String>',
  773                 'roles: <roundup.hyperdb.String>',
  774                 'organisation: <roundup.hyperdb.String>',
  775                 'queries: <roundup.hyperdb.Multilink to "query">',
  776                 'phone: <roundup.hyperdb.String>',
  777                 'address: <roundup.hyperdb.String>',
  778                 'timezone: <roundup.hyperdb.String>',
  779                 'password: <roundup.hyperdb.Password>',
  780             ]
  781             
  782         with captured_output() as (out, err):
  783             sys.argv=['main', '-i', self.dirname, 'specification', 'user']
  784             ret = self.admin.main()
  785 
  786         outlist = out.getvalue().strip().split("\n")
  787         print(outlist)
  788         self.assertEqual(sorted(outlist), sorted(spec))
  789 
  790     def testTable(self):
  791         ''' Note the tests will fail if you run this under pdb.
  792             the context managers capture the pdb prompts and this screws
  793             up the stdout strings with (pdb) prefixed to the line.
  794         '''
  795         import sys
  796 
  797         self.install_init()
  798         self.admin=AdminTool()
  799 
  800         with captured_output() as (out, err):
  801             sys.argv=['main', '-i', self.dirname, 'table' ]
  802             ret = self.admin.main()
  803 
  804         expected = 'Error: Not enough arguments supplied'
  805 
  806         out = out.getvalue().strip()
  807         print(out)
  808         print(expected)
  809         self.assertTrue(expected in out)
  810         ####
  811 
  812         self.admin=AdminTool()
  813 
  814         with captured_output() as (out, err):
  815             sys.argv=['main', '-i', self.dirname, 'table', 
  816                       'id,realname,username' ]
  817             ret = self.admin.main()
  818 
  819         expected = 'Error: no such class "id,realname,username"'
  820 
  821         out = out.getvalue().strip()
  822         print(out)
  823         print(expected)
  824         self.assertTrue(expected in out)
  825 
  826         ####
  827         self.admin=AdminTool()
  828 
  829         with captured_output() as (out, err):
  830             sys.argv=['main', '-i', self.dirname, 'table', 'user',
  831                       'id,realname,username:4:3' ]
  832             ret = self.admin.main()
  833         expected = 'Error: "username:4:3" not name:width'
  834 
  835         out = out.getvalue().strip()
  836         print(out)
  837         print(expected)
  838         self.assertTrue(expected in out)
  839  
  840         ####
  841         self.admin=AdminTool()
  842 
  843         with captured_output() as (out, err):
  844             sys.argv=['main', '-i', self.dirname, 'table', 'user',
  845                       'id,realname,title:4' ]
  846             ret = self.admin.main()
  847         expected = 'Error: user has no property "title"'
  848 
  849         out = out.getvalue().strip()
  850         print(out)
  851         print(expected)
  852         self.assertTrue(expected in out)
  853  
  854         ####
  855         self.admin=AdminTool()
  856 
  857         with captured_output() as (out, err):
  858             sys.argv=['main', '-i', self.dirname, 'table', 'user',
  859                       'id,realname,username:' ]
  860             ret = self.admin.main()
  861 
  862         # note whitespace matters. trailing spaces on lines 1 and 2
  863         expected = """Id Realname Username
  864 1  None     admin   
  865 2  None     anonymou"""
  866 
  867         out = out.getvalue().strip()
  868         print(out)
  869         print(expected)
  870         self.assertEqual(out, expected)
  871 
  872         ####
  873         self.admin=AdminTool()
  874 
  875         with captured_output() as (out, err):
  876             sys.argv=['main', '-i', self.dirname, 'table', 'user',
  877                       'id,realname,username' ]
  878             ret = self.admin.main()
  879 
  880         # note whitespace matters. trailing spaces on lines 1 and 2
  881         expected = """Id Realname Username 
  882 1  None     admin    
  883 2  None     anonymous"""
  884 
  885         out = out.getvalue().strip()
  886         print(out)
  887         print(expected)
  888         self.assertEqual(out, expected)
  889 
  890         ####
  891         self.admin=AdminTool()
  892 
  893         with captured_output() as (out, err):
  894             sys.argv=['main', '-i', self.dirname, 'table', 'user',
  895                       'id:4,realname:2,username:3' ]
  896             ret = self.admin.main()
  897 
  898         # note whitespace matters. trailing spaces on lines 1 and 2
  899         expected = """Id   Realname Username
  900 1    No adm
  901 2    No ano"""
  902 
  903         out = out.getvalue().strip()
  904         print(out)
  905         print(expected)
  906         self.assertEqual(out, expected)
  907 
  908 
  909 class anydbmAdminTest(AdminTest, unittest.TestCase):
  910     backend = 'anydbm'
  911 
  912 
  913 @skip_mysql
  914 class mysqlAdminTest(AdminTest, unittest.TestCase):
  915     backend = 'mysql'
  916 
  917 
  918 class sqliteAdminTest(AdminTest, unittest.TestCase):
  919     backend = 'sqlite'
  920 
  921 
  922 @skip_postgresql
  923 class postgresqlAdminTest(AdminTest, unittest.TestCase):
  924     backend = 'postgresql'