Example #1
0
    def test_app_without_pool(self):

        data = {
            "pools": [{
                "apps": [1],
                "cbm": 0xf0,
                "cores": [1],
                "id": 1,
                "name": "pool 1"
            }, {
                "cbm": 0xf0,
                "cores": [2],
                "id": 2,
                "name": "pool 2"
            }],
            "apps": [{
                "cores": [1],
                "id": 1,
                "name": "app 1",
                "pids": [1]
            }, {
                "cores": [1],
                "id": 2,
                "name": "app 2",
                "pids": [2]
            }]
        }

        with pytest.raises(ValueError, match="not assigned to any pool"):
            ConfigStore.validate(data)
Example #2
0
    def test_app_invalid_core(self):
        def check_core(core):
            return core != 3

        data = {
            "auth": {
                "password": "******",
                "username": "******"
            },
            "pools": [{
                "apps": [1],
                "cbm": 0xf0,
                "cores": [1],
                "id": 1,
                "name": "pool 1"
            }],
            "apps": [{
                "cores": [3],
                "id": 1,
                "name": "app 1",
                "pids": [1]
            }]
        }

        with mock.patch('common.PQOS_API.check_core', new=check_core):
            with pytest.raises(ValueError, match="Invalid core 3"):
                ConfigStore.validate(data)
Example #3
0
    def test_app_core_does_not_match_pool(self):
        data = {
            "auth": {
                "password": "******",
                "username": "******"
            },
            "pools": [{
                "apps": [1],
                "cbm": 0xf0,
                "cores": [1],
                "id": 1,
                "name": "pool 1"
            }],
            "apps": [{
                "cores": [3, 4, 5],
                "id": 1,
                "name": "app 1",
                "pids": [1]
            }]
        }

        with pytest.raises(
                ValueError,
                match="App 1, cores {3, 4, 5} does not match Pool 1"):
            ConfigStore.validate(data)
Example #4
0
    def test_pool_mba_mba_bw_enabled(self):
        data = {
            "rdt_iface": {
                "interface": "os"
            },
            "mba_ctrl": {
                "enabled": True
            },
            "pools": [{
                "cbm": 0xf,
                "mba": 50,
                "cores": [1, 3],
                "id": 1,
                "name": "pool 1"
            }, {
                "cbm": 0xf,
                "mba": 70,
                "cores": [2],
                "id": 2,
                "name": "pool 2"
            }]
        }

        with pytest.raises(
                ValueError,
                match="MBA % is not enabled. Disable MBA BW and try again"):
            ConfigStore.validate(data)
Example #5
0
    def test_app_same_ids(self):
        data = {
            "auth": {
                "password": "******",
                "username": "******"
            },
            "pools": [
                {
                    "apps": [1],
                    "cbm": 0xf0,
                    "cores": [1],
                    "id": 1,
                    "name": "pool 1"
                },
            ],
            "apps": [{
                "cores": [1],
                "id": 1,
                "name": "app 1",
                "pids": [1]
            }, {
                "cores": [1],
                "id": 1,
                "name": "app 2",
                "pids": [1]
            }]
        }

        with pytest.raises(ValueError,
                           match="App 1, multiple apps with same id"):
            ConfigStore.validate(data)
Example #6
0
    def test_app_without_pool(self):
        data = {
            "auth": {
                "password": "******",
                "username": "******"
            },
            "pools": [{
                "apps": [1],
                "cbm": 0xf0,
                "cores": [1],
                "id": 1,
                "name": "pool 1"
            }, {
                "apps": [1, 2],
                "cbm": 0xf0,
                "cores": [2],
                "id": 2,
                "name": "pool 2"
            }],
            "apps": [{
                "cores": [1],
                "id": 1,
                "name": "app 1",
                "pids": [1]
            }, {
                "cores": [2],
                "id": 2,
                "name": "app 2",
                "pids": [2]
            }]
        }

        with pytest.raises(ValueError,
                           match="App 1, Assigned to more than one pool"):
            ConfigStore.validate(data)
