Example #1
0
async def verifyDomain(domain):
    """ create domain if it doesn't already exist
    """
    params = {"host": domain}
    headers = getRequestHeaders()
    client = globals["client"]
    req = getEndpoint() + '/'
    root_id = None
    log.info("GET " + req)
    timeout = config.get("timeout")
    async with client.get(req, headers=headers, timeout=timeout,
                          params=params) as rsp:
        if rsp.status == 200:
            domain_json = await rsp.json()
        else:
            log.info("got status: {}".format(rsp.status))
    if rsp.status == 200:
        root_id = domain_json["root"]
    elif rsp.status == 404:
        # create the domain
        setupDomain(domain)
        async with client.get(req,
                              headers=headers,
                              timeout=timeout,
                              params=params) as rsp:
            if rsp.status == 200:
                domain_json = await rsp.json()
                root_id = domain_json["root"]
            else:
                log.error("got status: {} for GET req: {}".format(
                    rsp.status, req))
                raise HttpProcessingError(code=rsp.status,
                                          message="Service error")
    globals["root"] = root_id
Example #2
0
    def testExternalLink(self):
        domain = self.base_domain + "/testExternalLink.h5"
        print("testExternalLink", domain)
        helper.setupDomain(domain)
        headers = helper.getRequestHeaders(domain=domain)
        req = helper.getEndpoint() + '/'

        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        root_id = rspJson["root"]

        # get root group and check it has no links
        req = helper.getEndpoint() + "/groups/" + root_id
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertEqual(rspJson["linkCount"], 0)  # no links

        # create external link
        target_domain = self.base_domain + '/external_target.h5'
        target_path = 'somewhere'
        link_title = 'external_link'
        req = helper.getEndpoint(
        ) + "/groups/" + root_id + "/links/" + link_title
        payload = {"h5path": target_path, "h5domain": target_domain}
        rsp = requests.put(req, data=json.dumps(payload), headers=headers)
        self.assertEqual(rsp.status_code, 201)  # created

        # get root group and check it has one link
        req = helper.getEndpoint() + "/groups/" + root_id
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertEqual(rspJson["linkCount"], 1)  # no links

        # get the link
        req = helper.getEndpoint(
        ) + "/groups/" + root_id + "/links/" + link_title
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)  # should get the softlink
        rspJson = json.loads(rsp.text)
        self.assertTrue("created" in rspJson)
        self.assertTrue("lastModified" in rspJson)
        self.assertTrue("hrefs" in rspJson)
        self.assertTrue("link" in rspJson)
        rspLink = rspJson["link"]
        self.assertEqual(rspLink["title"], link_title)
        self.assertEqual(rspLink["class"], "H5L_TYPE_EXTERNAL")
        self.assertEqual(rspLink["h5path"], target_path)
        self.assertEqual(rspLink["h5domain"], target_domain)
Example #3
0
 def __init__(self, *args, **kwargs):
     super(GroupTest, self).__init__(*args, **kwargs)
     self.base_domain = helper.getTestDomainName(self.__class__.__name__)
     helper.setupDomain(self.base_domain)
