コード例 #1
0
    def start_drive(self):
        fl = self.fl
        server_url = fl.server_url
        fl.get(server_url + "/site/automation/",
               description="Hello automation with token")

        fl.addHeader('X-Nxdocumentproperties', '*')
        fl.addHeader('Accept', 'application/json+nxentity, */*')
        fl.post(server_url + "/site/automation/NuxeoDrive.GetChangeSummary",
                Data('application/json+nxrequest', '''{"params": {}}'''),
                description="GetChangeSummary")
        fl.assert_('activeSynchronizationRootDefinitions' in fl.getBody())
        self.sync_ids = extractSyncIds(fl.getBody())
        fl.post(server_url + "/site/automation/NuxeoDrive.GetFileSystemItem",
                Data('application/json+nxrequest',
                     '''{"params": {"id": "org.nuxeo.drive.service.impl.DefaultTopLevelFolderItemFactory#"}}'''),
                description="GetFileSystemItem")
        fl.assert_('canCreateChild' in fl.getBody())

        fl.post(server_url + "/site/automation/NuxeoDrive.GetChildren",
                Data('application/json+nxrequest',
                     '''{"params": {"id": "org.nuxeo.drive.service.impl.DefaultTopLevelFolderItemFactory#"}}'''),
                description="GetChildren")

        ids = extractIds(fl.getBody())
        self.root_ids = ids
        fl.assert_(len(ids) > 0, "No root to sync on server")
        self.navigate(ids)
        return self
コード例 #2
0
    def testCreateUpdate(self):
        self.initWorkspace()
        self.setBasicAuth(*self.cred_admin)
        dav_url = self.dav_url
        url = dav_url + "/" + self.ws_title

        folder_url = url + "/" + self._lipsum.getUniqWord()
        # create a folder
        self.method("MKCOL",
                    folder_url,
                    ok_codes=[
                        201,
                    ],
                    description="Create a folder")
        # create files
        for i in range(self.nb_docs):
            doc_url = folder_url + '/' + self._lipsum.getUniqWord() + '.txt'
            content = self._lipsum.getParagraph()
            self.put(doc_url,
                     params=Data(None, content),
                     description="Create a doc " + str(i),
                     ok_codes=[
                         201,
                     ])
            content += self._lipsum.getParagraph() + " UPDATE"
            self.put(doc_url,
                     params=Data(None, content),
                     description="Update doc " + str(i),
                     ok_codes=[
                         201,
                     ])
            #self.delete(doc_url, ok_codes=[204, ], description="Delete doc")
        self.clearBasicAuth()
    def test_create_db(self):
        #self._delete_db()

        print('Creating %d users with %d wbos each' %
              (self.vusers, self.num_wbos))
        # let's create 2k users (captcha needs to be deactivated)
        for i in range(self.vusers - 1):
            sys.stdout.write('.')
            sys.stdout.flush()
            name = 'funkloaduser%d' % i
            data = {'password': '******' * 10, 'email': '*****@*****.**' % name}
            data = Data('application/json', json.dumps(data))
            try:
                res = self.put(self.root + '/user/1.0/%s' % name, data)
            except AssertionError, e:
                print str(e)

            # each user will have 6000 wbos
            self.setBasicAuth(name, 'x' * 10)
            for id_ in range(self.num_wbos - 1):
                col = random.choice(_COLS)
                payload = 'a' * 500
                url = "/1.0/%s/storage/%s" % (name, col)
                data = [{'id': id_, 'payload': 'a' * 500}]
                data = Data('application/json', json.dumps(data))
                res = self.post(self.root + url, data)
                self.assertEquals(res.code, 200)

            self.clearBasicAuth()
コード例 #4
0
    def upload_file(self, parent_id, path, filename=None):
        fl = self.fl
        batch_id = uuid.uuid1().hex
        name = filename is None and os.path.basename(path) or filename
        data = open(os.path.join(path), "rb").read()
        fl.addHeader('X-Batch-Id', batch_id)
        fl.addHeader('X-File-Type', guess_type(name)[0])
        fl.addHeader('X-File-Size', len(data))
        fl.addHeader('X-File-Idx', '0')
        fl.addHeader('X-File-Name', name)
        fl.post(fl.server_url + "/site/automation/batch/upload",
                Data('binary/octet-stream', data),
                description="Upload file")
        data = None
        fl.delHeader('X-Batch-Id')
        fl.delHeader('X-File-Type')
        fl.delHeader('X-File-Size')
        fl.delHeader('X-File-Idx')
        fl.delHeader('X-File-Name')

        fl.post(fl.server_url + "/site/automation/batch/execute",
                Data('application/json+nxrequest',
                     '{"params": {"batchId": "' + batch_id + '", "parentId": "'
                     + parent_id + '", "fileIdx": "0", "name": "' + name +
                     '", "operationId": "NuxeoDrive.CreateFile"}}'),
                description="Create file")
        fl.assert_("downloadURL" in fl.getBody())
コード例 #5
0
    def __init__(self, data, content_type='application/json'):
        """Constructor

        :param data: data will be encoding to JSON.
        :type data: dict
        :param content_type: Content type for data
        :type content_type: str
        """
        Data.__init__(self, content_type, json.dumps(data))
コード例 #6
0
 def test_syncstore_read_and_write(self):
     COLLECTIONS = ["history", "bookmarks", "tabs", "passwords"]
     auth_token = uuid.uuid4().hex
     base_url = self.server_url + auth_token
     # Start by getting the info document.
     self.setHeader("Authorization", auth_token)
     self.setOkCodes([200])
     self.get(base_url + "/info/collections")
     # Read the items from a random collections.
     coll = random.choice(COLLECTIONS)
     self.setOkCodes([200, 404])
     self.get(base_url + "/storage/" + coll)
     # Write some new items into a random collection.
     coll = random.choice(COLLECTIONS)
     items = {}
     while len(items) < 10:
         id = "item%s" % (random.randrange(0, 100), )
         items[id] = {"id": id, "payload": "DATADATADATA"}
     data = Data("application/json", json.dumps(items.values()))
     self.setOkCodes([200])
     r = self.post(base_url + "/storage/" + coll, params=data)
     last_modified = int(r.headers["x-last-modified-version"])
     # Check the collection info again and sanity-check the version nums.
     r = self.get(base_url + "/info/collections")
     info = json.loads(r.body)
     assert last_modified <= info["collections"][coll]
