def get(self, request, form_initial=None, is_cloning=False): plan_id = request.GET.get("p") # note: ordered by pk for test_show_create_new_run_page() test_cases = (TestCase.objects.filter( pk__in=request.GET.getlist("c")).select_related( "author", "case_status", "category", "priority").order_by("pk")) test_plan = TestPlan.objects.filter(pk=plan_id).first() if not form_initial: form_initial = { "summary": f"Test run for {test_plan.name}" if test_plan else "", "manager": test_plan.author.email if test_plan else "", "default_tester": request.user.email, "notes": "", "plan": plan_id, } form = NewRunForm(initial=form_initial) form.populate(plan_id) context_data = { "plan_id": plan_id, # used for UI conditionals "test_cases": test_cases, "form": form, "disabled_cases": get_disabled_test_cases_count(test_cases), "is_cloning": is_cloning, } return render(request, self.template_name, context_data)
def create(values): """ .. function:: RPC TestRun.create(values) Create new TestRun object and store it in the database. :param values: Field values for :class:`tcms.testruns.models.TestRun` :type values: dict :return: Serialized :class:`tcms.testruns.models.TestRun` object :rtype: dict :raises PermissionDenied: if missing *testruns.add_testrun* permission :raises ValueError: if data validations fail Example:: >>> values = {'build': 384, 'manager': 137, 'plan': 137, 'summary': 'Testing XML-RPC for TCMS', } >>> TestRun.create(values) """ form = NewRunForm(values) form.populate(values.get('plan')) if form.is_valid(): test_run = form.save() return test_run.serialize() raise ValueError(form_errors_to_list(form))
def create(values): """ .. function:: RPC TestRun.create(values) Create new TestRun object and store it in the database. :param values: Field values for :class:`tcms.testruns.models.TestRun` :type values: dict :return: Serialized :class:`tcms.testruns.models.TestRun` object :rtype: dict :raises PermissionDenied: if missing *testruns.add_testrun* permission :raises ValueError: if data validations fail Example:: >>> values = {'build': 384, 'manager': 137, 'plan': 137, 'summary': 'Testing XML-RPC for TCMS', } >>> TestRun.create(values) """ form = NewRunForm(values) form.populate(values.get("plan")) if form.is_valid(): test_run = form.save() result = model_to_dict(test_run, exclude=["cc", "tag"]) # b/c value is set in the DB directly and if None # model_to_dict() will not return it result["start_date"] = test_run.start_date return result raise ValueError(form_errors_to_list(form))
def post(self, request): form = NewRunForm(data=request.POST) form.populate(request.POST.get("plan")) if form.is_valid(): test_run = form.save() # copy all of the selected properties into the test run for prop in EnvironmentProperty.objects.filter( environment__in=form.cleaned_data["environment"]): test_run.property_set.create(name=prop.name, value=prop.value) loop = 1 for case in form.cleaned_data["case"]: try: tcp = TestCasePlan.objects.get( plan=form.cleaned_data["plan"], case=case) sortkey = tcp.sortkey except ObjectDoesNotExist: sortkey = loop * 10 test_run.create_execution( case=case, assignee=form.cleaned_data["default_tester"], sortkey=sortkey, matrix_type=form.cleaned_data["matrix_type"], ) loop += 1 return HttpResponseRedirect( reverse( "testruns-get", args=[ test_run.pk, ], )) test_cases = (TestCase.objects.filter( pk__in=request.POST.getlist("case")).select_related( "author", "case_status", "category", "priority").order_by("pk")) context_data = { "plan_id": request.POST.get("plan"), "test_cases": test_cases, "form": form, "disabled_cases": get_disabled_test_cases_count(test_cases), } return render(request, self.template_name, context_data)
def get(self, request, form_initial=None, is_cloning=False): plan_id = request.GET.get("p") if not plan_id: messages.add_message( request, messages.ERROR, _("Creating a TestRun requires a TestPlan, select one"), ) return HttpResponseRedirect(reverse("plans-search")) if not request.GET.get("c"): messages.add_message( request, messages.ERROR, _("Creating a TestRun requires at least one TestCase"), ) return HttpResponseRedirect( reverse("test_plan_url_short", args=[plan_id])) test_cases = TestCase.objects.filter(pk__in=request.GET.getlist("c")) # note: ordered by pk for test_show_create_new_run_page() tcs_values = test_cases.select_related("author", "case_status", "category", "priority").order_by("pk") test_plan = TestPlan.objects.get(pk=plan_id) if not form_initial: form_initial = { "summary": "Test run for %s" % test_plan.name, "manager": test_plan.author.email, "default_tester": request.user.email, "notes": "", "plan": plan_id, } form = NewRunForm(initial=form_initial) form.populate(plan_id) context_data = { "test_cases": tcs_values, "form": form, "disabled_cases": get_disabled_test_cases_count(test_cases), "is_cloning": is_cloning, } return render(request, self.template_name, context_data)
def post(self, request): form = NewRunForm(data=request.POST) form.populate(request.POST.get("plan")) if form.is_valid(): test_run = form.save() loop = 1 for case in form.cleaned_data["case"]: try: tcp = TestCasePlan.objects.get( plan=form.cleaned_data["plan"], case=case) sortkey = tcp.sortkey except ObjectDoesNotExist: sortkey = loop * 10 test_run.create_execution( case=case, sortkey=sortkey, assignee=form.cleaned_data["default_tester"], ) loop += 1 return HttpResponseRedirect( reverse( "testruns-get", args=[ test_run.pk, ], )) test_cases = TestCase.objects.filter( pk__in=request.POST.getlist("case")) tcs_values = test_cases.select_related("author", "case_status", "category", "priority").order_by("pk") context_data = { "test_cases": tcs_values, "form": form, "disabled_cases": get_disabled_test_cases_count(test_cases), } return render(request, self.template_name, context_data)
def clone(request, run_id): """Clone cases from filter caserun""" test_run = get_object_or_404(TestRun, run_id=run_id) confirmed_case_status = TestCaseStatus.get_confirmed() disabled_cases = 0 if request.POST.get('case_run'): test_cases = [] for test_case_run in test_run.case_run.filter( pk__in=request.POST.getlist('case_run')): if test_case_run.case.case_status == confirmed_case_status: test_cases.append(test_case_run.case) else: disabled_cases += 1 else: test_cases = None if not test_cases: messages.add_message(request, messages.ERROR, _('At least one TestCase is required')) return HttpResponseRedirect(reverse('testruns-get', args=[run_id])) form = NewRunForm( initial={ 'summary': _('Clone of ') + test_run.summary, 'notes': test_run.notes, 'manager': test_run.manager, 'build': test_run.build_id, 'default_tester': test_run.default_tester, }) form.populate(product_id=test_run.plan.product_id) context_data = { 'is_cloning': True, 'disabled_cases': disabled_cases, 'test_plan': test_run.plan, 'test_cases': test_cases, 'form': form, } return render(request, 'testruns/mutable.html', context_data)
def get(self, request, form_initial=None, is_cloning=False): plan_id = request.GET.get('p') if not plan_id: messages.add_message( request, messages.ERROR, _('Creating a TestRun requires a TestPlan, select one')) return HttpResponseRedirect(reverse('plans-search')) if not request.GET.get('c'): messages.add_message( request, messages.ERROR, _('Creating a TestRun requires at least one TestCase')) return HttpResponseRedirect( reverse('test_plan_url_short', args=[plan_id])) test_cases = TestCase.objects.filter(pk__in=request.GET.getlist('c')) # note: ordered by pk for test_show_create_new_run_page() tcs_values = test_cases.select_related('author', 'case_status', 'category', 'priority').order_by('pk') test_plan = TestPlan.objects.get(pk=plan_id) if not form_initial: form_initial = { 'summary': 'Test run for %s' % test_plan.name, 'manager': test_plan.author.email, 'default_tester': request.user.email, 'notes': '', 'plan': plan_id, } form = NewRunForm(initial=form_initial) form.populate(plan_id) context_data = { 'test_cases': tcs_values, 'form': form, 'disabled_cases': get_disabled_test_cases_count(test_cases), 'is_cloning': is_cloning, } return render(request, self.template_name, context_data)
def post(self, request): form = NewRunForm(data=request.POST) form.populate(request.POST.get('plan')) if form.is_valid(): test_run = form.save() loop = 1 for case in form.cleaned_data['case']: try: tcp = TestCasePlan.objects.get( plan=form.cleaned_data['plan'], case=case) sortkey = tcp.sortkey except ObjectDoesNotExist: sortkey = loop * 10 test_run.create_execution( case=case, sortkey=sortkey, assignee=form.cleaned_data['default_tester']) loop += 1 return HttpResponseRedirect( reverse('testruns-get', args=[ test_run.pk, ])) test_cases = TestCase.objects.filter( pk__in=request.POST.getlist('case')) tcs_values = test_cases.select_related('author', 'case_status', 'category', 'priority').order_by('pk') context_data = { 'test_cases': tcs_values, 'form': form, 'disabled_cases': get_disabled_test_cases_count(test_cases) } return render(request, self.template_name, context_data)
def post(self, request, pk): test_run = get_object_or_404(TestRun, pk=pk) confirmed_case_status = TestCaseStatus.get_confirmed() disabled_cases = 0 if request.POST.get('case_run'): test_cases = [] for test_case_run in test_run.case_run.filter( pk__in=request.POST.getlist('case_run')): if test_case_run.case.case_status == confirmed_case_status: test_cases.append(test_case_run.case) else: disabled_cases += 1 else: test_cases = None if not test_cases: messages.add_message(request, messages.ERROR, _('At least one TestCase is required')) return HttpResponseRedirect(reverse('testruns-get', args=[pk])) form = NewRunForm( initial={ 'summary': _('Clone of ') + test_run.summary, 'notes': test_run.notes, 'manager': test_run.manager, 'build': test_run.build_id, 'default_tester': test_run.default_tester, 'plan': test_run.plan }) form.populate(test_run.plan_id) context_data = { 'is_cloning': True, 'disabled_cases': disabled_cases, 'test_cases': test_cases, 'form': form, } return render(request, self.template_name, context_data)
def new(request): """Display the create test run page.""" # If from_plan does not exist will redirect to plans for select a plan if not request.POST.get('from_plan'): messages.add_message( request, messages.ERROR, _('Creating a TestRun requires a TestPlan, select one')) return HttpResponseRedirect(reverse('plans-search')) plan_id = request.POST.get('from_plan') # case is required by a test run # NOTE: currently this is handled in JavaScript but in the TestRun creation # form cases can be deleted if not request.POST.get('case'): messages.add_message( request, messages.ERROR, _('Creating a TestRun requires at least one TestCase')) return HttpResponseRedirect( reverse('test_plan_url_short', args=[plan_id])) # Ready to write cases to test plan test_cases = get_selected_testcases(request) test_plan = TestPlan.objects.get(plan_id=plan_id) # note: ordered by case_id for test_show_create_new_run_page() tcs_values = test_cases.select_related('author', 'case_status', 'category', 'priority').order_by('case_id') if request.POST.get('POSTING_TO_CREATE'): form = NewRunForm(request.POST) form.populate(product_id=test_plan.product_id) if form.is_valid(): # Process the data in form.cleaned_data default_tester = form.cleaned_data['default_tester'] test_run = TestRun.objects.create( product_version=test_plan.product_version, stop_date=None, summary=form.cleaned_data.get('summary'), notes=form.cleaned_data.get('notes'), plan=test_plan, build=form.cleaned_data['build'], manager=form.cleaned_data['manager'], default_tester=default_tester, ) try: assignee_tester = User.objects.get(username=default_tester) except ObjectDoesNotExist: assignee_tester = None loop = 1 for case in form.cleaned_data['case']: try: tcp = TestCasePlan.objects.get(plan=test_plan, case=case) sortkey = tcp.sortkey except ObjectDoesNotExist: sortkey = loop * 10 test_run.add_case_run(case=case, sortkey=sortkey, assignee=assignee_tester) loop += 1 return HttpResponseRedirect( reverse('testruns-get', args=[ test_run.run_id, ])) else: form = NewRunForm( initial={ 'summary': 'Test run for %s' % test_plan.name, 'manager': test_plan.author.email, 'default_tester': request.user.email, 'notes': '', }) form.populate(product_id=test_plan.product_id) context_data = { 'test_plan': test_plan, 'test_cases': tcs_values, 'form': form, } return render(request, 'testruns/mutable.html', context_data)
def new(request, template_name='run/new.html'): """Display the create test run page.""" # If from_plan does not exist will redirect to plans for select a plan if not request.POST.get('from_plan'): return HttpResponseRedirect(reverse('plans-all')) plan_id = request.POST.get('from_plan') # case is required by a test run # NOTE: currently this is handled in JavaScript but in the TestRun creation # form cases can be deleted if not request.POST.get('case'): messages.add_message( request, messages.ERROR, _('Creating a TestRun requires at least one TestCase')) return HttpResponseRedirect( reverse('test_plan_url_short', args=[plan_id])) # Ready to write cases to test plan confirm_status = TestCaseStatus.get_CONFIRMED() test_cases = get_selected_testcases(request) # FIXME: optimize this query, only get necessary columns, not all fields # are necessary test_plan = TestPlan.objects.select_related().get(plan_id=plan_id) test_case_runs = TestCaseRun.objects.filter( case_run_id__in=request.POST.getlist('case_run_id')) num_unconfirmed_cases = test_cases.exclude( case_status=confirm_status).count() estimated_time = datetime.timedelta(seconds=0) tcs_values = test_cases.select_related('author', 'case_status', 'category', 'priority') # note: ordered for test_show_create_new_run_page() on PostgreSQL tcs_values = tcs_values.only('case_id', 'summary', 'estimated_time', 'author__email', 'create_date', 'category__name', 'priority__value', 'case_status__name').order_by('case_id') if request.POST.get('POSTING_TO_CREATE'): form = NewRunForm(request.POST) form.populate( product_id=request.POST.get('product', test_plan.product_id)) if form.is_valid(): # Process the data in form.cleaned_data default_tester = form.cleaned_data['default_tester'] test_run = TestRun.objects.create( product_version=form.cleaned_data['product_version'], stop_date=None, summary=form.cleaned_data.get('summary'), notes=form.cleaned_data.get('notes'), plan=test_plan, build=form.cleaned_data['build'], manager=form.cleaned_data['manager'], default_tester=default_tester, estimated_time=form.cleaned_data['estimated_time'], auto_update_run_status=form. cleaned_data['auto_update_run_status']) keep_status = form.cleaned_data['keep_status'] keep_assign = form.cleaned_data['keep_assignee'] try: assignee_tester = User.objects.get(username=default_tester) except ObjectDoesNotExist: assignee_tester = None loop = 1 # not reserve assignee and status, assignee will default set to # default_tester if not keep_assign and not keep_status: for case in form.cleaned_data['case']: try: tcp = TestCasePlan.objects.get(plan=test_plan, case=case) sortkey = tcp.sortkey except ObjectDoesNotExist: sortkey = loop * 10 test_run.add_case_run(case=case, sortkey=sortkey, assignee=assignee_tester) loop += 1 # Add case to the run for test_case_run in test_case_runs: if (keep_status and keep_assign): test_run.add_case_run( case=test_case_run.case, assignee=test_case_run.assignee, case_run_status=test_case_run.case_run_status, sortkey=test_case_run.sortkey or loop * 10) loop += 1 elif keep_status and not keep_assign: test_run.add_case_run( case=test_case_run.case, case_run_status=test_case_run.case_run_status, sortkey=test_case_run.sortkey or loop * 10) loop += 1 elif keep_assign and not keep_status: test_run.add_case_run(case=test_case_run.case, assignee=test_case_run.assignee, sortkey=test_case_run.sortkey or loop * 10) loop += 1 # Write the values into tcms_env_run_value_map table env_property_id_set = set(request.POST.getlist("env_property_id")) if env_property_id_set: args = list() for property_id in env_property_id_set: checkbox_name = 'select_property_id_%s' % property_id select_name = 'select_property_value_%s' % property_id checked = request.POST.getlist(checkbox_name) if checked: env_values = request.POST.getlist(select_name) if not env_values: continue if len(env_values) != len(checked): raise ValueError('Invalid number of env values.') for value_id in env_values: args.append( EnvRunValueMap(run=test_run, value_id=value_id)) EnvRunValueMap.objects.bulk_create(args) return HttpResponseRedirect( reverse('testruns-get', args=[ test_run.run_id, ])) else: estimated_time = reduce(lambda x, y: x + y, (tc.estimated_time for tc in tcs_values)) form = NewRunForm( initial={ 'summary': 'Test run for %s on %s' % (test_plan.name, test_plan.env_group.all() and test_plan.env_group.all()[0] or 'Unknown environment'), 'estimated_time': estimated_time, 'manager': test_plan.author.email, 'default_tester': request.user.email, 'product': test_plan.product_id, 'product_version': test_plan.product_version_id, }) form.populate(product_id=test_plan.product_id) # FIXME: pagination cases within Create New Run page. context_data = { 'from_plan': plan_id, 'test_plan': test_plan, 'test_cases': tcs_values, 'form': form, 'num_unconfirmed_cases': num_unconfirmed_cases, 'run_estimated_time': estimated_time.total_seconds(), } return render(request, template_name, context_data)
def post(self, request): # If from_plan does not exist will redirect to plans for select a plan plan_id = request.POST.get('from_plan') if not plan_id: messages.add_message( request, messages.ERROR, _('Creating a TestRun requires a TestPlan, select one')) return HttpResponseRedirect(reverse('plans-search')) if not request.POST.get('case'): messages.add_message( request, messages.ERROR, _('Creating a TestRun requires at least one TestCase')) return HttpResponseRedirect( reverse('test_plan_url_short', args=[plan_id])) # Ready to write cases to test plan test_cases = get_selected_testcases(request) test_plan = TestPlan.objects.get(pk=plan_id) # note: ordered by pk for test_show_create_new_run_page() tcs_values = test_cases.select_related('author', 'case_status', 'category', 'priority').order_by('pk') if request.POST.get('POSTING_TO_CREATE'): form = NewRunForm(request.POST) form.populate(product_id=test_plan.product_id) if form.is_valid(): # Process the data in form.cleaned_data default_tester = form.cleaned_data['default_tester'] test_run = TestRun.objects.create( product_version=test_plan.product_version, stop_date=None, summary=form.cleaned_data.get('summary'), notes=form.cleaned_data.get('notes'), plan=test_plan, build=form.cleaned_data['build'], manager=form.cleaned_data['manager'], default_tester=default_tester, ) loop = 1 for case in form.cleaned_data['case']: try: tcp = TestCasePlan.objects.get(plan=test_plan, case=case) sortkey = tcp.sortkey except ObjectDoesNotExist: sortkey = loop * 10 test_run.create_execution(case=case, sortkey=sortkey, assignee=default_tester) loop += 1 return HttpResponseRedirect( reverse('testruns-get', args=[ test_run.pk, ])) else: form = NewRunForm( initial={ 'summary': 'Test run for %s' % test_plan.name, 'manager': test_plan.author.email, 'default_tester': request.user.email, 'notes': '', }) form.populate(product_id=test_plan.product_id) context_data = { 'test_plan': test_plan, 'test_cases': tcs_values, 'form': form, } return render(request, self.template_name, context_data)
def new(request, template_name='run/new.html'): """Display the create test run page.""" SUB_MODULE_NAME = "new_run" # If from_plan does not exist will redirect to plans for select a plan if not request.POST.get('from_plan'): return HttpResponseRedirect(reverse('plans-all')) plan_id = request.POST.get('from_plan') # Case is required by a test run if not request.POST.get('case'): return prompt.info(request, 'At least one case is required by a run.', reverse('plan-get', args=[plan_id])) # Ready to write cases to test plan confirm_status = TestCaseStatus.get('CONFIRMED') tcs = get_selected_testcases(request) # FIXME: optimize this query, only get necessary columns, not all fields # are necessary tp = TestPlan.objects.select_related().get(plan_id=plan_id) tcrs = TestCaseRun.objects.filter( case_run_id__in=request.POST.getlist('case_run_id')) num_unconfirmed_cases = tcs.exclude(case_status=confirm_status).count() estimated_time = datetime.timedelta(seconds=0) tcs_values = tcs.select_related('author', 'case_status', 'category', 'priority').only( 'case_id', 'summary', 'create_date', 'estimated_time', 'author__email', 'case_status__name', 'priority__value', 'category__name').order_by('case_id') if request.POST.get('POSTING_TO_CREATE'): form = NewRunForm(request.POST) if request.POST.get('product'): form.populate(product_id=request.POST['product']) else: form.populate(product_id=tp.product_id) if form.is_valid(): # Process the data in form.cleaned_data default_tester = form.cleaned_data['default_tester'] tr = TestRun.objects.create( product_version=form.cleaned_data['product_version'], plan_text_version=tp.latest_text() and tp.latest_text().plan_text_version or 0, stop_date=None, summary=form.cleaned_data.get('summary'), notes=form.cleaned_data.get('notes'), plan=tp, build=form.cleaned_data['build'], manager=form.cleaned_data['manager'], default_tester=default_tester, estimated_time=form.cleaned_data['estimated_time'], auto_update_run_status=form. cleaned_data['auto_update_run_status']) keep_status = form.cleaned_data['keep_status'] keep_assign = form.cleaned_data['keep_assignee'] try: assignee_tester = User.objects.get(username=default_tester) except ObjectDoesNotExist: assignee_tester = None loop = 1 # not reserve assignee and status, assignee will default set to # default_tester if not keep_assign and not keep_status: for case in form.cleaned_data['case']: try: tcp = TestCasePlan.objects.get(plan=tp, case=case) sortkey = tcp.sortkey except ObjectDoesNotExist: sortkey = loop * 10 tr.add_case_run(case=case, sortkey=sortkey, assignee=assignee_tester) loop += 1 # Add case to the run for tcr in tcrs: if (keep_status and keep_assign): tr.add_case_run(case=tcr.case, assignee=tcr.assignee, case_run_status=tcr.case_run_status, sortkey=tcr.sortkey or loop * 10) loop += 1 elif keep_status and not keep_assign: tr.add_case_run(case=tcr.case, case_run_status=tcr.case_run_status, sortkey=tcr.sortkey or loop * 10) loop += 1 elif keep_assign and not keep_status: tr.add_case_run(case=tcr.case, assignee=tcr.assignee, sortkey=tcr.sortkey or loop * 10) loop += 1 # Write the values into tcms_env_run_value_map table env_property_id_set = set(request.POST.getlist("env_property_id")) if env_property_id_set: args = list() for property_id in env_property_id_set: checkbox_name = 'select_property_id_%s' % property_id select_name = 'select_property_value_%s' % property_id checked = request.POST.getlist(checkbox_name) if checked: env_values = request.POST.getlist(select_name) if not env_values: continue if len(env_values) != len(checked): raise ValueError('Invalid number of env values.') for value_id in env_values: args.append( TCMSEnvRunValueMap(run=tr, value_id=value_id)) TCMSEnvRunValueMap.objects.bulk_create(args) return HttpResponseRedirect(reverse('run-get', args=[tr.run_id])) else: estimated_time = functools.reduce(operator.add, (tc.estimated_time for tc in tcs_values)) form = NewRunForm( initial={ 'summary': 'Test run for {} on {}'.format( tp.name, tp.env_group.all() and tp.env_group.all()[0] or 'Unknown environment'), 'estimated_time': format_timedelta(estimated_time), 'manager': tp.author.email, 'default_tester': request.user.email, 'product': tp.product_id, 'product_version': tp.product_version_id, }) form.populate(product_id=tp.product_id) # FIXME: pagination cases within Create New Run page. context_data = { 'module': MODULE_NAME, 'sub_module': SUB_MODULE_NAME, 'from_plan': plan_id, 'test_plan': tp, 'test_cases': tcs_values, 'form': form, 'num_unconfirmed_cases': num_unconfirmed_cases, 'run_estimated_time': estimated_time, } return render(request, template_name, context=context_data)