Example #4
0
    def testGetDomains(self):
        folder = self.base_domain + "/testGetDomains"
        helper.setupDomain(folder, folder=True)
        print("testGetDomains", folder)

        # create some domains in the base_domain folder
        domain_count = 8
        basenames = []
        for i in range(domain_count):
            domain = "domain_" + str(i) + ".h5"
            basenames.append(domain)
            sub_domain = folder + '/' + domain
            helper.setupDomain(sub_domain)
            print(i, ':', sub_domain)
            headers = helper.getRequestHeaders(domain=sub_domain)
            # get root id
            req = helper.getEndpoint() + '/'
            rsp = requests.get(req, headers=headers)
            self.assertEqual(rsp.status_code, 200)
            rspJson = json.loads(rsp.text)
            root_id = rspJson["root"]
            helper.validateId(root_id)
            # create attr1 in root group
            attr_name = "attr1"
            attr_payload = {'type': 'H5T_STD_I32LE', 'value': i * 2}
            req = helper.getEndpoint(
            ) + '/groups/' + root_id + "/attributes/" + attr_name
            rsp = requests.put(req,
                               data=json.dumps(attr_payload),
                               headers=headers)
            self.assertEqual(rsp.status_code, 201)  # created
            # create attr2 in root group
            attr_name = "attr2"
            fixed_str_type = {
                "charSet": "H5T_CSET_ASCII",
                "class": "H5T_STRING",
                "length": 8,
                "strPad": "H5T_STR_NULLPAD"
            }
            attr_payload = {"type": fixed_str_type, "value": f"A{i:07}"}
            req = helper.getEndpoint(
            ) + '/groups/' + root_id + "/attributes/" + attr_name
            rsp = requests.put(req,
                               data=json.dumps(attr_payload),
                               headers=headers)
            self.assertEqual(rsp.status_code, 201)  # created

        headers = helper.getRequestHeaders()
        params = {"domain": folder + '/'}
        if config.get("bucket_name"):
            params["bucket"] = config.get("bucket_name")
        req = helper.getEndpoint() + '/domains'
        rsp = requests.get(req, headers=headers, params=params)
        self.assertEqual(rsp.status_code, 200)
        self.assertEqual(rsp.headers['content-type'],
                         'application/json; charset=utf-8')
        rspJson = json.loads(rsp.text)
        self.assertTrue("domains" in rspJson)
        domains = rspJson["domains"]

        self.assertEqual(domain_count, len(domains))

        for item in domains:
            self.assertTrue("name" in item)
            name = item["name"]
            self.assertTrue(pp.basename(name) in basenames)
            self.assertEqual(name[0], '/')
            self.assertTrue(name[-1] != '/')
            self.assertTrue("owner" in item)
            self.assertTrue("class" in item)
            self.assertEqual(item["class"], "domain")
            self.assertTrue("lastModified" in item)
            self.assertFalse("size" in item)

        # try getting the first 4 domains
        params = {"domain": folder + '/', "Limit": 4}
        if config.get("bucket_name"):
            params["bucket"] = config.get("bucket_name")
        rsp = requests.get(req, params=params, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("domains" in rspJson)
        part1 = rspJson["domains"]
        self.assertEqual(len(part1), 4)
        for item in part1:
            self.assertTrue("name" in item)
            name = item["name"]
            self.assertTrue(pp.basename(name) in basenames[0:4])
            self.assertEqual(name[0], '/')
            self.assertTrue(name[-1] != '/')

        # get next batch of 4
        params = {"domain": folder + '/', "Marker": name, "Limit": 4}
        if config.get("bucket_name"):
            params["bucket"] = config.get("bucket_name")
        rsp = requests.get(req, params=params, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("domains" in rspJson)
        part2 = rspJson["domains"]
        self.assertEqual(len(part2), 4)
        for item in part2:
            self.assertTrue("name" in item)
            name = item["name"]
            self.assertTrue(pp.basename(name) in basenames[4:8])
            self.assertTrue(name != params["Marker"])

        # try using a regex pattern
        pattern = "domain_[0,2,4,6]\.h5"
        params = {"domain": folder + '/', "pattern": pattern}
        rsp = requests.get(req, params=params, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("domains" in rspJson)
        domains = rspJson["domains"]
        self.assertEqual(len(domains), 4)
        for item in domains:
            self.assertTrue("name" in item)
            name = item["name"]
            self.assertTrue(
                pp.basename(name) in ("domain_0.h5", "domain_2.h5",
                                      "domain_4.h5", "domain_6.h5"))

        # use reg ex with attribute specification
        query = "attr1 > 7"
        params = {"domain": folder + '/', "query": query}
        rsp = requests.get(req, params=params, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("domains" in rspJson)
        domains = rspJson["domains"]
        self.assertEqual(len(domains), 4)

        # not equal query on attr2
        query = "attr2 != 'A0000004'"
        params = {"domain": folder + '/', "query": query}
        rsp = requests.get(req, params=params, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("domains" in rspJson)
        domains = rspJson["domains"]
        self.assertEqual(len(domains), 7)

        # combination query on attr1 and attr2
        query = "attr1 > 7 AND attr2 != 'A0000004'"
        params = {"domain": folder + '/', "query": query}
        rsp = requests.get(req, params=params, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("domains" in rspJson)
        domains = rspJson["domains"]
        self.assertEqual(len(domains), 3)

        # bad query expression
        query = "atttr1 > 7 AND"
        params = {"domain": folder + '/', "query": query}
        rsp = requests.get(req, params=params, headers=headers)
        self.assertEqual(rsp.status_code, 400)

        # empty sub-domains
        domain = helper.getTestDomain("tall.h5") + '/'
        params = {"domain": domain}
        if config.get("bucket_name"):
            params["bucket"] = config.get("bucket_name")
        rsp = requests.get(req, params=params, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("domains" in rspJson)
        domains = rspJson["domains"]
        self.assertEqual(len(domains), 0)
Example #5
0
    def testNewDomainCollections(self):
        # verify that newly added groups/datasets show up in the collections
        domain = self.base_domain + "/newDomainCollection.h5"
        helper.setupDomain(domain)
        print("testNewDomainCollections", domain)
        headers = helper.getRequestHeaders(domain=domain)

        # get root id
        req = helper.getEndpoint() + '/'
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        root_uuid = rspJson["root"]
        helper.validateId(root_uuid)

        def make_group(parent_id, name):
            # create new group
            payload = {'link': {'id': parent_id, 'name': name}}
            req = helper.getEndpoint() + "/groups"
            rsp = requests.post(req, data=json.dumps(payload), headers=headers)
            self.assertEqual(rsp.status_code, 201)
            rspJson = json.loads(rsp.text)
            new_group_id = rspJson["id"]
            self.assertTrue(helper.validateId(rspJson["id"]))
            return new_group_id

        def make_dset(parent_id, name):
            type_vstr = {
                "charSet": "H5T_CSET_ASCII",
                "class": "H5T_STRING",
                "strPad": "H5T_STR_NULLTERM",
                "length": "H5T_VARIABLE"
            }
            payload = {
                'type': type_vstr,
                'shape': 10,
                'link': {
                    'id': parent_id,
                    'name': name
                }
            }
            req = helper.getEndpoint() + "/datasets"
            rsp = requests.post(req, data=json.dumps(payload), headers=headers)
            self.assertEqual(rsp.status_code, 201)  # create dataset
            rspJson = json.loads(rsp.text)
            dset_id = rspJson["id"]
            self.assertTrue(helper.validateId(dset_id))
            return dset_id

        def make_ctype(parent_id, name):
            payload = {
                'type': 'H5T_IEEE_F64LE',
                'link': {
                    'id': parent_id,
                    'name': name
                }
            }
            req = helper.getEndpoint() + "/datatypes"
            rsp = requests.post(req, data=json.dumps(payload), headers=headers)
            self.assertEqual(rsp.status_code, 201)
            rspJson = json.loads(rsp.text)
            dtype_id = rspJson["id"]
            self.assertTrue(helper.validateId(dtype_id))
            return dtype_id

        group_ids = []
        group_ids.append(make_group(root_uuid, "g1"))
        group_ids.append(make_group(root_uuid, "g2"))
        group_ids.append(make_group(root_uuid, "g3"))
        g3_id = group_ids[2]
        dset_ids = []
        dset_ids.append(make_dset(g3_id, "ds1"))
        dset_ids.append(make_dset(g3_id, "ds2"))
        ctype_ids = []
        ctype_ids.append(make_ctype(g3_id, "ctype1"))

        # get the groups collection
        req = helper.getEndpoint() + '/groups'
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("hrefs" in rspJson)

        groups = rspJson["groups"]
        self.assertEqual(len(groups), len(group_ids))
        for objid in groups:
            helper.validateId(objid)
            self.assertTrue(objid in group_ids)

        # get the datasets collection
        req = helper.getEndpoint() + '/datasets'
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("hrefs" in rspJson)

        datasets = rspJson["datasets"]
        self.assertEqual(len(datasets), len(dset_ids))
        for objid in datasets:
            helper.validateId(objid)
            self.assertTrue(objid in dset_ids)

        # get the datatypes collection
        req = helper.getEndpoint() + '/datatypes'
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("hrefs" in rspJson)

        datatypes = rspJson["datatypes"]
        self.assertEqual(len(datatypes), len(ctype_ids))
        for objid in datatypes:
            helper.validateId(objid)
            self.assertTrue(objid in ctype_ids)
Example #6
0
 def __init__(self, *args, **kwargs):
     super(QueryTest, self).__init__(*args, **kwargs)
     self.base_domain = helper.getTestDomainName(self.__class__.__name__)
     helper.setupDomain(self.base_domain)
     self.endpoint = helper.getEndpoint()
Example #7
0
    def testGetDomains(self):
        folder = self.base_domain + "/testGetDomains"
        helper.setupDomain(folder, folder=True)
        print("testGetDomains", folder)

        # create some domains in the base_domain folder
        domain_count = 8
        for i in range(domain_count):
            domain = "domain_" + str(i) + ".h5"
            helper.setupDomain(folder + '/' + domain)

        headers = helper.getRequestHeaders()
        params = {"domain": folder+'/'}
        if config.get("bucket_name"):
            params["bucket"] = config.get("bucket_name")
        req = helper.getEndpoint() + '/domains'
        rsp = requests.get(req, headers=headers, params=params)
        self.assertEqual(rsp.status_code, 200)
        self.assertEqual(rsp.headers['content-type'], 'application/json; charset=utf-8')
        rspJson = json.loads(rsp.text)
        self.assertTrue("domains" in rspJson)
        domains = rspJson["domains"]

        self.assertEqual(domain_count, len(domains))

        for item in domains:
            self.assertTrue("name" in item)
            name = item["name"]
            self.assertEqual(name[0], '/')
            self.assertTrue(name[-1] != '/')
            self.assertTrue("owner" in item)
            self.assertTrue("class" in item)
            self.assertEqual(item["class"], "domain")
            self.assertTrue("lastModified" in item)
            self.assertFalse("size" in item)
       
        # try getting the first 4 domains
        params = {"domain": folder+'/', "Limit": 4}
        if config.get("bucket_name"):
            params["bucket"] = config.get("bucket_name")
        rsp = requests.get(req, params=params, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("domains" in rspJson)
        part1 = rspJson["domains"]
        self.assertEqual(len(part1), 4)
        for item in part1:
            self.assertTrue("name" in item)
            name = item["name"]
            self.assertEqual(name[0], '/')
            self.assertTrue(name[-1] != '/')
             
        # get next batch of 4
        params = {"domain": folder+'/', "Marker": name, "Limit": 4}
        if config.get("bucket_name"):
            params["bucket"] = config.get("bucket_name")
        rsp = requests.get(req, params=params, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("domains" in rspJson)
        part2 = rspJson["domains"]
        self.assertEqual(len(part2), 4)
        for item in part2:
            self.assertTrue("name" in item)
            name = item["name"]
            self.assertTrue(name != params["Marker"])

        # empty sub-domains
        domain = helper.getTestDomain("tall.h5") + '/'
        params = {"domain": domain}
        if config.get("bucket_name"):
            params["bucket"] = config.get("bucket_name")
        rsp = requests.get(req, params=params, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("domains" in rspJson)
        domains = rspJson["domains"]
        self.assertEqual(len(domains), 0)
Example #8
0
 def __init__(self, *args, **kwargs):
     super(DomainTest, self).__init__(*args, **kwargs)
     self.base_domain = helper.getTestDomainName(self.__class__.__name__)
     print("base_domain: {}".format(self.base_domain))
     helper.setupDomain(self.base_domain, folder=True)
Example #9
0
    def testGetLinks(self):
        domain = self.base_domain + "/testGetLinks.h5"
        print("testGetLinks", domain)
        helper.setupDomain(domain)
        headers = helper.getRequestHeaders(domain=domain)
        req = helper.getEndpoint() + '/'

        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        root_id = rspJson["root"]

        # get root group and check it has no links
        req = helper.getEndpoint() + "/groups/" + root_id
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertEqual(rspJson["linkCount"], 0)  # no links

        link_names = [
            "first", "second", "third", "fourth", "fifth", "sixth", "seventh",
            "eighth", "ninth", "tenth", "eleventh", "twelfth"
        ]

        # create subgroups and link them to root using the above names
        for link_name in link_names:
            req = helper.getEndpoint() + '/groups'
            rsp = requests.post(req, headers=headers)
            self.assertEqual(rsp.status_code, 201)
            rspJson = json.loads(rsp.text)
            grp_id = rspJson["id"]
            # link the new group
            req = helper.getEndpoint(
            ) + "/groups/" + root_id + "/links/" + link_name
            payload = {"id": grp_id}
            rsp = requests.put(req, data=json.dumps(payload), headers=headers)
            self.assertEqual(rsp.status_code, 201)  # created

        # get the root group and verify the link count is correct
        req = helper.getEndpoint() + "/groups/" + root_id
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertEqual(rspJson["linkCount"], len(link_names))

        # get all the links for the root group
        req = helper.getEndpoint() + "/groups/" + root_id + "/links"
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("links" in rspJson)
        self.assertTrue("hrefs" in rspJson)
        links = rspJson["links"]
        self.assertEqual(len(links), len(link_names))
        ret_names = []
        for link in links:
            self.assertTrue("title" in link)
            self.assertTrue("class" in link)
            self.assertEqual(link["class"], "H5L_TYPE_HARD")
            self.assertTrue("collection" in link)
            self.assertEqual(link["collection"], "groups")
            self.assertTrue("created" in link)
            ret_names.append(link["title"])

        # result should come back in sorted order
        sorted_names = copy(link_names)
        sorted_names.sort()
        # sorted list should be:
        # ['eighth', 'eleventh', 'fifth', 'first', 'fourth', 'ninth',
        #  'second', 'seventh', 'sixth', 'tenth', 'third', 'twelfth']
        #

        self.assertEqual(ret_names, sorted_names)

        # get links with a result limit of 4
        limit = 4
        req = helper.getEndpoint(
        ) + "/groups/" + root_id + "/links?Limit=" + str(limit)
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("links" in rspJson)
        self.assertTrue("hrefs" in rspJson)
        links = rspJson["links"]
        self.assertEqual(len(links), limit)
        last_link = links[-1]
        self.assertEqual(last_link["title"], sorted_names[limit - 1])

        # get links after the one with name: "seventh"
        marker = "seventh"
        req = helper.getEndpoint(
        ) + "/groups/" + root_id + "/links?Marker=" + marker
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("links" in rspJson)
        self.assertTrue("hrefs" in rspJson)
        links = rspJson["links"]
        self.assertEqual(len(links),
                         4)  #   "sixth", "tenth", "third", "twelfth"
        last_link = links[-1]
        self.assertEqual(last_link["title"], "twelfth")

        # Use a marker that is not present (should return 404)
        marker = "foobar"
        req = helper.getEndpoint(
        ) + "/groups/" + root_id + "/links?Marker=" + marker
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 404)

        # get links starting with name: "seventh", and limit to 3 results
        marker = "seventh"
        limit = 3
        req = helper.getEndpoint() + "/groups/" + root_id + "/links"
        req += "?Marker=" + marker + "&Limit=" + str(limit)
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertTrue("links" in rspJson)
        self.assertTrue("hrefs" in rspJson)
        links = rspJson["links"]
        self.assertEqual(len(links), 3)  #  "sixth", "tenth", "third"
        last_link = links[-1]
        self.assertEqual(last_link["title"], "third")
Example #10
0
    def testHardLink(self):
        domain = self.base_domain + "/testHardLink.h5"
        print("testHardLink", domain)
        helper.setupDomain(domain)
        headers = helper.getRequestHeaders(domain=domain)
        req = helper.getEndpoint() + '/'

        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        root_id = rspJson["root"]

        # get root group and check it has no links
        req = helper.getEndpoint() + "/groups/" + root_id
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertEqual(rspJson["linkCount"], 0)  # no links

        # create a new group
        req = helper.getEndpoint() + '/groups'
        rsp = requests.post(req, headers=headers)
        self.assertEqual(rsp.status_code, 201)
        rspJson = json.loads(rsp.text)
        self.assertEqual(rspJson["linkCount"], 0)
        self.assertEqual(rspJson["attributeCount"], 0)
        grp1_id = rspJson["id"]
        self.assertTrue(helper.validateId(grp1_id))

        # try to get "/g1"  (doesn't exist yet)
        link_title = "g1"
        req = helper.getEndpoint(
        ) + "/groups/" + root_id + "/links/" + link_title
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 404)  # link doesn't exist yet

        # try creating a link with a different user (should fail)
        headers = helper.getRequestHeaders(domain=domain,
                                           username="******")
        payload = {"id": grp1_id}
        rsp = requests.put(req, data=json.dumps(payload), headers=headers)
        self.assertEqual(rsp.status_code, 403)  # forbidden

        # create "/g1" with original user
        headers = helper.getRequestHeaders(domain=domain)
        rsp = requests.put(req, data=json.dumps(payload), headers=headers)
        self.assertEqual(rsp.status_code, 201)  # created

        # now gettting the link should succeed
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)  # should get link now
        rspJson = json.loads(rsp.text)
        self.assertTrue("created" in rspJson)
        self.assertTrue("lastModified" in rspJson)
        self.assertTrue("hrefs" in rspJson)
        self.assertTrue("link" in rspJson)
        rspLink = rspJson["link"]
        self.assertEqual(rspLink["title"], "g1")
        self.assertEqual(rspLink["class"], "H5L_TYPE_HARD")
        self.assertEqual(rspLink["id"], grp1_id)
        self.assertEqual(rspLink["collection"], "groups")

        # try creating the link again  (be ok = PUT is idempotent)
        rsp = requests.put(req, data=json.dumps(payload), headers=headers)
        self.assertEqual(rsp.status_code, 200)  # OK

        # try creating a link with different target id
        payload = {"id": root_id}
        rsp = requests.put(req, data=json.dumps(payload), headers=headers)
        self.assertEqual(rsp.status_code, 409)  # Conflict

        # get the root group and verify the link count is one
        req = helper.getEndpoint() + "/groups/" + root_id
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertEqual(rspJson["linkCount"], 1)  # link count is 1

        # try deleting link with a different user (should fail)
        headers = helper.getRequestHeaders(domain=domain,
                                           username="******")
        req = helper.getEndpoint(
        ) + "/groups/" + root_id + "/links/" + link_title
        rsp = requests.delete(req, headers=headers)
        self.assertEqual(rsp.status_code, 403)  # forbidden

        # delete the link with original user
        req = helper.getEndpoint(
        ) + "/groups/" + root_id + "/links/" + link_title
        headers = helper.getRequestHeaders(domain=domain)
        rsp = requests.delete(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)

        # try creating a link with a bogus id
        import uuid
        fake_id = "g-" + str(uuid.uuid1())
        payload = {"id": fake_id}
        rsp = requests.put(req, data=json.dumps(payload), headers=headers)
        self.assertEqual(rsp.status_code, 404)  # not found

        # try creating a link without a link name
        payload = {"id": grp1_id}
        req = helper.getEndpoint() + "/groups/" + root_id + "/links/"
        rsp = requests.put(req, data=json.dumps(payload), headers=headers)
        self.assertEqual(rsp.status_code, 404)  # Not Found

        # try creating a link with a forward slash in link name
        link_title = "one/two"
        payload = {"id": grp1_id}
        req = helper.getEndpoint(
        ) + "/groups/" + root_id + "/links/" + link_title
        rsp = requests.put(req, data=json.dumps(payload), headers=headers)
        self.assertEqual(rsp.status_code, 404)  # Not Found

        # try creating a link with a backward slash in link name
        link_title = "two\\one"
        payload = {"id": grp1_id}
        req = helper.getEndpoint(
        ) + "/groups/" + root_id + "/links/" + link_title
        rsp = requests.put(req, data=json.dumps(payload), headers=headers)
        self.assertEqual(rsp.status_code, 201)  # Created

        # delete the link
        rsp = requests.delete(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)

        # got a real id, but outside this domain
        req = helper.getEndpoint(
        ) + "/groups/" + root_id + "/links/another_domain"
        another_domain = self.base_domain + "/testHardLink2.h5"
        helper.setupDomain(another_domain)
        another_id = helper.getRootUUID(another_domain)
        payload = {"id": another_id}
        rsp = requests.put(req, data=json.dumps(payload), headers=headers)
        self.assertEqual(rsp.status_code, 400)  # Invalid request

        # try creating a link with a space in the title
        link_title = "name with spaces"
        payload = {"id": grp1_id}
        req = helper.getEndpoint(
        ) + "/groups/" + root_id + "/links/" + link_title
        rsp = requests.put(req, data=json.dumps(payload), headers=headers)
        self.assertEqual(rsp.status_code, 201)  # Created
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)  # should get link now
        rspJson = json.loads(rsp.text)
        self.assertTrue("link" in rspJson)
        rspLink = rspJson["link"]
        self.assertEqual(rspLink["title"], link_title)
        rsp = requests.delete(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)

        # get the root group and verify the link count is zero
        req = helper.getEndpoint() + "/groups/" + root_id
        headers = helper.getRequestHeaders(domain=domain)
        rsp = requests.get(req, headers=headers)
        self.assertEqual(rsp.status_code, 200)
        rspJson = json.loads(rsp.text)
        self.assertEqual(rspJson["linkCount"], 0)  # link count should zero