コード例 #7
0
    def testWriter(self):
        self.initWorkspace()
        self.setBasicAuth(*self.cred_admin)
        dav_url = self.dav_url
        url = dav_url + "/" + self.ws_title

        folder_url = url + "/" + self._lipsum.getUniqWord()
        # create a folder
        self.method("MKCOL",
                    folder_url,
                    ok_codes=[
                        201,
                    ],
                    description="Create a folder")
        #resp = self.propfind(folder_url, depth=0,
        #                     description="propfind root depth0")
        # create files
        for i in range(self.nb_docs):
            doc_url = folder_url + '/' + self._lipsum.getUniqWord() + '.txt'
            content = self._lipsum.getParagraph()
            self.put(doc_url,
                     params=Data(None, content),
                     description="Create a doc " + str(i),
                     ok_codes=[
                         201,
                     ])
        self.clearBasicAuth()
コード例 #8
0
    def bind_server(self, user, password):
        fl = self.fl
        server_url = fl.server_url
        fl.addHeader('X-Devince-Id', self.device_id)
        fl.addHeader('X-User-Id', user)
        fl.addHeader('X-Application-Name', 'Nuxeo Drive')
        fl.setBasicAuth(user, password)
        fl.get(server_url + "/site/automation/",
               description="Hello automation with basic auth")
        fl.assert_('NuxeoDrive.GetTopLevelFolder' in fl.getBody(),
                   "No NuxeoDrive automation operations found")
        fl.get(server_url + "/authentication/token",
               params=[['applicationName', 'Nuxeo Drive'],
                       ['deviceDescription',
                        'Funkload Test ' + time.asctime()],
                       ['revoke', 'false'],
                       ['deviceId', self.device_id],
                       ['permission', 'ReadWrite']],
               ok_codes=[200, 201],
               description="Bind server")
        fl.clearBasicAuth()
        if self.token is None:
            self.token = fl.getBody()
        fl.addHeader('X-Authentication-Token', self.token)

        fl.get(server_url + "/site/automation/",
               description="Hello automation with token")
        fl.assert_('NuxeoDrive.GetTopLevelFolder' in fl.getBody(),
                   "Fail to access automation with the token: " + self.token)
        fl.post(server_url + "/site/automation/NuxeoDrive.GetTopLevelFolder",
                Data('application/json+nxrequest', '''{"params": {}}'''),
                description="Get top level folder")
        fl.assert_('canCreateChild' in fl.getBody())
        return self
コード例 #9
0
    def grant(self, permission, user):
        """Grant perm to user."""
        fl = self.fl
        fl.assert_('Local rights' in fl.getBody(),
                   'Current page is not a rights tab.')
        server_url = fl.server_url
        state = fl.getLastJsfState()
        fl.post(server_url + "/site/automation/UserGroup.Suggestion",
                Data('application/json+nxrequest; charset=UTF-8',
                     '{"params":{"prefix":"' + user + '"},"context":{}}'),
                description="Search user")
        fl.assert_(user in fl.getBody(), "User not found")

        fl.post(server_url + "/view_documents.faces", params=[
            ['add_rights_form', 'add_rights_form'],
            ['add_rights_form:nxl_user_group_suggestion:nxw_selection_select2_init', '[{"parentGroups":[],"grouplabel":"Members group","label":"Members group","description":"Group of users with read access rights","groupname":"members","subGroups":[],"members":[],"id":"members","type":"group","prefixed_id":"group:members"}]'],
            ['add_rights_form:nxl_user_group_suggestion:nxw_selection_select2', 'members'],
            ['add_rights_form:nxl_user_group_suggestion:nxw_selection_select2_params', '{"multiple":"true","translateLabels":"true","template":"/select2/select2_multiple_user_widget_template.xhtml","inlinejs":"function userformater(entry) {\\n   var markup = \\"<table><tr>\\";\\n   markup += \\"<td><img src=\'/nuxeo/icons/\\" + entry.type + \\".png\'/></td>\\";\\n   markup += \\"<td style=\'padding:2px\'>\\" + entry.label + \\"</td>\\";\\n   markup += \\"</tr></table>\\";\\n   return markup;\\n  }","placeholder":"Rechercher des utilisateurs ou des groupes","hideInstructionLabel":"true","minimumInputLength":"3","width":"300","customFormater":"userformater","operationId":"UserGroup.Suggestion"}'],
            ['add_rights_form:rights_grant_select', 'Grant'],
            ['add_rights_form:rights_permission_select', permission],
            ['add_rights_form:rights_add_button', 'Add'],
            ['javax.faces.ViewState', state]],
            description="Add permission to user")

        params = [
            ['validate_rights:document_rights_validate_button', 'Save local rights'],
            ['validate_rights', 'validate_rights'],
            ['javax.faces.ViewState', fl.getLastJsfState()]]
        fl.post(server_url + "/view_documents.faces", params,
                description="Grant perm apply")
        fl.assert_('Rights updated' in fl.getBody())
        return self
    def test_simple(self):
        username = '******' % random.randint(0, self.vusers-1)
        self.setBasicAuth(username, 'x' * 10)

        # GET /1.0/username/info/collections
        res = self.get(self.root + '/1.0/%s/info/collections' % username)
        self.assertEquals(res.code, 200)

        # GET /1.0/username/storage/collection
        for collection in collections:
            if random.randint(1, 4) == 4:
                url = "/1.0/%s/storage/%s?full=1" % (username, collection)
                res = self.get(self.root + url)
                self.assertEquals(res.code, 200)

        # POST /1.0/username/storage/collection
        for collection in collections:
            if random.randint(1, 4) == 4:
                id = random.randint(1, 100)
                payload = 'a' * 500
                url = "/1.0/%s/storage/%s" % (username, collection)
                data = "[{\"id\": %i, \"payload\": \"%s\"}]" % (id, payload)
                data = Data('application/json', data)
                res = self.post(self.root + url, data)
                self.assertEquals(res.code, 200)
コード例 #11
0
 def assertPrint(self, url, data):
     response = self.post(url,
                          params=Data('application/json', dumps(data)),
                          description="Issue " + data['fpqqlsh'] + "")
     self.assert_(response.code in [200], "Http request code")
     json_data = loads(self.getBody())
     self.assert_(json_data.has_key("code"), "code exist")
     self.assert_(json_data['code'] == 0, "success print")
