Пример #1
0
 def test_get_schedules_many_workers_many_schedules(self):
     num_of_jobs = MANY
     num_of_schedules = num_of_jobs
     num_of_workers = num_of_schedules
     num_of_workers = MANY
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     jobs_list = api.get_jobs()
     test_workers = []
     # Create many workers and add them to a list for bookkeeping
     for worker in range(num_of_workers):
         test_workers.append(api.create_worker())
     # Create a schedule belonging to each worker representing the only job
     test_schedules = []
     for worker in test_workers:
         for job in jobs_list:
             test_schedules.append(api.Schedule(datetime.now(),
                                   job, worker))
     api.add_schedules(test_schedules)
     # Aggregate each worker's schedules into a single list for comparison
     # with test schedules
     schedules_for_workers = []
     for worker in test_workers:
         schedules_list = api.get_schedules(worker)
         schedules_for_workers.extend(schedules_list)
     # Verify that the information we get matches what was set
     check_schedule_fields(self, schedules_for_workers,
                           test_schedules)
Пример #2
0
def main():
    uid = os.getuid()

    if len(sys.argv) < 3:
        jobs_old = api.get_jobs_for_user(uid)
        with tempfile.NamedTemporaryFile('w', delete=False) as temp:
            for job in jobs_old:
                temp.write("%s %s\n" % (job.interval, job.command))

            tb_file = temp.name

        editor = os.getenv('EDITOR')
        if editor is not None:
            os.system("%s %s" % (editor, tb_file))
        else:
            subprocess.call("vim %s" % tb_file, shell=True)
    elif sys.argv[1] == '-u':
        tb_file = sys.argv[2]

    jobs_new = []
    with open(tb_file, 'r') as tab:
        for job in tab:
            tmp = job.strip().split(' ')
            interval = string.joinfields(tmp[:5], ' ')
            cmd = string.joinfields(tmp[5:], ' ')
            jobs_new.append(api.Job(interval, cmd, uid, datetime.now()))

    if len(sys.argv) < 3:
        os.unlink(tb_file)

    api.set_jobs(jobs_new, uid)
Пример #3
0
 def test_remove_schedule_many_schedules(self):
     # Number of jobs and floor(requests) + ceiling(requests) are equal
     num_of_jobs = MANY
     num_of_schedules = num_of_jobs
     # Automatic flooring care of Python
     num_of_requests = num_of_jobs / 2
     # Create a crontab with many jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     jobs_list = api.get_jobs()
     test_workers = []
     # Create one worker and add them to a list for bookkeeping
     test_workers.append(api.create_worker())
     # Create a schedule for many jobs
     test_schedules = []
     for schedule in range(num_of_schedules):
         test_schedules.append(api.Schedule(datetime.now(),
                               test_jobs[schedule], test_workers[0]))
     api.add_schedules(test_schedules)
     # Kill the floor of half of the workers in the list
     for request in range(num_of_requests):
         api.remove_schedule(test_schedules.pop())
     schedules_list = api.get_schedules(test_workers[0])
     # Verify that the correct remaining schedules are still in the list
     check_schedule_fields(self, schedules_list, test_schedules)
     # Remove all remaining test schedules
     while test_schedules:
         api.remove_schedule(test_schedules.pop())
     # Try to get schedules from an empty pool
     schedules_list = api.get_schedules(test_workers[0])
     # Verify that the next worker does not exist
     self.assertFalse(len(schedules_list))
