# Buggy code
def render_PATCH(self, request):
    """
    .. http:patch:: /download/(string: infohash)

    A PATCH request to this endpoint will update a download in Tribler.

    A state parameter can be passed to modify the state of the download. Valid states are "resume"
    (to resume a stopped/paused download), "stop" (to stop a running download) and "recheck"
    (to force a recheck of the hashes of a download).

    Another possible parameter is selected_files which manipulates which files are included in the download.
    The selected_files parameter is an array with the file indices as values.

    The anonymity of a download can be changed at runtime by passing the anon_hops parameter, however, this must
    be the only parameter in this request.

        **Example request**:

            .. sourcecode:: none

                curl -X PATCH http://localhost:8085/downloads/4344503b7e797ebf31582327a5baae35b11bda01
                --data "state=resume&selected_files[]=file1.iso&selected_files[]=1"

        **Example response**:

            .. sourcecode:: javascript

                {"modified": True}
    """
    download = self.session.get_download(self.infohash)
    if not download:
        return DownloadSpecificEndpoint.return_404(request)

    parameters = http.parse_qs(request.content.read(), 1)

    if len(parameters) > 1 and "anon_hops" in parameters:
        request.setResponseCode(http.BAD_REQUEST)
        return json.dumps(
            {"error": "anon_hops must be the only parameter in this request"}
        )
    elif "anon_hops" in parameters:
        anon_hops = int(parameters["anon_hops"][0])
        self.session.lm.update_download_hops(download, anon_hops)

    if "selected_files[]" in parameters:
        selected_files_list = []
        for ind in parameters["selected_files[]"]:
            try:
                selected_files_list.append(download.tdef.get_files()[int(ind)])
            except IndexError:  # File could not be found
                request.setResponseCode(http.BAD_REQUEST)
                return json.dumps({"error": "index %s out of range" % ind})
        download.set_selected_files(selected_files_list)

    if "state" in parameters and len(parameters["state"]) > 0:
        state = parameters["state"][0]
        if state == "resume":
            download.restart()
        elif state == "stop":
            download.stop()
        elif state == "recheck":
            download.force_recheck()
        else:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "unknown state parameter"})

    return json.dumps({"modified": True})


# Traceback (AssertionError)
Tuples differ: (2, ('127.0.0.1', [5, 4, 3, 2,... != (2, ('127.0.0.1', [5, 4, 3, 2,...

First differing element 2:
u'None'
''

- (2, ('127.0.0.1', [5, 4, 3, 2, 1]), u'None')
?                                     - ----

+ (2, ('127.0.0.1', [5, 4, 3, 2, 1]), '')
Stacktrace

Traceback (most recent call last):
File "c:\python27\lib\unittest\case.py", line 329, in run
testMethod()
File "C:\workspace\jenkins\workspace\GH_Tribler_PR_tests_win64\tribler\Tribler\Test\test_as_server.py", line 58, in check
result = fun(*argv, **kwargs)
File "C:\workspace\jenkins\workspace\GH_Tribler_PR_tests_win64\tribler\Tribler\Test\Core\Upgrade\test_config_upgrade_70_71.py", line 33, in test_read_test_libtribler_conf
self.assertEqual(result_config.get_anon_proxy_settings(), (2, ("127.0.0.1", [5, 4, 3, 2, 1]), ''))
File "c:\python27\lib\unittest\case.py", line 513, in assertEqual
assertion_func(first, second, msg=msg)
File "c:\python27\lib\unittest\case.py", line 753, in assertTupleEqual
self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
File "c:\python27\lib\unittest\case.py", line 724, in assertSequenceEqual
self.fail(msg)
File "c:\python27\lib\unittest\case.py", line 410, in fail
raise self.failureException(msg)
AssertionError: Tuples differ: (2, ('127.0.0.1', [5, 4, 3, 2,... != (2, ('127.0.0.1', [5, 4, 3, 2,...

First differing element 2:
u'None'
''

- (2, ('127.0.0.1', [5, 4, 3, 2, 1]), u'None')
?                                     - ----

+ (2, ('127.0.0.1', [5, 4, 3, 2, 1]), '')

# Fixed code
def render_PATCH(self, request):
    """
    .. http:patch:: /download/(string: infohash)

    A PATCH request to this endpoint will update a download in Tribler.

    A state parameter can be passed to modify the state of the download. Valid states are "resume"
    (to resume a stopped/paused download), "stop" (to stop a running download) and "recheck"
    (to force a recheck of the hashes of a download).

    Another possible parameter is selected_files which manipulates which files are included in the download.
    The selected_files parameter is an array with the file indices as values.

    The anonymity of a download can be changed at runtime by passing the anon_hops parameter, however, this must
    be the only parameter in this request.

        **Example request**:

            .. sourcecode:: none

                curl -X PATCH http://localhost:8085/downloads/4344503b7e797ebf31582327a5baae35b11bda01
                --data "state=resume&selected_files[]=file1.iso&selected_files[]=1"

        **Example response**:

            .. sourcecode:: javascript

                {"modified": True}
    """
    download = self.session.get_download(self.infohash)
    if not download:
        return DownloadSpecificEndpoint.return_404(request)

    parameters = http.parse_qs(request.content.read(), 1)

    if len(parameters) > 1 and "anon_hops" in parameters:
        request.setResponseCode(http.BAD_REQUEST)
        return json.dumps(
            {"error": "anon_hops must be the only parameter in this request"}
        )
    elif "anon_hops" in parameters:
        anon_hops = int(parameters["anon_hops"][0])
        deferred = self.session.lm.update_download_hops(download, anon_hops)

        def _on_download_readded(_):
            """
            Success callback
            """
            request.write(json.dumps({"modified": True}))
            request.finish()

        def _on_download_readd_failure(failure):
            """
            Error callback
            :param failure: from LibtorrentDownloadImp.setup()
            """
            self._logger.exception(failure)
            request.write(return_handled_exception(request, failure.value))
            # If the above request.write failed, the request will have already been finished
            if not request.finished:
                request.finish()

        deferred.addCallback(_on_download_readded)
        deferred.addErrback(_on_download_readd_failure)
        # As we already checked for len(parameters) > 1, we know there are no other parameters.
        # As such, we can return immediately.
        return NOT_DONE_YET

    if "selected_files[]" in parameters:
        selected_files_list = []
        for ind in parameters["selected_files[]"]:
            try:
                selected_files_list.append(download.tdef.get_files()[int(ind)])
            except IndexError:  # File could not be found
                request.setResponseCode(http.BAD_REQUEST)
                return json.dumps({"error": "index %s out of range" % ind})
        download.set_selected_files(selected_files_list)

    if "state" in parameters and len(parameters["state"]) > 0:
        state = parameters["state"][0]
        if state == "resume":
            download.restart()
        elif state == "stop":
            download.stop()
        elif state == "recheck":
            download.force_recheck()
        else:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "unknown state parameter"})

    return json.dumps({"modified": True})