Example #1
0
    def test_on_http_grid_response(self, server_session):
        (server, session) = server_session

        # Reset our counter
        session._on_http_grid_response_called = 0
        session._on_http_grid_response_last_args = None

        # Fetch a grid
        op = session._get_grid("dummy", callback=lambda *a, **kwa: None)

        # The operation should still be in progress
        assert not op.is_done

        # There shall be one request
        assert server.requests() == 1
        rq = server.next_request()
        # Make a grid to respond with
        expected = hszinc.Grid()

        expected.column["empty"] = {}
        rq.respond(
            status=200,
            headers={b"Content-Type": "text/zinc"},
            content=hszinc.dump(expected, mode=hszinc.MODE_ZINC),
        )

        # Our dummy function should have been called
        assert session._on_http_grid_response_called == 1
        assert isinstance(session._on_http_grid_response_last_args, tuple)
        assert len(session._on_http_grid_response_last_args) == 3

        (response, args, kwargs) = session._on_http_grid_response_last_args
        assert isinstance(response, HTTPResponse)
        assert len(args) == 0
        assert len(kwargs) == 0
Example #2
0
    def _on_read(self, ids, filter_expr, limit, callback, **kwargs):
        if isinstance(ids, string_types) or isinstance(ids, hszinc.Ref):
            # Make sure we always pass a list.
            ids = [ids]

        if bool(ids):
            if filter_expr is not None:
                raise ValueError("Either specify ids or filter_expr, not both")

            ids = [self._obj_to_ref(r) for r in ids]

            if len(ids) == 1:
                # Reading a single entity
                return self._get_grid("read", callback, args={"id": ids[0]}, **kwargs)
            else:
                # Reading several entities
                grid = hszinc.Grid()
                grid.column["id"] = {}
                grid.extend([{"id": r} for r in ids])
                return self._post_grid("read", grid, callback, **kwargs)
        else:
            args = {"filter": filter_expr}
            if limit is not None:
                args["limit"] = int(limit)

            return self._get_grid("read", callback, args=args, **kwargs)
Example #3
0
def test_grid_types_json():
    innergrid = hszinc.Grid(version=hszinc.VER_3_0)
    innergrid.column['comment'] = {}
    innergrid.extend([
        {
            'comment': 'A innergrid',
        },
    ])
    grid = hszinc.Grid(version=hszinc.VER_3_0)
    grid.column['inner'] = {}
    grid.extend([
        {
            'inner': innergrid,
        },
    ])
    grid_str = hszinc.dump(grid, mode=hszinc.MODE_JSON)
    grid_json = json.loads(grid_str)
    assert grid_json == {
        'meta': {
            'ver': '3.0'
        },
        'cols': [
            {
                'name': 'inner'
            },
        ],
        'rows': [
            {
                'inner': {
                    'meta': {
                        'ver': '3.0'
                    },
                    'cols': [
                        {
                            'name': 'comment'
                        },
                    ],
                    'rows': [
                        {
                            'comment': 's:A innergrid'
                        },
                    ],
                }
            },
        ],
    }
Example #4
0
    def _on_watch_poll(self, watch, refresh, callback, **kwargs):
        grid = hszinc.Grid()
        grid.column["empty"] = {}

        if not isinstance(watch, string_types):
            watch = watch.id
        grid.metadata["watchId"] = watch
        return self._post_grid("watchPoll", grid, callback, **kwargs)
Example #5
0
def make_grid_meta(version=hszinc.VER_2_0):
    grid = hszinc.Grid(version=version)
    grid.metadata['aString'] = 'aValue'
    grid.metadata['aNumber'] = 3.14159
    grid.metadata['aNull'] = None
    grid.metadata['aMarker'] = hszinc.MARKER
    grid.metadata['aQuantity'] = hszinc.Quantity(123,'Hz')
    grid.column['empty'] = {}
    return grid
Example #6
0
def dict_to_grid(d):
    if not "id" in d.keys():
        raise ValueError('Dict must contain an "id" key.')
    new_grid = hszinc.Grid()
    new_grid.metadata["id"] = d["id"]
    for k, v in d.items():
        new_grid.column[k] = {}
    new_grid.append(d)
    return new_grid