Пример #4
0
 def test_remove_schedules_many_schedules_random_schedules(self):
     # Number of jobs and floor(requests) + ceiling(requests) are equal
     num_of_jobs = MANY
     num_of_schedules = num_of_jobs
     # Leave one schedule remaining for comparison at the end
     num_of_requests = num_of_jobs - 1
     # Create a crontab with many jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     jobs_list = api.get_jobs()
     test_workers = []
     # Create one worker and add them to a list for bookkeeping
     test_workers.append(api.create_worker())
     test_schedules = []
     for schedule in range(num_of_schedules):
         test_schedules.append(api.Schedule(datetime.now(),
                               test_jobs[schedule], test_workers[0]))
     api.add_schedules(test_schedules)
     # Kill number of requests random schedules in the list
     for request in range(num_of_requests):
         random_schedule = random.randrange(len(test_schedules))
         api.remove_schedule(test_schedules.pop(random_schedule))
     schedules_list = []
     schedules_list = api.get_schedules(test_workers[0])
     # Verify that the schedules list contains exactly one schedule
     self.assertEqual(len(schedules_list), 1)
     # Verify that the correct remaining schedule is still in the list
     check_schedule_fields(self, schedules_list, test_schedules)
Пример #5
0
 def test_get_jobs_for_user_empty_jobs(self):
     num_of_jobs = ZERO
     # Create a crontab with zero jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     jobs_list_user1 = api.get_jobs_for_user(user1)
     # Verify that the jobs list for user1 is empty
     self.assertFalse(len(jobs_list_user1))
Пример #6
0
 def test_get_crontab_empty_jobs(self):
     num_of_jobs = ZERO
     # Create a crontab with zero jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     crontab = api.get_crontab(user1)
     # Verify that the crontab is empty
     self.assertEqual(crontab, False)
Пример #7
0
 def test_get_jobs_for_user_many_jobs(self):
     num_of_jobs = MANY
     # Create a crontab with many jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     jobs_list_user1 = api.get_jobs_for_user(user1)
     # Verify that the jobs list for user1
     # contains the correct number of jobs
     self.assertEqual(len(jobs_list_user1), num_of_jobs)
Пример #8
0
 def test_get_jobs_many_jobs(self):
     num_of_jobs = MANY
     # Create a crontab with many jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     jobs_list = api.get_jobs()
     self.assertEqual(len(jobs_list), num_of_jobs)
     # Verify that the information we get matches what was set
     check_job_fields(self, jobs_list, test_jobs, user1)
Пример #9
0
 def test_get_jobs_one_job(self):
     num_of_jobs = ONE
     # Create a crontab with one job
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     jobs_list = api.get_jobs()
     # Verify that the jobs list contains exactly one job
     self.assertEqual(len(jobs_list), num_of_jobs)
     # Verify that the information we get matches what was set
     check_job_fields(self, jobs_list, test_jobs, user1)
Пример #10
0
 def test_get_crontab_many_jobs(self):
     num_of_jobs = MANY
     # Create a crontab with many jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     with open(TAB_FILE, 'r') as tabfile:
         crontab = tabfile.read()
     api.set_crontab(crontab, user1)
     test_crontab = api.get_crontab(user1)
     self.assertEqual(crontab, test_crontab)
Пример #11
0
 def test_get_jobs_empty_jobs(self):
     num_of_jobs = ZERO
     # Create a crontab with zero jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     jobs_list = api.get_jobs()
     # Verify that the jobs list is empty
     self.assertEqual(len(jobs_list), num_of_jobs)
     # Verify that the information we get matches what was set
     check_job_fields(self, jobs_list, test_jobs, user1)
Пример #12
0
 def test_get_jobs_for_user_some_users_empty_jobs(self):
     jobs_list_user4 = api.get_jobs_for_user(user4)
     # Verify that the jobs_list for user4 is empty
     self.assertFalse(len(jobs_list_user4))
     num_of_jobs_user1 = ONE
     # Add one job to the tabfile user1
     test_jobs_user1 = create_test_tab(num_of_jobs_user1, user1)
     api.set_jobs(test_jobs_user1, user1)
     jobs_list_user4 = api.get_jobs_for_user(user4)
     # Verify that the jobs_list for user4 is empty
     self.assertFalse(len(jobs_list_user4))