Example #7
0
    def test_app_invalid_pid(self):
        data = {
            "auth": {
                "password": "******",
                "username": "******"
            },
            "pools": [
                {
                    "apps": [1, 2],
                    "cbm": 0xf0,
                    "cores": [1],
                    "id": 1,
                    "name": "pool 1"
                },
            ],
            "apps": [{
                "cores": [1],
                "id": 1,
                "name": "app 1",
                "pids": [1]
            }, {
                "cores": [1],
                "id": 2,
                "name": "app 2",
                "pids": [99999]
            }]
        }

        with pytest.raises(ValueError, match="App 2, PID 99999 is not valid"):
            ConfigStore.validate(data)
Example #8
0
    def test_app_same_pid(self):
        data = {
            "auth": {
                "password": "******",
                "username": "******"
            },
            "pools": [
                {
                    "apps": [1, 2],
                    "cbm": 0xf0,
                    "cores": [1],
                    "id": 1,
                    "name": "pool 1"
                },
            ],
            "apps": [{
                "cores": [1],
                "id": 1,
                "name": "app 1",
                "pids": [1]
            }, {
                "cores": [1],
                "id": 2,
                "name": "app 2",
                "pids": [1]
            }]
        }

        with pytest.raises(
                ValueError,
                match=r"App 2, PIDs \{1} already assigned to another App."):
            ConfigStore.validate(data)
 def run(self):
     while True:
         vehicle = API_Engine().get_vehicle()
         vehicle["vid"] = ConfigStore().get_vid()
         vehicle["did"] = ConfigStore().get_did()
         ConfigStore().set_vehicle(vehicle)
         time.sleep(60)
def main():
    app = FleetMonitorApp()
    parser = argparse.ArgumentParser()
    parser.add_argument("-s", "--serverUri", dest="serverUri", type=str, help="the server URI to send requests to")
    parser.add_argument("-d", "--driverID", dest="driverID", default=0, type=int, help="the ID of the driver using the vehicle")
    parser.add_argument("-v", "--vehicleID", dest="vehicleID", default=0, type=int, help="the ID of this vehicle")
    parser.add_argument("-l", "--log", help="output API calls", action="store_true")
    args = parser.parse_args()
    if args.serverUri:
        server = {"uri": args.serverUri}
        API_Engine().set_send(True)
        ConfigStore().set_server(server)
    else:
        API_Engine().set_send(False)
        API_Engine().set_logging(True)
    if args.log:
        API_Engine().set_logging(True)
    API_Engine().start()
    if args.vehicleID and args.driverID:
        vehicle = {"vid": args.vehicleID}
        vehicle["did"] = args.driverID
        vehicle["pids"] = []
        ConfigStore().set_vehicle(vehicle)
    if app.startup():
        app.start()
        time.sleep(5)
        print("Starting hardware")
        app.run_hardware()
Example #11
0
    def test_rdt_iface_invalid(self):
        data = {
            "auth": {
                "password": "******",
                "username": "******"
            },
            "pools": [],
            "apps": [],
            "rdt_iface": "os"
        }

        with pytest.raises(jsonschema.exceptions.ValidationError,
                           match="'os' is not of type 'object'"):
            ConfigStore.validate(data)

        data['rdt_iface'] = {}
        with pytest.raises(jsonschema.exceptions.ValidationError,
                           match="'interface' is a required property"):
            ConfigStore.validate(data)

        data['rdt_iface']['interface'] = None
        with pytest.raises(jsonschema.exceptions.ValidationError,
                           match="None is not of type 'string'"):
            ConfigStore.validate(data)

        data['rdt_iface']['interface'] = 2
        with pytest.raises(jsonschema.exceptions.ValidationError,
                           match="2 is not of type 'string'"):
            ConfigStore.validate(data)

        data['rdt_iface']['interface'] = "test_string"
        with pytest.raises(
                jsonschema.exceptions.ValidationError,
                match="'test_string' is not one of \\['msr', 'os'\\]"):
            ConfigStore.validate(data)
Example #12
0
def test_get_global_attr_power_profiles_verify(mock_get_config, cfg, default,
                                               result):
    mock_get_config.return_value = cfg
    config_store = ConfigStore()

    assert config_store.get_global_attr('power_profiles_verify',
                                        default) == result
