コード例 #1
0
def test_recalculate(client):

    user = UserFactory()
    surface = SurfaceFactory(creator=user)
    topo1 = Topography1DFactory(surface=surface)
    topo2 = Topography1DFactory(surface=surface)

    func = AnalysisFunctionFactory(name="test function")
    impl = AnalysisFunctionImplementationFactory(function=func)

    client.force_login(user)

    with transaction.atomic():
        # trigger "recalculate" for two topographies
        response = client.post(
            reverse('analysis:card-submit'), {
                'function_id': func.id,
                'subjects_ids_json': subjects_to_json([topo1, topo2]),
                'function_kwargs_json': '{}'
            },
            HTTP_X_REQUESTED_WITH='XMLHttpRequest')  # we need an AJAX request
        assert response.status_code == 200

    #
    # Analysis objects should be there and marked for the user
    #
    analysis1 = Analysis.objects.get(function=func, topography=topo1)
    analysis2 = Analysis.objects.get(function=func, topography=topo2)

    assert user in analysis1.users.all()
    assert user in analysis2.users.all()
コード例 #2
0
def test_card_templates_simple(client, mocker, handle_usage_statistics):
    """Check whether correct template is selected."""

    #
    # Create database objects
    #
    password = "******"
    user = UserFactory(password=password)
    func1 = AnalysisFunctionFactory(card_view_flavor='power spectrum')
    topo1 = Topography1DFactory()

    # An analysis function with card_view_flavor='power spectrum'
    # should use the template which is needed for PowerSpectrumCardView.
    #
    # For the "detail" mode, there is an own template for power spectrum,
    # which should be returned. The the "list" mode, there is no
    # special template. Therefore, since "PowerSpectrumCardView" is
    # derived from the "PlotCardView" so far, the resulting
    # template should be 'plot_card_list.html'.

    assert client.login(username=user.username, password=password)

    response = client.post(
        reverse('analysis:card'),
        data={
            'function_id': func1.id,
            'card_id': 'card',
            'template_flavor': 'list',
            'subjects_ids_json': subjects_to_json([topo1]),
        },
        HTTP_X_REQUESTED_WITH='XMLHttpRequest')  # we need an AJAX request

    assert response.template_name == ['analysis/plot_card_list.html']

    response = client.post(
        reverse('analysis:card'),
        data={
            'function_id': func1.id,
            'card_id': 'card',
            'template_flavor': 'detail',
            'subjects_ids_json': subjects_to_json([topo1]),
        },
        HTTP_X_REQUESTED_WITH='XMLHttpRequest')  # we need an AJAX request

    assert response.template_name == [
        'analysis/powerspectrum_card_detail.html'
    ]
コード例 #3
0
def test_warnings_for_different_arguments(client, handle_usage_statistics):
    user = UserFactory()
    surf1 = SurfaceFactory(creator=user)
    surf2 = SurfaceFactory(creator=user)
    topo1a = Topography1DFactory(surface=surf1)
    topo1b = Topography1DFactory(surface=surf1)
    topo2a = Topography1DFactory(surface=surf2)

    func = AnalysisFunctionFactory()
    topo_impl = AnalysisFunctionImplementationFactory(function=func,
                                                      subject_type=topo1a.get_content_type(),
                                                      code_ref='topography_analysis_function_for_tests')
    surf_impl = AnalysisFunctionImplementationFactory(function=func,
                                                      subject_type=surf1.get_content_type(),
                                                      code_ref='surface_analysis_function_for_tests')

    #
    # Generate analyses for topographies with differing arguments
    #
    kwargs_1a = pickle.dumps(dict(a=1, b=2))
    kwargs_1b = pickle.dumps(dict(a=1, b=3))  # differing from kwargs_1a!
    ana1a = TopographyAnalysisFactory(subject=topo1a, function=func, kwargs=kwargs_1a)
    ana1b = TopographyAnalysisFactory(subject=topo1b, function=func, kwargs=kwargs_1b)
    ana2a = TopographyAnalysisFactory(subject=topo2a, function=func)  # default arguments

    #
    # Generate analyses for surfaces with differing arguments
    #
    kwargs_1 = pickle.dumps(dict(a=1, c=2))
    kwargs_2 = pickle.dumps(dict(a=1, c=3))  # differing from kwargs_1a!
    ana1 = SurfaceAnalysisFactory(subject=surf1, function=func, kwargs=kwargs_1)
    ana2 = SurfaceAnalysisFactory(subject=surf2, function=func, kwargs=kwargs_2)

    client.force_login(user)

    #
    # request card, there should be warnings, one for topographies and one for surfaces
    #
    response = client.post(reverse("analysis:card"),
                           data={
                               'subjects_ids_json': subjects_to_json([topo1a, topo1b, topo2a, surf1, surf2]),
                               'function_id': func.id,
                               'card_id': "card-1",
                               'template_flavor': 'list'
                           },
                           HTTP_X_REQUESTED_WITH='XMLHttpRequest',
                           follow=True)

    assert response.status_code == 200

    assert_in_content(response,
                      "Arguments for this analysis function differ among chosen "
                      "subjects of type 'manager | topography'")
    assert_in_content(response,
                      "Arguments for this analysis function differ among chosen "
                      "subjects of type 'manager | surface'")