Example #7
0
def nav_view(request):
    g = hszinc.Grid()
    navId = request.GET.get('navId')
    root = None
    if navId:
        try:
            root = Entity.objects.get(entity_id=navId)
        except Entity.DoesNotExist:
            return _hzinc_response(g, status=404)

    entities = None
    if root:
        eid = root.entity_id
        if 'id' in root.kv_tags:
            eid = root.kv_tags['id']
        # list the entities linked to root
        if 'site' in root.m_tags:
            entities = Entity.objects.filter(kv_tags__contains={
                'siteRef': eid
            }).exclude(kv_tags__has_key='equipRef')
        elif 'equip' in root.m_tags:
            entities = Entity.objects.filter(
                kv_tags__contains={'equipRef': eid})
    else:
        # list the sites
        entities = Entity.objects.filter(m_tags__contains=['site'])

    if not entities or len(entities) == 0:
        return _hzinc_response(g, status=404)

    # stores the entity_id
    added_fields = []
    data = []
    g.column['navId'] = {}
    # read which fields to include
    for e in entities:
        e_data = {'navId': e.entity_id}
        if e.kv_tags:
            for f in e.kv_tags.keys():
                e_data[f] = e.kv_tags[f]
                if f not in added_fields:
                    added_fields.append(f)
                    g.column[f] = {}

        for f in e.m_tags:
            e_data[f] = hszinc.MARKER
            if f not in added_fields:
                added_fields.append(f)
                g.column[f] = {}

        logger.info("nav_view: add data %s", e_data)
        data.append(e_data)

    # set the data
    g.extend(data)
    return _hzinc_response(g)
Example #8
0
def make_col_meta(version=hszinc.VER_2_0):
    grid = hszinc.Grid(version=version)
    col_meta = hszinc.MetadataObject()
    col_meta['aString'] = 'aValue'
    col_meta['aNumber'] = 3.14159
    col_meta['aNull'] = None
    col_meta['aMarker'] = hszinc.MARKER
    col_meta['aQuantity'] = hszinc.Quantity(123,'Hz')
    grid.column['empty'] = col_meta
    return grid
Example #9
0
    def _on_invoke_action(self, entity, action, callback, action_args,
                          **kwargs):
        grid = hszinc.Grid()
        grid.metadata["id"] = self._obj_to_ref(entity)
        grid.metadata["action"] = action
        for arg in action_args.keys():
            grid.column[arg] = {}
        grid.append(action_args)

        return self._post_grid("invokeAction", grid, callback, **kwargs)
Example #10
0
 def _on_watch_sub(self, points, watch_id, watch_dis, lease, callback, **kwargs):
     grid = hszinc.Grid()
     grid.column["id"] = {}
     grid.extend([{"id": self._obj_to_ref(p)} for p in points])
     if watch_id is not None:
         grid.metadata["watchId"] = watch_id
     if watch_dis is not None:
         grid.metadata["watchDis"] = watch_dis
     if lease is not None:
         grid.metadata["lease"] = lease
     return self._post_grid("watchSub", grid, callback, **kwargs)
Example #11
0
    def test_formats(self, server_session):
        (server, session) = server_session
        op = session.formats()

        # The operation should still be in progress
        assert not op.is_done

        # There shall be one request
        assert server.requests() == 1
        rq = server.next_request()

        # Request shall be a GET
        assert rq.method == "GET", "Expecting GET, got %s" % rq

        # Request shall be for base + 'api/formats'
        assert rq.uri == BASE_URI + "api/formats"

        # Accept header shall be given
        assert rq.headers[b"Accept"] == "text/zinc"

        # Make a grid to respond with
        expected = hszinc.Grid()

        expected.column["mime"] = {}
        expected.column["receive"] = {}
        expected.column["send"] = {}
        expected.extend([
            {
                "mime": "text/csv",
                "receive": hszinc.MARKER,
                "send": hszinc.MARKER
            },
            {
                "mime": "text/zinc",
                "receive": hszinc.MARKER,
                "send": hszinc.MARKER
            },
            {
                "mime": "application/json",
                "receive": hszinc.MARKER,
                "send": hszinc.MARKER,
            },
        ])

        rq.respond(
            status=200,
            headers={b"Content-Type": "text/zinc"},
            content=hszinc.dump(expected, mode=hszinc.MODE_ZINC),
        )

        # State machine should now be done
        assert op.is_done
        actual = op.result
        grid_cmp(expected, actual)