Пример #13
0
 def test_set_crontab_one_job(self):
     num_of_jobs = ONE
     # Create a crontab with one jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     with open(TAB_FILE, 'r') as tabfile:
         crontab = tabfile.read()
     test_crontab = api.get_crontab(user1)
     self.assertEquals(test_crontab, False)
     api.set_crontab(crontab, user1)
     test_crontab = api.get_crontab(user1)
     self.assertEqual(crontab, test_crontab)
Пример #14
0
 def test_set_job_time_one_job(self):
     checkpoint1 = datetime.now()
     num_of_jobs = ONE
     # Create a crontab with one job
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     # Pop the only job in the list to modify its time
     job = test_jobs.pop()
     api.set_job_time(job)
     checkpoint2 = datetime.now()
     # Verify that the job's last time run was updated correctly
     self.assertTrue(job.last_time_run > checkpoint1 and
                     job.last_time_run < checkpoint2)
Пример #15
0
 def test_set_job_time_random_job_from_many(self):
     checkpoint1 = datetime.now()
     num_of_jobs = MANY
     # Create a crontab with many jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     # Pop a random job in list to modify its time
     job = test_jobs.pop(random.randrange(len(test_jobs)))
     api.set_job_time(job)
     checkpoint2 = datetime.now()
     # Verify that the job's last time run was updated correctly
     self.assertTrue(job.last_time_run > checkpoint1 and
                     job.last_time_run < checkpoint2)
Пример #16
0
def process_edits(uid, tb_file, using_local_file, old_tab):
    crontab = []
    jobs = []
    old_jobs = api.get_jobs_for_user(uid)
    with open(tb_file, "r") as tab:
        for line in tab:
            line = line.strip()
            crontab.append(line)
            # Ignore newlines and full line comments
            if line and (line[0] != "#"):
                split = line.split()
                interval = " ".join(split[:5])
                cmd = " ".join(split[5:])
                try:
                    # Ensure the crontab line is valid
                    croniter(interval)
                    if not cmd:
                        raise ValueError
                except (KeyError, ValueError):
                    # Otherwise prompt user to edit crontab
                    e_str = "The crontab you entered has invalid entries, " "would you like to edit it again? (y/n) "
                    while True:
                        cnt = _input(e_str)
                        if (cnt == "n") or (cnt == "N"):
                            if using_local_file is False:
                                os.unlink(tb_file)
                            sys.exit(1)
                        elif (cnt == "y") or (cnt == "Y"):
                            return False
                        e_str = "Please enter y or n: "

                # Check if job was already there
                job = None
                if line in old_tab:
                    for old_job in old_jobs:
                        if old_job.interval == interval and old_job.command == cmd:
                            job = old_job
                            old_jobs.remove(old_job)
                            break
                if not job:
                    old_tab.discard(line)
                    job = api.Job(interval, cmd, uid, datetime.now())
                jobs.append(job)

    if using_local_file is False:
        os.unlink(tb_file)

    api.set_crontab("\n".join(crontab), uid)
    api.set_jobs(jobs, uid)
    return True
Пример #17
0
 def test_set_jobs_empty_jobs(self):
     checkpoint1 = datetime.now()
     num_of_jobs = ZERO
     # Create a crontab with zero jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     # Query metadata for the database file creation time
     db_creation_time = datetime.fromtimestamp(
                        os.stat(api.FILE_NAME).st_mtime)
     # We are comparing different orders of time, so offset by one second
     new_time = db_creation_time.replace(second=db_creation_time.second + 1)
     checkpoint2 = datetime.now()
     checkpoint2 = checkpoint2.replace(second=checkpoint2.second + 1)
     # Verify that the jobs have been set just now
     self.assertTrue(new_time > checkpoint1 and new_time < checkpoint2)