Example #13
0
    def __init__(self, hatari):
        userconfdir = ".hatari"
        ConfigStore.__init__(self, userconfdir)
        conffilename = "hatari.cfg"
        self.load(self.get_filepath(conffilename))

        self._hatari = hatari
        self._lock_updates = False
        self._options = []
Example #14
0
    def __init__(self, previous):
        userconfdir = ".previous"
        ConfigStore.__init__(self, userconfdir)
        conffilename = "previous.cfg"
        self.load(self.get_filepath(conffilename))

        self._previous = previous
        self._lock_updates = False
        self._options = []
Example #15
0
    def __init__(self, hatari):
        userconfdir = ".hatari"
        ConfigStore.__init__(self, userconfdir)
        conffilename = "hatari.cfg"
        self.load(self.get_filepath(conffilename))

        self._hatari = hatari
        self._lock_updates = False
        self._options = []
Example #16
0
def test_config_remove_default_pool():
    config = deepcopy(CONFIG_POOLS)

    # default pool in config
    assert ConfigStore.is_default_pool_defined(config) == True

    # FUT
    ConfigStore.remove_default_pool(config)

    # no default pool in config
    assert not ConfigStore.is_default_pool_defined(config)
Example #17
0
    def test_pool_mba_not_supported(self):
        data = {
            "pools": [{
                "mba": 50,
                "cores": [1, 3],
                "id": 1,
                "name": "pool 1"
            }]
        }

        with pytest.raises(ValueError, match="MBA is not supported"):
            ConfigStore.validate(data)
Example #18
0
    def test_pool_cat_not_supported(self):
        data = {
            "pools": [{
                "apps": [],
                "cbm": 0x4,
                "cores": [1, 3],
                "id": 1,
                "name": "pool 1"
            }]
        }

        with pytest.raises(ValueError, match="CAT is not supported"):
            ConfigStore.validate(data)
Example #19
0
    def test_pool_mba_bw_not_supported_cat(self):
        data = {
            "pools": [{
                "cbm": 0xf,
                "mba_bw": 5000,
                "cores": [1, 3],
                "id": 1,
                "name": "pool 1"
            }]
        }

        with pytest.raises(ValueError,
                           match="MBA BW is not enabled/supported"):
            ConfigStore.validate(data)
Example #20
0
def test_config_is_default_pool_defined():
    config = deepcopy(CONFIG_POOLS)

    # FUT, default pool in config
    assert ConfigStore.is_default_pool_defined(config) == True

    # remove default pool from config
    for pool in config['pools'][:]:
        if pool['id'] == 0:
            config['pools'].remove(pool)
            break

    # FUT, no default pool in config
    assert not ConfigStore.is_default_pool_defined(config)
Example #21
0
def test_config_recreate_default_pool(def_pool_def):
    config_store = ConfigStore()

    with mock.patch('config.ConfigStore.is_default_pool_defined', mock.MagicMock(return_value=def_pool_def)) as mock_is_def_pool_def,\
         mock.patch('config.ConfigStore.remove_default_pool') as mock_rm_def_pool,\
         mock.patch('config.ConfigStore.add_default_pool') as mock_add_def_pool:

        config_store.recreate_default_pool()

        if def_pool_def:
            mock_rm_def_pool.assert_called_once()
        else:
            mock_rm_def_pool.assert_not_called()

        mock_add_def_pool.assert_called_once()
Example #22
0
    def __init__(self):

    def startup(self):
        result = True
		
        vehicle = API_Engine().get_vehicle()
		vehicle["did"] = ConfigStore().get_did()
        ConfigStore().set_vehicle(vehicle)

        # Check for PiCAN connection
        try:
            self.can = can_interface.CanHandler()
            if not self.can.startup():
                return False
        except:
            return False

        # Check for GPS connection
        try:
            self.gps = gps_interface.GPSHandler()
            if not self.gps.setup():
                return False
        except:
            return False
            
        API_Engine().start()