Example #12
0
    def test_about(self, server_session):
        (server, session) = server_session
        op = session.about()

        # The operation should still be in progress
        assert not op.is_done

        # There shall be one request
        assert server.requests() == 1
        rq = server.next_request()

        # Request shall be a GET
        assert rq.method == 'GET', 'Expecting GET, got %s' % rq

        # Request shall be for base + 'api/about'
        assert rq.uri == BASE_URI + 'api/about'

        # Accept header shall be given
        assert rq.headers['Accept'] == 'text/zinc'

        # Make a grid to respond with
        expected = hszinc.Grid()

        expected.column['haystackVersion'] = {}
        expected.column['tz'] = {}
        expected.column['serverName'] = {}
        expected.column['serverTime'] = {}
        expected.column['serverBootTime'] = {}
        expected.column['productName'] = {}
        expected.column['productUri'] = {}
        expected.column['productVersion'] = {}
        expected.column['moduleName'] = {}
        expected.column['moduleVersion'] = {}
        expected.append({
            'haystackVersion': '2.0',
            'tz': 'UTC',
            'serverName': 'pyhaystack dummy server',
            'serverTime': datetime.datetime.now(tz=pytz.UTC),
            'serverBootTime': datetime.datetime.now(tz=pytz.UTC),
            'productName': 'pyhaystack dummy server',
            'productVersion': '0.0.1',
            'productUri': hszinc.Uri('http://pyhaystack.readthedocs.io'),
            'moduleName': 'tests.client.base',
            'moduleVersion': '0.0.1',
        })

        rq.respond(status=200, headers={
            'Content-Type': 'text/zinc',
        }, content=hszinc.dump(expected, mode=hszinc.MODE_ZINC))

        # State machine should now be done
        assert op.is_done
        actual = op.result
        grid_cmp(expected, actual)
Example #13
0
def formats_view(request):
    g = hszinc.Grid()
    g.column['mime'] = {}
    g.column['read'] = {}
    g.column['write'] = {}
    g.extend([{
        'mime': 'text/zinc',
        'read': hszinc.MARKER,
        'write': hszinc.MARKER
    }])
    return HttpResponse(hszinc.dump(g), content_type="text/zinc;charset=utf-8")
Example #14
0
 def _on_watch_sub(self, points, watch_id, watch_dis, lease, callback,
                   **kwargs):
     grid = hszinc.Grid()
     grid.column['id'] = {}
     grid.extend([{'id': self._obj_to_ref(p)} for p in points])
     if watch_id is not None:
         grid.metadata['watchId'] = watch_id
     if watch_dis is not None:
         grid.metadata['watchDis'] = watch_dis
     if lease is not None:
         grid.metadata['lease'] = lease
     return self._post_grid('watchSub', grid, callback, **kwargs)
Example #15
0
def test_data_types_v3():
    grid = hszinc.Grid(version=hszinc.VER_3_0)
    grid.column['comment'] = {}
    grid.column['value'] = {}
    grid.extend([
        {
            'comment': 'A NA',
            'value': hszinc.NA,
        },
        {
            'comment': 'An empty list',
            'value': [],
        },
        {
            'comment': 'A null value in a list',
            'value': [None],
        },
        {
            'comment': 'A marker in a list',
            'value': [hszinc.MARKER],
        },
        {
            'comment': 'Booleans',
            'value': [True, False],
        },
        {
            'comment': 'References',
            'value': [hszinc.Ref('a-ref'),
                      hszinc.Ref('a-ref', 'a value')],
        },
        {
            'comment': 'A quantity',
            'value': [hszinc.Quantity(500, 'miles')],
        },
        {
            'comment': 'A XStr',
            'value': [hszinc.XStr("hex", 'deadbeef')],
        },
    ])
    grid_str = hszinc.dump(grid)
    ref_str = '''ver:"3.0"
comment,value
"A NA",NA
"An empty list",[]
"A null value in a list",[N]
"A marker in a list",[M]
"Booleans",[T,F]
"References",[@a-ref,@a-ref "a value"]
"A quantity",[500miles]
"A XStr",[hex("deadbeef")]
'''
    assert grid_str == ref_str