Пример #18
0
 def test_add_schedules_one_job_one_schedule(self):
     num_of_jobs = ONE
     num_of_schedules = num_of_jobs
     # Create a crontab with one job
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     jobs_list = api.get_jobs()
     test_workers = []
     # Create one worker and add them to a list for bookkeeping
     test_workers.append(api.create_worker())
     # Create a schedule for the only job
     test_schedules = []
     test_schedules.append(api.Schedule(datetime.now(), test_jobs[0],
                           test_workers[0]))
     api.add_schedules(test_schedules)
     schedules_list = api.get_schedules(test_workers[0])
     # Verify that the schedules list contains exactly one schedule
     self.assertEqual(len(schedules_list), num_of_schedules)
Пример #19
0
 def test_get_schedules_one_worker_many_schedules(self):
     num_of_jobs = MANY
     num_of_schedules = num_of_jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     jobs_list = api.get_jobs()
     test_workers = []
     # Create one worker and add them to a list for bookkeeping
     test_workers.append(api.create_worker())
     # Create a schedule for the only job
     test_schedules = []
     for job in range(num_of_jobs):
         test_schedules.append(api.Schedule(datetime.now(), test_jobs[job],
                               test_workers[0]))
     api.add_schedules(test_schedules)
     schedules_list = api.get_schedules(test_workers[0])
     # Verify that the information we get matches what was set
     check_schedule_fields(self, schedules_list, test_schedules)
Пример #20
0
 def test_get_crontab_different_users_many_jobs(self):
     num_of_jobs = MANY
     # Create a crontab with many jobs for another user from crontab owner
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     with open(TAB_FILE, 'r') as tabfile:
         crontab = tabfile.read()
     api.set_crontab(crontab, user2)
     test_crontab = api.get_crontab(user2)
     self.assertEqual(crontab, test_crontab)
     # Append crontab for another user
     test_jobs = create_test_tab(num_of_jobs, user3)
     api.set_jobs(test_jobs, user3)
     with open(TAB_FILE, 'r') as tabfile:
         crontab = tabfile.read()
     api.set_crontab(crontab, user3)
     test_crontab = api.get_crontab(user3)
     self.assertEqual(crontab, test_crontab)
Пример #21
0
 def test_remove_schedule_one_schedule(self):
     num_of_jobs = ONE
     num_of_schedules = num_of_jobs
     # Create a crontab with one job
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     jobs_list = api.get_jobs()
     test_workers = []
     # Create one worker and add them to a list for bookkeeping
     test_workers.append(api.create_worker())
     # Create a schedule for the only job
     test_schedules = []
     test_schedules.append(api.Schedule(datetime.now(), test_jobs[0],
                           test_workers[0]))
     api.add_schedules(test_schedules)
     # Kill the only schedule in the list
     api.remove_schedule(test_schedules[0])
     schedules_list = api.get_schedules(test_workers[0])
     # Verify that the schedules list is empty
     self.assertFalse(len(schedules_list))
Пример #22
0
    def test_get_jobs_for_user_different_users_some_jobs(self):
        num_of_jobs_user1 = ONE
        # Add one job to the tabfile for user1
        test_jobs_user1 = create_test_tab(num_of_jobs_user1, user1)
        api.set_jobs(test_jobs_user1, user1)
        jobs_list_user1 = api.get_jobs_for_user(user1)

        num_of_jobs_user2 = ZERO
        # Add zero jobs to the tabfile for user2
        test_jobs_user2 = create_test_tab(num_of_jobs_user2, user2)
        api.set_jobs(test_jobs_user2, user2)
        jobs_list_user2 = api.get_jobs_for_user(user2)

        num_of_jobs_user3 = SOME
        # Add some jobs to the tabfile for user3
        test_jobs_user3 = create_test_tab(num_of_jobs_user3, user3)
        api.set_jobs(test_jobs_user3, user3)
        jobs_list_user3 = api.get_jobs_for_user(user3)

        # Verify that the jobs list for user1 contains
        # the correct number of jobs
        self.assertEqual(len(jobs_list_user1), num_of_jobs_user1)
        # Verify that the jobs list for user2 contains
        # the correct number of jobs
        self.assertEqual(len(jobs_list_user2), num_of_jobs_user2)
        # Verify that the jobs list for user3 contains
        # the correct number of jobs
        self.assertEqual(len(jobs_list_user3), num_of_jobs_user3)
        # Verify that the information we get matches what was set
        check_job_fields(self, jobs_list_user1, test_jobs_user1, user1)
        # Verify that the information we get matches what was set
        check_job_fields(self, jobs_list_user2, test_jobs_user2, user2)
        # Verify that the information we get matches what was set
        check_job_fields(self, jobs_list_user3, test_jobs_user3, user3)
