def test__create_subscription__subscription_created_with_paths(self):
        path1 = "tag1"
        path2 = "tag2"
        token = uuid.uuid4()
        self._client.all_requests.configure_mock(
            side_effect=self._get_mock_request(token, {"subscriptionUpdates": []})
        )
        uut = HttpTagSelection(
            self._client, [tbase.TagData(path1), tbase.TagData(path2)]
        )

        with uut.create_subscription():
            pass

        assert self._client.all_requests.call_args_list == [
            mock.call(
                "POST",
                "/nitag/v2/subscriptions",
                params=None,
                data={"tags": AnyOrderList([path1, path2]), "updatesOnly": True},
            ),
            mock.call(
                "GET",
                "/nitag/v2/subscriptions/{id}/values/current",
                params={"id": token},
            ),
            mock.call("DELETE", "/nitag/v2/subscriptions/{id}", params={"id": token}),
        ]
 async def test__no_selection_created_by_constructor__close_async__no_server_calls(
     self,
 ):
     uut = HttpTagSelection(self._client, [tbase.TagData("tag")])
     await uut.close_async()
     await uut.close_async()
     uut.close()
     assert self._client.all_requests.call_count == 0
    def test__server_selection_created__open_tags__existing_selection_edited_on_refresh_metadata(
        self,
    ):
        path1 = "tag1"
        path2 = "tag2"
        token = uuid.uuid4()
        tags = [{"type": "DATE_TIME", "path": path1}]
        self._client.all_requests.configure_mock(
            side_effect=self._get_mock_request(token, tags)
        )

        uut = HttpTagSelection.open(self._client, [path1])
        uut.open_tags([path2])
        uut.refresh_metadata()

        assert self._client.all_requests.call_args_list == [
            mock.call(
                "POST",
                "/nitag/v2/selections",
                params=None,
                data={"searchPaths": AnyOrderList([path1])},
            ),
            mock.call("GET", "/nitag/v2/selections/{id}/tags", params={"id": token}),
            mock.call(
                "PUT",
                "/nitag/v2/selections/{id}",
                params={"id": token},
                data={"searchPaths": AnyOrderList([path1, path2]), "id": token},
            ),
            mock.call("GET", "/nitag/v2/selections/{id}/tags", params={"id": token}),
        ]
    def test__selection_created_by_constructor__refresh_metadata__tags_requeried(self):
        path1 = "tag1"
        path2 = "tag2"
        token = uuid.uuid4()
        tags = [
            {"type": "DATE_TIME", "path": path1},
            {"type": "INT", "path": path2},
        ]
        self._client.all_requests.configure_mock(
            side_effect=self._get_mock_request(token, tags)
        )

        uut = HttpTagSelection.open(self._client, [path1, path2])
        uut.refresh_metadata()

        assert self._client.all_requests.call_args_list == [
            mock.call(
                "POST",
                "/nitag/v2/selections",
                params=None,
                data={"searchPaths": AnyOrderList([path1, path2])},
            ),
            mock.call("GET", "/nitag/v2/selections/{id}/tags", params={"id": token}),
            mock.call("GET", "/nitag/v2/selections/{id}/tags", params={"id": token}),
        ]
    def test__reset_aggregates__aggregates_reset_on_server(self):
        path1 = "tag1"
        path2 = "tag2"
        paths = [path1, path2]
        token = uuid.uuid4()
        tags = [
            {"type": "DATE_TIME", "path": path1},
            {"type": "INT", "path": path2},
        ]
        self._client.all_requests.configure_mock(
            side_effect=self._get_mock_request(token, tags)
        )

        uut = HttpTagSelection.open(self._client, paths)
        uut.reset_aggregates()

        assert self._client.all_requests.call_args_list == [
            mock.call(
                "POST",
                "/nitag/v2/selections",
                params=None,
                data={"searchPaths": AnyOrderList(paths)},
            ),
            mock.call("GET", "/nitag/v2/selections/{id}/tags", params={"id": token}),
            mock.call(
                "POST",
                "/nitag/v2/selections/{id}/reset-aggregates",
                params={"id": token},
                data=None,
            ),
        ]
    def test__open__creates_selection_and_loads_all_data_from_server(self):
        path1 = "tag1"
        path2 = "tag2"
        paths = [path1, path2]
        public_properties = {
            "prop1": "value1",
            "prop2": "value2",
        }
        all_properties = dict(public_properties)
        dummy_tag = tbase.TagData(path1)
        dummy_tag.retention_type = tbase.RetentionType.COUNT
        dummy_tag.retention_count = 7
        dummy_tag.retention_days = 9
        dummy_tag._copy_retention_properties(all_properties)
        keywords = ["keyword1", "keyword2"]
        tags = [
            {
                "path": path1,
                "type": "BOOLEAN",
                "keywords": keywords,
                "properties": all_properties,
                "collectAggregates": True,
            },
            {"path": path2, "type": "DOUBLE"},
        ]
        token = uuid.uuid4()
        self._client.all_requests.configure_mock(
            side_effect=self._get_mock_request(token, tags)
        )

        uut = HttpTagSelection.open(self._client, paths)

        assert self._client.all_requests.call_args_list == [
            mock.call(
                "POST",
                "/nitag/v2/selections",
                params=None,
                data={"searchPaths": AnyOrderList(paths)},
            ),
            mock.call("GET", "/nitag/v2/selections/{id}/tags", params={"id": token}),
        ]
        assert 2 == len(uut.metadata)
        assert tbase.DataType.BOOLEAN == uut.metadata[path1].data_type
        assert uut.metadata[path1].collect_aggregates is True
        assert keywords == sorted(uut.metadata[path1].keywords)
        assert sorted(public_properties.items()) == sorted(
            uut.metadata[path1].properties.items()
        )
        assert dummy_tag.retention_count == uut.metadata[path1].retention_count
        assert dummy_tag.retention_days == uut.metadata[path1].retention_days
        assert dummy_tag.retention_type == uut.metadata[path1].retention_type

        assert tbase.DataType.DOUBLE == uut.metadata[path2].data_type
        assert uut.metadata[path2].collect_aggregates is False
        assert 0 == len(uut.metadata[path2].keywords)
        assert 0 == len(uut.metadata[path2].properties)
        assert uut.metadata[path2].retention_count is None
        assert uut.metadata[path2].retention_days is None
        assert tbase.RetentionType.NONE == uut.metadata[path2].retention_type
    def test__server_selection_expired__api_function_called__selection_recreated_and_operation_retried(
        self,
    ):
        path = "tag1"
        token1 = uuid.uuid4()
        token2 = uuid.uuid4()
        tags = [{"type": "DATE_TIME", "path": path}]
        tokens = [token1, token2]
        tag_delete_results = [core.ApiException("404", http_status_code=404), None]

        def mock_request(method, uri, params=None, data=None):
            if uri == "/nitag/v2/selections":
                data = dict(data)
                data.update({"id": tokens.pop(0)})
                return data, MockResponse(method, uri)
            elif uri.endswith("/tags"):
                if method == "DELETE":
                    result = tag_delete_results.pop(0)
                    if isinstance(result, Exception):
                        raise result
                    else:
                        return result, MockResponse(method, uri)
                else:
                    return tags, MockResponse(method, uri)
            elif uri.startswith("/nitag/v2/selections/"):
                assert method == "DELETE"
            else:
                assert False

        self._client.all_requests.configure_mock(side_effect=mock_request)

        uut = HttpTagSelection.open(self._client, [path])
        uut.delete_tags_from_server()

        assert self._client.all_requests.call_args_list == [
            mock.call(
                "POST",
                "/nitag/v2/selections",
                params=None,
                data={"searchPaths": AnyOrderList([path])},
            ),
            mock.call("GET", "/nitag/v2/selections/{id}/tags", params={"id": token1}),
            mock.call(
                "DELETE", "/nitag/v2/selections/{id}/tags", params={"id": token1}
            ),
            mock.call(
                "POST",
                "/nitag/v2/selections",
                params=None,
                data={"searchPaths": AnyOrderList([path])},
            ),
            mock.call(
                "DELETE", "/nitag/v2/selections/{id}/tags", params={"id": token2}
            ),
        ]
    def test__error_on_tag_query__open__selection_deleted(self):
        paths = ["path"]
        token = uuid.uuid4()
        self._client.all_requests.configure_mock(
            side_effect=self._get_mock_request(token, core.ApiException("Oops"))
        )

        with pytest.raises(core.ApiException):
            HttpTagSelection.open(self._client, paths)

        assert self._client.all_requests.call_args_list == [
            mock.call(
                "POST",
                "/nitag/v2/selections",
                params=None,
                data={"searchPaths": AnyOrderList(paths)},
            ),
            mock.call("GET", "/nitag/v2/selections/{id}/tags", params={"id": token}),
            mock.call("DELETE", "/nitag/v2/selections/{id}", params={"id": token}),
        ]
    def test__refresh_values__values_loaded(self):
        path1 = "tag1"
        path2 = "tag2"
        paths = [path1, path2]
        timestamp = datetime.now(timezone.utc)
        timestamp_str = timestamp.isoformat().rsplit("+", 1)[0] + "Z"
        token = uuid.uuid4()
        tags = [
            {"type": "DATE_TIME", "path": path1},
            {"type": "INT", "path": path2},
        ]
        values = [
            {"path": path1},
            {
                "path": path2,
                "current": {
                    "value": {"value": "2", "type": "INT"},
                    "timestamp": timestamp_str,
                },
                "aggregates": {"min": "1", "max": "5", "count": 4, "avg": 2.5},
            },
        ]
        self._client.all_requests.configure_mock(
            side_effect=self._get_mock_request(token, tags, values)
        )

        uut = HttpTagSelection.open(self._client, paths)
        uut.refresh_values()

        assert self._client.all_requests.call_args_list == [
            mock.call(
                "POST",
                "/nitag/v2/selections",
                params=None,
                data={"searchPaths": AnyOrderList(paths)},
            ),
            mock.call("GET", "/nitag/v2/selections/{id}/tags", params={"id": token}),
            mock.call("GET", "/nitag/v2/selections/{id}/values", params={"id": token}),
        ]

        value = uut.read(path2, include_timestamp=True, include_aggregates=True)
        assert uut.read(path1, include_timestamp=True, include_aggregates=True) is None

        assert self._client.all_requests.call_count == 3
        assert value is not None
        assert 4 == value.count
        assert tbase.DataType.INT32 == value.data_type
        assert 5 == value.max
        assert 2.5 == value.mean
        assert 1 == value.min
        assert path2 == value.path
        assert timestamp == value.timestamp
        assert 2 == value.value
    def test__no_selection_created_by_constructor__refresh_metadata__tags_queried(self):
        path1 = "tag1"
        path2 = "tag2"
        token = uuid.uuid4()
        self._client.all_requests.configure_mock(
            side_effect=self._get_mock_request(token, [])
        )

        uut = HttpTagSelection(
            self._client, [tbase.TagData(path1), tbase.TagData(path2)]
        )
        uut.refresh_metadata()

        assert self._client.all_requests.call_args_list == [
            mock.call(
                "POST",
                "/nitag/v2/selections",
                params=None,
                data={"searchPaths": AnyOrderList([path1, path2])},
            ),
            mock.call("GET", "/nitag/v2/selections/{id}/tags", params={"id": token}),
        ]