Example #16
0
def test_list_zinc_v2():
    try:
        grid = hszinc.Grid(version=hszinc.VER_2_0)
        grid.column['comment'] = {}
        grid.column['value'] = {}
        grid.extend([{
            'comment': 'An empty list',
            'value': [],
        }])
        hszinc.dump(grid, mode=hszinc.MODE_ZINC)
        assert False, 'Project Haystack 2.0 doesn\'t support lists'
    except ValueError:
        pass
Example #17
0
def test_dict_json_v2():
    try:
        grid = hszinc.Grid(version=hszinc.VER_2_0)
        grid.column['comment'] = {}
        grid.column['value'] = {}
        grid.extend([{
            'comment': 'An empty dict',
            'value': {},
        }])
        hszinc.dump(grid, mode=hszinc.MODE_JSON)
        assert False, 'Project Haystack 2.0 doesn\'t support dict'
    except ValueError:
        pass
Example #18
0
def test_grid_types_zinc():
    innergrid = hszinc.Grid(version=hszinc.VER_3_0)
    innergrid.column['comment'] = {}
    innergrid.extend([
        {
            'comment': 'A innergrid',
        },
    ])
    grid = hszinc.Grid(version=hszinc.VER_3_0)
    grid.column['inner'] = {}
    grid.extend([
        {
            'inner': innergrid,
        },
    ])
    grid_str = hszinc.dump(grid, mode=hszinc.MODE_ZINC)
    assert grid_str == ('ver:"3.0"\n'
                        'inner\n'
                        '<<ver:"3.0"\n'
                        'comment\n'
                        '"A innergrid"\n'
                        '>>\n')
Example #19
0
    def _on_watch_unsub(self, watch, points, callback, **kwargs):
        grid = hszinc.Grid()
        grid.column["id"] = {}

        if not isinstance(watch, string_types):
            watch = watch.id
        grid.metadata["watchId"] = watch

        if points is not None:
            grid.extend([{"id": self._obj_to_ref(p)} for p in points])
        else:
            grid.metadata["close"] = hszinc.MARKER
        return self._post_grid("watchSub", grid, callback, **kwargs)
Example #20
0
    def invoke_action(self, entity, action, callback=None, **kwargs):
        """
        entity is either the ID of the entity, or an instance of the entity to
        invoke the named action on.  Keyword arguments give any additional
        parameters required for the user action.
        """
        grid = hszinc.Grid()
        grid.metadata['id'] = self._obj_to_ref(entity)
        grid.metadata['action'] = action
        for arg in kwargs.keys():
            grid.column[arg] = {}
        grid.append(kwargs)

        return self._post_grid('invokeAction', grid, callback)
Example #21
0
    def _on_his_write(self, point, timestamp_records, callback, **kwargs):
        grid = hszinc.Grid()
        grid.metadata['id'] = self._obj_to_ref(point)
        grid.column['ts'] = {}
        grid.column['val'] = {}

        if hasattr(timestamp_records, 'to_dict'):
            timestamp_records = timestamp_records.to_dict()

        timestamp_records = list(timestamp_records.items())
        timestamp_records.sort(key=lambda rec: rec[0])
        for (ts, val) in timestamp_records:
            grid.append({'ts': ts, 'val': val})

        return self._post_grid('hisWrite', grid, callback, **kwargs)
Example #22
0
def make_simple_grid(version=hszinc.VER_2_0):
    grid = hszinc.Grid(version=version)
    grid.column['firstName'] = {}
    grid.column['bday'] = {}
    grid.extend([
        {
            'firstName': 'Jack',
            'bday': datetime.date(1973,7,23),
        },
        {
            'firstName': 'Jill',
            'bday': datetime.date(1975,11,15),
        },
    ])
    return grid
