def do_tests(inputargs=None):
    inputargs = (inputargs or sys.argv[1:])
    parser = argparse.ArgumentParser(description='Perform OSLC query on a Jazz application, with results output to CSV (and other) formats - use -h to get some basic help')
    parser.add_argument('spreadsheet', help='Name of the xlsx spreadsheet with tests')
    parser.add_argument('-d', '--dryrun', action='store_true', help="Dry run - show commandline but don't run the OSLC Query")
    parser.add_argument('-f', '--stoponfail', action='store_true', help='Stop at first failure')
    parser.add_argument('-g', '--group', default=None, help='Comma-separated list of regex pattern to match groups to be run, in the worksheet Group column')
    parser.add_argument('-j', '--just', default=None, help='Comma-separated list of tests to run, matching the TestId column in the worksheet')
    parser.add_argument('-L', '--loglevel', default=None, help='Set logging level - default is None - choose from INFO/DEBUG/ERROR')
    parser.add_argument('-r', '--reps', default=1, type=int, help='Number of times to repeat the selected tests (must be >=1')
    parser.add_argument('-s', '--save', action='store_true', help='UNFINISHED Retrieve and save query results forever (used to save reference for -t testing')
    parser.add_argument('-t', '--test', action='store_true', help='UNFINISHED Retrieve data and do comparison to test that results match saved results from -s')
    parser.add_argument('-w', '--sheetname', default=None, help='Name of the worksheet with tests (if not specified the workbook must only have one worksheet, which is used)')
    parser.add_argument('-W', '--cachecontrol', action='count', default=0, help='Used once -W erases cache for the first test then continues with caching enabled. Used twice -WW wipes cache and disables caching.')
    args = parser.parse_args(inputargs)
    if (args.reps < 1):
        raise Exception(f'Reps must be >=1')
    justtests = ([j.strip() for j in args.just.split(',')] if args.just else [])
    wb = XL.load_workbook(filename=args.spreadsheet, data_only=True)
    wss = wb.sheetnames
    if args.sheetname:
        tests = wb[args.sheetname]
    else:
        if (len(wss) > 1):
            raise Exception('Worksheet not specified but spreadsheet file includes more than one sheet!')
        print(f'Using worksheet {wss[0]}')
        tests = wb[wss[0]]
    colheadings = []
    for col in range(1, 50):
        thiscolheading = tests.cell(column=col, row=1).value
        if (not thiscolheading):
            break
        colheadings.append(thiscolheading)
    rows = []
    for rownum in range(2, 2000):
        row = {}
        for (i, col) in enumerate(colheadings):
            row[col] = tests.cell(column=(i + 1), row=rownum).value
        rows.append(row)
    wb.close()
    npassed = 0
    nfailed = 0
    firstquery = True
    for rep in range(args.reps):
        for (n, row) in enumerate(rows):
            testnumber = row['TestId']
            if (not testnumber):
                continue
            if (row['Disable'] and row['Disable'].startswith('#')):
                continue
            if args.group:
                if (not row['Group']):
                    continue
                rowgroups = [j.strip() for j in row['Group'].split(',')]
                regexes = [j.strip() for j in args.group.split(',')]
                if (not any([re.match(regex, group) for regex in regexes for group in rowgroups])):
                    continue
            if (justtests and (str(testnumber) not in justtests)):
                continue
            print(f'''=====================================================================
testnumber={testnumber!r} {row.get('Description', '')}''')
            exceptionexpected = (True if row['ExceptionExpected'] else False)
            csvname = (('test_' + str(testnumber)) + '.csv')
            queryargs = []
            for (k, v) in xlstoargs.items():
                if (k not in colheadings):
                    raise Exception(f'Heading {k} not present in spreadsheet!')
                cellvalue = row[k]
                if (cellvalue is not None):
                    if v:
                        cellvalue = str(row[k]).strip()
                        if cellvalue.startswith('-'):
                            queryargs.append(f'{v}={cellvalue}')
                        else:
                            queryargs.append(v)
                            queryargs.append(cellvalue)
                    else:
                        queryargs.append(str(cellvalue).strip())
            if args.save:
                queryargs.extend(['-0', '-O', csvname])
            if args.test:
                queryargs.extend(['-0', '-2', csvname])
            if (args.loglevel and ('-L' not in queryargs)):
                queryargs.extend(['-L', args.loglevel])
            if firstquery:
                if (args.cachecontrol == 1):
                    queryargs.extend(['-W'])
                elif (args.cachecontrol == 2):
                    queryargs.extend(['-WW'])
                firstquery = False
            elif (args.cachecontrol == 2):
                queryargs.extend(['-WW'])
            try:
                if args.dryrun:
                    print(f'Dry-run: query commandline is: oslcquery {argstocmd(queryargs)}')
                    result = 0
                else:
                    print(f'Query commandline is: oslcquery {argstocmd(queryargs)}')
                    result = querymain.do_oslc_query(queryargs)
                exceptionhappened = False
            except Exception as e:
                print(e)
                result = 1
                exceptionhappened = True
            if (((result != 0) and (not exceptionexpected)) or ((result == 0) and exceptionexpected)):
                nfailed += 1
                print(f''' TEST {testnumber} FAILED!!!!!!!!!!!!!!!!!!!!!
''')
                if args.stoponfail:
                    print(f'Stopping after first failure, {rep} repetitions')
                    return
            else:
                print(f'Test {testnumber} passed!')
                npassed += 1
    if (not args.dryrun):
        print(f'''
Passed {npassed} Failed {nfailed}''')
    else:
        print(f'Dry run completed')