コード例 #12
0
    def testDav(self):
        self.initWorkspace()
        self.setBasicAuth(*self.cred_admin)
        dav_url = self.dav_url

        resp = self.options(dav_url, description="option on root")
        dav = resp.headers.get('DAV')
        self.assert_(dav is not None)
        self.assert_(dav == '1,2')
        allow = resp.headers.get('Allow')
        for method in ['PROPPATCH', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK']:
            self.assert_(method in allow)

        resp = self.propfind(dav_url,
                             depth=0,
                             description="propfind root depth0")
        # dom = parseString(self.getBody())
        #for node in dom.firstChild.childNodes:
        #    print node.toxml()
        resp = self.propfind(dav_url,
                             depth=1,
                             description="propfind root depth1")
        dom = parseString(self.getBody())
        for node in dom.getElementsByTagName('ns2:href'):
            url = node.firstChild.data
            # print url

        url = dav_url + "/" + self.ws_title
        folder_url = url + "/" + self.dir_title
        self.delete(folder_url,
                    ok_codes=[204, 404],
                    description="Remove folder")

        self.method("MKCOL",
                    folder_url,
                    ok_codes=[
                        201,
                    ],
                    description="Create a folder")
        resp = self.propfind(folder_url,
                             depth=0,
                             description="propfind root depth0")

        # create file
        doc_url = folder_url + '/' + self._lipsum.getUniqWord() + '.txt'
        content = self._lipsum.getSentence()
        self.put(doc_url,
                 params=Data(None, content),
                 description="Create a doc",
                 ok_codes=[
                     201,
                 ])
        # self.delete(folder_url, ok_codes=[204, ],
        #            description="Remove folder")

        self.clearBasicAuth()
コード例 #13
0
 def executeApproveLinkOperation(self, user, passwd, mailboxId, caseId):
     self.logi("Execute approve op as: " + user)
     URL = "http://localhost:8080/nuxeo/site/automation/"
     self.setBasicAuth(user, passwd)
     data = Data(
         'application/json+nxrequest',
         '{"params":{},"context":{},"input":"docs:' + mailboxId + ',' +
         caseId + '"}')
     self.post(URL + 'Case.Management.Approve.CaseLink', data)
     self.clearBasicAuth()
コード例 #14
0
 def test_authenticate(self):
     server_url = self.server_url
     creds = self.users[randint(0, len(self.users) - 1)]
     user, password = creds.split(':')
     data = '{{"auth":{{"passwordCredentials": {{"username": "******", "password": "******"}}, "tenantName": "admin"}}}}'.format(
         user=user, password=password)
     ret = self.post(self.server_url + "/v2.0/tokens",
                     params=Data('application/json', data),
                     description="Authenticate with user")
     self.assert_(ret.code in [200, 203], "expecting 200 or 203")
コード例 #15
0
 def test_simple(self):
     server_url = self.server_url
     nb_time = self.conf_getInt('test_cloudy', 'nb_time')
     for i in range(nb_time):
         p = payload(random_line(open('urls.txt')))
         self.post(self.server_url,
                   params=Data('application/json', p),
                   description="post job api")
         status = json.loads(self.getBody())['status']
         self.assert_(status == 1)
コード例 #16
0
ファイル: test_Simple.py プロジェクト: ajbone/study_python
 def test_simple(self):
     # The description should be set in the configuration file
     server_url = self.server_url
     # begin test ---------------------------------------------
     #nb_time = self.conf_getInt('test_simple', 'nb_time')
     #for i in range(nb_time):
     req = self.post(server_url,
                     Data('text/json', self.server_params),
                     description='Get URL')
     # end test -----------------------------------------------
     print req.body
コード例 #17
0
 def assertIssue(self, url, data):
     response = self.post(url,
                          params=Data('application/json', dumps(data)),
                          description="Issue " + data['fplxdm'] + "")
     self.assert_(response.code in [200], "Http request code")
     json_data = loads(self.getBody())
     self.assert_(json_data.has_key("code"), "code exist")
     self.assert_(json_data['code'] == 0, "success issue")
     self.assert_(json_data.has_key("fpqqlsh"), "fpqqlsh exist")
     self.assert_(len(json_data['fpqqlsh']) > 0, "fpqqlsh correct")
     return json_data['fpqqlsh']
コード例 #18
0
    def testLocks(self):
        self.initWorkspace()
        self.setBasicAuth(*self.cred_admin)
        dav_url = self.dav_url
        url = dav_url + "/" + self.ws_title
        doc_url = url + "/" + "lockme"
        content = self._lipsum.getParagraph()

        self.delete(doc_url,
                    ok_codes=[204, 404],
                    description="Remove doc if exists")

        self.put(doc_url,
                 params=Data(None, content),
                 description="Create a doc",
                 ok_codes=[
                     201,
                 ])

        data = Data(
            'text/xml', """<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<lockinfo xmlns='DAV:'>
 <lockscope><exclusive/></lockscope>
<locktype><write/></locktype><owner>funkload test suite</owner>
</lockinfo>""")
        self.method("LOCK", doc_url, params=data, description="Lock")

        self.propfind(doc_url, ok_codes=[
            207,
        ], description="Get info")
        # nothing in the response tell that the doc is locked :/
        # print self.getBody()
        self.method("UNLOCK", doc_url, ok_codes=[
            204,
        ], description="Unlock")

        self.delete(doc_url, ok_codes=[
            204,
        ], description="Remove doc")
コード例 #19
0
 def navigate(self, ids):
     if len(ids) == 0:
         return
     fl = self.fl
     server_url = fl.server_url
     for id in ids:
         fl.post(server_url +
                 "/site/automation/NuxeoDrive.GetFileSystemItem",
                 Data('application/json+nxrequest',
                      '{"params": {"id": "' + id + '"}}'),
                 description="GetFileSystemItem " + id)
         download_url = extractDownloadUrl(fl.getBody())
         if download_url is not None:
             fl.get(server_url + '/' + download_url,
                    description="Download file")
         if '"folder":true' not in fl.getBody():
             continue
         fl.post(server_url + "/site/automation/NuxeoDrive.GetChildren",
                 Data('application/json+nxrequest',
                      '{"params": {"id": "' + id + '"}}'),
                 description="GetChildren " + id)
         children = extractIds(fl.getBody())
         self.navigate(children)
コード例 #20
0
    def test_app_storage_session(self):
        token, secret, endpoint_url = self._generate_token()

        # Initial GET of the (empty) set of apps.
        self.setOkCodes([200])
        url = endpoint_url + "/apps/"
        self.setMACAuthHeader("GET", url, token, secret)
        response = self.get(url)
        # The list of apps may not be empty, if we happen to be usinga a uid
        # that has already been used.  Just sanity-check that it parses.
        apps = json.loads(response.body)["apps"]

        TEST_APP_DATA = {
            "origin": "https://example.com",
            "manifestPath": "/manifest.webapp",
            "installOrigin": "https://marketplace.mozilla.org",
            "modifiedAt": 1234,  # this will be overwritten on write
            "installedAt": 1234,  # this will not be overwritten
            "name": "Examplinator 3000",
            "receipts": ["receipt1", "receipt2"],
        }

        # Alternating series of PUTs and GETs.
        for x in range(self._pick_weighted_count(put_count_distribution)):
            self.setOkCodes([201, 204])
            data = TEST_APP_DATA.copy()
            data["origin"] = origin = "https://example%d.com" % (x, )
            id = hashlib.sha1(data["origin"]).digest()
            id = base64.urlsafe_b64encode(id).rstrip("=")
            url = endpoint_url + "/apps/" + id
            data = Data('application/json', json.dumps(data))
            self.logi("about to PUT (x=%d) %s" % (x, url))
            self.setMACAuthHeader("PUT", url, token, secret)
            response = self.put(url, params=data)

            self.setOkCodes([200])
            url = endpoint_url + "/apps/"
            self.setMACAuthHeader("GET", url, token, secret)
            response = self.get(url)
            # Make sure that the app we just uploaded is included
            # in the list of apps.
            apps = json.loads(response.body)["apps"]
            for app in apps:
                if app["origin"] == origin:
                    break
            else:
                assert False, "uploaded app was not included in list"
コード例 #21
0
    def test_search(self):
        """ Query contacts and tags. Write a new tag, updating index. Query again. """
        contacts_url = self.server_url + '/contacts?q=rec'
        mail_tags_url = self.server_url + '/mail/%s/tags'
        all_tags_url = self.server_url + '/tags'
        tags = ['inbox', 'trash', 'drafts']
        nb_time = self.conf_getInt('main', 'nb_time')

        for i in range(nb_time):
            self.get(contacts_url, description='Query for contacts')
            idents = self.idents_by_tag(tags[i % 3])
            tag_data = Data('application/json', '{"newtags":["newtag%s"]}' % i)
            self.post(mail_tags_url % idents[i % 3],
                      tag_data,
                      description='Change tags on a mail')
            self.idents_by_tag(tags[i % 3])
            self.get(all_tags_url, description='Query for all tags listing')
コード例 #22
0
    def createUser(self, username, email, password, firstname='',
                   lastname='', company='', groups=''):
        """This method does not raise exception if user already exists"""
        fl = self.fl
        if (not 'createUser:button_save_and_create' in fl.getBody()):
            fl.assert_('createUserButton' in fl.getBody(),
                       "You should call usersAndGroupsPage first")
            fl.post(fl.server_url + "/view_admin.faces", params=[
                    ['AJAXREQUEST', 'usersListingView:cv_users_listing_search_only__region'],
                    ['usersListingView:createUserActionsForm', 'usersListingView:createUserActionsForm'],
                    ['javax.faces.ViewState', fl.getLastJsfState()],
                    ['usersListingView:createUserActionsForm:createUserButton', 'usersListingView:createUserActionsForm:createUserButton']],
                    description="View user creation form")
        fl.assert_('createUser:button_save_and_create' in fl.getBody(),
                   'Wrong page')

        jsfState = fl.getLastJsfState()
        fl.post(fl.server_url + "/site/automation/UserGroup.Suggestion",
                Data('application/json+nxrequest; charset=UTF-8',
                     '{"params":{"prefix":"' + groups + '"},"context":{}}'),
                description="Search group")
        fl.assert_(groups in fl.getBody(), "Group not found")

        # /tmp/tmp2uCzyC_funkload/watch0001.request
        fl.post(fl.server_url + "/view_admin.faces", params=[
            ['AJAXREQUEST', '_viewRoot'],
            ['createUserView:createUser:nxl_user:nxw_username', username],
            ['createUserView:createUser:nxl_user:nxw_firstname', firstname],
            ['createUserView:createUser:nxl_user:nxw_lastname', lastname],
            ['createUserView:createUser:nxl_user:nxw_company', company],
            ['createUserView:createUser:nxl_user:nxw_email', email],
            ['createUserView:createUser:nxl_user:nxw_firstPassword', password],
            ['createUserView:createUser:nxl_user:nxw_secondPassword', password],
            ['createUserView:createUser:nxl_user:nxw_passwordMatcher', 'needed'],
            # ['createUserView:createUser:nxl_user:nxw_groups_select2_init', '[{"parentGroups":[],"grouplabel":"Members group","label":"Members group","description":"Group of users with read access rights","groupname":"members","subGroups":[],"members":[],"id":"members","type":"group","prefixed_id":"group:members"}]'],
            ['createUserView:createUser:nxl_user:nxw_groups_select2', groups],
            # ['createUserView:createUser:nxl_user:nxw_groups_select2_params', '{"multiple":"true","translateLabels":"true","template":"/select2/select2_multiple_user_widget_template.xhtml","hideVirtualGroups":"true","userSuggestionSearchType":"GROUP_TYPE","inlinejs":"function userformater(entry) {\\n   var markup = \\"<table><tr>\\";\\n   markup += \\"<td><img src=\'/nuxeo/icons/\\" + entry.type + \\".png\'/></td>\\";\\n   markup += \\"<td style=\'padding:2px\'>\\" + entry.label + \\"</td>\\";\\n   markup += \\"</tr></table>\\";\\n   return markup;\\n  }","minimumInputLength":"3","width":"300","searchType":"group","customFormater":"userformater","operationId":"UserGroup.Suggestion","placeholder":"S\xc3\xa9lectionnez une valeur."}'],
            ['createUserView:createUser', 'createUserView:createUser'],
            ['autoScroll', ''],
            ['javax.faces.ViewState', jsfState],
            ['createUserView:createUser:button_save_and_create', 'createUserView:createUser:button_save_and_create'],
            ['AJAX:EVENTS_COUNT', '1']],
            description="Create user")
        fl.assert_('User already exists' in fl.getBody() or
                   'User created' in fl.getBody())
        return self
コード例 #23
0
 def get_update(self, comment="", since=None):
     fl = self.fl
     if since is None:
         since = self.last_sync
         if since is None:
             since = str(int((time.time() - 10) * 1000))
     fl.post(self.fl.server_url +
             "/site/automation/NuxeoDrive.GetChangeSummary",
             Data('application/json+nxrequest',
                  '{"params": {"lastSyncDate": ' +
                  since +
                  ', "lastSyncActiveRootDefinitions": "' +
                  self.sync_ids + '"}}'),
             description="GetChangeSummary" + comment)
     fl.assert_('hasTooManyChanges' in fl.getBody())
     self.last_sync = extractSyncDate(fl.getBody())
     return self
    def _content(self):
        apps_url = self.start_session()

        # filling with some data
        # XXX We need realistic stuff here
        for i in range(10):
            app1 = {'origin': 'app1-%d' % i ,
                    'last_modified': time.time() + 0.1}
            app2 = {'origin': 'app2-%d' % i,
                    'last_modified': time.time() + 0.1}
            apps = json.dumps([app1, app2])

            apps = Data('application/json', apps)
            resp = self.post(apps_url, params=apps)
            self.assertEquals(resp.code, 200)
            res = json.loads(resp.body)
            self.assertTrue('received' in res)

        # checking what we have
        myapps = json.loads(self.get(apps_url).body)
        self.assertEquals(len(myapps['applications']), 20)
コード例 #25
0
    def test_storage_session(self):
        self._generate_token_credentials()
        self.logi("using endpoint url %s" % (self.endpoint_url,))

        # Always GET info/collections
        self.setOkCodes([200, 404])
        url = self.endpoint_url + "/info/collections"
        response = self.get(url)

        # GET requests to meta/global.
        num_requests = self._pick_weighted_count(metaglobal_count_distribution)
        self.setOkCodes([200, 404])
        for x in range(num_requests):
            url = self.endpoint_url + "/storage/meta/global"
            response = self.get(url)
            if response.code == 404:
                metapayload = "This is the metaglobal payload which contains"\
                              " some client data that doesnt look much"\
                              " like this"
                data = json.dumps({"id": "global", "payload": metapayload})
                data = Data('application/json', data)
                self.setOkCodes([200, 201])
                self.put(url, params=data)

        # GET requests to individual collections.
        num_requests = self._pick_weighted_count(get_count_distribution)
        cols = random.sample(collections, num_requests)
        self.setOkCodes([200, 404])
        for x in range(num_requests):
            url = self.endpoint_url + "/storage/" + cols[x]
            newer = int(time.time() - random.randint(3600, 360000))
            params = {"full": "1", "newer": str(newer)}
            self.logi("about to GET (x=%d) %s" % (x, url))
            response = self.get(url, params)

        # PUT requests with 100 WBOs batched together
        num_requests = self._pick_weighted_count(post_count_distribution)
        cols = random.sample(collections, num_requests)
        self.setOkCodes([200])
        for x in range(num_requests):
            url = self.endpoint_url + "/storage/" + cols[x]
            data = []
            items_per_batch = 10
            for i in range(items_per_batch):
                id = base64.urlsafe_b64encode(os.urandom(10)).rstrip("=")
                id += str(int((time.time() % 100) * 100000))
                payload = self.auth_token * random.randint(50, 200)
                wbo = {'id': id, 'payload': payload}
                data.append(wbo)
            data = json.dumps(data)
            data = Data('application/json', data)
            self.logi("about to POST (x=%d) %s" % (x, url))
            response = self.post(url, params=data)
            body = response.body
            self.assertTrue(body != '')
            result = json.loads(body)
            self.assertEquals(len(result["success"]), items_per_batch)
            self.assertEquals(len(result["failed"]), 0)

        # DELETE requests.
        # We might choose to delete some individual collections, or to do
        # a full reset and delete all the data.  Never both in the same run.
        num_requests = self._pick_weighted_count(delete_count_distribution)
        self.setOkCodes([204])
        if num_requests:
            cols = random.sample(collections, num_requests)
            for x in range(num_requests):
                url = self.endpoint_url + "/storage/" + cols[x]
                self.delete(url)
        else:
            if random.random() <= deleteall_probability:
                url = self.endpoint_url + "/storage"
                self.delete(url)
コード例 #26
0
ファイル: pages.py プロジェクト: skogtroll/nuxeo
    def dashboardNew(self):
        """open social dashboard"""
        fl = self.fl
        server_url = fl.server_url
        fl.post(
            fl.server_url + "/view_documents.faces",
            params=[[
                'userServicesForm:userServicesActionsTable:0:userServicesActionCommandLink',
                'userServicesForm:userServicesActionsTable:0:userServicesActionCommandLink'
            ], ['javax.faces.ViewState',
                fl.getLastJsfState()],
                    ['userServicesForm', 'userServicesForm']],
            description="Dashboard opensocial")

        ts = str(time.time())
        jid = extractJsessionId(fl)
        uid = extractToken(fl.getBody(), """return "{docRef:'""", "'")
        fl.assert_(len(uid) == 36)

        fl.get(
            server_url +
            "/org.nuxeo.opensocial.container.ContainerEntryPoint/org.nuxeo.opensocial.container.ContainerEntryPoint.nocache.js",
            description="Get container entry point")
        data = Data(
            'text/x-gwt-rpc; charset=utf-8', '''5|0|17|''' + server_url +
            '''/org.nuxeo.opensocial.container.ContainerEntryPoint/|9CCFB53A0997F1E4596C8EE4765CCBAA|org.nuxeo.opensocial.container.client.service.api.ContainerService|getContainer|java.util.Map|java.util.HashMap/962170901|java.lang.String/2004016611|docRef|'''
            + uid + '''|clientUrl|''' + server_url +
            '''/|windowWidth|10|nxBaseUrl|userLanguage|fr|locale|1|2|3|4|1|5|6|6|7|8|7|9|7|10|7|11|7|12|7|13|7|14|-5|7|15|7|16|7|17|-10|'''
        )
        fl.post(server_url + "/gwtcontainer",
                data,
                description="dashboard gwt container")
        fl.assert_('//OK' in fl.getBody())

        # Extract iframes from the gwtcontainer response
        iframes = extractIframes(fl.getBody())
        fl.assert_(len(iframes))

        i = 0
        for iframe in iframes:
            i += 1
            # print "iframe: " + iframe
            fl.get(server_url + iframe, description="dashboard iframe %d" % i)
            fl.assert_(fl.getBody().startswith('<html>'))

        fl.get(
            server_url + "/opensocial/gadgets/makeRequest?refresh=3600&url=" +
            quote_plus(server_url) +
            "%2FrestAPI%2Fdashboard%2FUSER_SITES%3Fformat%3DJSON%26page%3D0%26domain%3Ddefault-domain%26lang%3Den%26ts%3D12766046361930.9475744903817575&httpMethod=GET&headers=Cache-control%3Dno-cache%252C%2520must-revalidate%26X-NUXEO-INTEGRATED-AUTH%3D"
            + jid +
            "&postData=&authz=&st=&contentType=JSON&numEntries=3&getSummaries=false&signOwner=true&signViewer=true&gadget="
            + quote_plus(server_url) +
            "%2Fsite%2Fgadgets%2Fuserdocuments%2Fusersites.xml&container=default&bypassSpecCache=1&nocache=0",
            description="dashboard req1: user sites")
        fl.assert_('USER_SITES' in fl.getBody())

        fl.post(
            server_url + "/opensocial/gadgets/makeRequest",
            params=
            [['authz', ''], ['signOwner', 'true'], ['contentType', 'JSON'],
             ['nocache', '0'
              ],
             ['postData', ''
              ],
             [
                 'headers',
                 'Cache-control=no-cache%2C%20must-revalidate&X-NUXEO-INTEGRATED-AUTH='
                 + jid
             ],
             [
                 'url', server_url +
                 '/restAPI/workflowTasks/default?mytasks=false&format=JSON&ts='
                 + ts +
                 '&lang=en&labels=workflowDirectiveValidation,workflowDirectiveOpinion,workflowDirectiveVerification,workflowDirectiveCheck,workflowDirectiveDiffusion,label.workflow.task.name,label.workflow.task.duedate,label.workflow.task.directive'
             ], ['numEntries', '3'], ['bypassSpecCache', '1'], ['st', ''],
             ['httpMethod', 'GET'], ['signViewer', 'true'],
             ['container', 'default'], ['getSummaries', 'false'],
             [
                 'gadget',
                 server_url + '/site/gadgets/waitingfor/waitingfor.xml'
             ]],
            description="dashboard req2: other tasks")
        fl.assert_('Tasks for' in fl.getBody())

        fl.get(
            server_url + "/opensocial/gadgets/makeRequest?refresh=3600&url=" +
            quote_plus(server_url) +
            "%2FrestAPI%2Fdashboard%2FUSER_WORKSPACES%3Fformat%3DJSON%26page%3D0%26domain%3Ddefault-domain%26lang%3Den%26ts%3D12766046364186.08350334148753&httpMethod=GET&headers=Cache-control%3Dno-cache%252C%2520must-revalidate%26X-NUXEO-INTEGRATED-AUTH%3DEB4D8F264629C549917996193637A4F4&postData=&authz=&st=&contentType=JSON&numEntries=3&getSummaries=false&signOwner=true&signViewer=true&gadget="
            + quote_plus(server_url) +
            "%2Fsite%2Fgadgets%2Fuserworkspaces%2Fuserworkspaces.xml&container=default&bypassSpecCache=1&nocache=0",
            description="dashboard req3: user workspaces")
        fl.assert_('USER_WORKSPACES' in fl.getBody())

        fl.post(
            server_url + "/opensocial/gadgets/makeRequest",
            params=
            [['authz', ''], ['signOwner', 'true'], ['contentType', 'JSON'],
             ['nocache', '0'
              ],
             ['postData', ''
              ],
             [
                 'headers',
                 'Cache-control=no-cache%2C%20must-revalidate&X-NUXEO-INTEGRATED-AUTH=EB4D8F264629C549917996193637A4F4'
             ],
             [
                 'url', server_url +
                 '/restAPI/workflowTasks/default?mytasks=true&format=JSON&ts='
                 + ts +
                 '&lang=en&labels=workflowDirectiveValidation,workflowDirectiveOpinion,workflowDirectiveVerification,workflowDirectiveCheck,workflowDirectiveDiffusion,label.workflow.task.name,label.workflow.task.duedate,label.workflow.task.directive'
             ], ['numEntries', '3'], ['bypassSpecCache', '1'], ['st', ''],
             ['httpMethod', 'GET'], ['signViewer', 'true'],
             ['container', 'default'], ['getSummaries', 'false'],
             ['gadget', server_url + '/site/gadgets/tasks/tasks.xml']],
            description="dashboard req4: my tasks")
        fl.assert_('Tasks for' in fl.getBody())

        fl.get(
            server_url + "/opensocial/gadgets/makeRequest?refresh=3600&url=" +
            quote_plus(server_url) +
            "%2FrestAPI%2Fdashboard%2FRELEVANT_DOCUMENTS%3Fformat%3DJSON%26page%3D0%26domain%3Ddefault-domain%26lang%3Den%26ts%3D12766046370131.186666326174645&httpMethod=GET&headers=Cache-control%3Dno-cache%252C%2520must-revalidate%26X-NUXEO-INTEGRATED-AUTH%3DEB4D8F264629C549917996193637A4F4&postData=&authz=&st=&contentType=JSON&numEntries=3&getSummaries=false&signOwner=true&signViewer=true&gadget="
            + quote_plus(server_url) +
            "%2Fsite%2Fgadgets%2Fuserdocuments%2Fuserdocuments.xml&container=default&bypassSpecCache=1&nocache=0",
            description="dashboard req5: relevant docs")
        fl.assert_('RELEVANT_DOCUMENTS' in fl.getBody())
        return self
コード例 #27
0
ファイル: stress.py プロジェクト: jisqyv/server-syncstorage
    def test_storage_session(self):
        self._generate_token_credentials()
        self.logi("using endpoint url %s" % (self.endpoint_url, ))

        # Always GET info/collections
        self.setOkCodes([200, 404])
        url = self.endpoint_url + "/info/collections"
        response = self.get(url)

        # GET requests to meta/global.
        num_requests = self._pick_weighted_count(metaglobal_count_distribution)
        self.setOkCodes([200, 404])
        for x in range(num_requests):
            url = self.endpoint_url + "/storage/meta/global"
            response = self.get(url)
            if response.code == 404:
                metapayload = "This is the metaglobal payload which contains"\
                              " some client data that doesnt look much"\
                              " like this"
                data = json.dumps({"id": "global", "payload": metapayload})
                data = Data('application/json', data)
                self.setOkCodes([200, 201])
                self.put(url, params=data)

        # GET requests to individual collections.
        num_requests = self._pick_weighted_count(get_count_distribution)
        cols = random.sample(collections, num_requests)
        self.setOkCodes([200, 404])
        for x in range(num_requests):
            url = self.endpoint_url + "/storage/" + cols[x]
            newer = int(time.time() - random.randint(3600, 360000))
            params = {"full": "1", "newer": str(newer)}
            self.logi("about to GET (x=%d) %s" % (x, url))
            response = self.get(url, params)

        # PUT requests with 100 WBOs batched together
        num_requests = self._pick_weighted_count(post_count_distribution)
        cols = random.sample(collections, num_requests)
        self.setOkCodes([200])
        for x in range(num_requests):
            url = self.endpoint_url + "/storage/" + cols[x]
            data = []
            items_per_batch = 10
            for i in range(items_per_batch):
                id = base64.urlsafe_b64encode(os.urandom(10)).rstrip("=")
                id += str(int((time.time() % 100) * 100000))
                payload = self.auth_token * random.randint(50, 200)
                wbo = {'id': id, 'payload': payload}
                data.append(wbo)
            data = json.dumps(data)
            data = Data('application/json', data)
            self.logi("about to POST (x=%d) %s" % (x, url))
            response = self.post(url, params=data)
            body = response.body
            self.assertTrue(body != '')
            result = json.loads(body)
            self.assertEquals(len(result["success"]), items_per_batch)
            self.assertEquals(len(result["failed"]), 0)

        # DELETE requests.
        # We might choose to delete some individual collections, or to do
        # a full reset and delete all the data.  Never both in the same run.
        num_requests = self._pick_weighted_count(delete_count_distribution)
        self.setOkCodes([204])
        if num_requests:
            cols = random.sample(collections, num_requests)
            for x in range(num_requests):
                url = self.endpoint_url + "/storage/" + cols[x]
                self.delete(url)
        else:
            if random.random() <= deleteall_probability:
                url = self.endpoint_url + "/storage"
                self.delete(url)
コード例 #28
0
ファイル: pages.py プロジェクト: skogtroll/nuxeo
    def createUser(self,
                   username,
                   email,
                   password,
                   firstname='',
                   lastname='',
                   company='',
                   groups=''):
        """This method does not raise exception if user already exists"""
        fl = self.fl
        if (not 'createUser:button_save' in fl.getBody()):
            fl.assert_('createUserButton' in fl.getBody(),
                       "You should call usersAndGroupsPage first")
            fl.post(
                fl.server_url + "/view_admin.faces?conversationId=0NXMAIN1",
                params=[
                    [
                        'usersListingView:createUserActionsForm',
                        'usersListingView:createUserActionsForm'
                    ],
                    ['javax.faces.ViewState',
                     fl.getLastJsfState()],
                    [
                        'javax.faces.source',
                        'usersListingView:createUserActionsForm:createUserButton'
                    ],
                    ['javax.faces.partial.event', 'click'],
                    [
                        'javax.faces.partial.execute',
                        'usersListingView:createUserActionsForm:createUserButton'
                    ],
                    ['javax.faces.partial.render', 'usersPanel'],
                    ['javax.faces.behavior.event', 'action'],
                    ['AJAX:EVENTS_COUNT', '1'],
                    ['rfExt', 'null'],
                    # FIXME: for some unknown reason, funkload needs this param for request to be ajaxified
                    ['Faces-Request', 'partial/ajax'],
                    ['javax.faces.partial.ajax', 'true']
                ],
                description="View user creation form")
            fl.assert_(
                'createUserView:createUser:nxl_user:nxw_passwordMatcher_immediate_creation'
                in fl.getBody(), 'Wrong user creation page')

        fl.post(
            fl.server_url + "/view_admin.faces",
            params=
            [[
                'createUserView:createUser:nxl_user:nxw_passwordMatcher_immediate_creation',
                'true'
            ],
             [
                 'ajaxSingle',
                 'createUserView:createUser:nxl_user:nxw_passwordMatcher_immediate_creation:1'
             ], ['AJAX:EVENTS_COUNT', '1'],
             ['createUserView:createUser', 'createUserView:createUser'],
             [
                 'createUserView:createUser:nxl_user:nxw_passwordMatcher_immediate_creation',
                 'true'
             ], ['javax.faces.ViewState',
                 fl.getLastJsfState()],
             [
                 'javax.faces.source',
                 'createUserView:createUser:nxl_user:nxw_passwordMatcher_immediate_creation:1'
             ], ['javax.faces.partial.event', 'click'],
             [
                 'javax.faces.partial.execute',
                 'createUserView:createUser:nxl_user:nxw_passwordMatcher_immediate_creation:1'
             ], ['javax.faces.partial.render', 'createUserView:createUser'],
             ['javax.faces.behavior.event', 'click'],
             ['AJAX:EVENTS_COUNT', '1'], ['rfExt', 'null'],
             ['javax.faces.partial.ajax', 'true']],
            description="Set immediate user creation")

        # The assert is removed because the body contains now the Ajax
        # response and not the body of the page so the assert will
        # always fail:
        #fl.assert_('createUser:button_save_and_create' in
        #fl.getBody(), 'Wrong page')

        jsfState = fl.getLastJsfState()
        fl.post(
            fl.server_url + "/site/automation/UserGroup.Suggestion",
            Data('application/json+nxrequest; charset=UTF-8',
                 '{"params":{"searchTerm":"' + groups + '"},"context":{}}'),
            description="Search group")
        fl.assert_(groups in fl.getBody(), "Group not found")

        fl.post(
            fl.server_url + "/view_admin.faces",
            params=
            [['createUserView:createUser', 'createUserView:createUser'],
             [
                 'createUserView:createUser:nxl_user:nxw_passwordMatcher_immediate_creation',
                 'true'
             ], ['createUserView:createUser:nxl_user:nxw_username', username],
             ['createUserView:createUser:nxl_user:nxw_firstname', firstname],
             ['createUserView:createUser:nxl_user:nxw_lastname', lastname],
             ['createUserView:createUser:nxl_user:nxw_company', company],
             ['createUserView:createUser:nxl_user:nxw_email', email],
             [
                 'createUserView:createUser:nxl_user:nxw_passwordMatcher_firstPassword',
                 password
             ],
             [
                 'createUserView:createUser:nxl_user:nxw_passwordMatcher_secondPassword',
                 password
             ],
             [
                 'createUserView:createUser:nxl_user:nxw_passwordMatcher',
                 'needed'
             ],
             ['createUserView:createUser:nxl_user:nxw_groups_select2', groups],
             ['javax.faces.ViewState', jsfState],
             ['javax.faces.source', 'createUserView:createUser:button_save'],
             ['javax.faces.partial.event', 'click'],
             [
                 'javax.faces.partial.execute',
                 'createUserView:createUser:button_save createUserView:createUser'
             ],
             [
                 'javax.faces.partial.render',
                 'usersPanel facesStatusMessagePanel'
             ], ['javax.faces.behavior.event', 'action'],
             ['AJAX:EVENTS_COUNT', '1'], ['rfExt', 'null'],
             ['javax.faces.partial.ajax', 'true']],
            description="Create user")

        fl.assert_('User already exists' in fl.getBody()
                   or 'User created' in fl.getBody())
        return self
コード例 #29
0
 def test_common(self):
     try:
         #获取测试网页的数量
         page_number = int(self.conf_get("pages", "page_number"))
         #获取需测试网页编号
         test_page_list_conf = self.conf_get("pages", "test_page_list")
 
         for page_index in range(page_number):
             section = "page_%s_section" % page_index
             if test_page_list_conf.lower() not in ["noset", "all"]:
                 if page_index not in json.loads(test_page_list_conf):
                     continue
             elif test_page_list_conf.lower() == "noset":
                 if "false" == self.conf_get(section, "need_test").lower():
                     continue
                 
             http_method = self.conf_get(section, "page_method")
             function = getattr(self, http_method.lower())
             self.url_path = self.conf_get(section, "page_path")
             
             request_type = self.conf_get(section, "request_type").lower()
             if request_type == "none":
                 self.request = None
             elif request_type == "data":
                 data_type = self.conf_get(section, "data_type")
                 data = self.conf_get(section, "data")
                 if data.startswith("@"):
                     data = open(data[1:]).read()
                 
                 self.request = Data(data_type, data)
             elif request_type == "params":
                 data = json.loads(self.conf_get(section, "data").replace("'", '"'))
                 for items in data:
                     if items[1].startswith("upload@"):
                         items[1] = Upload(items[1][7:])
                     elif items[1].startswith("@"):
                         items[1] = open(items[1][1:]).read()
                 
                 #这里可能需要处理一下数据,请填写自定义代码
                 pass
                 self.request = data
             
             ok_codes = self.conf_get(section, "ok_codes")
             if ok_codes.lower() != "none":
                 ok_codes = map(lambda x:int(x.replace(" ", "")), ok_codes.split(","))
             else:
                 ok_codes = None
                 
             #添加头
             try:
                 self.clearHeaders()
                 heads = self.conf_get(section, "headers")
                 for head in heads.split("&&&"):
                     item = head.split("===")
                     self.addHeader(item[0], item[1])
             except NoOptionError, ex:
                 pass
             
             #前处理
             self.request_preprocess(page_index)
             
             #接口调用
             self.response = function(self.host + self.url_path, self.request, description = self.host + self.url_path, ok_codes = ok_codes)
             #print self.response.headers
             self.log_write(self.response.body)
             
             #后处理
             self.postprocess(page_index)
             
     except Exception,ex:
         self.error_log_write(str(ex))
コード例 #30
0
ファイル: pages.py プロジェクト: skogtroll/nuxeo
 def auto_DocumentQuery(self, nxql):
     data = Data('application/json+nxrequest',
                 '{"params":{"query":"' + nxql + '"},"context":{}}')
     self.fl.post(self.fl.server_url + '/site/automation/Document.Query',
                  data)
コード例 #31
0
ファイル: stress.py プロジェクト: jbonacci/server-storage
    def test_storage_session(self):
        username = self._pick_user()
        password = "******"
        node = self._pick_node()
        self.logi("choosing node %s" % (node))
        self.setBasicAuth(username, password)

        # Always GET /username/info/collections
        self.setOkCodes([200, 404])
        url = node + "/%s/%s/info/collections" % (VERSION, username)
        response = self.get(url)

        # GET requests to meta/global.
        num_requests = self._pick_weighted_count(metaglobal_count_distribution)
        self.setOkCodes([200, 404])
        for x in range(num_requests):
            url = node + "/%s/%s/storage/meta/global" % (VERSION, username)
            response = self.get(url)
            if response.code == 404:
                metapayload = "This is the metaglobal payload which contains"\
                              " some client data that doesnt look much"\
                              " like this"
                data = json.dumps({"id": "global", "payload": metapayload})
                data = Data('application/json', data)
                self.put(url, params=data)

        # GET requests to individual collections.
        num_requests = self._pick_weighted_count(get_count_distribution)
        cols = random.sample(collections, num_requests)
        self.setOkCodes([200, 404])
        for x in range(num_requests):
            url = node + "/%s/%s/storage/%s" % (VERSION, username, cols[x])
            newer = int(time.time() - random.randint(3600, 360000))
            params = {"full": "1", "newer": str(newer)}
            self.logi("about to GET (x=%d) %s" % (x, url))
            response = self.get(url, params)

        # PUT requests with 100 WBOs batched together
        num_requests = self._pick_weighted_count(post_count_distribution)
        cols = random.sample(collections, num_requests)
        self.setOkCodes([200])
        for x in range(num_requests):
            url = node + "/%s/%s/storage/%s" % (VERSION, username, cols[x])
            data = []
            items_per_batch = 10
            for i in range(items_per_batch):
                id = base64.b64encode(os.urandom(10))
                id += str(time.time() % 100)
                payload = username * random.randint(50, 200)
                wbo = {'id': id, 'payload': payload}
                data.append(wbo)
            data = json.dumps(data)
            data = Data('application/json', data)
            self.logi("about to POST (x=%d) %s" % (x, url))
            response = self.post(url, params=data)
            body = response.body
            self.assertTrue(body != '')
            result = json.loads(body)
            self.assertEquals(len(result["success"]), items_per_batch)
            self.assertEquals(len(result["failed"]), 0)

        # DELETE requests.
        # We might choose to delete some individual collections, or to do
        # a full reset and delete all the data.  Never both in the same run.
        num_requests = self._pick_weighted_count(delete_count_distribution)
        self.setOkCodes([200])
        if num_requests:
            cols = random.sample(collections, num_requests)
            for x in range(num_requests):
                url = node + "/%s/%s/storage/%s" % (VERSION, username, cols[x])
                self.delete(url)
        else:
            if random.random() <= deleteall_probability:
                url = node + "/%s/%s/storage" % (VERSION, username)
                self.setHeader("X-Confirm-Delete", "true")
                self.delete(url)