示例#11
0
    def create_selection(self, tags: List[tbase.TagData]) -> tbase.TagSelection:
        """Create an :class:`TagSelection` that initially contains the given ``tags``
        without retrieving any additional data from the server.

        Args:
            tags: The tags to include in the selection.

        Returns:
            The created selection.

        Raises:
            ValueError: if any of the given ``tags`` is None or has an invalid path.
            ValueError: if ``tags`` is None.
        """
        return HttpTagSelection(self._http_client, tags)
    def test__no_selection_created_by_constructor__api_function_called__selection_created(
        self,
    ):
        path1 = "tag1"
        path2 = "tag2"
        token = uuid.uuid4()
        self._client.all_requests.configure_mock(
            side_effect=self._get_mock_request(token, AssertionError())
        )

        uut = HttpTagSelection(
            self._client, [tbase.TagData(path1), tbase.TagData(path2)]
        )
        uut.delete_tags_from_server()

        assert self._client.all_requests.call_args_list == [
            mock.call(
                "POST",
                "/nitag/v2/selections",
                params=None,
                data={"searchPaths": AnyOrderList([path1, path2])},
            ),
            mock.call("DELETE", "/nitag/v2/selections/{id}/tags", params={"id": token}),
        ]
示例#13
0
    def open_selection(self, paths: List[str]) -> tbase.TagSelection:
        """Query the server for the metadata for the given tag ``paths`` and return the
        results in a :class:`TagSelection`.

        Args:
            paths: The paths of the tags to include in the selection. May include
                glob-style wildcards.

        Returns:
            The created selection with :attr:`TagSelection.metadata` containing the
            metadata.

        Raises:
            ValueError: if any of the given ``paths`` is None or invalid.
            ValueError: if ``paths`` contains duplicate paths.
            ValueError: if ``paths`` is None.
            ApiException: if the API call fails.
        """
        return HttpTagSelection.open(self._http_client, paths)
 def test__metadata_supplied__constructed__no_server_queries(self):
     tags = [tbase.TagData("tag", tbase.DataType.BOOLEAN)]
     uut = HttpTagSelection(self._client, tags)
     assert tags == list(uut.metadata.values())
     assert self._client.all_requests.call_count == 0