예제 #1
0
    def test_MOVE_create(self):
        """
        MOVE to new resource.
        """
        def test(response, path, isfile, sum, uri, depth, dst_path):
            if response.code != responsecode.CREATED:
                self.fail("Incorrect response code for MOVE %s: %s != %s" %
                          (uri, response.code, responsecode.CREATED))

            if response.headers.getHeader("location") is None:
                self.fail(
                    "Reponse to MOVE %s with CREATE status is missing location: header."
                    % (uri, ))

            if isfile:
                if not os.path.isfile(dst_path):
                    self.fail("MOVE %s produced no output file" % (uri, ))
                if sum != sumFile(dst_path):
                    self.fail("MOVE %s produced different file" % (uri, ))
            else:
                if not os.path.isdir(dst_path):
                    self.fail("MOVE %s produced no output directory" % (uri, ))
                if sum != sumFile(dst_path):
                    self.fail("isdir %s produced different directory" %
                              (uri, ))

        return serialize(self.send, work(self, test))
예제 #2
0
    def test_DELETE(self):
        """
        DELETE request
        """
        def check_result(response, path):
            response = IResponse(response)

            if response.code != responsecode.NO_CONTENT:
                self.fail("DELETE response %s != %s" %
                          (response.code, responsecode.NO_CONTENT))

            if os.path.exists(path):
                self.fail("DELETE did not remove path %s" % (path, ))

        def work():
            for filename in os.listdir(self.docroot):
                path = os.path.join(self.docroot, filename)
                uri = urllib.quote("/" + filename)

                if os.path.isdir(path): uri = uri + "/"

                def do_test(response, path=path):
                    return check_result(response, path)

                request = SimpleRequest(self.site, "DELETE", uri)

                depth = random.choice(("infinity", None))
                if depth is not None:
                    request.headers.setHeader("depth", depth)

                yield (request, do_test)

        return serialize(self.send, work())
예제 #3
0
    def test_COPY_exists(self):
        """
        COPY to existing resource.
        """
        def test(response, path, isfile, sum, uri, depth, dst_path):
            if response.code != responsecode.PRECONDITION_FAILED:
                self.fail("Incorrect response code for COPY without overwrite %s: %s != %s"
                          % (uri, response.code, responsecode.PRECONDITION_FAILED))
            else:
                # FIXME: Check XML error code (2518bis)
                pass

        return serialize(self.send, work(self, test, overwrite=False))
예제 #4
0
    def test_COPY_no_parent(self):
        """
        COPY to resource with no parent.
        """
        def test(response, path, isfile, sum, uri, depth, dst_path):
            if response.code != responsecode.CONFLICT:
                self.fail("Incorrect response code for COPY with no parent %s: %s != %s"
                          % (uri, response.code, responsecode.CONFLICT))
            else:
                # FIXME: Check XML error code (2518bis)
                pass

        return serialize(self.send, work(self, test, dst=os.path.join(self.docroot, "elvislives!")))
예제 #5
0
    def test_PUT_simple(self):
        """
        PUT request
        """
        dst_path = os.path.join(self.docroot, "dst")

        def checkResult(response, path):
            response = IResponse(response)

            if response.code not in (responsecode.CREATED,
                                     responsecode.NO_CONTENT):
                self.fail("PUT failed: %s" % (response.code, ))

            if not os.path.isfile(dst_path):
                self.fail("PUT failed to create file %s." % (dst_path, ))

            if not filecmp.cmp(path, dst_path):
                self.fail(
                    "PUT failed to preserve data for file %s in file %s." %
                    (path, dst_path))

            etag = response.headers.getHeader("etag")
            if not etag:
                self.fail("No etag header in PUT response %r." % (response, ))

        #
        # We need to serialize these request & test iterations because they can
        # interfere with each other.
        #
        def work():
            dst_uri = "/dst"

            for name in os.listdir(self.docroot):
                if name == "dst":
                    continue

                path = os.path.join(self.docroot, name)

                # Can't really PUT something you can't read
                if not os.path.isfile(path): continue

                def do_test(response):
                    checkResult(response, path)

                request = SimpleRequest(self.site, "PUT", dst_uri)
                request.stream = FileStream(file(path, "rb"))

                yield (request, do_test)

        return serialize(self.send, work())
예제 #6
0
    def test_MOVE_overwrite(self):
        """
        MOVE to existing resource with overwrite header.
        """
        def test(response, path, isfile, sum, uri, depth, dst_path):
            if response.code != responsecode.NO_CONTENT:
                self.fail(
                    "Incorrect response code for MOVE with overwrite %s: %s != %s"
                    % (uri, response.code, responsecode.NO_CONTENT))
            else:
                # FIXME: Check XML error code (2518bis)
                pass

        return serialize(self.send, work(self, test, overwrite=True))
예제 #7
0
    def test_COPY_overwrite(self):
        """
        COPY to existing resource with overwrite header.
        """
        def test(response, path, isfile, sum, uri, depth, dst_path):
            if response.code != responsecode.NO_CONTENT:
                self.fail("Incorrect response code for COPY with overwrite %s: %s != %s"
                          % (uri, response.code, responsecode.NO_CONTENT))
            else:
                # FIXME: Check XML error code (2518bis)
                pass

            self.failUnless(os.path.exists(dst_path), "COPY didn't produce file: %s" % (dst_path,))

        return serialize(self.send, work(self, test, overwrite=True))