コード例 #4
0
 def send_card_request():
     response = client.post(
         reverse('analysis:card'),
         data={
             'function_id': function.id,
             'card_id': 'card',
             'template_flavor': 'list',
             'subjects_ids_json': subjects_to_json([topography]),
         },
         HTTP_X_REQUESTED_WITH='XMLHttpRequest')  # we need an AJAX request
     return response
コード例 #5
0
def test_card_templates_for_power_spectrum(client, mocker,
                                           handle_usage_statistics):
    #
    # Create database objects
    #
    password = "******"
    user = UserFactory(password=password)
    func1 = AnalysisFunctionFactory(card_view_flavor='power spectrum')
    topo1 = Topography1DFactory()

    assert client.login(username=user.username, password=password)

    response = client.post(
        reverse('analysis:card'),
        data={
            'function_id': func1.id,
            'card_id': 'card',
            'template_flavor': 'list',
            'subjects_ids_json': subjects_to_json([topo1]),
        },
        HTTP_X_REQUESTED_WITH='XMLHttpRequest')  # we need an AJAX request

    # we get the inherited "plot" template with "list" flavor, because power spectrum
    # hasn't got an own template with "list" flavor
    assert response.template_name == ['analysis/plot_card_list.html']

    response = client.post(
        reverse('analysis:card'),
        data={
            'function_id': func1.id,
            'card_id': 'card',
            'template_flavor': 'detail',
            'subjects_ids_json': subjects_to_json([topo1]),
        },
        HTTP_X_REQUESTED_WITH='XMLHttpRequest')  # we need an AJAX request

    # for the power spectrum detail card there should be an own template
    assert response.template_name == [
        'analysis/powerspectrum_card_detail.html'
    ]
コード例 #6
0
def test_analysis_times(client, two_topos, django_user_model, handle_usage_statistics):
    user = django_user_model.objects.get(username='******')
    client.force_login(user)

    topo = Topography.objects.first()
    af = AnalysisFunction.objects.first()

    pickled_result = pickle.dumps({'name': 'test function',
                                   'xlabel': 'x',
                                   'ylabel': 'y',
                                   'xunit': '1',
                                   'yunit': '1',
                                   'series': [],
                                   })

    analysis = TopographyAnalysisFactory.create(
        subject=topo,
        function=af,
        task_state=Analysis.SUCCESS,
        start_time=datetime.datetime(2018, 1, 1, 12),
        end_time=datetime.datetime(2018, 1, 1, 13, 1, 1),  # duration: 1 hour, 1 minute, 1 sec
        result=pickled_result,
    )
    analysis.users.add(user)
    analysis.save()

    response = client.post(reverse("analysis:card"),
                           data={
                               'subjects_ids_json': subjects_to_json([topo]),
                               'function_id': af.id,
                               'card_id': "card-1",
                               'template_flavor': 'list',
                           },
                           HTTP_X_REQUESTED_WITH='XMLHttpRequest',
                           follow=True)

    assert response.status_code == 200

    assert_in_content(response, "2018-01-01 12:00:00")  # start_time
    assert_in_content(response, "1:01:01")  # duration