Example #23
0
    def watch_poll(self, watch, refresh=False, callback=None):
        """
        watch is either the value of watch_id given when creating a watch, or
        an instance of a Watch object.

        If refresh is True, then all points on the watch will be updated, not
        just those that have changed since the last poll.
        """
        grid = hszinc.Grid()
        grid.column['empty'] = {}

        if not isinstance(watch, string_types):
            watch = watch.id
        grid.metadata['watchId'] = watch
        return self._post_grid('watchPoll', grid, callback)
Example #24
0
    def _on_his_write(self, point, timestamp_records, callback, **kwargs):
        grid = hszinc.Grid()
        grid.metadata["id"] = self._obj_to_ref(point)
        grid.column["ts"] = {}
        grid.column["val"] = {}

        if hasattr(timestamp_records, "to_dict"):
            timestamp_records = timestamp_records.to_dict()

        timestamp_records = list(timestamp_records.items())
        timestamp_records.sort(key=lambda rec: rec[0])
        for (ts, val) in timestamp_records:
            grid.append({"ts": ts, "val": val})

        return self._post_grid("hisWrite", grid, callback, **kwargs)
Example #25
0
    def test_get_single_entity(self, server_session):
        (server, session) = server_session
        # Try retrieving an existing single entity
        op = session.get_entity("my.entity.id", single=True)

        # The operation should still be in progress
        assert not op.is_done

        # There shall be one request
        assert server.requests() == 1
        rq = server.next_request()

        # Request shall be a GET
        assert rq.method == "GET", "Expecting GET, got %s" % rq

        # Request shall be for base + 'api/[email protected]'
        assert rq.uri == BASE_URI + "api/read?id=%40my.entity.id"

        # Accept header shall be given
        assert rq.headers[b"Accept"] == "text/zinc"

        # Make a grid to respond with
        response = hszinc.Grid()

        response.column["id"] = {}
        response.column["dis"] = {}
        response.column["randomTag"] = {}
        response.append({
            "id": hszinc.Ref("my.entity.id", value="id"),
            "dis": "A test entity",
            "randomTag": hszinc.MARKER,
        })

        rq.respond(
            status=200,
            headers={b"Content-Type": "text/zinc"},
            content=hszinc.dump(response, mode=hszinc.MODE_ZINC),
        )

        # State machine should now be done
        assert op.is_done
        entity = op.result
        # Response should be an entity
        assert isinstance(entity, Entity), "%r not an entity" % entity
        # The tags should be passed through from the response
        assert entity.id.name == "my.entity.id"
        assert entity.tags["dis"] == response[0]["dis"]
        assert entity.tags["randomTag"] == response[0]["randomTag"]
    def test_get_single_entity(self, server_session):
        (server, session) = server_session
        # Try retrieving an existing single entity
        op = session.get_entity('my.entity.id', single=True)

        # The operation should still be in progress
        assert not op.is_done

        # There shall be one request
        assert server.requests() == 1
        rq = server.next_request()

        # Request shall be a GET
        assert rq.method == 'GET', 'Expecting GET, got %s' % rq

        # Request shall be for base + 'api/[email protected]'
        assert rq.uri == BASE_URI + 'api/read?id=%40my.entity.id'

        # Accept header shall be given
        assert rq.headers[b'Accept'] == 'text/zinc'

        # Make a grid to respond with
        response = hszinc.Grid()

        response.column['id'] = {}
        response.column['dis'] = {}
        response.column['randomTag'] = {}
        response.append({
            'id': hszinc.Ref('my.entity.id', value='id'),
            'dis': 'A test entity',
            'randomTag': hszinc.MARKER
        })

        rq.respond(status=200,
                   headers={
                       b'Content-Type': 'text/zinc',
                   },
                   content=hszinc.dump(response, mode=hszinc.MODE_ZINC))

        # State machine should now be done
        assert op.is_done
        entity = op.result
        # Response should be an entity
        assert isinstance(entity, Entity), '%r not an entity' % entity
        # The tags should be passed through from the response
        assert entity.id.name == 'my.entity.id'
        assert entity.tags['dis'] == response[0]['dis']
        assert entity.tags['randomTag'] == response[0]['randomTag']