예제 #8
0
    def test_PUT_again(self):
        """
        PUT on existing resource with If-None-Match header
        """
        dst_path = os.path.join(self.docroot, "dst")
        dst_uri = "/dst"

        def work():
            for code in (
                    responsecode.CREATED,
                    responsecode.PRECONDITION_FAILED,
                    responsecode.NO_CONTENT,
                    responsecode.PRECONDITION_FAILED,
                    responsecode.NO_CONTENT,
                    responsecode.CREATED,
            ):

                def checkResult(response, code=code):
                    response = IResponse(response)

                    if response.code != code:
                        self.fail(
                            "Incorrect response code for PUT (%s != %s)" %
                            (response.code, code))

                def onError(f):
                    f.trap(HTTPError)
                    return checkResult(f.value.response)

                request = SimpleRequest(self.site, "PUT", dst_uri)
                request.stream = FileStream(file(__file__, "rb"))

                if code == responsecode.CREATED:
                    if os.path.isfile(dst_path):
                        os.remove(dst_path)
                    request.headers.setHeader("if-none-match", ("*", ))
                elif code == responsecode.PRECONDITION_FAILED:
                    request.headers.setHeader("if-none-match", ("*", ))

                yield (request, (checkResult, onError))

        return serialize(self.send, work())
예제 #9
0
    def test_COPY_create(self):
        """
        COPY to new resource.
        """
        def test(response, path, isfile, sum, uri, depth, dst_path):
            if response.code != responsecode.CREATED:
                self.fail("Incorrect response code for COPY %s (depth=%r): %s != %s"
                          % (uri, depth, response.code, responsecode.CREATED))

            if response.headers.getHeader("location") is None:
                self.fail("Reponse to COPY %s (depth=%r) with CREATE status is missing location: header."
                          % (uri, depth))

            if os.path.isfile(path):
                if not os.path.isfile(dst_path):
                    self.fail("COPY %s (depth=%r) produced no output file" % (uri, depth))
                if not cmp(path, dst_path):
                    self.fail("COPY %s (depth=%r) produced different file" % (uri, depth))
                os.remove(dst_path)

            elif os.path.isdir(path):
                if not os.path.isdir(dst_path):
                    self.fail("COPY %s (depth=%r) produced no output directory" % (uri, depth))

                if depth in ("infinity", None):
                    if dircmp(path, dst_path):
                        self.fail("COPY %s (depth=%r) produced different directory" % (uri, depth))

                elif depth == "0":
                    for filename in os.listdir(dst_path):
                        self.fail("COPY %s (depth=%r) shouldn't copy directory contents (eg. %s)" % (uri, depth, filename))

                else: raise AssertionError("Unknown depth: %r" % (depth,))

                rmdir(dst_path)

            else:
                self.fail("Source %s is neither a file nor a directory"
                          % (path,))

        return serialize(self.send, work(self, test))
예제 #10
0
    def test_PROPFIND_list(self):
        """
        PROPFIND with allprop, propname
        """
        def check_result(which):
            def _check_result(response):
                response = IResponse(response)

                if response.code != responsecode.MULTI_STATUS:
                    self.fail(
                        "Incorrect response code for PROPFIND (%s != %s)" %
                        (response.code, responsecode.MULTI_STATUS))

                return davXMLFromStream(response.stream).addCallback(
                    check_xml, which)

            return _check_result

        def check_xml(doc, which):
            response = doc.root_element.childOfType(
                davxml.PropertyStatusResponse)

            self.failUnless(
                response.childOfType(davxml.HRef) == "/",
                "Incorrect response URI: %s != /" %
                (response.childOfType(davxml.HRef), ))

            for propstat in response.childrenOfType(davxml.PropertyStatus):
                status = propstat.childOfType(davxml.Status)
                properties = propstat.childOfType(
                    davxml.PropertyContainer).children

                if status.code != responsecode.OK:
                    self.fail(
                        "PROPFIND failed (status %s) to locate live properties: %s"
                        % (status.code, properties))

                if which.name == "allprop":
                    properties_to_find = [
                        p.qname() for p in live_properties if not p.hidden
                    ]
                else:
                    properties_to_find = [p.qname() for p in live_properties]

                for property in properties:
                    qname = property.qname()
                    if qname in properties_to_find:
                        properties_to_find.remove(qname)
                    elif qname[0] != dav_namespace:
                        pass
                    else:
                        self.fail(
                            "PROPFIND with %s found property we didn't expect: %r"
                            % (which.name, property))

                    if which.name == "propname":
                        # Element should be empty
                        self.failUnless(len(property.children) == 0)
                    else:
                        # Element should have a value
                        # Actually, this isn't necessarily true, but it is for the live
                        # properties we've defined so far...
                        self.failIf(len(property.children) == 0)

                if properties_to_find:
                    self.fail(
                        "PROPFIND with %s failed to find properties: %r" %
                        (which.name, properties_to_find))

            properties = propstat.childOfType(
                davxml.PropertyContainer).children

        def work():
            for which in (davxml.AllProperties(), davxml.PropertyName()):
                query = davxml.PropertyFind(which)

                request = SimpleRequest(self.site, "PROPFIND", "/")
                request.headers.setHeader("depth", "0")
                request.stream = MemoryStream(query.toxml())

                yield (request, check_result(which))

        return serialize(self.send, work())