コード例 #7
0
def test_view_shared_analysis_results(client, handle_usage_statistics):
    password = '******'

    #
    # create database objects
    #
    user1 = UserFactory(password=password)
    user2 = UserFactory(password=password)

    surface1 = SurfaceFactory(creator=user1)
    surface2 = SurfaceFactory(creator=user2)

    # create topographies + functions + analyses
    func1 = AnalysisFunctionFactory()
    impl1 = AnalysisFunctionImplementationFactory(function=func1)
    # func2 = AnalysisFunctionFactory()

    # Two topographies for surface1
    topo1a = Topography1DFactory(surface=surface1, name='topo1a')
    topo1b = Topography1DFactory(surface=surface1, name='topo1b')

    # One topography for surface2
    topo2a = Topography1DFactory(surface=surface2, name='topo2a')

    # analyses, differentiate by start time
    analysis1a_1 = TopographyAnalysisFactory(subject=topo1a, function=func1,
                                             start_time=datetime.datetime(2019, 1, 1, 12))
    analysis1b_1 = TopographyAnalysisFactory(subject=topo1b, function=func1,
                                             start_time=datetime.datetime(2019, 1, 1, 13))
    analysis2a_1 = TopographyAnalysisFactory(subject=topo2a, function=func1,
                                             start_time=datetime.datetime(2019, 1, 1, 14))

    # Function should have three analyses, all successful (the default when using the factory)
    assert func1.analysis_set.count() == 3
    assert all(a.task_state == 'su' for a in func1.analysis_set.all())

    # user2 shares surfaces, so user 1 should see surface1+surface2
    surface2.share(user1)

    #
    # Now we change to the analysis card view and look what we get
    #
    assert client.login(username=user1.username, password=password)

    response = client.post(reverse("analysis:card"),
                           data={
                               'subjects_ids_json': subjects_to_json([topo1a, topo1b, topo2a]),
                               'function_id': func1.id,
                               'card_id': 1,
                               'template_flavor': 'list'
                           },
                           HTTP_X_REQUESTED_WITH='XMLHttpRequest',
                           follow=True)

    # Function should still have three analyses, all successful (the default when using the factory)
    assert func1.analysis_set.count() == 3
    assert all(a.task_state == 'su' for a in func1.analysis_set.all())

    assert response.status_code == 200

    # We should see start times of all three topographies
    assert_in_content(response, '2019-01-01 12:00:00')  # topo1a
    assert_in_content(response, '2019-01-01 13:00:00')  # topo1b
    assert_in_content(response, '2019-01-01 14:00:00')  # topo2a

    client.logout()

    #
    # user 2 cannot access results from topo1, it is not shared
    #
    assert client.login(username=user2.username, password=password)

    response = client.post(reverse("analysis:card"),
                           data={
                               'subjects_ids_json': subjects_to_json([topo1a, topo1b, topo2a]),
                               'function_id': func1.id,
                               'card_id': 1,
                               'template_flavor': 'list'
                           },
                           HTTP_X_REQUESTED_WITH='XMLHttpRequest',
                           follow=True)

    assert response.status_code == 200

    assert_not_in_content(response, '2019-01-01 12:00:00')  # topo1a
    assert_not_in_content(response, '2019-01-01 13:00:00')  # topo1b
    assert_in_content(response, '2019-01-01 14:00:00')  # topo2a

    client.logout()
