예제 #1
0
    def test_command_parsing_ok(self, executor, ndjson_bytes):
        """Sanity test that hits most elements of parsing."""

        BulkAPI.from_byte_stream(ndjson_bytes,
                                 executor=executor,
                                 observer=Observer())

        executor.configure.assert_called_with(
            config=Any.instance_of(Configuration))

        executor.execute_batch.assert_has_calls([
            call(
                command_type=CommandType.UPSERT,
                data_type=DataType.USER,
                batch=[Any.instance_of(DataCommand)],
                default_config={},
            ),
            call(
                command_type=CommandType.UPSERT,
                data_type=DataType.GROUP,
                batch=[Any.instance_of(DataCommand)],
                default_config={},
            ),
            call(
                command_type=CommandType.CREATE,
                data_type=DataType.GROUP_MEMBERSHIP,
                batch=[Any.instance_of(DataCommand)],
                default_config={"on_duplicate": "continue"},
            ),
        ])
예제 #2
0
    def test_round_tripping(self, commands, collecting_observer):
        """Check that sending and decoding results in the same data."""

        original_raw = [command.raw for command in commands]

        BulkAPI.from_byte_stream(
            BytesIO(BulkAPI.to_string(commands).encode("utf-8")),
            executor=AutomaticReportExecutor(),
            observer=collecting_observer,
        )

        final_raw = [command.raw for command in collecting_observer.commands]

        assert original_raw == final_raw
예제 #3
0
def bulk(request):
    """
    Perform a bulk request which can modify multiple records in on go.

    This end-point can:

     * Upsert users
     * Upsert groups
     * Add users to groups

    This end-point is intended to be called using the classes provided by
    `h_api.bulk_api`.
    """

    results = BulkAPI.from_byte_stream(
        request.body_file,
        executor=BulkExecutor(db=request.db,
                              authority=client_authority(request)),
    )

    if results is None:
        return Response(status=204)

    # When we get an iterator we must force the first return value to be
    # created to be sure input validation has occurred. Otherwise we might
    # raise errors outside of the view when called

    try:
        results = chain(  # pylint: disable=redefined-variable-type
            [next(results)], results)
    except StopIteration:
        results = []

    # An NDJSON response is required
    return Response(
        app_iter=((json.dumps(result) + "\n").encode("utf-8")
                  for result in results),
        status=200,
        content_type="application/x-ndjson",
    )