Example #23
0
    def put():
        """
        Handles PUT /caps/rdt_iface request.
        Raises BadRequest, InternalError

        Returns:
            response, status code
        """
        json_data = request.get_json()

        # validate request
        try:
            schema, resolver = ConfigStore.load_json_schema('modify_rdt_iface.json')
            jsonschema.validate(json_data, schema, resolver=resolver)
        except (jsonschema.ValidationError, OverflowError) as error:
            raise BadRequest("Request validation failed - %s" % (str(error)))

        if not json_data['interface'] in common.PQOS_API.supported_iface():
            raise BadRequest("RDT interface '%s' not supported!" % (json_data['interface']))

        if common.CONFIG_STORE.is_any_pool_defined():
            return {'message': "Please remove all Pools first!"}, 409

        data = deepcopy(common.CONFIG_STORE.get_config())

        if 'rdt_iface' not in data:
            data['rdt_iface'] = {}

        data['rdt_iface']['interface'] = json_data['interface']
        CapsMbaCtrl.set_mba_ctrl_enabled(data, False)

        common.CONFIG_STORE.set_config(data)

        res = {'message': "RDT Interface modified"}
        return res, 200
Example #24
0
    def make_refresh(self,
                     tp,
                     set_timestamp=False,
                     save=True,
                     send_notify=True):
        club_level = get_club_property(self.server_id, self.char_id, 'level')
        goods = ConfigStore.refresh(tp, club_level)

        try:
            tp_doc = self.doc['tp'][str(tp)]
        except KeyError:
            tp_doc = MongoStore.document_tp()

        if set_timestamp:
            tp_doc['refresh_at'] = arrow.utcnow().timestamp

        tp_doc['goods'] = {
            str(_id): {
                'index': _index,
                'times': 0
            }
            for _id, _index in goods
        }
        self.doc['tp'][str(tp)] = tp_doc

        if save:
            MongoStore.db(self.server_id).update_one(
                {'_id': self.char_id}, {'$set': {
                    'tp.{0}'.format(tp): tp_doc
                }})

        if send_notify:
            self.send_notify(tp=tp)
Example #25
0
    def send_notify(self, tp=None):
        if tp:
            act = ACT_UPDATE
            tps = [tp]
        else:
            act = ACT_INIT
            tps = ConfigStoreType.INSTANCES.keys()

        notify = StoreNotify()
        notify.act = act
        for _t in tps:
            ri = RefreshInfo(self.server_id, self.char_id, _t)

            notify_type = notify.store_types.add()
            notify_type.tp = _t
            notify_type.auto_refresh_at = self.next_auto_refresh_timestamp(_t)
            notify_type.remained_refresh_times = ri.remained_refresh_times
            notify_type.refresh_cost = ri.refresh_cost

            for _g in self.doc['tp'][str(_t)]['goods'].keys():
                _g_data = self.doc['tp'][str(_t)]['goods'][str(_g)]
                notify_type_goods = notify_type.goods.add()
                notify_type_goods.id = int(_g)
                notify_type_goods.content_index = _g_data['index']
                notify_type_goods.remained_times = ConfigStore.get(
                    int(_g)).times_limit - _g_data['times']

        MessagePipe(self.char_id).put(msg=notify)
Example #26
0
    def send_notify(self, tp=None):
        if tp:
            act = ACT_UPDATE
            tps = [tp]
        else:
            act = ACT_INIT
            tps = ConfigStoreType.INSTANCES.keys()

        notify = StoreNotify()
        notify.act = act
        for _t in tps:
            ri = RefreshInfo(self.server_id, self.char_id, _t)

            notify_type = notify.store_types.add()
            notify_type.tp = _t
            notify_type.auto_refresh_at = self.next_auto_refresh_timestamp(_t)
            notify_type.remained_refresh_times = ri.remained_refresh_times
            notify_type.refresh_cost = ri.refresh_cost

            for _g in self.doc['tp'][str(_t)]['goods'].keys():
                _g_data = self.doc['tp'][str(_t)]['goods'][str(_g)]
                notify_type_goods = notify_type.goods.add()
                notify_type_goods.id = int(_g)
                notify_type_goods.content_index = _g_data['index']
                notify_type_goods.remained_times = ConfigStore.get(int(_g)).times_limit - _g_data['times']

        MessagePipe(self.char_id).put(msg=notify)