Пример #23
0
def main():
    tb_file = None
    valid_crontab = None
    usr_euid = os.geteuid()
    opts = parse_args()

    # Convert given username into (uid, username)
    if opts.usr:
        try:
            opts.usr = (pwd.getpwnam(opts.usr).pw_uid, opts.usr)
        except KeyError:
            sys.exit("User '%s' does not exist." % opts.usr)

        # Verify permissions for selected crontab
        if (usr_euid != 0) and (opts.usr[0] != usr_euid):
            sys.exit("Access denied. You do not have permission to edit %s's " "crontab." % opts.usr[1])
    # If no user is specified, set to current user (euid or uid?)
    else:
        opts.usr = (usr_euid, pwd.getpwuid(usr_euid).pw_name)

    # Perform rm operation
    if opts.rm:
        if opts.rm_prompt:
            rm = None
            e_str = "You are about to delete %s's crontab, continue? " "(y/n) " % opts.usr[1]
            while (rm != "Y") and (rm != "y"):
                rm = _input(e_str)
                if (rm == "N") or (rm == "n"):
                    sys.exit(0)
                e_str = "Please enter y or n: "

        api.set_jobs([], opts.usr[0])
        api.set_crontab(False, opts.usr[0])
        sys.exit(0)

    while not valid_crontab:
        tb_file, old_tab = get_crontab(opts, valid_crontab, tb_file)
        valid_crontab = process_edits(opts.usr[0], tb_file, opts.file, old_tab)
Пример #24
0
def main():
    tb_file = None
    valid_crontab = None
    usr_euid = os.geteuid()
    opts = parse_args()

    # Convert given username into (uid, username)
    if opts.usr:
        try:
            opts.usr = (pwd.getpwnam(opts.usr).pw_uid, opts.usr)
        except KeyError:
            sys.exit("User `%s' does not exist." % opts.usr)
    # If no user is specified, set to current user (euid or uid?)
    else:
        opts.usr = (usr_euid, pwd.getpwuid(usr_euid).pw_name)

    check_permissions(opts.usr, usr_euid)

    # Perform rm operation
    if opts.rm:
        if opts.rm_prompt:
            rm = None
            e_str = ("You are about to delete %s's crontab, continue? "
                     "(y/n) " % opts.usr[1])
            while (rm != 'Y') and (rm != 'y'):
                rm = _input(e_str)
                if (rm == 'N') or (rm == 'n'):
                    sys.exit(0)
                e_str = "Please enter y or n: "

        api.set_jobs([], opts.usr[0])
        api.set_crontab(False, opts.usr[0])
        sys.exit(0)

    while not valid_crontab:
        tb_file, old_tab = get_crontab(opts, valid_crontab, tb_file)
        valid_crontab = process_edits(opts.usr[0], tb_file, opts.file, old_tab)
Пример #25
0
def test_set_jobs():
    api.set_jobs(test_jobs, uid)