コード例 #8
0
def test_roughness_params_rounded(rf, mocker):
    from django.core.management import call_command
    call_command('register_analysis_functions')

    m = mocker.patch('topobank.analysis.functions.roughness_parameters')
    m.return_value = [  # some fake values for rounding
        {
            'quantity': 'RMS Height',
            'direction': None,
            'from': 'area (2D)',
            'symbol': 'Sq',
            'value': np.float32(1.2345678),
            'unit': 'm',
        },
        {
            'quantity': 'RMS Height',
            'direction': 'x',
            'from': 'profile (1D)',
            'symbol': 'Rq',
            'value': np.float32(8.7654321),
            'unit': 'm',
        },
        {
            'quantity': 'RMS Curvature',
            'direction': None,
            'from': 'profile (1D)',
            'symbol': '',
            'value': np.float32(0.9),
            'unit': '1/m',
        },
        {
            'quantity': 'RMS Slope',
            'direction': 'x',
            'from': 'profile (1D)',
            'symbol': 'SΔq',
            'value': np.float32(-1.56789),
            'unit': 1,
        },
        {
            'quantity': 'RMS Slope',
            'direction': 'y',
            'from': 'profile (1D)',
            'symbol': 'SΔq',
            'value': np.float32('nan'),
            'unit': 1,
        }
    ]

    topo = Topography2DFactory(size_x=1, size_y=1)

    func = AnalysisFunction.objects.get(name='Roughness parameters')
    TopographyAnalysisFactory(subject=topo, function=func)

    request = rf.post(reverse('analysis:card'), data={
        'function_id': func.id,
        'card_id': 'card',
        'template_flavor': 'list',
        'subjects_ids_json': subjects_to_json([topo]),
    }, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
    request.user = topo.surface.creator
    request.session = {}

    rms_table_card_view = RoughnessParametersCardView.as_view()
    response = rms_table_card_view(request)
    assert response.status_code == 200

    response.render()
    # we want rounding to 5 digits
    assert NUM_SIGNIFICANT_DIGITS_RMS_VALUES == 5
    assert b"1.2346" in response.content
    assert b"8.7654" in response.content
    assert b"0.9" in response.content
    assert b"-1.5679" in response.content
    assert b"NaN" in response.content
コード例 #9
0
def test_show_analyses_with_different_arguments(client, two_topos, django_user_model, handle_usage_statistics):
    user = django_user_model.objects.get(username='******')
    client.force_login(user)

    topo1 = Topography.objects.first()
    af = AnalysisFunction.objects.first()

    pickled_result = pickle.dumps({'name': 'test function',
                                   'xlabel': 'x',
                                   'ylabel': 'y',
                                   'xunit': '1',
                                   'yunit': '1',
                                   'series': [],
                                   })

    #
    # Create analyses for same function and topography but with different arguments
    #
    analysis = TopographyAnalysisFactory.create(
        subject=topo1,
        function=af,
        task_state=Analysis.SUCCESS,
        kwargs=pickle.dumps({'bins': 10}),
        start_time=datetime.datetime(2018, 1, 1, 12),
        end_time=datetime.datetime(2018, 1, 1, 13, 1, 1),
        result=pickled_result,
    )
    analysis.users.add(user)
    analysis.save()

    # save a second, which has a later start time
    analysis = TopographyAnalysisFactory.create(
        subject=topo1,
        function=af,
        task_state=Analysis.SUCCESS,
        kwargs=pickle.dumps({'bins': 20}),
        start_time=datetime.datetime(2018, 1, 2, 12),
        end_time=datetime.datetime(2018, 1, 2, 13, 1, 1),
        result=pickled_result,
    )
    analysis.users.add(user)
    analysis.save()

    # save a third, which has a later start time
    analysis = TopographyAnalysisFactory.create(
        subject=topo1,
        function=af,
        task_state=Analysis.SUCCESS,
        kwargs=pickle.dumps({'bins': 30}),
        start_time=datetime.datetime(2018, 1, 3, 12),
        end_time=datetime.datetime(2018, 1, 3, 13, 1, 1),
        result=pickled_result,
    )
    analysis.users.add(user)
    analysis.save()

    #
    # Check response, all three analyses should be shown
    #
    response = client.post(reverse("analysis:card"),
                           data={
                               'subjects_ids_json': subjects_to_json([topo1]),
                               'function_id': af.id,
                               'card_id': "card-1",
                               'template_flavor': 'list'
                           },
                           HTTP_X_REQUESTED_WITH='XMLHttpRequest',
                           follow=True)

    assert response.status_code == 200

    assert_in_content(response, "2018-01-01 12:00:00")
    assert_in_content(response, "2018-01-02 12:00:00")
    assert_in_content(response, "2018-01-03 12:00:00")

    # arguments should be visible in output

    import html.parser
    unescaped = html.unescape(response.content.decode())

    assert str(dict(bins=10)) in unescaped
    assert str(dict(bins=20)) in unescaped
コード例 #10
0
def test_show_only_last_analysis(client, two_topos, django_user_model, handle_usage_statistics):
    username = '******'
    user = django_user_model.objects.get(username=username)
    client.force_login(user)

    topo1 = Topography.objects.first()
    topo2 = Topography.objects.last()
    af = AnalysisFunction.objects.first()

    pickled_result = pickle.dumps({'name': 'test function',
                                   'xlabel': 'x',
                                   'ylabel': 'y',
                                   'xunit': '1',
                                   'yunit': '1',
                                   'series': [],
                                   })

    #
    # Topography 1
    #
    analysis = TopographyAnalysisFactory.create(
        subject=topo1,
        function=af,
        task_state=Analysis.SUCCESS,
        kwargs=pickle.dumps({}),
        start_time=datetime.datetime(2018, 1, 1, 12),
        end_time=datetime.datetime(2018, 1, 1, 13, 1, 1),
        result=pickled_result,
    )
    analysis.users.add(user)
    analysis.save()

    # save a second only, which has a later start time
    analysis = TopographyAnalysisFactory.create(
        subject=topo1,
        function=af,
        task_state=Analysis.SUCCESS,
        kwargs=pickle.dumps({}),
        start_time=datetime.datetime(2018, 1, 2, 12),
        end_time=datetime.datetime(2018, 1, 2, 13, 1, 1),
        result=pickled_result,
    )
    analysis.users.add(user)
    analysis.save()

    #
    # Topography 2
    #
    analysis = TopographyAnalysisFactory.create(
        subject=topo2,
        function=af,
        task_state=Analysis.SUCCESS,
        kwargs=pickle.dumps({}),
        start_time=datetime.datetime(2018, 1, 3, 12),
        end_time=datetime.datetime(2018, 1, 3, 13, 1, 1),
        result=pickled_result,
    )
    analysis.users.add(user)
    analysis.save()

    # save a second only, which has a later start time
    analysis = TopographyAnalysisFactory.create(
        subject=topo2,
        function=af,
        task_state=Analysis.SUCCESS,
        kwargs=pickle.dumps({}),
        start_time=datetime.datetime(2018, 1, 4, 12),
        end_time=datetime.datetime(2018, 1, 4, 13, 1, 1),
        result=pickled_result,
    )
    analysis.users.add(user)
    analysis.save()

    #
    # Check response, for both topographies only the
    # latest results should be shown
    #
    response = client.post(reverse("analysis:card"),
                           data={
                               'subjects_ids_json': subjects_to_json([topo1, topo2]),
                               'function_id': af.id,
                               'card_id': 1,
                               'template_flavor': 'list'
                           },
                           HTTP_X_REQUESTED_WITH='XMLHttpRequest',
                           follow=True)

    assert response.status_code == 200

    assert b"2018-01-02 12:00:00" in response.content
    assert b"2018-01-04 12:00:00" in response.content

    assert b"2018-01-01 12:00:00" not in response.content
    assert b"2018-01-03 12:00:00" not in response.content
コード例 #11
0
def test_plot_card_if_no_successful_topo_analysis(client,
                                                  handle_usage_statistics):
    #
    # Create database objects
    #
    password = "******"
    user = UserFactory(password=password)
    topography_ct = ContentType.objects.get_for_model(Topography)
    surface_ct = ContentType.objects.get_for_model(Surface)
    func1 = AnalysisFunctionFactory(card_view_flavor='power spectrum')
    AnalysisFunctionImplementationFactory(function=func1,
                                          subject_type=topography_ct)
    AnalysisFunctionImplementationFactory(function=func1,
                                          subject_type=surface_ct)

    surf = SurfaceFactory(creator=user)
    topo = Topography1DFactory(surface=surf)  # also generates the surface

    # There is a successful surface analysis, but no successful topography analysis
    SurfaceAnalysisFactory(task_state='su',
                           subject_id=topo.surface.id,
                           subject_type_id=surface_ct.id,
                           function=func1,
                           users=[user])

    # add a failed analysis for the topography
    TopographyAnalysisFactory(task_state='fa',
                              subject_id=topo.id,
                              subject_type_id=topography_ct.id,
                              function=func1,
                              users=[user])

    assert Analysis.objects.filter(function=func1,
                                   subject_id=topo.id,
                                   subject_type_id=topography_ct.id,
                                   task_state='su').count() == 0
    assert Analysis.objects.filter(function=func1,
                                   subject_id=topo.id,
                                   subject_type_id=topography_ct.id,
                                   task_state='fa').count() == 1
    assert Analysis.objects.filter(function=func1,
                                   subject_id=topo.surface.id,
                                   subject_type_id=surface_ct.id,
                                   task_state='su').count() == 1

    # login and request plot card view
    assert client.login(username=user.username, password=password)

    response = client.post(
        reverse('analysis:card'),
        data={
            'function_id': func1.id,
            'card_id': 'card',
            'template_flavor': 'list',
            'subjects_ids_json':
            subjects_to_json([topo, topo.surface
                              ]),  # also request results for surface here
        },
        HTTP_X_REQUESTED_WITH='XMLHttpRequest')  # we need an AJAX request

    # should return without errors
    assert response.status_code == 200