diff --git a/.gitignore b/.gitignore index 7f249738c56e97da80aaecaebb99c528eba78d3a..60c6519f7724a7ca08cac3263b595400dba9fdd2 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,8 @@ **/.project **/.pydevproject **/.settings/org.eclipse.core.resources.prefs +tangostationcontrol/dist +tangostationcontrol/build +**/.ipynb_checkpoints +**/pending_log_messages.db +**/.eggs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 14ee77667f38df99badcb69c35a823b7ca62a283..27593ca877e544634c42b303a1dc3d756df4cb41 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,9 +4,6 @@ image: artefact.skao.int/ska-tango-images-tango-itango:9.3.5 variables: GIT_SUBMODULE_STRATEGY: recursive PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" - # The PBR dependency requires a set version, not actually used - # Instead `util/lofar_git.py:get_version()` is used. - PBR_VERSION: "0.1" cache: paths: - .cache/pip @@ -16,22 +13,29 @@ stages: - static-analysis - unit-tests - integration-tests + - packaging newline_at_eof: stage: linting before_script: - - pip3 install -r devices/test-requirements.txt + - pip3 install -r tangostationcontrol/test-requirements.txt script: # TODO(Corne): Ignore shell files in submodules more cleanly - flake8 --filename *.sh,*.conf,*.md,*.yml --select=W292 --exclude docker-compose/tango-prometheus-exporter,.tox,.egg-info,docker python_linting: stage: linting + before_script: + - sudo apt-get update + - sudo apt-get install -y git script: - - cd devices + - cd tangostationcontrol - tox -e pep8 bandit: stage: static-analysis + before_script: + - sudo apt-get update + - sudo apt-get install -y git script: - - cd devices + - cd tangostationcontrol - tox -e bandit shellcheck: stage: static-analysis @@ -47,7 +51,7 @@ unit_test: - sudo apt-get update - sudo apt-get install -y git script: - - cd devices + - cd tangostationcontrol - tox -e py37 integration_test_docker: stage: integration-tests @@ -78,3 +82,16 @@ integration_test_docker: - chmod u+x $CI_PROJECT_DIR/sbin/run_integration_test.sh # Do not remove 'bash' or statement will be ignored by primitive docker shell - bash $CI_PROJECT_DIR/sbin/run_integration_test.sh +wheel_packaging: + stage: packaging + artifacts: + paths: + - tangostationcontrol/dist/*.whl + before_script: + - sudo apt-get update + - sudo apt-get install -y git + - pip3 install -r tangostationcontrol/test-requirements.txt + - pip3 install -r docker-compose/itango/lofar-requirements.txt + script: + - cd tangostationcontrol + - python setup.py bdist_wheel diff --git a/bin/start-ds.sh b/bin/start-ds.sh new file mode 100755 index 0000000000000000000000000000000000000000..e7fab7e9331b4512f9caf13bb9096146605fd4d9 --- /dev/null +++ b/bin/start-ds.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Serves as entrypoint script for docker containers + +# Check required support file exists +if [[ ! -f "/usr/local/bin/wait-for-it.sh" ]]; then + >&2 echo "/usr/local/bin/wait-for-it.sh file does not exist!" + exit 1 +fi + +# Check required environment variable is set +if [[ ! $TANGO_HOST ]]; then + >&2 echo "TANGO_HOST environment variable unset!" + exit 1 +fi + +# Check if configured for specific version +if [[ $TANGOSTATIONCONTROL ]]; then + # TODO (Corne): Download version from artifacts or pypi. + # Consider exit 2 an UnImplementedError + exit 2 +else + # Install the package, exit 1 if it fails + cd tangostationcontrol || exit 1 + mkdir -p /tmp/tangostationcontrol + python3 setup.py build --build-base /tmp/tangostationcontrol egg_info --egg-base /tmp/tangostationcontrol bdist_wheel --dist-dir /tmp/tangostationcontrol || exit 1 + # shellcheck disable=SC2012 + sudo pip install "$(ls -Art /tmp/tangostationcontrol/*.whl | tail -n 1)" +fi + +/usr/local/bin/wait-for-it.sh "$TANGO_HOST" --timeout=30 --strict -- "$@" diff --git a/devices/.stestr.conf b/devices/.stestr.conf deleted file mode 100644 index 07147c8697683f270e9388da8b914c20cb8e4c45..0000000000000000000000000000000000000000 --- a/devices/.stestr.conf +++ /dev/null @@ -1,3 +0,0 @@ -[DEFAULT] -test_path=${TESTS_DIR:-./test} -top_dir=./ diff --git a/devices/LICENSE.txt b/devices/LICENSE.txt deleted file mode 100644 index c9978b8eee263aebfdd8d0a016e447940682ba8b..0000000000000000000000000000000000000000 --- a/devices/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright 2021 ASTRON Netherlands Institute for Radio Astronomy - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/devices/__init__.py b/devices/__init__.py deleted file mode 100644 index 82b2af0e96f75105253e501e47f8861218132f63..0000000000000000000000000000000000000000 --- a/devices/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from util.lofar_git import get_version - -__version__ = get_version() - diff --git a/devices/common/lofar_git.py b/devices/common/lofar_git.py deleted file mode 100644 index f4f6217280fe612fa2e9a7830c1f026c1e36a815..0000000000000000000000000000000000000000 --- a/devices/common/lofar_git.py +++ /dev/null @@ -1,84 +0,0 @@ -import git # pip3 install gitpython -import os -from functools import lru_cache - -def get_repo(starting_directory: str = os.path.dirname(os.path.abspath(__file__))) -> git.Repo: - """ Try finding the repository by traversing up the tree. - - By default, the repository containing this module is returned. - """ - - directory = starting_directory - - try: - return git.Repo(directory) - except git.InvalidGitRepositoryError: - pass - - # We now have to traverse up the tree - while directory != "/" and os.path.exists(directory): - # Go to parent - directory = os.path.abspath(directory + os.path.sep + "..") - - try: - return git.Repo(directory) - except git.InvalidGitRepositoryError: - pass - - raise git.InvalidGitRepositoryError("Could not find git repository root in {}".format(starting_directory)) - - -@lru_cache(maxsize=None) -def get_version(repo: git.Repo = None) -> str: - """ Return a version string for the current commit. - - There is a practical issue: the repository changes over time, f.e. switching branches with 'git checkout'. We want - to know the version that is running in memory, not the one that is on disk. - - As a work-around, we cache the version information, in that it is at least consistent. It is up to the caller - to request the version early enough. - - The version string is one of: - - <tag> - - <branch> [<commit>] - - In both cases, a "*" prefix indicates this code is not production ready. Code is considered production ready if - it is a tag and there are no local modifications. - - """ - - if repo is None: - repo = get_repo() - - commit = repo.commit() - tags = {tag.commit: tag for tag in repo.tags} - - if commit in tags: - # a tag = production ready - commit_str = "{}".format(tags[commit]) - production_ready = True - elif repo.head.is_detached: - # no active branch - commit_str = "<detached HEAD> [{}]".format(commit) - production_ready = False - else: - # HEAD of a branch - branch = repo.active_branch - commit_str = "{} [{}]".format(branch, commit) - production_ready = False - - if repo.is_dirty(): - production_ready = False - - return "{}{}".format("*" if not production_ready else "", commit_str) - - -# at least cache the current repo version immediately -try: - _ = get_version() -except: - pass - - -if __name__ == "__main__": - print(get_version()) diff --git a/devices/requirements.txt b/devices/requirements.txt deleted file mode 100644 index 8e11e2f537bf59f3602379c853976696df7524f0..0000000000000000000000000000000000000000 --- a/devices/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -# the order of packages is of significance, because pip processes them in the -# order of appearance. Changing the order has an impact on the overall -# integration process, which may cause wedges in the gate later. - -pbr>=2.0 # Apache-2.0 diff --git a/devices/setup.cfg b/devices/setup.cfg deleted file mode 100644 index 55b29032e6aefc1787179c054b701b7fc51323ac..0000000000000000000000000000000000000000 --- a/devices/setup.cfg +++ /dev/null @@ -1,30 +0,0 @@ -[metadata] -name = TangoStationControl -summary = LOFAR 2.0 Station Control -description_file = - README.md -description_content_type = text/x-rst; charset=UTF-8 -author = ASTRON -home_page = https://astron.nl -project_urls = - Bug Tracker = https://support.astron.nl/jira/projects/L2SS/issues/ - Source Code = https://git.astron.nl/lofar2.0/tango -license = Apache-2 -classifier = - Environment :: Console - License :: Apache Software License - Operating System :: POSIX :: Linux - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - -[files] -package_dir=./ - -[entry_points] -console_scripts = - SDP = SDP:main - RECV = RECV:main diff --git a/devices/setup.py b/devices/setup.py deleted file mode 100644 index 4fa0ce44d0caa9b174fc65a699e63b31e43aee9b..0000000000000000000000000000000000000000 --- a/devices/setup.py +++ /dev/null @@ -1,4 +0,0 @@ -import setuptools - -# Requires: setup.cfg -setuptools.setup(setup_requires=['pbr>=2.0.0'], pbr=True) diff --git a/devices/test/common/test_lofar_git.py b/devices/test/common/test_lofar_git.py deleted file mode 100644 index 52a1c7d876fc2827757f082e0f44a0a64b1ffc78..0000000000000000000000000000000000000000 --- a/devices/test/common/test_lofar_git.py +++ /dev/null @@ -1,100 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of the LOFAR 2.0 Station Software -# -# -# -# Distributed under the terms of the APACHE license. -# See LICENSE.txt for more info. - -import git -from unittest import mock - -from common import lofar_git - -from test import base - - -class TestLofarGit(base.TestCase): - - def setUp(self): - super(TestLofarGit, self).setUp() - - # Clear the cache as this function of lofar_git uses LRU decorator - # This is a good demonstration of how unit tests in Python can have - # permanent effects, typically fixtures are needed to restore these. - lofar_git.get_version.cache_clear() - - def test_get_version(self): - """Test if attributes of get_repo are correctly used by get_version""" - - with mock.patch.object(lofar_git, 'get_repo') as m_get_repo: - m_commit = mock.Mock() - m_commit.return_value = "123456" - - m_is_dirty = mock.Mock() - m_is_dirty.return_value = True - - m_head = mock.Mock(is_detached=False) - - m_get_repo.return_value = mock.Mock( - active_branch="main", commit=m_commit, tags=[], - is_dirty=m_is_dirty, head=m_head) - - # No need for special string equal in Python - self.assertEqual("*main [123456]", lofar_git.get_version()) - - def test_get_version_tag(self): - """Test if get_version determines production_ready for tagged commit""" - - with mock.patch.object(lofar_git, 'get_repo') as m_get_repo: - m_commit = mock.Mock() - m_commit.return_value = "123456" - - m_is_dirty = mock.Mock() - m_is_dirty.return_value = False - - m_head = mock.Mock(is_detached=False) - - m_tag = mock.Mock(commit="123456") - m_tag.__str__ = mock.Mock(return_value= "version-1.2") - - m_get_repo.return_value = mock.Mock( - active_branch="main", commit=m_commit, - tags=[m_tag], is_dirty=m_is_dirty, head=m_head) - - self.assertEqual("version-1.2", lofar_git.get_version()) - - @mock.patch.object(lofar_git, 'get_repo') - def test_get_version_tag_dirty(self, m_get_repo): - """Test if get_version determines dirty tagged commit""" - - m_commit = mock.Mock() - m_commit.return_value = "123456" - - m_is_dirty = mock.Mock() - m_is_dirty.return_value = False - - m_head = mock.Mock(is_detached=False) - - m_tag = mock.Mock(commit="123456") - m_tag.__str__ = mock.Mock(return_value= "version-1.2") - - # Now m_get_repo is mocked using a decorator - m_get_repo.return_value = mock.Mock( - active_branch="main", commit=m_commit, - tags=[m_tag], is_dirty=m_is_dirty, head=m_head) - - self.assertEqual("version-1.2", lofar_git.get_version()) - - def test_catch_repo_error(self): - """Test if invalid git directories will raise error""" - - with mock.patch.object(lofar_git, 'get_repo') as m_get_repo: - - # Configure lofar_git.get_repo to raise InvalidGitRepositoryError - m_get_repo.side_effect = git.InvalidGitRepositoryError - - # Test that error is raised by get_version - self.assertRaises( - git.InvalidGitRepositoryError, lofar_git.get_version) diff --git a/docker-compose/device-boot.yml b/docker-compose/device-boot.yml index d51f91614a483feb8c5956d3d35942843c4be3ce..131e5644399eeae7b0e043a7aca9829d45a9a167 100644 --- a/docker-compose/device-boot.yml +++ b/docker-compose/device-boot.yml @@ -32,12 +32,8 @@ services: environment: - TANGO_HOST=${TANGO_HOST} entrypoint: - - /usr/local/bin/wait-for-it.sh - - ${TANGO_HOST} - - --timeout=30 - - --strict - - -- + - bin/start-ds.sh # configure CORBA to _listen_ on 0:port, but tell others we're _reachable_ through ${HOSTNAME}:port, since CORBA # can't know about our Docker port forwarding - - python3 -u /opt/lofar/tango/devices/devices/boot.py LTS -v -ORBendPoint giop:tcp:0:5708 -ORBendPointPublish giop:tcp:${HOSTNAME}:5708 + - l2ss-boot Boot LTS -v -ORBendPoint giop:tcp:0:5708 -ORBendPointPublish giop:tcp:${HOSTNAME}:5708 restart: unless-stopped diff --git a/docker-compose/device-docker.yml b/docker-compose/device-docker.yml index 49144b7bb61ed1ca30c83b26e0c5443761411c54..93e7cd8eaca8ea2ad6a024fa6fab7a1902b693c1 100644 --- a/docker-compose/device-docker.yml +++ b/docker-compose/device-docker.yml @@ -34,13 +34,10 @@ services: user: 1000:${DOCKER_GID} # uid 1000 is the default "tango" user environment: - TANGO_HOST=${TANGO_HOST} + working_dir: /opt/lofar/tango entrypoint: - - /usr/local/bin/wait-for-it.sh - - ${TANGO_HOST} - - --timeout=30 - - --strict - - -- + - bin/start-ds.sh # configure CORBA to _listen_ on 0:port, but tell others we're _reachable_ through ${HOSTNAME}:port, since CORBA # can't know about our Docker port forwarding - - python3 -u /opt/lofar/tango/devices/devices/docker_device.py LTS -v -ORBendPoint giop:tcp:0:5705 -ORBendPointPublish giop:tcp:${HOSTNAME}:5705 + - l2ss-docker-device Docker LTS -v -ORBendPoint giop:tcp:0:5705 -ORBendPointPublish giop:tcp:${HOSTNAME}:5705 restart: unless-stopped diff --git a/docker-compose/device-observation_control.yml b/docker-compose/device-observation_control.yml index b057df808d9f7c0fc3a2e5fb8bb9a3f0504ff388..d15fb8a8e708ce7e01e27a300348a5f47b09aa24 100644 --- a/docker-compose/device-observation_control.yml +++ b/docker-compose/device-observation_control.yml @@ -31,13 +31,10 @@ services: - ..:/opt/lofar/tango:rw environment: - TANGO_HOST=${TANGO_HOST} + working_dir: /opt/lofar/tango entrypoint: - - /usr/local/bin/wait-for-it.sh - - ${TANGO_HOST} - - --timeout=30 - - --strict - - -- + - bin/start-ds.sh # configure CORBA to _listen_ on 0:port, but tell others we're _reachable_ through ${HOSTNAME}:port, since CORBA # can't know about our Docker port forwarding - - python3 -u /opt/lofar/tango/devices/devices/observation_control.py LTS -v -ORBendPoint giop:tcp:0:5703 -ORBendPointPublish giop:tcp:${HOSTNAME}:5703 + - l2ss-observation-control ObservationControl LTS -v -ORBendPoint giop:tcp:0:5703 -ORBendPointPublish giop:tcp:${HOSTNAME}:5703 restart: unless-stopped diff --git a/docker-compose/device-recv.yml b/docker-compose/device-recv.yml index 0b860949bb44cd8301986f732df99a8a3d58d8aa..c1269ab89e34798b8766ced06d7df3394cbaf3b7 100644 --- a/docker-compose/device-recv.yml +++ b/docker-compose/device-recv.yml @@ -32,13 +32,10 @@ services: - ..:/opt/lofar/tango:rw environment: - TANGO_HOST=${TANGO_HOST} + working_dir: /opt/lofar/tango entrypoint: - - /usr/local/bin/wait-for-it.sh - - ${TANGO_HOST} - - --timeout=30 - - --strict - - -- + - bin/start-ds.sh # configure CORBA to _listen_ on 0:port, but tell others we're _reachable_ through ${HOSTNAME}:port, since CORBA # can't know about our Docker port forwarding - - python3 -u /opt/lofar/tango/devices/devices/recv.py LTS -v -ORBendPoint giop:tcp:0:5707 -ORBendPointPublish giop:tcp:${HOSTNAME}:5707 + - l2ss-receiver RECV LTS -v -ORBendPoint giop:tcp:0:5707 -ORBendPointPublish giop:tcp:${HOSTNAME}:5707 restart: unless-stopped diff --git a/docker-compose/device-sdp.yml b/docker-compose/device-sdp.yml index c1685235467277ac60f781918aa98fde6394877d..0768d39cd4a75d4d92abd59f42cbb436ac4c2f48 100644 --- a/docker-compose/device-sdp.yml +++ b/docker-compose/device-sdp.yml @@ -32,13 +32,10 @@ services: - ..:/opt/lofar/tango:rw environment: - TANGO_HOST=${TANGO_HOST} + working_dir: /opt/lofar/tango entrypoint: - - /usr/local/bin/wait-for-it.sh - - ${TANGO_HOST} - - --timeout=30 - - --strict - - -- + - bin/start-ds.sh # configure CORBA to _listen_ on 0:port, but tell others we're _reachable_ through ${HOSTNAME}:port, since CORBA # can't know about our Docker port forwarding - - python3 -u /opt/lofar/tango/devices/devices/sdp/sdp.py LTS -v -ORBendPoint giop:tcp:0:5701 -ORBendPointPublish giop:tcp:${HOSTNAME}:5701 + - l2ss-sdp SDP LTS -v -ORBendPoint giop:tcp:0:5701 -ORBendPointPublish giop:tcp:${HOSTNAME}:5701 restart: unless-stopped diff --git a/docker-compose/device-sst.yml b/docker-compose/device-sst.yml index 68164379ed1e7d3fa985cb9f3c5f620c09b71d50..3924b4bf18c1a221a8859a32a73f9ccccb4fdfc1 100644 --- a/docker-compose/device-sst.yml +++ b/docker-compose/device-sst.yml @@ -35,13 +35,10 @@ services: - ..:/opt/lofar/tango:rw environment: - TANGO_HOST=${TANGO_HOST} + working_dir: /opt/lofar/tango entrypoint: - - /usr/local/bin/wait-for-it.sh - - ${TANGO_HOST} - - --timeout=30 - - --strict - - -- + - bin/start-ds.sh # configure CORBA to _listen_ on 0:port, but tell others we're _reachable_ through ${HOSTNAME}:port, since CORBA # can't know about our Docker port forwarding - - python3 -u /opt/lofar/tango/devices/devices/sdp/sst.py LTS -v -ORBendPoint giop:tcp:0:5702 -ORBendPointPublish giop:tcp:${HOSTNAME}:5702 + - l2ss-sst SST LTS -v -ORBendPoint giop:tcp:0:5702 -ORBendPointPublish giop:tcp:${HOSTNAME}:5702 restart: unless-stopped diff --git a/docker-compose/device-unb2.yml b/docker-compose/device-unb2.yml index bd9b6496332994171959967ff358115ac91e5ca7..9e9f8797ce62f57c3fd3434dd41c36412df2150f 100644 --- a/docker-compose/device-unb2.yml +++ b/docker-compose/device-unb2.yml @@ -32,13 +32,10 @@ services: - ..:/opt/lofar/tango:rw environment: - TANGO_HOST=${TANGO_HOST} + working_dir: /opt/lofar/tango entrypoint: - - /usr/local/bin/wait-for-it.sh - - ${TANGO_HOST} - - --timeout=30 - - --strict - - -- + - bin/start-ds.sh # configure CORBA to _listen_ on 0:port, but tell others we're _reachable_ through ${HOSTNAME}:port, since CORBA # can't know about our Docker port forwarding - - python3 -u /opt/lofar/tango/devices/devices/unb2.py LTS -v -ORBendPoint giop:tcp:0:5704 -ORBendPointPublish giop:tcp:${HOSTNAME}:5704 + - l2ss-unb2 UNB2 LTS -v -ORBendPoint giop:tcp:0:5704 -ORBendPointPublish giop:tcp:${HOSTNAME}:5704 restart: unless-stopped diff --git a/docker-compose/device-xst.yml b/docker-compose/device-xst.yml index 619b532e694f502b93638c2427bb7d9464138e82..6d7a1036dfa965750bcf7212ae865a1b71e3de3a 100644 --- a/docker-compose/device-xst.yml +++ b/docker-compose/device-xst.yml @@ -35,13 +35,10 @@ services: - ..:/opt/lofar/tango:rw environment: - TANGO_HOST=${TANGO_HOST} + working_dir: /opt/lofar/tango entrypoint: - - /usr/local/bin/wait-for-it.sh - - ${TANGO_HOST} - - --timeout=30 - - --strict - - -- + - bin/start-ds.sh # configure CORBA to _listen_ on 0:port, but tell others we're _reachable_ through ${HOSTNAME}:port, since CORBA # can't know about our Docker port forwarding - - python3 -u /opt/lofar/tango/devices/devices/sdp/xst.py LTS -v -ORBendPoint giop:tcp:0:5706 -ORBendPointPublish giop:tcp:${HOSTNAME}:5706 + - l2ss-xst XST LTS -v -ORBendPoint giop:tcp:0:5706 -ORBendPointPublish giop:tcp:${HOSTNAME}:5706 restart: unless-stopped diff --git a/docker-compose/integration-test.yml b/docker-compose/integration-test.yml index 1811645b06f4d576a71a66d2f36a475c976a2308..defb45e3c3183516131795b283372ca784635d8c 100644 --- a/docker-compose/integration-test.yml +++ b/docker-compose/integration-test.yml @@ -21,7 +21,7 @@ services: - ..:/opt/lofar/tango:rw environment: - TANGO_HOST=${TANGO_HOST} - working_dir: /opt/lofar/tango/devices + working_dir: /opt/lofar/tango/tangostationcontrol entrypoint: - /usr/local/bin/wait-for-it.sh - ${TANGO_HOST} diff --git a/docker-compose/itango/lofar-requirements.txt b/docker-compose/itango/lofar-requirements.txt index 1349c50ca993b51bb866a7880e3e7fb185049de8..b193887dbfdb59a4bc143ce6dd48a720ec5ad00c 100644 --- a/docker-compose/itango/lofar-requirements.txt +++ b/docker-compose/itango/lofar-requirements.txt @@ -1,8 +1,4 @@ +# Do not put tangostationcontrol dependencies here parso == 0.7.1 jedi == 0.17.2 -asyncua -astropy -python-logstash-async -gitpython -PyMySQL[rsa] -sqlalchemy +astropy diff --git a/docker-compose/lofar-device-base/lofar-requirements.txt b/docker-compose/lofar-device-base/lofar-requirements.txt index 31b22c71689b481357cef56bf4940c1575a3b01d..10ad55d977c97793a352c13da323d84d3c826c0e 100644 --- a/docker-compose/lofar-device-base/lofar-requirements.txt +++ b/docker-compose/lofar-device-base/lofar-requirements.txt @@ -1,7 +1,5 @@ -asyncua +# Do not put tangostationcontrol dependencies here astropy -python-logstash-async -gitpython -PyMySQL[rsa] -sqlalchemy -docker + +# requirements to build tangocontrol +GitPython >= 3.1.24 # BSD diff --git a/tangostationcontrol/.stestr.conf b/tangostationcontrol/.stestr.conf new file mode 100644 index 0000000000000000000000000000000000000000..59b161cddad8a253059cf201b8872bc946f78c64 --- /dev/null +++ b/tangostationcontrol/.stestr.conf @@ -0,0 +1,3 @@ +[DEFAULT] +test_path=${TESTS_DIR:-./tangostationcontrol/test} +top_dir=./ diff --git a/devices/README.md b/tangostationcontrol/README.md similarity index 100% rename from devices/README.md rename to tangostationcontrol/README.md diff --git a/tangostationcontrol/requirements.txt b/tangostationcontrol/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..b1620255b5a45c9e3f653661e65de6732fd93a07 --- /dev/null +++ b/tangostationcontrol/requirements.txt @@ -0,0 +1,13 @@ +# the order of packages is of significance, because pip processes them in the +# order of appearance. Changing the order has an impact on the overall +# integration process, which may cause wedges in the gate later. + +asyncua >= 0.9.90 # LGPLv3 +PyMySQL[rsa] >= 1.0.2 # MIT +sqlalchemy >= 1.4.26 #MIT +GitPython >= 3.1.24 # BSD +snmp >= 0.1.7 # GPL3 +h5py >= 3.5.0 # BSD +psutil >= 5.8.0 # BSD +docker >= 5.0.3 # Apache 2 +python-logstash-async >= 2.3.0 # MIT \ No newline at end of file diff --git a/tangostationcontrol/setup.cfg b/tangostationcontrol/setup.cfg new file mode 100644 index 0000000000000000000000000000000000000000..daee0edbff26ee8f44613d75dd8a6bcd411906e0 --- /dev/null +++ b/tangostationcontrol/setup.cfg @@ -0,0 +1,56 @@ +[metadata] +name = tangostationcontrol +version = attr: tangostationcontrol.__version__ +summary = LOFAR 2.0 Station Control +description_file = + README.md +description_content_type = text/x-rst; charset=UTF-8 +author = ASTRON +home_page = https://astron.nl +project_urls = + Bug Tracker = https://support.astron.nl/jira/projects/L2SS/issues/ + Source Code = https://git.astron.nl/lofar2.0/tango +license = Apache-2 +classifier = + Environment :: Console + License :: Apache Software License + Operating System :: POSIX :: Linux + Programming Language :: Python + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 + +[options] +package_dir= + =./ +packages=find: +python_requires = >=3.6 + +[options.packages.find] +where=./ + +[options.entry_points] +console_scripts = + l2ss-boot = tangostationcontrol.devices.boot:main + l2ss-docker-device = tangostationcontrol.devices.docker_device:main + l2ss-observation = tangostationcontrol.devices.observation:main + l2ss-observation-control = tangostationcontrol.devices.observation_control:main + l2ss-receiver = tangostationcontrol.devices.recv:main + l2ss-sdp = tangostationcontrol.devices.sdp.sdp:main + l2ss-sst = tangostationcontrol.devices.sdp.sst:main + l2ss-unb2 = tangostationcontrol.devices.unb2:main + l2ss-xst = tangostationcontrol.devices.sdp.xst:main + l2ss-statistics-reader = tangostationcontrol.statistics_writer.statistics_reader:main + l2ss-statistics-writer = tangostationcontrol.statistics_writer.statistics_writer:main + +# The following entry points should eventually be removed / replaced + l2ss-cold-start = tangostationcontrol.toolkit.lts_cold_start:main + l2ss-hardware-device-template = tangostationcontrol.examples.HW_device_template:main + l2ss-ini-device = tangostationcontrol.examples.load_from_disk.ini_device:main + l2ss-parse-statistics-packet = tangostationcontrol.devices.sdp.statistics_packet:main + l2ss-random-data = tangostationcontrol.test.devices.random_data:main + l2ss-snmp = tangostationcontrol.examples.snmp.snmp:main + l2ss-version = tangostationcontrol.common.lofar_version:main diff --git a/tangostationcontrol/setup.py b/tangostationcontrol/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..6356812fdc2951fff6af9659feca273df06efca3 --- /dev/null +++ b/tangostationcontrol/setup.py @@ -0,0 +1,7 @@ +import setuptools + +with open('requirements.txt') as f: + required = f.read().splitlines() + +# Requires: setup.cfg +setuptools.setup(install_requires=required) diff --git a/tangostationcontrol/tangostationcontrol/__init__.py b/tangostationcontrol/tangostationcontrol/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c6e48f3e8c0b11146b60c5fb7b8b2285fd7124d0 --- /dev/null +++ b/tangostationcontrol/tangostationcontrol/__init__.py @@ -0,0 +1,3 @@ +from tangostationcontrol.common.lofar_version import get_version + +__version__ = get_version() diff --git a/devices/clients/README.md b/tangostationcontrol/tangostationcontrol/clients/README.md similarity index 100% rename from devices/clients/README.md rename to tangostationcontrol/tangostationcontrol/clients/README.md diff --git a/devices/devices/__init__.py b/tangostationcontrol/tangostationcontrol/clients/__init__.py similarity index 100% rename from devices/devices/__init__.py rename to tangostationcontrol/tangostationcontrol/clients/__init__.py diff --git a/devices/clients/attribute_wrapper.py b/tangostationcontrol/tangostationcontrol/clients/attribute_wrapper.py similarity index 98% rename from devices/clients/attribute_wrapper.py rename to tangostationcontrol/tangostationcontrol/clients/attribute_wrapper.py index e025d56d3421144b0dfeb1457f417fd4946a2671..f9cc13b3bfa8738414fa265c5a2154c0c471a493 100644 --- a/devices/clients/attribute_wrapper.py +++ b/tangostationcontrol/tangostationcontrol/clients/attribute_wrapper.py @@ -2,7 +2,7 @@ from tango.server import attribute from tango import AttrWriteType import numpy -from devices.device_decorators import only_when_on, fault_on_error +from tangostationcontrol.devices.device_decorators import only_when_on, fault_on_error import logging logger = logging.getLogger() diff --git a/devices/clients/comms_client.py b/tangostationcontrol/tangostationcontrol/clients/comms_client.py similarity index 100% rename from devices/clients/comms_client.py rename to tangostationcontrol/tangostationcontrol/clients/comms_client.py diff --git a/devices/clients/docker_client.py b/tangostationcontrol/tangostationcontrol/clients/docker_client.py similarity index 100% rename from devices/clients/docker_client.py rename to tangostationcontrol/tangostationcontrol/clients/docker_client.py diff --git a/devices/clients/opcua_client.py b/tangostationcontrol/tangostationcontrol/clients/opcua_client.py similarity index 99% rename from devices/clients/opcua_client.py rename to tangostationcontrol/tangostationcontrol/clients/opcua_client.py index 1c6ee35621dcc1ca5671ffbb31bbc71ddfa75faf..145c0ebe68c3824d764dd4417a81afeae8ce0247 100644 --- a/devices/clients/opcua_client.py +++ b/tangostationcontrol/tangostationcontrol/clients/opcua_client.py @@ -1,11 +1,10 @@ -from threading import Thread import socket import numpy import asyncua import asyncio from asyncua import Client -from clients.comms_client import AsyncCommClient +from tangostationcontrol.clients.comms_client import AsyncCommClient import logging logger = logging.getLogger() diff --git a/devices/clients/statistics_client.py b/tangostationcontrol/tangostationcontrol/clients/statistics_client.py similarity index 98% rename from devices/clients/statistics_client.py rename to tangostationcontrol/tangostationcontrol/clients/statistics_client.py index 3fd470fbf0319e45242abbc3a79362584628f844..2790197bdb90f2483d872f0dfd5978fa088d4980 100644 --- a/devices/clients/statistics_client.py +++ b/tangostationcontrol/tangostationcontrol/clients/statistics_client.py @@ -6,7 +6,7 @@ from .comms_client import AsyncCommClient from .tcp_replicator import TCPReplicator from .udp_receiver import UDPReceiver -from devices.sdp.statistics_collector import StatisticsConsumer +from tangostationcontrol.devices.sdp.statistics_collector import StatisticsConsumer logger = logging.getLogger() diff --git a/devices/clients/statistics_client_thread.py b/tangostationcontrol/tangostationcontrol/clients/statistics_client_thread.py similarity index 100% rename from devices/clients/statistics_client_thread.py rename to tangostationcontrol/tangostationcontrol/clients/statistics_client_thread.py diff --git a/devices/clients/tcp_replicator.py b/tangostationcontrol/tangostationcontrol/clients/tcp_replicator.py similarity index 99% rename from devices/clients/tcp_replicator.py rename to tangostationcontrol/tangostationcontrol/clients/tcp_replicator.py index 5ac6e492d977cf14452d4f97bd213c0d12af7cbb..8b820cc765daa193fe142f4a3f49ef7a3f643c76 100644 --- a/devices/clients/tcp_replicator.py +++ b/tangostationcontrol/tangostationcontrol/clients/tcp_replicator.py @@ -6,7 +6,7 @@ from threading import Thread import asyncio import logging -from clients.statistics_client_thread import StatisticsClientThread +from tangostationcontrol.clients.statistics_client_thread import StatisticsClientThread logger = logging.getLogger() diff --git a/devices/clients/udp_receiver.py b/tangostationcontrol/tangostationcontrol/clients/udp_receiver.py similarity index 98% rename from devices/clients/udp_receiver.py rename to tangostationcontrol/tangostationcontrol/clients/udp_receiver.py index 8a9d1429945cdd5c41c47bf45edc5034c1cafa0c..2bda038a1fb0646af2d2e14082e10ca3d7866816 100644 --- a/devices/clients/udp_receiver.py +++ b/tangostationcontrol/tangostationcontrol/clients/udp_receiver.py @@ -7,7 +7,7 @@ import socket import time from typing import List # not needed for python3.9+, where we can use the type "list[Queue]" directly -from clients.statistics_client_thread import StatisticsClientThread +from tangostationcontrol.clients.statistics_client_thread import StatisticsClientThread logger = logging.getLogger() diff --git a/devices/devices/sdp/__init__.py b/tangostationcontrol/tangostationcontrol/common/__init__.py similarity index 100% rename from devices/devices/sdp/__init__.py rename to tangostationcontrol/tangostationcontrol/common/__init__.py diff --git a/devices/common/baselines.py b/tangostationcontrol/tangostationcontrol/common/baselines.py similarity index 100% rename from devices/common/baselines.py rename to tangostationcontrol/tangostationcontrol/common/baselines.py diff --git a/tangostationcontrol/tangostationcontrol/common/entrypoint.py b/tangostationcontrol/tangostationcontrol/common/entrypoint.py new file mode 100644 index 0000000000000000000000000000000000000000..d5b9d4952ee08180162b3bdca7417fff31f456f0 --- /dev/null +++ b/tangostationcontrol/tangostationcontrol/common/entrypoint.py @@ -0,0 +1,21 @@ +import sys + +from tango.server import run + +from tangostationcontrol.common.lofar_logging import configure_logger + + +def entry(Device, **kwargs): + """General device entrypoint""" + + # Remove first argument which is filename + args = sys.argv[1:] + + # Setup logging + configure_logger() + + # Start the device server + if type(Device) is tuple: + return run(Device, args=args, **kwargs) + else: + return run((Device,), args=args, **kwargs) diff --git a/devices/common/lofar_logging.py b/tangostationcontrol/tangostationcontrol/common/lofar_logging.py similarity index 99% rename from devices/common/lofar_logging.py rename to tangostationcontrol/tangostationcontrol/common/lofar_logging.py index 826e484e6e2bd321c343b814ccb734472e8bf73c..46d417c67987b1cec37897552ad35446ac7fdae1 100644 --- a/devices/common/lofar_logging.py +++ b/tangostationcontrol/tangostationcontrol/common/lofar_logging.py @@ -1,12 +1,11 @@ import logging from functools import wraps from tango.server import Device -import sys import traceback import socket import time -from .lofar_git import get_version +from .lofar_version import get_version class TangoLoggingHandler(logging.Handler): level_to_device_stream = { diff --git a/tangostationcontrol/tangostationcontrol/common/lofar_version.py b/tangostationcontrol/tangostationcontrol/common/lofar_version.py new file mode 100644 index 0000000000000000000000000000000000000000..89cb22f9fe6b76caf438984c673b21d00bc25645 --- /dev/null +++ b/tangostationcontrol/tangostationcontrol/common/lofar_version.py @@ -0,0 +1,103 @@ +import git +import os +import functools +import pkg_resources +import re + +def get_repo(starting_directory: str = os.path.dirname(os.path.abspath(__file__)), limit = 10) -> git.Repo: + """ Try finding the repository by traversing up the tree. + + By default, the repository containing this module is returned. + """ + + directory = starting_directory + + try: + return git.Repo(directory) + except git.InvalidGitRepositoryError: + pass + + # We now have to traverse up the tree up until limit diretories + for i in range(limit): + if directory == "/" or not os.path.exists(directory): + break + + directory = os.path.abspath(directory + os.path.sep + "..") + + try: + return git.Repo(directory) + except git.InvalidGitRepositoryError: + pass + + # Could not find a repo within the limit so return None + return None + + +@functools.lru_cache(maxsize=None) +def get_version(repo: git.Repo = None) -> str: + """ Return a version string for the current commit. + + There is a practical issue: the repository changes over time, f.e. switching branches with 'git checkout'. We want + to know the version that is running in memory, not the one that is on disk. + + As a work-around, we cache the version information, in that it is at least consistent. It is up to the caller + to request the version early enough. + + The version string is of the following pattern: + - ${MAJOR}.${MINOR}.${PATCH}[.${BRANCH}$.{COMMIT}][.dirty] + + For releases only ${MAJOR}.${MINOR}.${PATCH} should be set. Versioning is + achieved by tagging commits using the `v${MAJOR}.${MINOR}.${PATCH}` pattern. + The leading `v` is none optional! + + """ + + if repo is None: + repo = get_repo() + + # When we can't find a git repo anymore, we must be packaged. Extract the + # package version directly + if repo is None: + try: + return pkg_resources.require("tangostationcontrol")[0].version + except Exception: + pass + + # Filter all tags so that they must match vMAJOR.MINOR.PATCH or + # vMAJOR.MINOR.PATCH.BRANCHCOMMIT + reg = re.compile(r'^v[0-9](\.[0-9]){2}(\.[a-z]*[0-9]*)?') + + commit = repo.commit() + filtered_tags = [tag.name for tag in repo.tags if reg.search(tag.name)] + # Order tags from newest to oldest + tags = {tag.commit: tag for tag in reversed(repo.tags) if tag.name in filtered_tags} + + # Find closest tag for commit + closest_tag = type('',(object,),{"name": 'v0.0.0'})() + for item in commit.iter_items(repo, commit): + if item.type == 'commit' and item in tags: + closest_tag = tags[item] + break + + if commit in tags: + # a tag = production ready + commit_str = "{}".format(tags[commit].name[1:]) + elif repo.head.is_detached: + # no active branch + commit_str = "{}.{}".format(closest_tag.name[1:], commit) + else: + # HEAD of a branch + branch = repo.active_branch + commit_str = "{}.{}.{}".format(closest_tag.name[1:], branch, commit) + + return "{}{}".format(commit_str, ".dirty" if repo.is_dirty() else "") + +# at least cache the current repo version immediately +try: + _ = get_version() +except: + pass + + +def main(args=None, **kwargs): + print(get_version()) diff --git a/devices/examples/__init__.py b/tangostationcontrol/tangostationcontrol/devices/__init__.py similarity index 100% rename from devices/examples/__init__.py rename to tangostationcontrol/tangostationcontrol/devices/__init__.py diff --git a/devices/devices/abstract_device.py b/tangostationcontrol/tangostationcontrol/devices/abstract_device.py similarity index 100% rename from devices/devices/abstract_device.py rename to tangostationcontrol/tangostationcontrol/devices/abstract_device.py diff --git a/devices/devices/apsct.py b/tangostationcontrol/tangostationcontrol/devices/apsct.py similarity index 100% rename from devices/devices/apsct.py rename to tangostationcontrol/tangostationcontrol/devices/apsct.py diff --git a/devices/devices/apspu.py b/tangostationcontrol/tangostationcontrol/devices/apspu.py similarity index 100% rename from devices/devices/apspu.py rename to tangostationcontrol/tangostationcontrol/devices/apspu.py diff --git a/devices/devices/boot.py b/tangostationcontrol/tangostationcontrol/devices/boot.py similarity index 93% rename from devices/devices/boot.py rename to tangostationcontrol/tangostationcontrol/devices/boot.py index 5d9540aa52ffa1f177b3cd615110676f73466343..40fb6f5f4fb6f8648adf8897340278fed2040f43 100644 --- a/devices/devices/boot.py +++ b/tangostationcontrol/tangostationcontrol/devices/boot.py @@ -13,12 +13,6 @@ Boots the rest of the station software. """ -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -sys.path.append(parentdir) - # PyTango imports from tango import DebugIt from tango.server import run, command @@ -29,10 +23,9 @@ import numpy from device_decorators import * -from clients.attribute_wrapper import attribute_wrapper -from devices.hardware_device import hardware_device -from common.lofar_logging import device_logging_to_python, log_exceptions -from common.lofar_git import get_version +from tangostationcontrol.common.entry import entry +from tangostationcontrol.devices.hardware_device import hardware_device +from tangostationcontrol.common.lofar_logging import device_logging_to_python, log_exceptions import logging logger = logging.getLogger() @@ -294,14 +287,6 @@ class Boot(hardware_device): # ---------- # Run server # ---------- -def main(args=None, **kwargs): - """Main function of the RECV module.""" - - from common.lofar_logging import configure_logger - configure_logger() - - return run((Boot,), args=args, **kwargs) - - -if __name__ == '__main__': - main() +def main(**kwargs): + """Main function of the Boot module.""" + return entry(Boot, **kwargs) diff --git a/devices/devices/device_decorators.py b/tangostationcontrol/tangostationcontrol/devices/device_decorators.py similarity index 100% rename from devices/devices/device_decorators.py rename to tangostationcontrol/tangostationcontrol/devices/device_decorators.py diff --git a/devices/devices/docker_device.py b/tangostationcontrol/tangostationcontrol/devices/docker_device.py similarity index 91% rename from devices/devices/docker_device.py rename to tangostationcontrol/tangostationcontrol/devices/docker_device.py index f8a83dd41f9a81a217dcab9a2dc54201ecff1025..d00ce507d85fcb6333ab913c5c9678da47736108 100644 --- a/devices/devices/docker_device.py +++ b/tangostationcontrol/tangostationcontrol/devices/docker_device.py @@ -11,14 +11,7 @@ """ -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -sys.path.append(parentdir) - # PyTango imports -from tango import DebugIt from tango.server import run, command from tango.server import device_property, attribute from tango import AttrWriteType @@ -28,10 +21,12 @@ import asyncio from device_decorators import * -from clients.docker_client import DockerClient -from clients.attribute_wrapper import attribute_wrapper -from devices.hardware_device import hardware_device -from common.lofar_logging import device_logging_to_python, log_exceptions +# Additional import +from tangostationcontrol.common.entrypoint import entry +from tangostationcontrol.clients.docker_client import DockerClient +from tangostationcontrol.clients.attribute_wrapper import attribute_wrapper +from tangostationcontrol.devices.hardware_device import hardware_device +from tangostationcontrol.common.lofar_logging import device_logging_to_python, log_exceptions __all__ = ["Docker", "main"] @@ -131,14 +126,6 @@ class Docker(hardware_device): # ---------- # Run server # ---------- -def main(args=None, **kwargs): +def main(**kwargs): """Main function of the Docker module.""" - - from common.lofar_logging import configure_logger - configure_logger() - - return run((Docker,), args=args, **kwargs) - - -if __name__ == '__main__': - main() + return entry(Docker, **kwargs) diff --git a/devices/devices/hardware_device.py b/tangostationcontrol/tangostationcontrol/devices/hardware_device.py similarity index 95% rename from devices/devices/hardware_device.py rename to tangostationcontrol/tangostationcontrol/devices/hardware_device.py index 89cc9f58cbd592c5321302abfb184bfd4dc72067..9ebff00d7554040425e3fdd6630e0a833d48fa4f 100644 --- a/devices/devices/hardware_device.py +++ b/tangostationcontrol/tangostationcontrol/devices/hardware_device.py @@ -15,17 +15,19 @@ from abc import abstractmethod # PyTango imports from tango.server import Device, command, DeviceMeta, attribute -from tango import DevState, DebugIt, Attribute, DeviceProxy, AttrWriteType -# Additional import +from tango import AttrWriteType, DevState, DebugIt, Attribute, DeviceProxy -from clients.attribute_wrapper import attribute_wrapper -from common.lofar_logging import log_exceptions -from common.lofar_git import get_version -from devices.abstract_device import AbstractDeviceMetas -from devices.device_decorators import only_in_states, fault_on_error import time import math +# Additional import +from tangostationcontrol.clients.attribute_wrapper import attribute_wrapper +from tangostationcontrol.common.lofar_logging import log_exceptions +from tangostationcontrol.common.lofar_version import get_version +from tangostationcontrol.devices.abstract_device import AbstractDeviceMetas +from tangostationcontrol.devices.device_decorators import only_in_states, fault_on_error + + __all__ = ["hardware_device"] import logging @@ -279,4 +281,3 @@ class hardware_device(Device, metaclass=AbstractDeviceMetas): time.sleep(pollperiod) raise Exception(f"{attr} != {value} after f{timeout} seconds still.") - diff --git a/devices/devices/observation.py b/tangostationcontrol/tangostationcontrol/devices/observation.py similarity index 89% rename from devices/devices/observation.py rename to tangostationcontrol/tangostationcontrol/devices/observation.py index fc69158c7215b29c3fd05c204032a15661ec3e15..0c38ed93c76f0e03aa71de0a0d880d8ede6d8251 100644 --- a/devices/devices/observation.py +++ b/tangostationcontrol/tangostationcontrol/devices/observation.py @@ -5,22 +5,16 @@ # Distributed under the terms of the APACHE license. # See LICENSE.txt for more info. - -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -sys.path.append(parentdir) - # PyTango imports from tango import server, Except, DevState, AttrWriteType, DevString, DebugIt from tango.server import Device, run, command, attribute import numpy from time import time -from devices.device_decorators import * -from common.lofar_logging import device_logging_to_python, log_exceptions -from common.lofar_git import get_version +from tangostationcontrol.common.entrypoint import entry +from tangostationcontrol.common.lofar_logging import device_logging_to_python, log_exceptions +from tangostationcontrol.common.lofar_version import get_version +from tangostationcontrol.devices.device_decorators import * from json import loads @@ -117,10 +111,6 @@ class Observation(Device): # ---------- # Run server # ---------- -def main(args = None, **kwargs): +def main(**kwargs): """Main function of the ObservationControl module.""" - return run((Observation,), args = args, **kwargs) - - -if __name__ == '__main__': - main() + return entry(Observation, **kwargs) diff --git a/devices/devices/observation_control.py b/tangostationcontrol/tangostationcontrol/devices/observation_control.py similarity index 97% rename from devices/devices/observation_control.py rename to tangostationcontrol/tangostationcontrol/devices/observation_control.py index 42a8c5d8298df0ec215f862598fd8dc71fb9eaff..0383b9ab7e0b69e54feddd40af2bdc6eb4da3bb0 100644 --- a/devices/devices/observation_control.py +++ b/tangostationcontrol/tangostationcontrol/devices/observation_control.py @@ -5,13 +5,6 @@ # Distributed under the terms of the APACHE license. # See LICENSE.txt for more info. - -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -sys.path.append(parentdir) - # PyTango imports from tango import Except, DevFailed, DevState, AttrWriteType, DebugIt, DeviceProxy, Util, DevBoolean, DevString from tango.server import Device, run, command, device_property, attribute @@ -21,11 +14,11 @@ import numpy import time from json import loads -from devices.device_decorators import * -from common.lofar_logging import device_logging_to_python, log_exceptions -from common.lofar_git import get_version - -from observation import Observation +from tangostationcontrol.common.entrypoint import entry +from tangostationcontrol.common.lofar_logging import device_logging_to_python, log_exceptions +from tangostationcontrol.common.lofar_version import get_version +from tangostationcontrol.devices.device_decorators import * +from tangostationcontrol.devices.observation import Observation __all__ = ["ObservationControl", "main"] @@ -445,10 +438,6 @@ class ObservationControl(Device): # ---------- # Run server # ---------- -def main(args = None, **kwargs): +def main(**kwargs): """Main function of the ObservationControl module.""" - return run((ObservationControl, Observation), verbose = True, args = args, **kwargs) - - -if __name__ == '__main__': - main() + return entry((ObservationControl, Observation), verbose=True, **kwargs) diff --git a/devices/devices/opcua_device.py b/tangostationcontrol/tangostationcontrol/devices/opcua_device.py similarity index 92% rename from devices/devices/opcua_device.py rename to tangostationcontrol/tangostationcontrol/devices/opcua_device.py index fd49b90f122868a0741ebe91ba69d71a434143d6..801c71c09a96fd631db23a57ca123f3ceaebd843 100644 --- a/devices/devices/opcua_device.py +++ b/tangostationcontrol/tangostationcontrol/devices/opcua_device.py @@ -25,11 +25,10 @@ import numpy import asyncio # Additional import -from devices.device_decorators import * - -from clients.opcua_client import OPCUAConnection -from devices.hardware_device import hardware_device -from common.lofar_logging import device_logging_to_python, log_exceptions +from tangostationcontrol.common.lofar_logging import device_logging_to_python, log_exceptions +from tangostationcontrol.clients.opcua_client import OPCUAConnection +from tangostationcontrol.devices.device_decorators import * +from tangostationcontrol.devices.hardware_device import hardware_device __all__ = ["opcua_device", "main"] diff --git a/devices/devices/recv.py b/tangostationcontrol/tangostationcontrol/devices/recv.py similarity index 94% rename from devices/devices/recv.py rename to tangostationcontrol/tangostationcontrol/devices/recv.py index b5cc7f6e7cd6031d290f0d2509ec651dc181765a..a9eee4160f9b7a6f981119c58ad2e707df0cf717 100644 --- a/devices/devices/recv.py +++ b/tangostationcontrol/tangostationcontrol/devices/recv.py @@ -11,25 +11,19 @@ """ -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -sys.path.append(parentdir) - # PyTango imports from tango import DebugIt from tango.server import run, command from tango.server import device_property, attribute from tango import AttrWriteType import numpy -# Additional import -from device_decorators import * - -from clients.attribute_wrapper import attribute_wrapper -from devices.opcua_device import opcua_device -from common.lofar_logging import device_logging_to_python, log_exceptions +# Additional import +from tangostationcontrol.common.entrypoint import entry +from tangostationcontrol.common.lofar_logging import device_logging_to_python, log_exceptions +from tangostationcontrol.clients.attribute_wrapper import attribute_wrapper +from tangostationcontrol.devices.device_decorators import * +from tangostationcontrol.devices.opcua_device import opcua_device import logging logger = logging.getLogger() @@ -234,14 +228,6 @@ class RECV(opcua_device): # ---------- # Run server # ---------- -def main(args=None, **kwargs): +def main(**kwargs): """Main function of the RECV module.""" - - from common.lofar_logging import configure_logger - configure_logger() - - return run((RECV,), args=args, **kwargs) - - -if __name__ == '__main__': - main() + return entry(RECV, **kwargs) diff --git a/devices/integration_test/__init__.py b/tangostationcontrol/tangostationcontrol/devices/sdp/__init__.py similarity index 100% rename from devices/integration_test/__init__.py rename to tangostationcontrol/tangostationcontrol/devices/sdp/__init__.py diff --git a/devices/devices/sdp/sdp.py b/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py similarity index 94% rename from devices/devices/sdp/sdp.py rename to tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py index d41d50af989c47ec0ee2fac3f0349bf8f00a3d53..4c4b03f8a75d026f2f322ea9b301b9d2b537a6ba 100644 --- a/devices/devices/sdp/sdp.py +++ b/tangostationcontrol/tangostationcontrol/devices/sdp/sdp.py @@ -11,28 +11,22 @@ """ -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -parentdir = os.path.dirname(parentdir) -sys.path.append(parentdir) - # PyTango imports from tango.server import run from tango.server import device_property, attribute from tango import AttrWriteType -# Additional import - -from clients.attribute_wrapper import attribute_wrapper -from devices.opcua_device import opcua_device -from common.lofar_logging import device_logging_to_python, log_exceptions +# Additional import +from tangostationcontrol.clients.attribute_wrapper import attribute_wrapper +from tangostationcontrol.devices.opcua_device import opcua_device +from tangostationcontrol.common.entrypoint import entry +from tangostationcontrol.common.lofar_logging import device_logging_to_python, log_exceptions import numpy __all__ = ["SDP", "main"] + @device_logging_to_python() class SDP(opcua_device): # ----------------- @@ -77,7 +71,7 @@ class SDP(opcua_device): mandatory=False, default_value=[[0.0] * 12] * 16 ) - + FPGA_sdp_info_station_id_RW_default = device_property( dtype='DevVarULongArray', mandatory=False, @@ -167,7 +161,6 @@ class SDP(opcua_device): FPGA_bsn_monitor_input_nof_valid_R = attribute_wrapper(comms_annotation=["FPGA_bsn_monitor_input_nof_valid_R"], datatype=numpy.int32, dims=(N_pn,)) FPGA_bsn_monitor_input_nof_err_R = attribute_wrapper(comms_annotation=["FPGA_bsn_monitor_input_nof_err_R"], datatype=numpy.int32, dims=(N_pn,)) - # -------- # overloaded functions # -------- @@ -179,14 +172,6 @@ class SDP(opcua_device): # ---------- # Run server # ---------- -def main(args=None, **kwargs): +def main(**kwargs): """Main function of the SDP module.""" - - from common.lofar_logging import configure_logger - configure_logger() - - return run((SDP,), args=args, **kwargs) - - -if __name__ == '__main__': - main() + return entry(SDP, **kwargs) diff --git a/devices/devices/sdp/sst.py b/tangostationcontrol/tangostationcontrol/devices/sdp/sst.py similarity index 88% rename from devices/devices/sdp/sst.py rename to tangostationcontrol/tangostationcontrol/devices/sdp/sst.py index d790170bb997f5e69044a2ef45754e04b9d62d1c..18f000697b5351487ce4c75c0796e2cc81c28740 100644 --- a/devices/devices/sdp/sst.py +++ b/tangostationcontrol/tangostationcontrol/devices/sdp/sst.py @@ -11,29 +11,24 @@ """ -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -parentdir = os.path.dirname(parentdir) -sys.path.append(parentdir) - # PyTango imports from tango.server import run from tango.server import device_property, attribute from tango import AttrWriteType # Additional import -from clients.attribute_wrapper import attribute_wrapper -from clients.statistics_client import StatisticsClient -from clients.opcua_client import OPCUAConnection -from devices.sdp.statistics import Statistics -from devices.sdp.statistics_collector import SSTCollector +from tangostationcontrol.common.entrypoint import entry +from tangostationcontrol.clients.attribute_wrapper import attribute_wrapper +from tangostationcontrol.clients.opcua_client import OPCUAConnection +from tangostationcontrol.clients.statistics_client import StatisticsClient +from tangostationcontrol.devices.sdp.statistics import Statistics +from tangostationcontrol.devices.sdp.statistics_collector import SSTCollector import numpy __all__ = ["SST", "main"] + class SST(Statistics): STATISTICS_COLLECTOR_CLASS = SSTCollector @@ -120,14 +115,6 @@ class SST(Statistics): # ---------- # Run server # ---------- -def main(args=None, **kwargs): +def main(**kwargs): """Main function of the SST Device module.""" - - from common.lofar_logging import configure_logger - configure_logger() - - return run((SST,), args=args, **kwargs) - - -if __name__ == '__main__': - main() + return entry(SST, **kwargs) diff --git a/devices/devices/sdp/statistics.py b/tangostationcontrol/tangostationcontrol/devices/sdp/statistics.py similarity index 92% rename from devices/devices/sdp/statistics.py rename to tangostationcontrol/tangostationcontrol/devices/sdp/statistics.py index af1cf0201fd4dc244b8495730660b7c84398a518..aa56e71f047ebd8412deb77fa315dd6e2a7d8c16 100644 --- a/devices/devices/sdp/statistics.py +++ b/tangostationcontrol/tangostationcontrol/devices/sdp/statistics.py @@ -11,27 +11,20 @@ """ -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -parentdir = os.path.dirname(parentdir) -sys.path.append(parentdir) - from abc import ABCMeta, abstractmethod # PyTango imports from tango.server import device_property, attribute from tango import AttrWriteType + # Additional import import asyncio -from clients.statistics_client import StatisticsClient -from clients.attribute_wrapper import attribute_wrapper - -from devices.opcua_device import opcua_device +from tangostationcontrol.clients.statistics_client import StatisticsClient +from tangostationcontrol.clients.attribute_wrapper import attribute_wrapper +from tangostationcontrol.devices.opcua_device import opcua_device +from tangostationcontrol.common.lofar_logging import device_logging_to_python, log_exceptions -from common.lofar_logging import device_logging_to_python, log_exceptions import logging logger = logging.getLogger() diff --git a/devices/devices/sdp/statistics_collector.py b/tangostationcontrol/tangostationcontrol/devices/sdp/statistics_collector.py similarity index 98% rename from devices/devices/sdp/statistics_collector.py rename to tangostationcontrol/tangostationcontrol/devices/sdp/statistics_collector.py index d9e5668b7e9b3db288a4b2360f4fa298594bbc1c..29503ca58ef25fcd3cb0b4ced4ff09ddaa62ecc6 100644 --- a/devices/devices/sdp/statistics_collector.py +++ b/tangostationcontrol/tangostationcontrol/devices/sdp/statistics_collector.py @@ -4,8 +4,8 @@ import logging import numpy from .statistics_packet import SSTPacket, XSTPacket -from common.baselines import nr_baselines, baseline_index, baseline_from_index -from clients.statistics_client_thread import StatisticsClientThread +from tangostationcontrol.common.baselines import nr_baselines, baseline_index, baseline_from_index +from tangostationcontrol.clients.statistics_client_thread import StatisticsClientThread logger = logging.getLogger() @@ -184,6 +184,7 @@ class XSTCollector(StatisticsCollector): # process the packet self.parameters["nof_valid_payloads"][fields.gn_index] += numpy.uint64(1) + self.parameters["xst_blocks"][block_index][:fields.nof_statistics_per_packet] = fields.payload self.parameters["xst_timestamps"][block_index] = numpy.float64(fields.timestamp().timestamp()) self.parameters["xst_conjugated"][block_index] = conjugated diff --git a/devices/devices/sdp/statistics_packet.py b/tangostationcontrol/tangostationcontrol/devices/sdp/statistics_packet.py similarity index 99% rename from devices/devices/sdp/statistics_packet.py rename to tangostationcontrol/tangostationcontrol/devices/sdp/statistics_packet.py index 9bac227071dfbdec9ea0b0fd1fa63fa36176a8d9..c98ae9b5bdc604e8a55480cc5473e658b10cefa1 100644 --- a/devices/devices/sdp/statistics_packet.py +++ b/tangostationcontrol/tangostationcontrol/devices/sdp/statistics_packet.py @@ -1,6 +1,5 @@ import struct from datetime import datetime, timezone -from typing import Tuple import numpy __all__ = ["StatisticsPacket", "SSTPacket", "XSTPacket", "BSTPacket"] @@ -331,7 +330,7 @@ class BSTPacket(StatisticsPacket): return header -if __name__ == "__main__": +def main(args=None, **kwargs): # parse one packet from stdin import sys import pprint diff --git a/devices/devices/sdp/xst.py b/tangostationcontrol/tangostationcontrol/devices/sdp/xst.py similarity index 90% rename from devices/devices/sdp/xst.py rename to tangostationcontrol/tangostationcontrol/devices/sdp/xst.py index 1740563c916115373d435896c075815a477795ea..dcbda73c6570f6db966eaf5518e2129ecea41187 100644 --- a/devices/devices/sdp/xst.py +++ b/tangostationcontrol/tangostationcontrol/devices/sdp/xst.py @@ -11,27 +11,19 @@ """ -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -parentdir = os.path.dirname(parentdir) -sys.path.append(parentdir) - # PyTango imports from tango.server import run from tango.server import device_property, attribute from tango import AttrWriteType -# Additional import -from clients.attribute_wrapper import attribute_wrapper -from clients.statistics_client import StatisticsClient -from clients.opcua_client import OPCUAConnection - -from common.lofar_logging import device_logging_to_python, log_exceptions +# Additional import +from tangostationcontrol.common.entrypoint import entry +from tangostationcontrol.clients.attribute_wrapper import attribute_wrapper +from tangostationcontrol.clients.opcua_client import OPCUAConnection +from tangostationcontrol.clients.statistics_client import StatisticsClient -from devices.sdp.statistics import Statistics -from devices.sdp.statistics_collector import XSTCollector +from tangostationcontrol.devices.sdp.statistics import Statistics +from tangostationcontrol.devices.sdp.statistics_collector import XSTCollector import numpy @@ -160,14 +152,6 @@ class XST(Statistics): # ---------- # Run server # ---------- -def main(args=None, **kwargs): +def main(**kwargs): """Main function of the XST Device module.""" - - from common.lofar_logging import configure_logger - configure_logger() - - return run((XST,), args=args, **kwargs) - - -if __name__ == '__main__': - main() + return entry(XST, **kwargs) diff --git a/devices/devices/unb2.py b/tangostationcontrol/tangostationcontrol/devices/unb2.py similarity index 94% rename from devices/devices/unb2.py rename to tangostationcontrol/tangostationcontrol/devices/unb2.py index 0feb3e53d90e84a708aeaed9a511b86975801cfa..0076a37a25c0838f8324a409f08223fab79b92f1 100644 --- a/devices/devices/unb2.py +++ b/tangostationcontrol/tangostationcontrol/devices/unb2.py @@ -11,22 +11,16 @@ """ -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -sys.path.append(parentdir) - # PyTango imports from tango.server import run from tango.server import device_property, attribute from tango import AttrWriteType # Additional import -from clients.attribute_wrapper import attribute_wrapper -from devices.opcua_device import opcua_device - -from common.lofar_logging import device_logging_to_python, log_exceptions +from tangostationcontrol.common.entrypoint import entry +from tangostationcontrol.clients.attribute_wrapper import attribute_wrapper +from tangostationcontrol.devices.opcua_device import opcua_device +from tangostationcontrol.common.lofar_logging import device_logging_to_python, log_exceptions import numpy @@ -132,13 +126,4 @@ class UNB2(opcua_device): # ---------- def main(args=None, **kwargs): """Main function of the UNB2 module.""" - - from common.lofar_logging import configure_logger - configure_logger() - - return run((UNB2,), args=args, **kwargs) - - -if __name__ == '__main__': - main() - + return entry(UNB2, **kwargs) diff --git a/devices/examples/HW_device_template.py b/tangostationcontrol/tangostationcontrol/examples/HW_device_template.py similarity index 85% rename from devices/examples/HW_device_template.py rename to tangostationcontrol/tangostationcontrol/examples/HW_device_template.py index 6059733023c5ee8448369a706ea2be5c8fa6b840..4645488405ac1dc23acde36a7659e3b9182c57a7 100644 --- a/devices/examples/HW_device_template.py +++ b/tangostationcontrol/tangostationcontrol/examples/HW_device_template.py @@ -9,19 +9,11 @@ """ -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -sys.path.append(parentdir) - # PyTango imports from tango.server import run -from tango import AttrWriteType # Additional import -from clients.attribute_wrapper import attribute_wrapper -from devices.hardware_device import hardware_device +from tangostationcontrol.devices.hardware_device import hardware_device __all__ = ["HW_dev"] @@ -90,7 +82,3 @@ class HW_dev(hardware_device): def main(args=None, **kwargs): """Main function of the hardware device module.""" return run((HW_dev,), args=args, **kwargs) - - -if __name__ == '__main__': - main() diff --git a/devices/integration_test/client/__init__.py b/tangostationcontrol/tangostationcontrol/examples/__init__.py similarity index 100% rename from devices/integration_test/client/__init__.py rename to tangostationcontrol/tangostationcontrol/examples/__init__.py diff --git a/devices/integration_test/devices/__init__.py b/tangostationcontrol/tangostationcontrol/examples/load_from_disk/__init__.py similarity index 100% rename from devices/integration_test/devices/__init__.py rename to tangostationcontrol/tangostationcontrol/examples/load_from_disk/__init__.py diff --git a/devices/examples/load_from_disk/ini_client.py b/tangostationcontrol/tangostationcontrol/examples/load_from_disk/ini_client.py similarity index 98% rename from devices/examples/load_from_disk/ini_client.py rename to tangostationcontrol/tangostationcontrol/examples/load_from_disk/ini_client.py index cd227f23458c672c08b3acf08ba65fa9a48b581d..82c57a685e105527625c7dd3c0acdb77e59e1c8c 100644 --- a/devices/examples/load_from_disk/ini_client.py +++ b/tangostationcontrol/tangostationcontrol/examples/load_from_disk/ini_client.py @@ -1,4 +1,4 @@ -from clients.comms_client import CommClient +from tangostationcontrol.clients.comms_client import CommClient import configparser import numpy diff --git a/devices/examples/load_from_disk/ini_device.py b/tangostationcontrol/tangostationcontrol/examples/load_from_disk/ini_device.py similarity index 93% rename from devices/examples/load_from_disk/ini_device.py rename to tangostationcontrol/tangostationcontrol/examples/load_from_disk/ini_device.py index 07b2f419ab6b4cd5d78eb84a66c3906e169da99d..1f65d3ccd5f0827305a2d1a91e958b6e6241bc85 100644 --- a/devices/examples/load_from_disk/ini_device.py +++ b/tangostationcontrol/tangostationcontrol/examples/load_from_disk/ini_device.py @@ -9,26 +9,17 @@ """ -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -parentdir = os.path.dirname(parentdir) -sys.path.append(parentdir) - # PyTango imports from tango.server import run from tango import AttrWriteType -# Additional import -from clients.attribute_wrapper import attribute_wrapper -from devices.hardware_device import hardware_device - import configparser import numpy -from ini_client import * - +# Additional import +from tangostationcontrol.clients.attribute_wrapper import attribute_wrapper +from tangostationcontrol.devices.hardware_device import hardware_device +from tangostationcontrol.examples.load_from_disk.ini_client import * __all__ = ["ini_device"] @@ -130,10 +121,5 @@ class ini_device(hardware_device): def main(args=None, **kwargs): write_ini_file("example.ini") - """Main function of the hardware device module.""" return run((ini_device,), args=args, **kwargs) - - -if __name__ == '__main__': - main() diff --git a/devices/test/__init__.py b/tangostationcontrol/tangostationcontrol/examples/snmp/__init__.py similarity index 100% rename from devices/test/__init__.py rename to tangostationcontrol/tangostationcontrol/examples/snmp/__init__.py diff --git a/devices/examples/snmp/snmp.py b/tangostationcontrol/tangostationcontrol/examples/snmp/snmp.py similarity index 85% rename from devices/examples/snmp/snmp.py rename to tangostationcontrol/tangostationcontrol/examples/snmp/snmp.py index 2a912ce1443bbd8e83b662d4ed9764627d947943..845ff0937ccaaf3ad120fe6c96acfce581417f0f 100644 --- a/devices/examples/snmp/snmp.py +++ b/tangostationcontrol/tangostationcontrol/examples/snmp/snmp.py @@ -11,22 +11,15 @@ """ -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -parentdir = os.path.dirname(parentdir) -sys.path.append(parentdir) - # PyTango imports from tango.server import run from tango.server import device_property from tango import AttrWriteType # Additional import -from examples.snmp.snmp_client import SNMP_client -from clients.attribute_wrapper import attribute_wrapper -from devices.hardware_device import hardware_device +from tangostationcontrol.examples.snmp.snmp_client import SNMP_client +from tangostationcontrol.clients.attribute_wrapper import attribute_wrapper +from tangostationcontrol.devices.hardware_device import hardware_device import numpy @@ -118,12 +111,7 @@ class SNMP(hardware_device): def main(args=None, **kwargs): """Main function of the module.""" - from common.lofar_logging import configure_logger - import logging - configure_logger(logging.getLogger()) + from tangostationcontrol.common.lofar_logging import configure_logger + configure_logger() return run((SNMP,), args=args, **kwargs) - - -if __name__ == '__main__': - main() diff --git a/devices/examples/snmp/snmp_client.py b/tangostationcontrol/tangostationcontrol/examples/snmp/snmp_client.py similarity index 98% rename from devices/examples/snmp/snmp_client.py rename to tangostationcontrol/tangostationcontrol/examples/snmp/snmp_client.py index 96ac67140b9bdbdba7ab4d4fb8651b5e9674c219..00464f37d92800207fec524279126e494886d01a 100644 --- a/devices/examples/snmp/snmp_client.py +++ b/tangostationcontrol/tangostationcontrol/examples/snmp/snmp_client.py @@ -1,5 +1,5 @@ -from clients.comms_client import CommClient +from tangostationcontrol.clients.comms_client import CommClient import snmp diff --git a/devices/integration_test/README.md b/tangostationcontrol/tangostationcontrol/integration_test/README.md similarity index 100% rename from devices/integration_test/README.md rename to tangostationcontrol/tangostationcontrol/integration_test/README.md diff --git a/devices/test/clients/__init__.py b/tangostationcontrol/tangostationcontrol/integration_test/__init__.py similarity index 100% rename from devices/test/clients/__init__.py rename to tangostationcontrol/tangostationcontrol/integration_test/__init__.py diff --git a/devices/integration_test/base.py b/tangostationcontrol/tangostationcontrol/integration_test/base.py similarity index 92% rename from devices/integration_test/base.py rename to tangostationcontrol/tangostationcontrol/integration_test/base.py index 241f0ecd409fd16484d81e31f1e1f83dc1b9d81b..ed1eb2239af74251e22b42adf8ea5e2596688076 100644 --- a/devices/integration_test/base.py +++ b/tangostationcontrol/tangostationcontrol/integration_test/base.py @@ -7,7 +7,7 @@ # Distributed under the terms of the APACHE license. # See LICENSE.txt for more info. -from common.lofar_logging import configure_logger +from tangostationcontrol.common.lofar_logging import configure_logger import unittest import asynctest diff --git a/devices/test/common/__init__.py b/tangostationcontrol/tangostationcontrol/integration_test/client/__init__.py similarity index 100% rename from devices/test/common/__init__.py rename to tangostationcontrol/tangostationcontrol/integration_test/client/__init__.py diff --git a/devices/integration_test/client/test_sdptr_sim.py b/tangostationcontrol/tangostationcontrol/integration_test/client/test_sdptr_sim.py similarity index 92% rename from devices/integration_test/client/test_sdptr_sim.py rename to tangostationcontrol/tangostationcontrol/integration_test/client/test_sdptr_sim.py index ab9288b727e515c19b07c99d1fe8a233d7032055..a09f407e2982d7b873021f03b1eb9e78fe336e44 100644 --- a/devices/integration_test/client/test_sdptr_sim.py +++ b/tangostationcontrol/tangostationcontrol/integration_test/client/test_sdptr_sim.py @@ -9,7 +9,7 @@ from asyncua import Client -from integration_test import base +from tangostationcontrol.integration_test import base class TestSDPTRSim(base.IntegrationAsyncTestCase): diff --git a/devices/integration_test/client/test_tcp_replicator.py b/tangostationcontrol/tangostationcontrol/integration_test/client/test_tcp_replicator.py similarity index 97% rename from devices/integration_test/client/test_tcp_replicator.py rename to tangostationcontrol/tangostationcontrol/integration_test/client/test_tcp_replicator.py index ca45c4c52ab7f5e379c484b964a05225950fc9e1..2467fd6dd8a7b24cc786c5b2cc10a25a610b88f1 100644 --- a/devices/integration_test/client/test_tcp_replicator.py +++ b/tangostationcontrol/tangostationcontrol/integration_test/client/test_tcp_replicator.py @@ -7,18 +7,16 @@ # Distributed under the terms of the APACHE license. # See LICENSE.txt for more info. -from asyncio import Queue - import logging import time import socket import sys -from clients.tcp_replicator import TCPReplicator +import timeout_decorator -from integration_test import base +from tangostationcontrol.clients.tcp_replicator import TCPReplicator -import timeout_decorator +from tangostationcontrol.integration_test import base logger = logging.getLogger() diff --git a/devices/integration_test/client/test_unb2_sim.py b/tangostationcontrol/tangostationcontrol/integration_test/client/test_unb2_sim.py similarity index 92% rename from devices/integration_test/client/test_unb2_sim.py rename to tangostationcontrol/tangostationcontrol/integration_test/client/test_unb2_sim.py index d934c06fb6dfb40dad1c8b54dc00a00715deedc8..261441901c589a26256b586dc571f7b063c08408 100644 --- a/devices/integration_test/client/test_unb2_sim.py +++ b/tangostationcontrol/tangostationcontrol/integration_test/client/test_unb2_sim.py @@ -9,7 +9,7 @@ from asyncua import Client -from integration_test import base +from tangostationcontrol.integration_test import base class TestUNB2Sim(base.IntegrationAsyncTestCase): diff --git a/devices/integration_test/device_proxy.py b/tangostationcontrol/tangostationcontrol/integration_test/device_proxy.py similarity index 100% rename from devices/integration_test/device_proxy.py rename to tangostationcontrol/tangostationcontrol/integration_test/device_proxy.py diff --git a/devices/test/devices/__init__.py b/tangostationcontrol/tangostationcontrol/integration_test/devices/__init__.py similarity index 100% rename from devices/test/devices/__init__.py rename to tangostationcontrol/tangostationcontrol/integration_test/devices/__init__.py diff --git a/devices/integration_test/devices/test_device_recv.py b/tangostationcontrol/tangostationcontrol/integration_test/devices/test_device_recv.py similarity index 90% rename from devices/integration_test/devices/test_device_recv.py rename to tangostationcontrol/tangostationcontrol/integration_test/devices/test_device_recv.py index 72199e292d9a8ce5ab90c69d764d03a342bb41c9..6e6e8602e0662750b7b097c4e60f7fef0ce056a2 100644 --- a/devices/integration_test/devices/test_device_recv.py +++ b/tangostationcontrol/tangostationcontrol/integration_test/devices/test_device_recv.py @@ -9,8 +9,8 @@ from tango._tango import DevState -from integration_test.device_proxy import TestDeviceProxy -from integration_test import base +from tangostationcontrol.integration_test.device_proxy import TestDeviceProxy +from tangostationcontrol.integration_test import base class TestDeviceRECV(base.IntegrationTestCase): diff --git a/devices/integration_test/devices/test_device_sdp.py b/tangostationcontrol/tangostationcontrol/integration_test/devices/test_device_sdp.py similarity index 91% rename from devices/integration_test/devices/test_device_sdp.py rename to tangostationcontrol/tangostationcontrol/integration_test/devices/test_device_sdp.py index 3db8b744ffc6679cfd9389640a9d27e18c3d2ca1..faf965eb00c8c57785712b6bb581d9118c4632ba 100644 --- a/devices/integration_test/devices/test_device_sdp.py +++ b/tangostationcontrol/tangostationcontrol/integration_test/devices/test_device_sdp.py @@ -7,10 +7,11 @@ # Distributed under the terms of the APACHE license. # See LICENSE.txt for more info. +from tango import DeviceProxy from tango._tango import DevState -from integration_test.device_proxy import TestDeviceProxy -from integration_test import base +from tangostationcontrol.integration_test.device_proxy import TestDeviceProxy +from tangostationcontrol.integration_test import base class TestDeviceSDP(base.IntegrationTestCase): diff --git a/devices/integration_test/devices/test_device_sst.py b/tangostationcontrol/tangostationcontrol/integration_test/devices/test_device_sst.py similarity index 96% rename from devices/integration_test/devices/test_device_sst.py rename to tangostationcontrol/tangostationcontrol/integration_test/devices/test_device_sst.py index 759028324d5c63dea55a930c2bd0557d69f7213d..194313fd6708d01ab70bda04563ce038bb55086c 100644 --- a/devices/integration_test/devices/test_device_sst.py +++ b/tangostationcontrol/tangostationcontrol/integration_test/devices/test_device_sst.py @@ -12,8 +12,8 @@ import time from tango._tango import DevState -from integration_test.device_proxy import TestDeviceProxy -from integration_test import base +from tangostationcontrol.integration_test.device_proxy import TestDeviceProxy +from tangostationcontrol.integration_test import base class TestDeviceSST(base.IntegrationTestCase): diff --git a/devices/integration_test/devices/test_device_unb2.py b/tangostationcontrol/tangostationcontrol/integration_test/devices/test_device_unb2.py similarity index 91% rename from devices/integration_test/devices/test_device_unb2.py rename to tangostationcontrol/tangostationcontrol/integration_test/devices/test_device_unb2.py index 00702a36a1b480ad583d29d80da69874cc1e98af..c699e225c05861f61786f332a70ccb3191f2dc5f 100644 --- a/devices/integration_test/devices/test_device_unb2.py +++ b/tangostationcontrol/tangostationcontrol/integration_test/devices/test_device_unb2.py @@ -9,8 +9,8 @@ from tango._tango import DevState -from integration_test.device_proxy import TestDeviceProxy -from integration_test import base +from tangostationcontrol.integration_test.device_proxy import TestDeviceProxy +from tangostationcontrol.integration_test import base class TestDeviceUNB2(base.IntegrationTestCase): diff --git a/devices/integration_test/devices/test_tango_database.py b/tangostationcontrol/tangostationcontrol/integration_test/devices/test_tango_database.py similarity index 93% rename from devices/integration_test/devices/test_tango_database.py rename to tangostationcontrol/tangostationcontrol/integration_test/devices/test_tango_database.py index 0ae65d5c51a98898e4016bbb231baa18b025dba9..b14cc363f24b3ea8e77ecd59e1184500fe40e0d4 100644 --- a/devices/integration_test/devices/test_tango_database.py +++ b/tangostationcontrol/tangostationcontrol/integration_test/devices/test_tango_database.py @@ -12,7 +12,7 @@ import time from tango import Database from tango._tango import DevState -from integration_test import base +from tangostationcontrol.integration_test import base class TestTangoDatabase(base.IntegrationTestCase): diff --git a/devices/statistics_writer/README.md b/tangostationcontrol/tangostationcontrol/statistics_writer/README.md similarity index 100% rename from devices/statistics_writer/README.md rename to tangostationcontrol/tangostationcontrol/statistics_writer/README.md diff --git a/devices/statistics_writer/SST_2021-10-04-07-36-52.h5 b/tangostationcontrol/tangostationcontrol/statistics_writer/SST_2021-10-04-07-36-52.h5 similarity index 100% rename from devices/statistics_writer/SST_2021-10-04-07-36-52.h5 rename to tangostationcontrol/tangostationcontrol/statistics_writer/SST_2021-10-04-07-36-52.h5 diff --git a/tangostationcontrol/tangostationcontrol/statistics_writer/__init__.py b/tangostationcontrol/tangostationcontrol/statistics_writer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/devices/statistics_writer/hdf5_writer.py b/tangostationcontrol/tangostationcontrol/statistics_writer/hdf5_writer.py similarity index 98% rename from devices/statistics_writer/hdf5_writer.py rename to tangostationcontrol/tangostationcontrol/statistics_writer/hdf5_writer.py index 6715dd870608a0202610ea52c417695844f0d1c9..eb7fa643bd9c8d74b1e946f468532c4852ecaba5 100644 --- a/devices/statistics_writer/hdf5_writer.py +++ b/tangostationcontrol/tangostationcontrol/statistics_writer/hdf5_writer.py @@ -11,8 +11,8 @@ import logging # import statistics classes with workaround import sys sys.path.append("..") -from devices.sdp.statistics_packet import SSTPacket, XSTPacket, BSTPacket, StatisticsPacket -import devices.sdp.statistics_collector as statistics_collector +from tangostationcontrol.devices.sdp.statistics_packet import SSTPacket, XSTPacket, BSTPacket, StatisticsPacket +import tangostationcontrol.devices.sdp.statistics_collector as statistics_collector logger = logging.getLogger("statistics_writer") diff --git a/devices/statistics_writer/receiver.py b/tangostationcontrol/tangostationcontrol/statistics_writer/receiver.py similarity index 96% rename from devices/statistics_writer/receiver.py rename to tangostationcontrol/tangostationcontrol/statistics_writer/receiver.py index 92d0d6d34bfc69f8f89f306c86b906c68956e47b..cd6c0af4cd5d4a1f8cdc3c2e37d86f6bd655db53 100644 --- a/devices/statistics_writer/receiver.py +++ b/tangostationcontrol/tangostationcontrol/statistics_writer/receiver.py @@ -2,7 +2,7 @@ import socket import sys sys.path.append("..") -from devices.sdp.statistics_packet import StatisticsPacket +from tangostationcontrol.devices.sdp.statistics_packet import StatisticsPacket import os class receiver: diff --git a/devices/statistics_writer/statistics_reader.py b/tangostationcontrol/tangostationcontrol/statistics_writer/statistics_reader.py similarity index 93% rename from devices/statistics_writer/statistics_reader.py rename to tangostationcontrol/tangostationcontrol/statistics_writer/statistics_reader.py index f0906e7d4122b2f1d0d8d864d8c6a47ad793c0f4..67ff6377cdf90326d7a9fa33a015c1ac5861064d 100644 --- a/devices/statistics_writer/statistics_reader.py +++ b/tangostationcontrol/tangostationcontrol/statistics_writer/statistics_reader.py @@ -5,16 +5,9 @@ import argparse import os import psutil import pytz -import time process = psutil.Process(os.getpid()) -parser = argparse.ArgumentParser(description='Select a file to explore') -parser.add_argument('--files', type=str, nargs="+", help='the name and path of the files, takes one or more files') -parser.add_argument('--start_time', type=str, help='lowest timestamp to process (uses isoformat, ex: 2021-10-04T07:50:08.937+00:00)') -parser.add_argument('--end_time', type=str, help='highest timestamp to process (uses isoformat, ex: 2021-10-04T07:50:08.937+00:00)') - - import logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger("hdf5_explorer") @@ -219,7 +212,20 @@ class statistics_data: self.values = numpy.array(file.get(f"{group_key}/values")) -if __name__ == "__main__": +def main(): + parser = argparse.ArgumentParser(description='Select a file to explore') + parser.add_argument( + '--files', type=str, nargs="+", required=True, + help='the name and path of the files, takes one or more files') + parser.add_argument( + '--start_time', type=str, required=True, + help='lowest timestamp to process (uses isoformat, ex: 2021-10-04T07:50' + ':08.937+00:00)') + parser.add_argument( + '--end_time', type=str, required=True, + help='highest timestamp to process (usesisoformat, ex: 2021-10-04T07:50' + ':08.937+00:00)') + args = parser.parse_args() files = args.files end_time = args.end_time diff --git a/devices/statistics_writer/statistics_writer.py b/tangostationcontrol/tangostationcontrol/statistics_writer/statistics_writer.py similarity index 56% rename from devices/statistics_writer/statistics_writer.py rename to tangostationcontrol/tangostationcontrol/statistics_writer/statistics_writer.py index 8bf8fa64fbba9626f60abec0bb6cacb7e7288c51..1a1ecb671159e1b3ca143ecbf860000d6cdbe0c5 100644 --- a/devices/statistics_writer/statistics_writer.py +++ b/tangostationcontrol/tangostationcontrol/statistics_writer/statistics_writer.py @@ -1,32 +1,49 @@ import argparse -from receiver import tcp_receiver, file_receiver -from hdf5_writer import hdf5_writer - import time -from datetime import datetime - import sys -import signal + +from tangostationcontrol.statistics_writer.receiver import tcp_receiver, file_receiver +from tangostationcontrol.statistics_writer.hdf5_writer import hdf5_writer import logging logging.basicConfig(level=logging.INFO, format = '%(asctime)s:%(levelname)s: %(message)s') logger = logging.getLogger("statistics_writer") +def main(): + parser = argparse.ArgumentParser( + description='Converts a stream of statistics packets into HDF5 files.') + parser.add_argument( + '-a', '--host', type=str, required=True, help='the host to connect to') + parser.add_argument( + '-p', '--port', type=int, default=0, + help='the port to connect to, or 0 to use default port for the ' + 'selected mode (default: %(default)s)') + parser.add_argument( + '-f', '--file', type=str, required=True, help='the file to read from') + parser.add_argument( + '-m', '--mode', type=str, choices=['SST', 'XST', 'BST'], default='SST', + help='sets the statistics type to be decoded options (default: ' + '%(default)s)') + parser.add_argument( + '-i', '--interval', type=float, default=3600, nargs="?", + help='The time between creating new files in seconds (default: ' + '%(default)s)') + parser.add_argument( + '-o', '--output_dir', type=str, default=".", nargs="?", + help='specifies the folder to write all the files (default: ' + '%(default)s)') + parser.add_argument( + '-v', '--debug', dest='debug', action='store_true', default=False, + help='increase log output') + parser.add_argument( + '-d', '--decimation', type=int, default=1, + help='Configure the writer to only store one every n samples. Saves ' + 'storage space') + parser.add_argument( + '-r', '--reconnect', dest='reconnect', action='store_true', default=False, + help='Set the writer to keep trying to reconnect whenever connection ' + 'is lost. (default: %(default)s)') -parser = argparse.ArgumentParser(description='Converts a stream of statistics packets into HDF5 files.') -parser.add_argument('-a', '--host', type=str, help='The host to connect to.') -parser.add_argument('-p', '--port', type=int, default=0, help='The port to connect to, or 0 to use default port for the selected mode. (default: %(default)s)') -parser.add_argument('-f', '--file', type=str, help='The file to read from. (will ignore --host and --port)') - -parser.add_argument('-m', '--mode', type=str, choices=['SST', 'XST', 'BST'], default='SST', help='Sets the statistics type to be decoded options. (default: %(default)s)') -parser.add_argument('-i', '--interval', type=float, default=3600, nargs="?", help='The time between creating new files in seconds. (default: %(default)s)') -parser.add_argument('-o', '--output_dir', type=str, default=".", nargs="?", help='Specifies the folder to write all the files. (default: %(default)s)') -parser.add_argument('-d', '--decimation', type=int, default=1, help='Configure the writer to only store one every n samples. Saves storage space.') -parser.add_argument('-v', '--debug', dest='debug', action='store_true', default=False, help='Increase log output.') -parser.add_argument('-r', '--reconnect', dest='reconnect', action='store_true', default=False, help='Set the writer to keep trying to reconnect whenever connection is lost. (default: %(default)s)') - - -if __name__ == "__main__": args = parser.parse_args() # argparse arguments diff --git a/devices/statistics_writer/test/SST_10m_test_1.h5 b/tangostationcontrol/tangostationcontrol/statistics_writer/test/SST_10m_test_1.h5 similarity index 100% rename from devices/statistics_writer/test/SST_10m_test_1.h5 rename to tangostationcontrol/tangostationcontrol/statistics_writer/test/SST_10m_test_1.h5 diff --git a/devices/statistics_writer/test/SST_10m_test_2.h5 b/tangostationcontrol/tangostationcontrol/statistics_writer/test/SST_10m_test_2.h5 similarity index 100% rename from devices/statistics_writer/test/SST_10m_test_2.h5 rename to tangostationcontrol/tangostationcontrol/statistics_writer/test/SST_10m_test_2.h5 diff --git a/devices/statistics_writer/test/SST_10m_test_3.h5 b/tangostationcontrol/tangostationcontrol/statistics_writer/test/SST_10m_test_3.h5 similarity index 100% rename from devices/statistics_writer/test/SST_10m_test_3.h5 rename to tangostationcontrol/tangostationcontrol/statistics_writer/test/SST_10m_test_3.h5 diff --git a/tangostationcontrol/tangostationcontrol/statistics_writer/test/__init__.py b/tangostationcontrol/tangostationcontrol/statistics_writer/test/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/devices/statistics_writer/test/devices_test_SDP_SST_statistics_packets.bin b/tangostationcontrol/tangostationcontrol/statistics_writer/test/devices_test_SDP_SST_statistics_packets.bin similarity index 100% rename from devices/statistics_writer/test/devices_test_SDP_SST_statistics_packets.bin rename to tangostationcontrol/tangostationcontrol/statistics_writer/test/devices_test_SDP_SST_statistics_packets.bin diff --git a/devices/statistics_writer/test/test_server.py b/tangostationcontrol/tangostationcontrol/statistics_writer/test/test_server.py similarity index 100% rename from devices/statistics_writer/test/test_server.py rename to tangostationcontrol/tangostationcontrol/statistics_writer/test/test_server.py diff --git a/tangostationcontrol/tangostationcontrol/statistics_writer/udp_dev/__init__.py b/tangostationcontrol/tangostationcontrol/statistics_writer/udp_dev/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/devices/statistics_writer/udp_dev/udp_client.py b/tangostationcontrol/tangostationcontrol/statistics_writer/udp_dev/udp_client.py similarity index 100% rename from devices/statistics_writer/udp_dev/udp_client.py rename to tangostationcontrol/tangostationcontrol/statistics_writer/udp_dev/udp_client.py diff --git a/devices/statistics_writer/udp_dev/udp_server.py b/tangostationcontrol/tangostationcontrol/statistics_writer/udp_dev/udp_server.py similarity index 100% rename from devices/statistics_writer/udp_dev/udp_server.py rename to tangostationcontrol/tangostationcontrol/statistics_writer/udp_dev/udp_server.py diff --git a/devices/statistics_writer/udp_dev/udp_write_manager.py b/tangostationcontrol/tangostationcontrol/statistics_writer/udp_dev/udp_write_manager.py similarity index 100% rename from devices/statistics_writer/udp_dev/udp_write_manager.py rename to tangostationcontrol/tangostationcontrol/statistics_writer/udp_dev/udp_write_manager.py diff --git a/devices/test/README.md b/tangostationcontrol/tangostationcontrol/test/README.md similarity index 100% rename from devices/test/README.md rename to tangostationcontrol/tangostationcontrol/test/README.md diff --git a/devices/test/SDP_SST_statistics_packet.bin b/tangostationcontrol/tangostationcontrol/test/SDP_SST_statistics_packet.bin similarity index 100% rename from devices/test/SDP_SST_statistics_packet.bin rename to tangostationcontrol/tangostationcontrol/test/SDP_SST_statistics_packet.bin diff --git a/devices/test/SDP_SST_statistics_packets.bin b/tangostationcontrol/tangostationcontrol/test/SDP_SST_statistics_packets.bin similarity index 100% rename from devices/test/SDP_SST_statistics_packets.bin rename to tangostationcontrol/tangostationcontrol/test/SDP_SST_statistics_packets.bin diff --git a/devices/test/SDP_XST_statistics_packets.bin b/tangostationcontrol/tangostationcontrol/test/SDP_XST_statistics_packets.bin similarity index 100% rename from devices/test/SDP_XST_statistics_packets.bin rename to tangostationcontrol/tangostationcontrol/test/SDP_XST_statistics_packets.bin diff --git a/tangostationcontrol/tangostationcontrol/test/__init__.py b/tangostationcontrol/tangostationcontrol/test/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/devices/test/base.py b/tangostationcontrol/tangostationcontrol/test/base.py similarity index 91% rename from devices/test/base.py rename to tangostationcontrol/tangostationcontrol/test/base.py index 1c2eff09be8e6a4034a476173944c8ec2a1fe61c..7cf3af7f8becb1f92cde139290394ea540f5d8d6 100644 --- a/devices/test/base.py +++ b/tangostationcontrol/tangostationcontrol/test/base.py @@ -7,7 +7,7 @@ # Distributed under the terms of the APACHE license. # See LICENSE.txt for more info. -from common.lofar_logging import configure_logger +from tangostationcontrol.common.lofar_logging import configure_logger import unittest import testscenarios diff --git a/tangostationcontrol/tangostationcontrol/test/clients/__init__.py b/tangostationcontrol/tangostationcontrol/test/clients/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/devices/test/clients/test_attr_wrapper.py b/tangostationcontrol/tangostationcontrol/test/clients/test_attr_wrapper.py similarity index 99% rename from devices/test/clients/test_attr_wrapper.py rename to tangostationcontrol/tangostationcontrol/test/clients/test_attr_wrapper.py index 8711d989a67730667c10aed91de7c9929c500fcb..f1c5b652c545b31f897388ddce0c8f66df37912e 100644 --- a/devices/test/clients/test_attr_wrapper.py +++ b/tangostationcontrol/tangostationcontrol/test/clients/test_attr_wrapper.py @@ -10,13 +10,13 @@ from tango import DevState # Internal imports -from test.clients.test_client import test_client -from clients.attribute_wrapper import * -from devices.hardware_device import * +from tangostationcontrol.test.clients.test_client import test_client +from tangostationcontrol.clients.attribute_wrapper import * +from tangostationcontrol.devices.hardware_device import * # Test imports from tango.test_context import DeviceTestContext -from test import base +from tangostationcontrol.test import base import asyncio diff --git a/devices/test/clients/test_client.py b/tangostationcontrol/tangostationcontrol/test/clients/test_client.py similarity index 98% rename from devices/test/clients/test_client.py rename to tangostationcontrol/tangostationcontrol/test/clients/test_client.py index 7e002c3ad28a531b0ba16f12a22e782d4ba3bb01..ee3e0faf62b780dfb83a252dcf99897690090a35 100644 --- a/devices/test/clients/test_client.py +++ b/tangostationcontrol/tangostationcontrol/test/clients/test_client.py @@ -3,7 +3,7 @@ import numpy # Test imports -from clients.comms_client import CommClient +from tangostationcontrol.clients.comms_client import CommClient class test_client(CommClient): diff --git a/devices/test/clients/test_opcua_client.py b/tangostationcontrol/tangostationcontrol/test/clients/test_opcua_client.py similarity index 98% rename from devices/test/clients/test_opcua_client.py rename to tangostationcontrol/tangostationcontrol/test/clients/test_opcua_client.py index bc13dc5e1d1d04c800e35f113825015b38779cd9..c1c29ee04279bab3c943ccc35d4e3a5071345607 100644 --- a/devices/test/clients/test_opcua_client.py +++ b/tangostationcontrol/tangostationcontrol/test/clients/test_opcua_client.py @@ -1,16 +1,15 @@ import numpy -from clients.opcua_client import OPCUAConnection -from clients import opcua_client - import asyncua import io -import asyncio +import asynctest from unittest import mock -import unittest -from test import base -import asynctest + +from tangostationcontrol.clients.opcua_client import OPCUAConnection +from tangostationcontrol.clients import opcua_client + +from tangostationcontrol.test import base class attr_props: diff --git a/devices/test/clients/test_statistics_client_thread.py b/tangostationcontrol/tangostationcontrol/test/clients/test_statistics_client_thread.py similarity index 86% rename from devices/test/clients/test_statistics_client_thread.py rename to tangostationcontrol/tangostationcontrol/test/clients/test_statistics_client_thread.py index fd7ce0701f9d792863909b9f8ee4a9d39a2b1fd1..17f866871bd682b3f289364c16a55e5ee2010a7c 100644 --- a/devices/test/clients/test_statistics_client_thread.py +++ b/tangostationcontrol/tangostationcontrol/test/clients/test_statistics_client_thread.py @@ -10,9 +10,10 @@ import logging from unittest import mock -from clients.statistics_client_thread import StatisticsClientThread +from tangostationcontrol.clients.statistics_client_thread import \ + StatisticsClientThread -from test import base +from tangostationcontrol.test import base logger = logging.getLogger() diff --git a/devices/test/clients/test_tcp_replicator.py b/tangostationcontrol/tangostationcontrol/test/clients/test_tcp_replicator.py similarity index 97% rename from devices/test/clients/test_tcp_replicator.py rename to tangostationcontrol/tangostationcontrol/test/clients/test_tcp_replicator.py index a9babed0eb7af7a58544b3ff7535c3113ed12ca3..04c87f1d5a15705f7d0b8ce1460141255cb02b27 100644 --- a/devices/test/clients/test_tcp_replicator.py +++ b/tangostationcontrol/tangostationcontrol/test/clients/test_tcp_replicator.py @@ -9,15 +9,14 @@ import logging import time -from queue import Queue from unittest import mock -from clients.tcp_replicator import TCPReplicator -from clients import tcp_replicator +import timeout_decorator -from test import base +from tangostationcontrol.clients.tcp_replicator import TCPReplicator +from tangostationcontrol.clients import tcp_replicator -import timeout_decorator +from tangostationcontrol.test import base logger = logging.getLogger() diff --git a/tangostationcontrol/tangostationcontrol/test/common/__init__.py b/tangostationcontrol/tangostationcontrol/test/common/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/devices/test/common/test_baselines.py b/tangostationcontrol/tangostationcontrol/test/common/test_baselines.py similarity index 91% rename from devices/test/common/test_baselines.py rename to tangostationcontrol/tangostationcontrol/test/common/test_baselines.py index 206b4ca0eccefe1012519c8236d158e52f1cdc38..25eb5d1dfffa2fca8748d74020893edfb17c2037 100644 --- a/devices/test/common/test_baselines.py +++ b/tangostationcontrol/tangostationcontrol/test/common/test_baselines.py @@ -7,9 +7,9 @@ # Distributed under the terms of the APACHE license. # See LICENSE.txt for more info. -from common import baselines +from tangostationcontrol.common import baselines -from test import base +from tangostationcontrol.test import base class TestBaselines(base.TestCase): diff --git a/devices/test/common/test_lofar_logging.py b/tangostationcontrol/tangostationcontrol/test/common/test_lofar_logging.py similarity index 97% rename from devices/test/common/test_lofar_logging.py rename to tangostationcontrol/tangostationcontrol/test/common/test_lofar_logging.py index c1030b28f3b9b7861e6eec9d25b4ca6ef22a0c22..5140d05e58ca370509a080211ca96f2df21fe399 100644 --- a/devices/test/common/test_lofar_logging.py +++ b/tangostationcontrol/tangostationcontrol/test/common/test_lofar_logging.py @@ -7,16 +7,16 @@ # Distributed under the terms of the APACHE license. # See LICENSE.txt for more info. -import git from unittest import mock - -from common import lofar_logging import logging + from tango.server import Device from tango import device_server from tango.test_context import DeviceTestContext -from test import base +from tangostationcontrol.common import lofar_logging + +from tangostationcontrol.test import base class TestLofarLogging(base.TestCase): diff --git a/tangostationcontrol/tangostationcontrol/test/common/test_lofar_version.py b/tangostationcontrol/tangostationcontrol/test/common/test_lofar_version.py new file mode 100644 index 0000000000000000000000000000000000000000..89ac894d9388d3939671c43239033ce1147fef30 --- /dev/null +++ b/tangostationcontrol/tangostationcontrol/test/common/test_lofar_version.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +# +# This file is part of the LOFAR 2.0 Station Software +# +# +# +# Distributed under the terms of the APACHE license. +# See LICENSE.txt for more info. + +import git +from unittest import mock + +from tangostationcontrol.common import lofar_version + +from tangostationcontrol.test import base + + +class TestLofarVersion(base.TestCase): + + def setUp(self): + super(TestLofarVersion, self).setUp() + + # Clear the cache as this function of lofar_version uses LRU decorator + # This is a good demonstration of how unit tests in Python can have + # permanent effects, typically fixtures are needed to restore these. + lofar_version.get_version.cache_clear() + + def test_get_version(self): + """Test if attributes of get_repo are correctly used by get_version""" + + with mock.patch.object(lofar_version, 'get_repo') as m_get_repo: + m_commit = mock.Mock() + m_commit.return_value.__str__ = mock.Mock(return_value="123456") + m_commit.return_value.iter_items.return_value = [] + + m_is_dirty = mock.Mock() + m_is_dirty.return_value = False + + m_head = mock.Mock(is_detached=False) + + m_get_repo.return_value = mock.Mock( + active_branch="main", commit=m_commit, tags=[], + is_dirty=m_is_dirty, head=m_head) + + # No need for special string equal in Python + self.assertEqual("0.0.0.main.123456", lofar_version.get_version()) + + def test_get_version_tag(self): + """Test if get_version determines production_ready for tagged commit""" + + with mock.patch.object(lofar_version, 'get_repo') as m_get_repo: + m_commit = mock.Mock() + m_commit.return_value.__str__ = mock.Mock(return_value="123456") + m_commit.return_value.iter_items.return_value = [] + + m_is_dirty = mock.Mock() + m_is_dirty.return_value = False + + m_head = mock.Mock(is_detached=False) + + m_tag_commit = mock.Mock(type="commit") + m_tag_commit.__str__ = mock.Mock(return_value="123456") + + m_tag = mock.Mock(commit=m_tag_commit) + m_tag.name = "v0.0.3" + m_tag.__str__ = mock.Mock(return_value= "v0.0.3") + + m_commit.return_value = m_tag_commit + m_commit.return_value.iter_items.return_value = [m_tag_commit] + + m_get_repo.return_value = mock.Mock( + active_branch="main", commit=m_commit, + tags=[m_tag], is_dirty=m_is_dirty, head=m_head) + + self.assertEqual("0.0.3", lofar_version.get_version()) + + @mock.patch.object(lofar_version, 'get_repo') + def test_get_version_tag_dirty(self, m_get_repo): + + """Test if get_version determines dirty tagged commit""" + m_commit = mock.Mock() + m_commit.return_value.__str__ = mock.Mock(return_value="123456") + m_commit.return_value.iter_items.return_value = [] + + m_is_dirty = mock.Mock() + m_is_dirty.return_value = True + + m_head = mock.Mock(is_detached=False) + + m_get_repo.return_value = mock.Mock( + active_branch="main", commit=m_commit, tags=[], + is_dirty=m_is_dirty, head=m_head) + + # No need for special string equal in Python + self.assertEqual("0.0.0.main.123456.dirty", lofar_version.get_version()) + + def test_catch_repo_error(self): + """Test if invalid git directories will raise error""" + + with mock.patch.object(lofar_version, 'get_repo') as m_get_repo: + + # Configure lofar_version.get_repo to raise InvalidGitRepositoryError + m_get_repo.side_effect = git.InvalidGitRepositoryError + + # Test that error is raised by get_version + self.assertRaises( + git.InvalidGitRepositoryError, lofar_version.get_version) diff --git a/tangostationcontrol/tangostationcontrol/test/devices/__init__.py b/tangostationcontrol/tangostationcontrol/test/devices/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/devices/test/devices/random_data.py b/tangostationcontrol/tangostationcontrol/test/devices/random_data.py similarity index 97% rename from devices/test/devices/random_data.py rename to tangostationcontrol/tangostationcontrol/test/devices/random_data.py index 43e1a037624a516f88d05d644fd86e23fab6baa8..51d7b269f99c814cb340dc9f0e8feb44f3393f94 100644 --- a/devices/test/devices/random_data.py +++ b/tangostationcontrol/tangostationcontrol/test/devices/random_data.py @@ -7,13 +7,6 @@ # Distributed under the terms of the APACHE license. # See LICENSE.txt for more info. -# TODO(Corne): Remove sys.path.append hack once packaging is in place! -import os, sys -currentdir = os.path.dirname(os.path.realpath(__file__)) -parentdir = os.path.dirname(currentdir) -parentdir = os.path.dirname(parentdir) -sys.path.append(parentdir) - # PyTango imports from tango import DevState from tango.server import run, Device, attribute, command @@ -497,6 +490,3 @@ def main(args = None, **kwargs): Main function of the RandomData module. """ return run((Random_Data,), args = args, **kwargs) - -if __name__ == '__main__': - main() diff --git a/devices/test/devices/test_abstract_device.py b/tangostationcontrol/tangostationcontrol/test/devices/test_abstract_device.py similarity index 95% rename from devices/test/devices/test_abstract_device.py rename to tangostationcontrol/tangostationcontrol/test/devices/test_abstract_device.py index f54383c9a1b85f5c9e442f51d7f04d061951f772..469ea19fa970cf48c2de9c4c6b5648bd7b756040 100644 --- a/devices/test/devices/test_abstract_device.py +++ b/tangostationcontrol/tangostationcontrol/test/devices/test_abstract_device.py @@ -16,9 +16,9 @@ from tango.server import attribute from tango.test_context import DeviceTestContext -from devices.abstract_device import AbstractDeviceMetas +from tangostationcontrol.devices.abstract_device import AbstractDeviceMetas -from test import base +from tangostationcontrol.test import base class TestAbstractDevice(base.TestCase): diff --git a/devices/test/devices/test_statistics_collector.py b/tangostationcontrol/tangostationcontrol/test/devices/test_statistics_collector.py similarity index 96% rename from devices/test/devices/test_statistics_collector.py rename to tangostationcontrol/tangostationcontrol/test/devices/test_statistics_collector.py index 5fe4e24dabbf169664b19250cba13f19b8020327..4b58141c06d9b09d68dba295b007b41081ca3618 100644 --- a/devices/test/devices/test_statistics_collector.py +++ b/tangostationcontrol/tangostationcontrol/test/devices/test_statistics_collector.py @@ -1,7 +1,7 @@ -from devices.sdp.statistics_collector import XSTCollector -from devices.sdp.statistics_packet import XSTPacket +from tangostationcontrol.devices.sdp.statistics_collector import XSTCollector +from tangostationcontrol.devices.sdp.statistics_packet import XSTPacket -from test import base +from tangostationcontrol.test import base class TestXSTCollector(base.TestCase): def test_valid_packet(self): diff --git a/devices/toolkit/README.md b/tangostationcontrol/tangostationcontrol/toolkit/README.md similarity index 100% rename from devices/toolkit/README.md rename to tangostationcontrol/tangostationcontrol/toolkit/README.md diff --git a/tangostationcontrol/tangostationcontrol/toolkit/__init__.py b/tangostationcontrol/tangostationcontrol/toolkit/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/devices/toolkit/archiver.py b/tangostationcontrol/tangostationcontrol/toolkit/archiver.py similarity index 99% rename from devices/toolkit/archiver.py rename to tangostationcontrol/tangostationcontrol/toolkit/archiver.py index 35012767add234b2b0421b359bfacf19ca6b9155..f4a0974f82a18b213746264be133911893ab54ee 100644 --- a/devices/toolkit/archiver.py +++ b/tangostationcontrol/tangostationcontrol/toolkit/archiver.py @@ -3,7 +3,9 @@ #from logging import raiseExceptions import logging import traceback -from clients.attribute_wrapper import attribute_wrapper + +from tangostationcontrol.clients.attribute_wrapper import attribute_wrapper + from tango import DeviceProxy, AttributeProxy from datetime import datetime, timedelta diff --git a/devices/toolkit/archiver_base.py b/tangostationcontrol/tangostationcontrol/toolkit/archiver_base.py similarity index 100% rename from devices/toolkit/archiver_base.py rename to tangostationcontrol/tangostationcontrol/toolkit/archiver_base.py diff --git a/devices/toolkit/archiver_config/lofar2.json b/tangostationcontrol/tangostationcontrol/toolkit/archiver_config/lofar2.json similarity index 100% rename from devices/toolkit/archiver_config/lofar2.json rename to tangostationcontrol/tangostationcontrol/toolkit/archiver_config/lofar2.json diff --git a/devices/toolkit/get_internal_attribute_history.py b/tangostationcontrol/tangostationcontrol/toolkit/get_internal_attribute_history.py similarity index 99% rename from devices/toolkit/get_internal_attribute_history.py rename to tangostationcontrol/tangostationcontrol/toolkit/get_internal_attribute_history.py index 735be01613611d73f39678f6b0ed5fb1f1c56a70..8b6b4254f6c10dc8207232b16fd5e22d44e7c556 100644 --- a/devices/toolkit/get_internal_attribute_history.py +++ b/tangostationcontrol/tangostationcontrol/toolkit/get_internal_attribute_history.py @@ -1,10 +1,8 @@ #! /usr/bin/env python3 - from tango import DeviceProxy from numpy import array, transpose - def get_internal_attribute_history(device: DeviceProxy, attribute_name: str, depth: int = 10): try: history = array(device.attribute_history(attr_name = attribute_name, depth = depth)) diff --git a/devices/toolkit/lofar2_config.py b/tangostationcontrol/tangostationcontrol/toolkit/lofar2_config.py similarity index 99% rename from devices/toolkit/lofar2_config.py rename to tangostationcontrol/tangostationcontrol/toolkit/lofar2_config.py index 581eea4f73a4d276613123ec9bf86bdb7e97a0ea..811f4f27abbbac832c6de6811a223a27229e9032 100644 --- a/devices/toolkit/lofar2_config.py +++ b/tangostationcontrol/tangostationcontrol/toolkit/lofar2_config.py @@ -2,7 +2,6 @@ import logging - def configure_logging(): # Always also log the hostname because it makes the origin of the log clear. import socket diff --git a/devices/toolkit/udp_simulator.py b/tangostationcontrol/tangostationcontrol/toolkit/udp_simulator.py similarity index 100% rename from devices/toolkit/udp_simulator.py rename to tangostationcontrol/tangostationcontrol/toolkit/udp_simulator.py diff --git a/devices/test-requirements.txt b/tangostationcontrol/test-requirements.txt similarity index 100% rename from devices/test-requirements.txt rename to tangostationcontrol/test-requirements.txt diff --git a/devices/tox.ini b/tangostationcontrol/tox.ini similarity index 95% rename from devices/tox.ini rename to tangostationcontrol/tox.ini index 59d2347f3ff42ccb084033aea67d478fd63513cb..69782d5e33c1ab14ce9abcd50253e0db9eabdf9a 100644 --- a/devices/tox.ini +++ b/tangostationcontrol/tox.ini @@ -22,7 +22,7 @@ commands = stestr run {posargs} ; Warning running integration tests will make changes to your docker system! ; These tests should only be run by the integration-test docker container. passenv = TANGO_HOST -setenv = TESTS_DIR=./integration_test +setenv = TESTS_DIR=./tangostationcontrol/integration_test commands = stestr run --serial {posargs}