Example #27
0
    def put():
        """
        Handles HTTP PUT /caps/sstbf request.
        Raises BadRequest, InternalError

        Returns:
            response, status code
        """
        json_data = request.get_json()

        # validate app schema
        try:
            schema, resolver = ConfigStore.load_json_schema('modify_sstbf.json')
            jsonschema.validate(json_data, schema, resolver=resolver)
        except (jsonschema.ValidationError, OverflowError) as error:
            raise BadRequest("Request validation failed - %s" % (str(error)))

        if not sstbf.configure_sstbf(json_data['configured']) == 0:
            raise InternalError("Failed to change SST-BF configured state.")

        # update power profile configuration
        power.configure_power()

        res = {'message': "SST-BF caps modified"}
        return res, 200
    def startup(self):
        result = True
		
        vehicle = API_Engine().get_vehicle()
        vehicle["did"] = ConfigStore().get_did()
        ConfigStore().set_vehicle(vehicle)

        # Check for PiCAN connection
        self.can = can_interface.CANHandler()
        self.can.startup()

        # Check for GPS connection
        self.gps = gps_interface.GPSHandler()
        self.gps.startup() 

        return True 
Example #29
0
    def __init__(self, hatari):
        confdirs = [".config/hatari", ".hatari"]
        ConfigStore.__init__(self, confdirs)
        conffilename = "hatari.cfg"
        self.load(self.get_filepath(conffilename))

        self._hatari = hatari
        self._lock_updates = False
        self._desktop_w = 0
        self._desktop_h = 0
        self._options = []
        self._winuae = hatari.is_winuae()
        # initialize has_* attribs for things that may not be anymore
        # valid on Hatari config file and/or command line
        self.get_machine()
        self.get_desktop_st()
Example #30
0
    def put():
        """
        Handles PUT /caps/mba_ctrl request.
        Raises BadRequest, InternalError

        Returns:
            response, status code
        """
        json_data = request.get_json()

        # validate request
        try:
            schema, resolver = ConfigStore.load_json_schema(
                'modify_mba_ctrl.json')
            jsonschema.validate(json_data, schema, resolver=resolver)
        except jsonschema.ValidationError as error:
            raise BadRequest("Request validation failed - %s" % (str(error)))

        if not caps.mba_bw_supported():
            return {'message': "MBA CTRL not supported!"}, 409

        if common.CONFIG_STORE.is_any_pool_defined():
            return {'message': "Please remove all Pools first!"}, 409

        data = deepcopy(common.CONFIG_STORE.get_config())

        CapsMbaCtrl.set_mba_ctrl_enabled(data, json_data['enabled'])

        common.CONFIG_STORE.set_config(data)

        return {'message': "MBA CTRL status changed."}, 200
Example #31
0
    def make_refresh(self, tp, set_timestamp=False, save=True, send_notify=True):
        club_level = get_club_property(self.server_id, self.char_id, 'level')
        goods = ConfigStore.refresh(tp, club_level)

        try:
            tp_doc = self.doc['tp'][str(tp)]
        except KeyError:
            tp_doc = MongoStore.document_tp()

        if set_timestamp:
            tp_doc['refresh_at'] = arrow.utcnow().timestamp

        tp_doc['goods'] = {str(_id): {'index': _index, 'times': 0} for _id, _index in goods}
        self.doc['tp'][str(tp)] = tp_doc

        if save:
            MongoStore.db(self.server_id).update_one(
                {'_id': self.char_id},
                {'$set': {
                    'tp.{0}'.format(tp): tp_doc
                }}
            )

        if send_notify:
            self.send_notify(tp=tp)
