Example #1
0
    def test_alpha_char_rejected(self):
        # Check the single case first
        with self.assertRaises(SyntaxError):
            input_processing.parse_user_run_numbers('a')

        # Check all individual characters
        for char in string.ascii_letters:
            with self.assertRaises(SyntaxError):
                input_processing.parse_user_run_numbers(char)
Example #2
0
    def test_list_case(self):
        input_value = "10-20"
        # Returns inclusive values
        expected_value = list(range(10, 21))

        result = input_processing.parse_user_run_numbers(input_value)
        self.assertEqual(expected_value, result)
Example #3
0
 def test_excessive_range(self):
     input_string = "-5-2-3"
     with self.assertRaises(SyntaxError):
         input_processing.parse_user_run_numbers(input_string)
Example #4
0
    def test_negative_ranges(self):
        input_string = "-5-2"
        expected_val = list(range(-5, 2 + 1))

        result = input_processing.parse_user_run_numbers(input_string)
        self.assertEqual(expected_val, result)
Example #5
0
    def test_negative_numbers(self):
        input_string = "-10"
        expected_val = [-10]

        result = input_processing.parse_user_run_numbers(input_string)
        self.assertEqual(expected_val, result)
Example #6
0
    def test_mixed_list(self):
        input_string = "10,20-22,30"
        expected_vals = [10, 20, 21, 22, 30]

        result = input_processing.parse_user_run_numbers(input_string)
        self.assertEqual(expected_vals, result)
Example #7
0
    def test_commas(self):
        input_string = "10,15,20"
        expected_vals = [10, 15, 20]

        result = input_processing.parse_user_run_numbers(input_string)
        self.assertEqual(expected_vals, result)
Example #8
0
    def test_single_value_case(self):
        input_value = "101"
        expected_value = [int(input_value)]

        result = input_processing.parse_user_run_numbers(input_value)
        self.assertEqual(expected_value, result)
Example #9
0
 def test_empty_input(self):
     input_value = ""
     with self.assertRaises(SyntaxError):
         input_processing.parse_user_run_numbers(input_value)
Example #10
0
def run_confirmation(request, instrument):
    """
    Handles request for user to confirm re-run
    """
    if request.method != 'POST':
        return redirect('instrument_summary', instrument=instrument.name)

    # POST
    # pylint:disable=no-member
    instrument = Instrument.objects.get(name=instrument)
    range_string = request.POST.get('run_range')

    queued_status = StatusUtils().get_queued()
    # pylint:disable=no-member
    queue_count = ReductionRun.objects.filter(instrument=instrument,
                                              status=queued_status).count()
    context_dictionary = {
        'runs': [],
        'variables': None,
        'queued': queue_count,
    }

    try:
        run_numbers = input_processing.parse_user_run_numbers(range_string)
    except SyntaxError as exception:
        context_dictionary['error'] = exception.msg
        return context_dictionary

    # Determine user level to set a maximum limit to the number of runs that can be re-queued
    if request.user.is_superuser:
        max_runs = 500
    elif request.user.is_staff:
        max_runs = 50
    else:
        max_runs = 20

    if len(run_numbers) > max_runs:
        context_dictionary["error"] = "{0} runs were requested, but only {1} runs can be " \
                                      "queued at a time".format(len(run_numbers), max_runs)
        return context_dictionary

    # Check that RB numbers are the same for the range entered
    # pylint:disable=no-member
    rb_number = ReductionRun.objects.filter(instrument=instrument, run_number__in=run_numbers) \
        .values_list('experiment__reference_number', flat=True).distinct()
    if len(rb_number) > 1:
        context_dictionary['error'] = 'Runs span multiple experiment numbers ' \
                                      '(' + ','.join(str(i) for i in rb_number) + ')' \
                                      ' please select a different range.'
        return context_dictionary

    for run_number in run_numbers:
        # pylint:disable=no-member
        matching_previous_runs_queryset = ReductionRun.objects.\
            filter(instrument=instrument,
                   run_number=run_number).order_by('-run_version')
        most_recent_previous_run = matching_previous_runs_queryset.first()

        # Check old run exists
        if most_recent_previous_run is None:
            context_dictionary['error'] = "Run number %s hasn't been" \
                                          "ran by autoreduction yet." % str(run_number)

        # Check it is not currently queued
        queued_runs = matching_previous_runs_queryset.filter(
            status=queued_status).first()
        if queued_runs is not None:
            context_dictionary['error'] = "Run number {0} is already queued to run".\
                format(queued_runs.run_number)
            return context_dictionary

        use_current_script = request.POST.get('use_current_script',
                                              u"true").lower() == u"true"
        if use_current_script:
            script_text = InstrumentVariablesUtils().get_current_script_text(
                instrument.name)[0]
            default_variables = InstrumentVariablesUtils(
            ).get_default_variables(instrument.name)
        else:
            script_text = most_recent_previous_run.script
            default_variables = most_recent_previous_run.run_variables.all()

        new_variables = []

        for key, value in list(request.POST.items()):
            if 'var-' in key:
                name = None
                if 'var-advanced-' in key:
                    name = key.replace('var-advanced-', '').replace('-', ' ')
                    is_advanced = True
                if 'var-standard-' in key:
                    name = key.replace('var-standard-', '').replace('-', ' ')
                    is_advanced = False

                if name is not None:
                    default_var = next(
                        (x for x in default_variables if x.name == name), None)
                    if not default_var:
                        continue
                    # pylint:disable=protected-access,no-member
                    if len(value) > InstrumentVariable._meta.get_field(
                            'value').max_length:
                        context_dictionary['error'] = 'Value given in {} is too long.'\
                            .format(str(name))
                    variable = RunVariable(name=default_var.name,
                                           value=value,
                                           is_advanced=is_advanced,
                                           type=default_var.type,
                                           help_text=default_var.help_text)
                    new_variables.append(variable)

        if not new_variables:
            context_dictionary[
                'error'] = 'No variables were found to be submitted.'

        # User can choose whether to overwrite with the re-run or create new data
        overwrite_previous_data = bool(
            request.POST.get('overwrite_checkbox') == 'on')

        if 'error' in context_dictionary:
            return context_dictionary

        run_description = request.POST.get('run_description')
        max_desc_len = 200
        if len(run_description) > max_desc_len:
            context_dictionary["error"] = "The description contains {0} characters, " \
                                          "a maximum of {1} are allowed".\
                format(len(run_description), max_desc_len)
            return context_dictionary

        new_job = ReductionRunUtils().createRetryRun(
            user_id=request.user.id,
            reduction_run=most_recent_previous_run,
            script=script_text,
            overwrite=overwrite_previous_data,
            variables=new_variables,
            description=run_description)

        try:
            MessagingUtils().send_pending(new_job)
            context_dictionary['runs'].append(new_job)
            context_dictionary['variables'] = new_variables

        # pylint:disable=broad-except
        except Exception as exception:
            new_job.delete()
            context_dictionary['error'] = 'Failed to send new job. (%s)' % str(
                exception)

    return context_dictionary