Example #27
0
    def _crud_op(self, op, entities, callback, **kwargs):
        """
        Perform a repeated operation on the given entities with the given
        values for each entity.  `entities` should be a list of dicts, each
        dict having an `id` key that specifies the entity's ID and other keys
        giving the values.

        :param entities: The entities to be inserted.
        """
        if isinstance(entities, dict):
            # Convert single entity to list.
            entities = [entities]

        # Construct a list of columns
        all_columns = set()
        list(map(all_columns.update, [e.keys() for e in entities]))
        # We'll put 'id' first sort the others.
        if "id" in all_columns:
            all_columns.discard("id")
            all_columns = ["id"] + sorted(all_columns)
        else:
            all_columns = sorted(all_columns)

        # Construct the grid
        grid = hszinc.Grid()
        for column in all_columns:
            grid.column[column] = {}

        for entity in entities:
            # Take a copy
            entity = entity.copy()

            # Ensure 'id' is a ref
            if "id" in entity:
                entity["id"] = self._obj_to_ref(entity["id"])

            # Ensure all other columns are present
            for column in all_columns:
                if column not in entity:
                    entity[column] = None

            # Add to the grid
            grid.append(entity)

        # Post the grid
        return self._post_grid(op, grid, callback, **kwargs)
Example #28
0
def make_metadata_grid(version=hszinc.VER_2_0):
    grid = hszinc.Grid(version=version)
    grid.metadata['database'] = 'test'
    grid.metadata['dis'] = 'Site Energy Summary'
    grid.column['siteName'] = {'dis': 'Sites'}
    grid.column['val'] = hszinc.MetadataObject()
    grid.column['val']['dis'] = 'Value'
    grid.column['val']['unit'] = 'kW'
    grid.extend([
        {
            'siteName': 'Site 1',
            'val': hszinc.Quantity(356.214,'kW'),
        },
        {
            'siteName': 'Site 2',
            'val': hszinc.Quantity(463.028,'kW'),
        },
    ])
    return grid
Example #29
0
    def test_get_single_entity_missing(self, server_session):
        (server, session) = server_session
        # Try retrieving an existing single entity that does not exist
        op = session.get_entity("my.nonexistent.id", single=True)

        # The operation should still be in progress
        assert not op.is_done

        # There shall be one request
        assert server.requests() == 1
        rq = server.next_request()

        # Request shall be a GET
        assert rq.method == "GET", "Expecting GET, got %s" % rq

        # Request shall be for base + 'api/[email protected]'
        assert rq.uri == BASE_URI + "api/read?id=%40my.nonexistent.id"

        # Accept header shall be given
        assert rq.headers[b"Accept"] == "text/zinc"

        # Make a grid to respond with.  Note, server might also choose to
        # throw an error, but we'll pretend it doesn't.
        response = hszinc.Grid()

        response.column["id"] = {}
        response.column["dis"] = {}

        rq.respond(
            status=200,
            headers={b"Content-Type": "text/zinc"},
            content=hszinc.dump(response, mode=hszinc.MODE_ZINC),
        )

        # State machine should now be done
        assert op.is_done
        # This should trigger a name error:
        try:
            entity = op.result
            assert entity is None
        except NameError as e:
            assert str(e) == "No matching entity found"
Example #30
0
 def _create_equipment_grid(self, equip_name, markers):
     grid = hszinc.Grid()
     grid.metadata['commit'] = 'add'
     # grid.metadata['projName'] = 'Springfield'
     grid.column['dis'] = {}
     grid.column["equip"] = {}
     grid.column["siteRef"] = {}
     grid.column["navName"] = {}
     # grid.column['disMacro'] = {}
     g = {
         'dis': equip_name,
         'navName': equip_name,
         'equip': hszinc.MARKER,
         "siteRef": self._site.id
     }
     for marker in markers:
         grid.column[marker] = {}
         g[marker] = hszinc.MARKER
     grid.append(g)
     return grid