Example #32
0
 def __init__(self, hatari):
     confdirs = [".config/hatari", ".hatari"]
     ConfigStore.__init__(self, confdirs)
     conffilename = "hatari.cfg"
     confpath = self.get_filepath(conffilename)
     print("confpath: %s" % confpath)
     error = self.load(confpath)
     if error:
         print("WARNING: %s %s!" % (confpath, error))
     else:
         print("loaded config: %s" % confpath)
     self._hatari = hatari
     self._lock_updates = False
     self._desktop_w = 0
     self._desktop_h = 0
     self._options = []
     self._winuae = hatari.is_winuae()
    def write_requests(self):
        while True:
            for pid in ConfigStore().get_pids():
                message = get_request_message(pid)
                self.bus.send(message)
                time.sleep(0.05)

            time.sleep(2)
Example #34
0
    def test_pool_mba_not_supported_cat(self):
        data = {
            "auth": {
                "password": "******",
                "username": "******"
            },
            "pools": [{
                "cbm": 0xf,
                "mba": 50,
                "cores": [1, 3],
                "id": 1,
                "name": "pool 1"
            }]
        }

        with pytest.raises(ValueError, match="MBA is not supported"):
            ConfigStore.validate(data)
Example #35
0
    def buy(self, tp, goods_id):
        if tp not in ALL_TYPES:
            raise GameException(ConfigErrorMessage.get_error_id("INVALID_OPERATE"))

        config = ConfigStore.get(goods_id)
        if not config:
            raise GameException(ConfigErrorMessage.get_error_id("STORE_GOODS_NOT_EXIST"))

        try:
            data = self.doc['tp'][str(tp)]['goods'][str(goods_id)]
        except KeyError:
            raise GameException(ConfigErrorMessage.get_error_id("INVALID_OPERATE"))

        if data['times'] >= config.times_limit:
            raise GameException(ConfigErrorMessage.get_error_id("STORE_GOODS_NO_TIMES"))

        if config.condition_id == 1:
            # VIP 等级
            VIP(self.server_id, self.char_id).check(config.condition_value)
        elif config.condition_id == 2:
            # 爬塔历史最高星
            Tower(self.server_id, self.char_id).check_history_max_star(config.condition_value)
        elif config.condition_id == 3:
            # 竞技场当前排名
            Arena(self.server_id, self.char_id).check_current_rank(config.condition_value)
        elif config.condition_id == 4:
            # 当前公会等级
            Union(self.server_id, self.char_id).check_level(config.condition_value)

        item_id, item_amount, need_id, need_amount = config.content[data['index']]
        resource_classify = ResourceClassification.classify([(need_id, need_amount)])
        resource_classify.check_exist(self.server_id, self.char_id)
        resource_classify.remove(self.server_id, self.char_id, message="Store.buy:{0}".format(goods_id))

        resource_classify = ResourceClassification.classify([(item_id, item_amount)])
        resource_classify.add(self.server_id, self.char_id, message="Store.buy:{0}".format(goods_id))

        data['times'] += 1

        MongoStore.db(self.server_id).update_one(
            {'_id': self.char_id},
            {'$set': {
                'tp.{0}.goods.{1}.times'.format(tp, goods_id): data['times']
            }}
        )

        self.send_notify(tp=tp)
        return resource_classify
Example #36
0
    def post():
        """
        Handles HTTP POST /pools request.
        Add a new Pool
        Raises NotFound, BadRequest, InternalError

        Returns:
            response, status code
        """
        json_data = request.get_json()

        # validate pool schema
        try:
            schema, resolver = ConfigStore.load_json_schema('add_pool.json')
            jsonschema.validate(json_data, schema, resolver=resolver)
        except jsonschema.ValidationError as error:
            raise BadRequest("Request validation failed - %s" % (str(error)))

        post_data = json_data.copy()
        post_data['id'] = common.CONFIG_STORE.get_new_pool_id(post_data)
        if post_data['id'] is None:
            raise InternalError("New POOL not added, maximum number of POOLS"\
                " reached for requested allocation combination")

        # convert cbm from string to int
        if 'cbm' in post_data:
            cbm = post_data['cbm']
            if not isinstance(cbm, int):
                cbm = int(cbm, 16)

            post_data['cbm'] = cbm

        data = common.CONFIG_STORE.get_config().copy()
        data['pools'].append(post_data)

        try:
            common.CONFIG_STORE.validate(data)
        except Exception as ex:
            raise BadRequest("New POOL not added, " + str(ex))
        else:
            common.CONFIG_STORE.set_config(data)
            res = {'id': post_data['id']}
            return res, 201
