diff --git a/Jenkinsfile b/Jenkinsfile index 2e4c232..e86918b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -53,7 +53,7 @@ pipeline { goto ERROR ) - C:/Instrument/Apps/Python/python.exe run_tests.py || echo "running tests failed." + C:/Instrument/Apps/Python3/python.exe run_tests.py || echo "running tests failed." """ } } diff --git a/block.py b/block.py index 3e087e7..5e4fdd9 100644 --- a/block.py +++ b/block.py @@ -17,10 +17,11 @@ Classes for Blocks """ +from builtins import object from block_utils import format_block_value -class Block: +class Block(object): """ Class holding Block details. Used for displaying in dataweb """ diff --git a/block_utils.py b/block_utils.py index c417906..e905ec7 100644 --- a/block_utils.py +++ b/block_utils.py @@ -86,7 +86,7 @@ def format_block_value(val, precision): assert small_number_threshold < big_number_threshold # No precision specified = do not format. - if precision is None or precision < 0: + if precision is None or not isinstance(precision, int) or precision < 0: return u"{}".format(val) try: float_val = float(val) diff --git a/external_webpage/data_source_reader.py b/external_webpage/data_source_reader.py index eeaee75..2a7daed 100644 --- a/external_webpage/data_source_reader.py +++ b/external_webpage/data_source_reader.py @@ -101,9 +101,9 @@ def read_config(self): """ # read config - page = requests.get('http://%s:%s/' % (self._host, PORT_CONFIG)) - corrected_page = page.content\ - .replace("'", '"')\ + page = requests.get('http://{}:{}/'.format(self._host, PORT_CONFIG)) + content = page.content.decode("utf-8") + corrected_page = content.replace("'", '"')\ .replace("None", "null")\ .replace("True", "true")\ .replace("False", "false") diff --git a/external_webpage/instrument_information_collator.py b/external_webpage/instrument_information_collator.py index 506606b..8bccb8a 100644 --- a/external_webpage/instrument_information_collator.py +++ b/external_webpage/instrument_information_collator.py @@ -17,6 +17,8 @@ Classes getting external resources from an instrument and formating them for the info page. """ +from builtins import str +from builtins import object import logging from block_utils import (format_blocks, set_rc_values_for_blocks) @@ -87,7 +89,7 @@ def block_is_visible(self, block_name): return True -class InstrumentInformationCollator: +class InstrumentInformationCollator(object): """ Collect instrument information and summarise as a dictionary. """ diff --git a/external_webpage/instrument_scapper.py b/external_webpage/instrument_scapper.py index 95605f3..958ea5f 100644 --- a/external_webpage/instrument_scapper.py +++ b/external_webpage/instrument_scapper.py @@ -1,3 +1,5 @@ +from builtins import str +from builtins import range import logging import traceback from threading import Thread, Event, RLock diff --git a/external_webpage/request_handler_utils.py b/external_webpage/request_handler_utils.py index 1a22058..6b7885f 100644 --- a/external_webpage/request_handler_utils.py +++ b/external_webpage/request_handler_utils.py @@ -1,3 +1,4 @@ +from builtins import str import re from collections import OrderedDict diff --git a/external_webpage/web_page_parser.py b/external_webpage/web_page_parser.py index 296662d..4b6949f 100644 --- a/external_webpage/web_page_parser.py +++ b/external_webpage/web_page_parser.py @@ -17,6 +17,8 @@ Classes for parsing web pages """ +from builtins import str +from builtins import object import logging import re @@ -90,9 +92,9 @@ def _create_block_from_channel(self, channel): if connected: units = current_value.get("Units", "") - precision = unicode(current_value.get("Precision", "")) + precision = str(current_value.get("Precision", "")) - value = unicode(current_value["Value"]) + value = str(current_value["Value"]) replaced = True while replaced: diff --git a/external_webpage/web_scrapper_manager.py b/external_webpage/web_scrapper_manager.py index 73c177c..91cff9c 100644 --- a/external_webpage/web_scrapper_manager.py +++ b/external_webpage/web_scrapper_manager.py @@ -1,6 +1,9 @@ """ Relation to web scrapper management. """ +from __future__ import print_function +from builtins import range +from builtins import object import json import logging import zlib @@ -190,7 +193,7 @@ def _is_scrapper_in_inst_list(self, inst_list, scrapper): Returns: True if in; False otherwise """ - for name, host in inst_list.items(): + for name, host in list(inst_list.items()): if scrapper.is_instrument(name, host): return True return False @@ -204,7 +207,7 @@ def _scrapper_to_start(self, instruments): Returns: """ - for name, host in instruments.items(): + for name, host in list(instruments.items()): for scrapper in self.scrappers: if scrapper.is_instrument(name, host): break diff --git a/run_tests.py b/run_tests.py index c7d9087..1f03ed4 100644 --- a/run_tests.py +++ b/run_tests.py @@ -1,3 +1,4 @@ +from __future__ import print_function # This file is part of the ISIS IBEX application. # Copyright (C) 2017 Science & Technology Facilities Council. # All rights reserved. @@ -37,10 +38,10 @@ test_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "tests")) test_suite = unittest.TestLoader().discover(test_dir, pattern="test_*.py") - print "\n\n------ BEGINNING JSON Bourne UNIT TESTS ------" + print("\n\n------ BEGINNING JSON Bourne UNIT TESTS ------") ret_vals = list() ret_vals.append(xmlrunner.XMLTestRunner(output=xml_dir).run(test_suite)) - print "------ UNIT TESTS COMPLETE ------\n\n" + print("------ UNIT TESTS COMPLETE ------\n\n") # Return failure exit code if a test failed sys.exit(False in ret_vals) diff --git a/tests/data_mother.py b/tests/data_mother.py index 99421ce..907bacd 100644 --- a/tests/data_mother.py +++ b/tests/data_mother.py @@ -1,3 +1,4 @@ +from builtins import object class ArchiveMother(object): """ Data mother for JSON objects. @@ -50,7 +51,7 @@ def create_channel(name=None, is_connected=True, value=u"0.000", alarm=u"", unit u'State': True} -class ConfigMother(): +class ConfigMother(object): @staticmethod def create_config(name="conf", blocks=None, groups=None): diff --git a/tests/test_block_utils.py b/tests/test_block_utils.py index b6636e9..d16bd0e 100644 --- a/tests/test_block_utils.py +++ b/tests/test_block_utils.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +from builtins import str import os import sys @@ -114,7 +115,7 @@ def test_format_blocks_with_empty_dict(self): formatted_blocks = format_blocks(test_blocks) #Assert - self.assertEquals(formatted_blocks, expected_result) + self.assertEqual(formatted_blocks, expected_result) def test_GIVEN_dict_of_ordered_blocks_WHEN_formatted_blocks_called_THEN_return_same_block_order(self): #Arrange @@ -130,7 +131,7 @@ def test_GIVEN_dict_of_ordered_blocks_WHEN_formatted_blocks_called_THEN_return_s formatted_blocks = format_blocks(test_blocks) #Assert - self.assertListEqual(expected_order_blocks.keys(), formatted_blocks.keys()) + self.assertSequenceEqual(expected_order_blocks.keys(), formatted_blocks.keys()) def test_shorten_title_for_default_case(self): @@ -141,7 +142,7 @@ def test_shorten_title_for_default_case(self): shortened_title = shorten_title(test_pv) #Assert - self.assertEquals(shortened_title, "COUNTRATE.VAL") + self.assertEqual(shortened_title, "COUNTRATE.VAL") def test_shorten_title_with_rc_in_range(self): #Arrange @@ -151,7 +152,7 @@ def test_shorten_title_with_rc_in_range(self): shortened_title = shorten_title(test_pv) #Assert - self.assertEquals(shortened_title, "NEW_BLOCK:RC:INRANGE.VAL") + self.assertEqual(shortened_title, "NEW_BLOCK:RC:INRANGE.VAL") def test_shorten_title_with_rc_enabled(self): # Arrange @@ -161,7 +162,7 @@ def test_shorten_title_with_rc_enabled(self): shortened_title = shorten_title(test_pv) # Assert - self.assertEquals(shortened_title, "NEW_BLOCK:RC:ENABLE.VAL") + self.assertEqual(shortened_title, "NEW_BLOCK:RC:ENABLE.VAL") def test_shorten_title_with_rc_in_range(self): # Arrange @@ -171,7 +172,7 @@ def test_shorten_title_with_rc_in_range(self): shortened_title = shorten_title(test_pv) # Assert - self.assertEquals(shortened_title, "OLD_BLOCK:RC:INRANGE.VAL") + self.assertEqual(shortened_title, "OLD_BLOCK:RC:INRANGE.VAL") def test_shorten_title_with_empty_string(self): # Arrange @@ -181,7 +182,7 @@ def test_shorten_title_with_empty_string(self): shortened_title = shorten_title(test_pv) # Assert - self.assertEquals(shortened_title, "") + self.assertEqual(shortened_title, "") def test_shorten_title_with_bad_rc_value(self): # Arrange @@ -191,7 +192,7 @@ def test_shorten_title_with_bad_rc_value(self): shortened_title = shorten_title(test_pv) # Assert - self.assertEquals(shortened_title, "OUTRANGE.VAL") + self.assertEqual(shortened_title, "OUTRANGE.VAL") def test_shorten_title_with_malformed_input_end_of_title(self): # Arrange @@ -201,7 +202,7 @@ def test_shorten_title_with_malformed_input_end_of_title(self): shortened_title = shorten_title(test_pv) # Assert - self.assertEquals(shortened_title, "INRANGE.VAL") + self.assertEqual(shortened_title, "INRANGE.VAL") def test_shorten_title_with_malformed_input_rc_value(self): # Arrange @@ -211,7 +212,7 @@ def test_shorten_title_with_malformed_input_rc_value(self): shortened_title = shorten_title(test_pv) # Assert - self.assertEquals(shortened_title, "RC:INRANGE.VAL") + self.assertEqual(shortened_title, "RC:INRANGE.VAL") def test_shorten_title_rc_in_pv_doesnt_count(self): # Arrange @@ -221,7 +222,7 @@ def test_shorten_title_rc_in_pv_doesnt_count(self): shortened_title = shorten_title(test_pv) # Assert - self.assertEquals(shortened_title, "RC.VAL") + self.assertEqual(shortened_title, "RC.VAL") def test_shorten_title_larmor_block_high_rc(self): # Arrange @@ -231,7 +232,7 @@ def test_shorten_title_larmor_block_high_rc(self): shortened_title = shorten_title(test_pv) # Assert - self.assertEquals(shortened_title, "CJHCent:RC:HIGH.VAL") + self.assertEqual(shortened_title, "CJHCent:RC:HIGH.VAL") def test_shorten_title_larmor_block_low_rc(self): # Arrange @@ -241,7 +242,7 @@ def test_shorten_title_larmor_block_low_rc(self): shortened_title = shorten_title(test_pv) # Assert - self.assertEquals(shortened_title, "Chi:RC:LOW.VAL") + self.assertEqual(shortened_title, "Chi:RC:LOW.VAL") def test_when_rc_values_given_block_description_contains_rc_values(self): # Arrange @@ -254,12 +255,12 @@ def test_when_rc_values_given_block_description_contains_rc_values(self): description = test_block.get_description() # Assert - self.assertEquals(description["visibility"], "OFF") - self.assertEquals(description["status"], "INVALID") - self.assertEquals(description["alarm"], "UDF_ALARM") - self.assertEquals(description["rc_low"], 0) - self.assertEquals(description["rc_high"], 100) - self.assertEquals(description["rc_inrange"], False) + self.assertEqual(description["visibility"], "OFF") + self.assertEqual(description["status"], "INVALID") + self.assertEqual(description["alarm"], "UDF_ALARM") + self.assertEqual(description["rc_low"], 0) + self.assertEqual(description["rc_high"], 100) + self.assertEqual(description["rc_inrange"], False) def test_when_rc_values_not_given_block_description_do_not_contain_rc_values(self): # Arrange @@ -269,9 +270,9 @@ def test_when_rc_values_not_given_block_description_do_not_contain_rc_values(sel description = test_block.get_description() # Assert - self.assertEquals(description["visibility"], "OFF") - self.assertEquals(description["status"], "INVALID") - self.assertEquals(description["alarm"], "UDF_ALARM") + self.assertEqual(description["visibility"], "OFF") + self.assertEqual(description["status"], "INVALID") + self.assertEqual(description["alarm"], "UDF_ALARM") self.assertTrue("rc_low" not in description) self.assertTrue("rc_high" not in description) self.assertTrue("rc_inrange" not in description) @@ -290,7 +291,7 @@ def test_set_rc_low_value_for_block_based_on_pv(self): set_rc_values_for_blocks(blocks, runcontrol) # Assert - self.assertEquals(blocks[block_name].get_rc_low(), expected_value) + self.assertEqual(blocks[block_name].get_rc_low(), expected_value) def test_set_rc_high_value_for_block_based_on_pv(self): # Arrange @@ -306,8 +307,8 @@ def test_set_rc_high_value_for_block_based_on_pv(self): set_rc_values_for_blocks(blocks, runcontrol) # Assert - self.assertEquals(blocks[block_name].get_rc_low(), 10) - self.assertEquals(blocks[block_name].get_rc_high(), 100) + self.assertEqual(blocks[block_name].get_rc_low(), 10) + self.assertEqual(blocks[block_name].get_rc_high(), 100) def test_set_rc_inrange_value_for_block_based_on_pv(self): # Arrange @@ -324,9 +325,9 @@ def test_set_rc_inrange_value_for_block_based_on_pv(self): set_rc_values_for_blocks(blocks, runcontrol) # Assert - self.assertEquals(blocks[block_name].get_rc_low(), 10) - self.assertEquals(blocks[block_name].get_rc_high(), 100) - self.assertEquals(blocks[block_name].get_rc_inrange(), False) + self.assertEqual(blocks[block_name].get_rc_low(), 10) + self.assertEqual(blocks[block_name].get_rc_high(), 100) + self.assertEqual(blocks[block_name].get_rc_inrange(), False) def test_set_rc_not_low_value_for_block_based_on_pv(self): # Arrange @@ -341,7 +342,7 @@ def test_set_rc_not_low_value_for_block_based_on_pv(self): set_rc_values_for_blocks(blocks, runcontrol) # Assert - self.assertEquals(blocks[block_name].get_rc_low(), None) + self.assertEqual(blocks[block_name].get_rc_low(), None) def test_set_rc_values_for_two_blocks_based_on_pv(self): # Arrange @@ -358,8 +359,8 @@ def test_set_rc_values_for_two_blocks_based_on_pv(self): set_rc_values_for_blocks(blocks, runcontrol) # Assert - self.assertEquals(blocks[new_block_name].get_rc_low(), 10) - self.assertEquals(blocks[not_new_block_name].get_rc_low(), 100) + self.assertEqual(blocks[new_block_name].get_rc_low(), 10) + self.assertEqual(blocks[not_new_block_name].get_rc_low(), 100) def test_set_rc_values_for_one_blocks_based_on_pv_leaves_other_unchanged(self): # Arrange @@ -375,8 +376,8 @@ def test_set_rc_values_for_one_blocks_based_on_pv_leaves_other_unchanged(self): set_rc_values_for_blocks(blocks, runcontrol) # Assert - self.assertEquals(blocks[new_block_name].get_rc_low(), 10) - self.assertEquals(blocks[not_new_block_name].get_rc_low(), None) + self.assertEqual(blocks[new_block_name].get_rc_low(), 10) + self.assertEqual(blocks[not_new_block_name].get_rc_low(), None) def test_set_rc_values_for_leaves_both_unchanged(self): # Arrange @@ -392,14 +393,14 @@ def test_set_rc_values_for_leaves_both_unchanged(self): set_rc_values_for_blocks(blocks, {}) # Assert - self.assertEquals(blocks[block1_name].get_rc_low(), None) - self.assertEquals(blocks[block2_name].get_rc_low(), None) + self.assertEqual(blocks[block1_name].get_rc_low(), None) + self.assertEqual(blocks[block2_name].get_rc_low(), None) def test_set_rc_values_with_empty_block_list(self): # Act try: set_rc_values_for_blocks({}, {}) - except Exception, e: + except Exception as e: self.fail("set_rc_values_for_blocks should handle empty block list") def _assert_blocks(self, actual_blocks, expected_blocks): @@ -540,6 +541,5 @@ def test_GIVEN_nonsense_precision_containing_unicode_WHEN_formatting_THEN_origin self.assertEqual(format_block_value(value, precision), value) - if __name__ == '__main__': unittest.main() diff --git a/tests/test_blocks.py b/tests/test_blocks.py index cb9677a..02eeb70 100644 --- a/tests/test_blocks.py +++ b/tests/test_blocks.py @@ -5,6 +5,7 @@ import unittest from block import Block + class TestBlock(unittest.TestCase): def test_can_set_rc_low_on_a_block(self): @@ -15,7 +16,7 @@ def test_can_set_rc_low_on_a_block(self): test_block.set_rc_low(10) # Assert - self.assertEquals(test_block.get_rc_low(), 10) + self.assertEqual(test_block.get_rc_low(), 10) def test_can_set_rc_high_on_a_block(self): # Arrange @@ -25,7 +26,7 @@ def test_can_set_rc_high_on_a_block(self): test_block.set_rc_high(100) # Assert - self.assertEquals(test_block.get_rc_high(), 100) + self.assertEqual(test_block.get_rc_high(), 100) def test_can_set_rc_inrange_on_a_block(self): # Arrange @@ -35,7 +36,7 @@ def test_can_set_rc_inrange_on_a_block(self): test_block.set_rc_inrange(False) # Assert - self.assertEquals(test_block.get_rc_inrange(), False) + self.assertEqual(test_block.get_rc_inrange(), False) def test_can_set_rc_enabled_on_a_block(self): @@ -46,7 +47,8 @@ def test_can_set_rc_enabled_on_a_block(self): test_block.set_rc_enabled("YES") # Assert - self.assertEquals(test_block.get_rc_enabled(), "YES") + self.assertEqual(test_block.get_rc_enabled(), "YES") + if __name__ == '__main__': unittest.main() diff --git a/tests/test_data_source_reader.py b/tests/test_data_source_reader.py new file mode 100644 index 0000000..9b2ea37 --- /dev/null +++ b/tests/test_data_source_reader.py @@ -0,0 +1,47 @@ +import unittest +from mock import MagicMock, patch +from external_webpage.data_source_reader import DataSourceReader +from hamcrest import * + + +def patch_page_contents(request_response, json): + page = MagicMock() + page.content = json + request_response.return_value = page + + +class TestDataSourceReader(unittest.TestCase): + def setUp(self): + self.reader = DataSourceReader("HOST") + + @patch("requests.get") + def test_GIVEN_JSON_with_single_quotes_WHEN_read_THEN_conversion_successful(self, request_response): + patch_page_contents(request_response, b"{'data': 'some_data'}") + + json_object = self.reader.read_config() + + assert_that(json_object, is_({"data": "some_data"})) + + @patch("requests.get") + def test_GIVEN_JSON_with_None_WHEN_read_THEN_conversion_successful(self, request_response): + patch_page_contents(request_response, b'{"data": None}') + + json_object = self.reader.read_config() + + assert_that(json_object, is_({"data": None})) + + @patch("requests.get") + def test_GIVEN_JSON_with_True_WHEN_read_THEN_conversion_successful(self, request_response): + patch_page_contents(request_response, b'{"data": True}') + + json_object = self.reader.read_config() + + assert_that(json_object, is_({"data": True})) + + @patch("requests.get") + def test_GIVEN_JSON_with_False_WHEN_read_THEN_conversion_successful(self, request_response): + patch_page_contents(request_response, b'{"data": False}') + + json_object = self.reader.read_config() + + assert_that(json_object, is_({"data": False})) diff --git a/tests/test_get_blocks_from_json.py b/tests/test_get_blocks_from_json.py index e7bdefe..20303a0 100644 --- a/tests/test_get_blocks_from_json.py +++ b/tests/test_get_blocks_from_json.py @@ -1,3 +1,4 @@ +from builtins import zip import os import sys import unittest diff --git a/tests/test_get_info_from_config_and_web.py b/tests/test_get_info_from_config_and_web.py index 7105278..8966288 100644 --- a/tests/test_get_info_from_config_and_web.py +++ b/tests/test_get_info_from_config_and_web.py @@ -180,5 +180,6 @@ def test_GIVEN_hidden_block_WHEN_parse_THEN_block_is_marked_as_visible(self): assert_that(result["groups"][group_name][block_name]["visibility"], is_(expected_is_visible)) + if __name__ == '__main__': unittest.main() diff --git a/tests/test_handler_utils.py b/tests/test_handler_utils.py index fe2e434..8114223 100644 --- a/tests/test_handler_utils.py +++ b/tests/test_handler_utils.py @@ -134,7 +134,7 @@ def test_GIVEN_dict_with_multiple_instruments_WHEN_get_summary_details_THEN_inst expected_instrument_names = ["anInst", "Another", "B", "CAPITAL", "clower"] inp = {"B": "", "Another": "", "CAPITAL": "", "clower": "", "anInst": ""} - result = get_summary_details_of_all_instruments(inp).keys() + result = list(get_summary_details_of_all_instruments(inp).keys()) assert_that(result, is_(expected_instrument_names)) diff --git a/tests/test_inst_list.py b/tests/test_inst_list.py index 0f9fd19..521ec38 100644 --- a/tests/test_inst_list.py +++ b/tests/test_inst_list.py @@ -7,7 +7,8 @@ from CaChannel import CaChannelException from hamcrest import * import unittest - +from builtins import bytes +import binascii from mock import Mock sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) @@ -39,8 +40,8 @@ def compress_and_hex(self, value): Returns: string : A compressed and hexed version of the inputted string """ - compr = zlib.compress(value) - return compr.encode('hex') + compr = zlib.compress(bytes(value, 'utf-8')) + return binascii.hexlify(bytearray(compr)) def test_GIVEN_caget_contains_one_instrument_WHEN_retrive_THEN_list_returned(self): global caget_value, caget_error diff --git a/tests/test_instrument_information_collator.py b/tests/test_instrument_information_collator.py index 82c1f8f..cfa98f3 100644 --- a/tests/test_instrument_information_collator.py +++ b/tests/test_instrument_information_collator.py @@ -67,7 +67,7 @@ def test_GIVEN_ordered_groups_WHEN_create_groups_dictionary_called_THEN_return_s {'name': 'test_group_3', 'blocks': []}] result = create_groups_dictionary({}, instrument_config) - self.assertListEqual(result.keys(), [group['name'] for group in instrument_config.groups]) + self.assertListEqual(list(result.keys()), [group['name'] for group in instrument_config.groups]) if __name__ == '__main__': diff --git a/tests/test_web_scrapper_manager.py b/tests/test_web_scrapper_manager.py index eae5633..330ceb1 100644 --- a/tests/test_web_scrapper_manager.py +++ b/tests/test_web_scrapper_manager.py @@ -1,3 +1,4 @@ +from builtins import object import os import sys from hamcrest import * diff --git a/webserver.py b/webserver.py index c714c65..abc447a 100644 --- a/webserver.py +++ b/webserver.py @@ -1,8 +1,12 @@ +from __future__ import print_function +from future import standard_library +standard_library.install_aliases() +from builtins import str import json import logging import os -from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer -from SocketServer import ThreadingMixIn +from http.server import BaseHTTPRequestHandler, HTTPServer +from socketserver import ThreadingMixIn from logging.handlers import TimedRotatingFileHandler from external_webpage.request_handler_utils import get_detailed_state_of_specific_instrument, \ @@ -34,7 +38,7 @@ def do_GET(self): instrument, callback = get_instrument_and_callback(self.path) # Warn level so as to avoid many log messages that come from other modules - logger.warn("Connected to from " + str(self.client_address) + " looking at " + str(instrument)) + logger.warning("Connected to from " + str(self.client_address) + " looking at " + str(instrument)) with scraped_data_lock: if instrument == "ALL": @@ -55,7 +59,7 @@ def do_GET(self): self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() - self.wfile.write(response) + self.wfile.write(response.encode("utf-8")) except ValueError as e: logger.error(e) self.send_response(400)