def do_tests(inputargs=None):
    inputargs = (inputargs or sys.argv[1:])
    parser = argparse.ArgumentParser(description='Perform OSLC query on a Jazz application, with results output to CSV (and other) formats - use -h to get some basic help')
    parser.add_argument('spreadsheet', help='Name of the xlsx spreadsheet with tests')
    parser.add_argument('-d', '--dryrun', action='store_true', help="Dry run - show commandline but don't run the OSLC Query")
    parser.add_argument('-f', '--stoponfail', action='store_true', help='Stop at first failure')
    parser.add_argument('-g', '--group', default=None, help='Comma-separated list of regex pattern to match groups to be run, in the worksheet Group column')
    parser.add_argument('-j', '--just', default=None, help='Comma-separated list of tests to run, matching the TestId column in the worksheet')
    parser.add_argument('-L', '--loglevel', default=None, help='Set logging level - default is None - choose from INFO/DEBUG/ERROR')
    parser.add_argument('-r', '--reps', default=1, type=int, help='Number of times to repeat the selected tests (must be >=1')
    parser.add_argument('-s', '--save', action='store_true', help='UNFINISHED Retrieve and save query results forever (used to save reference for -t testing')
    parser.add_argument('-t', '--test', action='store_true', help='UNFINISHED Retrieve data and do comparison to test that results match saved results from -s')
    parser.add_argument('-w', '--sheetname', default=None, help='Name of the worksheet with tests (if not specified the workbook must only have one worksheet, which is used)')
    parser.add_argument('-W', '--cachecontrol', action='count', default=0, help='Used once -W erases cache for the first test then continues with caching enabled. Used twice -WW wipes cache and disables caching.')
    args = parser.parse_args(inputargs)
    if (args.reps < 1):
        raise Exception(f'Reps must be >=1')
    justtests = ([j.strip() for j in args.just.split(',')] if args.just else [])
    wb = XL.load_workbook(filename=args.spreadsheet, data_only=True)
    wss = wb.sheetnames
    if args.sheetname:
        tests = wb[args.sheetname]
    else:
        if (len(wss) > 1):
            raise Exception('Worksheet not specified but spreadsheet file includes more than one sheet!')
        print(f'Using worksheet {wss[0]}')
        tests = wb[wss[0]]
    colheadings = []
    for col in range(1, 50):
        thiscolheading = tests.cell(column=col, row=1).value
        if (not thiscolheading):
            break
        colheadings.append(thiscolheading)
    rows = []
    for rownum in range(2, 2000):
        row = {}
        for (i, col) in enumerate(colheadings):
            row[col] = tests.cell(column=(i + 1), row=rownum).value
        rows.append(row)
    wb.close()
    npassed = 0
    nfailed = 0
    firstquery = True
    for rep in range(args.reps):
        for (n, row) in enumerate(rows):
            testnumber = row['TestId']
            if (not testnumber):
                continue
            if (row['Disable'] and row['Disable'].startswith('#')):
                continue
            if args.group:
                if (not row['Group']):
                    continue
                rowgroups = [j.strip() for j in row['Group'].split(',')]
                regexes = [j.strip() for j in args.group.split(',')]
                if (not any([re.match(regex, group) for regex in regexes for group in rowgroups])):
                    continue
            if (justtests and (str(testnumber) not in justtests)):
                continue
            print(f'=====================================================================
testnumber={testnumber!r} {row.get('Description', )}')
            exceptionexpected = (True if row['ExceptionExpected'] else False)
            csvname = (('test_' + str(testnumber)) + '.csv')
            queryargs = []
            for (k, v) in xlstoargs.items():
                if (k not in colheadings):
                    raise Exception(f'Heading {k} not present in spreadsheet!')
                cellvalue = row[k]
                if (cellvalue is not None):
                    if v:
                        cellvalue = str(row[k]).strip()
                        if cellvalue.startswith('-'):
                            queryargs.append(f'{v}={cellvalue}')
                        else:
                            queryargs.append(v)
                            queryargs.append(cellvalue)
                    else:
                        queryargs.append(str(cellvalue).strip())
            if args.save:
                queryargs.extend(['-0', '-O', csvname])
            if args.test:
                queryargs.extend(['-0', '-2', csvname])
            if (args.loglevel and ('-L' not in queryargs)):
                queryargs.extend(['-L', args.loglevel])
            if firstquery:
                if (args.cachecontrol == 1):
                    queryargs.extend(['-W'])
                elif (args.cachecontrol == 2):
                    queryargs.extend(['-WW'])
                firstquery = False
            elif (args.cachecontrol == 2):
                queryargs.extend(['-WW'])
            try:
                if args.dryrun:
                    print(f'Dry-run: query commandline is: oslcquery {argstocmd(queryargs)}')
                    result = 0
                else:
                    print(f'Query commandline is: oslcquery {argstocmd(queryargs)}')
                    result = querymain.do_oslc_query(queryargs)
                exceptionhappened = False
            except Exception as e:
                print(e)
                result = 1
                exceptionhappened = True
            if (((result != 0) and (not exceptionexpected)) or ((result == 0) and exceptionexpected)):
                nfailed += 1
                print(f' TEST {testnumber} FAILED!!!!!!!!!!!!!!!!!!!!!
')
                if args.stoponfail:
                    print(f'Stopping after first failure, {rep} repetitions')
                    return
            else:
                print(f'Test {testnumber} passed!')
                npassed += 1
    if (not args.dryrun):
        print(f'
Passed {npassed} Failed {nfailed}')
    else:
        print(f'Dry run completed')