Example #37
0
 def load_options(self):
     # TODO: move config to MemoryAddress class?
     # (depends on how monitoring of addresses should work)
     lines = self.address.get_lines()
     follow_pc = self.address.get_follow_pc()
     miss_is_error = False # needed for adding windows
     defaults = {
         "[General]": {
         	"nLines": lines,
             "bFollowPC": follow_pc
         }
     }
     userconfdir = ".hatari"
     config = ConfigStore(userconfdir, defaults, miss_is_error)
     configpath = config.get_filepath("debugui.cfg")
     config.load(configpath) # set defaults
     try:
         self.address.set_lines(config.get("[General]", "nLines"))
         self.address.set_follow_pc(config.get("[General]", "bFollowPC"))
     except (KeyError, AttributeError):
         ErrorDialog(None).run("Debug UI configuration mismatch!\nTry again after removing: '%s'." % configpath)
     self.config = config
Example #38
0
    def put(pool_id):
        # pylint: disable=too-many-branches
        """
        Handles HTTP PUT /pools/<pool_id> request.
        Modifies a Pool
        Raises NotFound, BadRequest, InternalError

        Parameters:
            pool_id: Id of pool

        Returns:
            response, status code
        """
        def check_alloc_tech(pool_id, json_data):
            alloc_tech = []
            if 'cbm' in json_data:
                alloc_tech.append(common.CAT_CAP)
            if 'mba' in json_data:
                alloc_tech.append(common.MBA_CAP)

            if not alloc_tech:
                return True

            return pool_id <= common.PQOS_API.get_max_cos_id(alloc_tech)

        json_data = request.get_json()

        # validate app schema
        try:
            schema, resolver = ConfigStore.load_json_schema('modify_pool.json')
            jsonschema.validate(json_data, schema, resolver=resolver)
        except jsonschema.ValidationError as error:
            raise BadRequest("Request validation failed - %s" % (str(error)))

        data = common.CONFIG_STORE.get_config().copy()
        if 'pools' not in data:
            raise NotFound("No pools in config file")

        for pool in data['pools']:
            if pool['id'] != int(pool_id):
                continue

            if not check_alloc_tech(int(pool_id), json_data):
                raise BadRequest("Pool {} does not support requested technologies!"\
                    .format(pool_id))

            # set new cbm
            if 'cbm' in json_data:
                cbm = json_data['cbm']
                if not isinstance(cbm, int):
                    cbm = int(cbm, 16)

                pool['cbm'] = cbm

            # set new mba
            if 'mba' in json_data:
                pool['mba'] = json_data['mba']

            # set new cores
            if 'cores' in json_data:
                pool['cores'] = json_data['cores']

            if 'apps' in pool and pool['apps']:
                for app_id in pool['apps']:
                    for app in data['apps']:
                        if app['id'] != app_id or 'cores' not in app:
                            continue
                        if not set(app['cores']).issubset(pool['cores']):
                            app.pop('cores')

            # set new name
            if 'name' in json_data:
                pool['name'] = json_data['name']

            try:
                common.CONFIG_STORE.validate(data)
            except Exception as ex:
                raise BadRequest("POOL " + str(pool_id) + " not updated, " + str(ex))
            else:
                common.CONFIG_STORE.set_config(data)
                return "POOL " + str(pool_id) + " updated", 200

        raise NotFound("POOL " + str(pool_id) + " not found in config")