Пример #26
0
def process_edits(uid, tb_file, using_local_file, old_tab):
    e_str = ""
    jobs = []
    crontab = []
    old_jobs = api.get_jobs_for_user(uid)
    with open(tb_file, 'r') as tab:
        for i, line in enumerate(tab):
            line = line.strip()
            crontab.append(line)
            # Ignore newlines and comments
            if line and (line[0] != '#'):
                split = line.split()
                # Check for special interval syntax
                if split[0][0] == '@':
                    try:
                        interval = _special_intervals[split[0]]
                    except KeyError:
                        e_str += ("Error in line %i: Bad special interval "
                                  "syntax, %s\n" % (i + 1, split[0]))
                        continue
                    cmd = ' '.join(split[1:])

                # Check if setting variable
                elif '=' in ''.join(split[:5]):
                    name, _, value = line.partition('=')

                    # Check if var name is zero or multiple words
                    name = name.strip()
                    num_names = len(name.split())
                    if num_names != 1:
                        if num_names:
                            e_str += ("Error in line %i: Bad variable "
                                      "assignment syntax; multiple variable "
                                      "names given\n" % (i + 1))
                        else:
                            e_str += ("Error in line %i: Bad variable "
                                      "assignment syntax; no variable name "
                                      "given\n" % (i + 1))
                    else:
                        value = value.strip()
                        if (((value[0] == "'") or (value[0] == '"')) and
                           (value[-1] == value[0])):
                            # If properly wrapped in quotes, check if escaped
                            for i, char in enumerate(reversed(value[:-1])):
                                if char != '\\':
                                    i += 1
                                    break
                            if i % 2 != 0:
                                value = value[1:-1]
                        os.environ[name] = value
                    continue

                else:
                    # Check if five or six time/date fields
                    if (len(split) > 5 and
                            not any(c.isalpha() for c in split[5]) and
                            ('*' in split[5] or
                             any(c.isdigit() for c in split[5])) and
                            split[5][0] != '/'):
                        # Could print warning that using 6 time fields
                        interval = ' '.join(split[:6])
                        cmd = ' '.join(split[6:])
                    else:
                        interval = ' '.join(split[:5])
                        cmd = ' '.join(split[5:])

                # Check for un-escaped %s in command
                job_input = None
                index = cmd.find('%')
                while (index != -1) and (cmd[index-1] == '\\'):
                    index = cmd.find('%', index + 1)
                if index != -1:
                    job_input = _escaped_pct.sub('%', _unescaped_pct.sub(
                                                 r"\1\n", cmd[index+1:]))
                    cmd = cmd[:index]
                cmd = _escaped_pct.sub('%', cmd)

                # Ensure the crontab line is valid
                try:
                    croniter(interval)
                    if not cmd:
                        raise ValueError("Missing command")
                except (KeyError, ValueError) as e:
                    if isinstance(e, KeyError):
                        e = "Bad time interval syntax, %s " % e
                    # Replace croniter's typo-riddled error msg
                    elif str(e) == ("Exactly 5 or 6 columns has to be "
                                    "specified for iteratorexpression."):
                        e = ("Less than 5 fields separated by whitespace in "
                             "the time interval (requires 5 or 6)")
                    e_str += "Error in line %i: %s\n" % (i + 1, e)
                else:
                    if not e_str:
                        job = None
                        # Check if job was in the old crontab
                        if line in old_tab:
                            for old_job in old_jobs:
                                if (old_job.interval == interval and
                                        old_job.command == cmd and
                                        old_job.job_input == job_input and
                                        old_job.environment == os.environ):
                                    job = old_job
                                    old_jobs.remove(old_job)
                                    break
                        if not job:
                            old_tab.discard(line)
                            job = api.Job(interval, cmd, uid,
                                          os.environ.copy(), job_input,
                                          datetime.now())
                        jobs.append(job)
    # Prompt user to edit crontab on error
    if e_str:
        e_str += ("The crontab you entered has invalid entries, "
                  "would you like to edit it again? (y/n) ")
        while True:
            cnt = _input(e_str)
            if (cnt == 'n') or (cnt == 'N'):
                if using_local_file is False:
                    os.unlink(tb_file)
                sys.exit(1)
            elif (cnt == 'y') or (cnt == 'Y'):
                return False
            e_str = "Please enter y or n: "

    if using_local_file is False:
        os.unlink(tb_file)

    api.set_crontab('\n'.join(crontab), uid)
    api.set_jobs(jobs, uid)
    return True