Example #39
0
    def post():
        # pylint: disable=too-many-branches
        """
        Handles HTTP POST /apps request.
        Add a new App
        Raises NotFound, BadRequest, InternalError

        Returns:
            response, status code
        """

        def get_app_id():
            """
            Get ID for new App

            Returns:
                ID for new App
            """
            # put all ids into list
            app_ids = []
            for app in data['apps']:
                app_ids.append(app['id'])
            app_ids = sorted(app_ids)
            # no app found in config
            if not app_ids:
                return 1

            # add new app to apps
            # find an id
            new_ids = list(set(range(1, app_ids[-1])) - set(app_ids))
            if new_ids:
                return new_ids[0]

            return app_ids[-1] + 1

        json_data = request.get_json()

        # validate app schema
        try:
            schema, resolver = ConfigStore.load_json_schema('add_app.json')
            jsonschema.validate(json_data, schema, resolver=resolver)
        except jsonschema.ValidationError as error:
            raise BadRequest("Request validation failed - %s" % (str(error)))

        data = deepcopy(common.CONFIG_STORE.get_config())

        if 'pools' not in data:
            raise NotFound("No pools in config file")

        json_data['id'] = get_app_id()

        if 'pids' in json_data:
            # validate pids
            for pid in json_data['pids']:
                valid = pid_ops.is_pid_valid(pid)
                if not valid:
                    raise BadRequest("New APP not added, please provide valid pid's")

        # if pool_id not provided on app creation
        if 'pool_id' not in json_data or not json_data['pool_id']:
            json_data['pool_id'] = None

            # if apps cores list is a subset of existing pool cores list,
            # make existing pool a destination pool for app
            if 'cores' in json_data and json_data['cores']:
                for pool in data['pools']:
                    if set(json_data['cores']).issubset(pool['cores']):
                        json_data['pool_id'] = pool['id']
                        break

            # if it is not, make default pool a destination pool
            if json_data['pool_id'] is None:
                json_data['pool_id'] = 0
                if 'cores' in json_data:
                    json_data.pop('cores')

        # update pool configuration to include new app
        for pool in data['pools']:
            if pool['id'] == json_data['pool_id']:
                if not 'apps' in pool:
                    pool['apps'] = []
                pool['apps'].append(json_data['id'])
                break

        json_data.pop('pool_id')
        data['apps'].append(json_data)

        try:
            common.CONFIG_STORE.validate(data)
        except Exception as ex:
            raise BadRequest("New APP not added, " + str(ex))
        else:
            common.CONFIG_STORE.set_config(data)
            res = {'id': json_data['id']}
            return res, 201
Example #40
0
    def put(app_id):
        """
        Handles HTTP PUT /apps/<app_id> request.
        Modifies an App (e.g.: moves to different pool)
        Raises NotFound, InternalError

        Parameters:
            app_id: Id of app to modify

        Returns:
            response, status code
        """
        json_data = request.get_json()

        # validate app schema
        try:
            schema, resolver = ConfigStore.load_json_schema('move_app.json')
            jsonschema.validate(json_data, schema, resolver=resolver)
        except jsonschema.ValidationError as error:
            raise BadRequest("Request validation failed - %s" % (str(error)))

        pool_id = json_data["pool_id"]

        data = deepcopy(common.CONFIG_STORE.get_config())
        if 'apps' not in data or 'pools' not in data:
            raise NotFound("No apps or pools in config file")

        for app in data['apps']:
            if app['id'] != int(app_id):
                continue

            # remove app id from pool
            for pool in data['pools']:
                if 'apps' in pool:
                    if app['id'] in pool['apps']:
                        pool['apps'].remove(app['id'])
                        break
            # add app id to new pool
            for pool in data['pools']:
                if pool['id'] == int(pool_id):
                    if 'apps' in pool:
                        pool['apps'].append(app['id'])
                        break
                    else:
                        pool['apps'] = [app['id']]
                        break
            # set new cores
            if 'cores' in json_data:
                app['cores'] = json_data['cores']
            elif 'cores' in app:
                app.pop('cores')

            try:
                common.CONFIG_STORE.validate(data)
            except Exception as ex:
                raise BadRequest("APP not updated, " + str(ex))
            else:
                common.CONFIG_STORE.set_config(data)
                common.STATS_STORE.general_stats_inc_apps_moves()
                return "APP " + str(app_id) + " moved to new pool", 200

        raise NotFound("APP " + str(app_id) + " not found in config")