def build_network(conn, name=None, project_id=None, num_nodes=10): """ Create a network with the correct """ #Does nothing if project id is None, just returns the project id, otherwise #finds or creates the project project_id = get_project(conn, project_id) template = create_template(conn) network_type = template.templatetypes[0] node_type = template.templatetypes[ 1] #For the purposes of this example, there is only 1 type of node. The 'default node' link_type = template.templatetypes[ 2] #For the purposes of this example, there is only 1 type of link. The 'default link' group_type = template.templatetypes[3] nodes, links = create_nodes_and_links(node_type, link_type, num_nodes=num_nodes) groups, group_items = create_groups(nodes, links, group_type) #way so I can check the value is correct after the network is created. layout = dict(color='red', shapefile='blah.shp') network_attributes = create_network_attributes(conn, network_type) net_type = [] net_type = JSONObject( dict( template_id=template.id, template_name=template.name, id=network_type.id, name=network_type.name, )) #The the contents of a group are scenario-dependent scenario = create_scenario(nodes, links, groups, group_items, node_type, link_type) network = JSONObject( dict( name='Network @ %s' % datetime.datetime.now(), description='An example network', project_id=project_id, links=links, nodes=nodes, layout=layout, scenarios=[scenario ], #a list as a network can contain multipl scenarios resourcegroups=groups, projection='EPSG:4326', attributes=network_attributes, types=[net_type], #a list as a network can have multiple types )) return network
def test_delete_scenario(self): net = self.test_clone() scenarios_before = net.scenarios assert len(scenarios_before) == 2 hydra_base.delete_scenario(scenarios_before[1].id, user_id=self.user_id) updated_net = JSONObject(hydra_base.get_network(net.id, user_id=self.user_id)) scenarios_after_delete = updated_net.scenarios assert len(scenarios_after_delete) == 1 hydra_base.activate_scenario(scenarios_before[1].id, user_id=self.user_id) updated_net2 = JSONObject(hydra_base.get_network(net.id, user_id=self.user_id)) scenarios_after_reactivate = updated_net2.scenarios assert len(scenarios_after_reactivate) == 2 hydra_base.delete_scenario(scenarios_before[1].id, user_id=self.user_id) hydra_base.clean_up_network(net.id, user_id=self.user_id) updated_net3 = JSONObject(hydra_base.get_network(net.id, user_id=self.user_id)) scenarios_after_cleanup = updated_net3.scenarios assert len(scenarios_after_cleanup) == 1 self.assertRaises(HydraError, self.get_scenario, scenarios_before[1].id)
def test_get_dataset_scenarios(self): """ Test to get the scenarios attached to a dataset """ network = self.create_network_with_data() #Create the new scenario scenario = network.scenarios[0] rs = scenario.resourcescenarios dataset_id_to_check = rs[0].value.id dataset_scenarios = [JSONObject(s) for s in hydra_base.get_dataset_scenarios(dataset_id_to_check, user_id=self.user_id)] assert len(dataset_scenarios) == 1 assert dataset_scenarios[0].id == scenario.id clone = self.clone_scenario(scenario.id) new_scenario = self.get_scenario(clone.id) dataset_scenarios = [JSONObject(s) for s in hydra_base.get_dataset_scenarios(dataset_id_to_check, user_id=self.user_id)] assert len(dataset_scenarios) == 2 assert dataset_scenarios[0].id == scenario.id assert dataset_scenarios[1].id == new_scenario.id
def session_with_pywr_network(pywr_json_filename, session_with_pywr_template, projectmaker, root_user_id): project = projectmaker.create() template = JSONObject( hydra_base.get_template_by_name(pywr_template_name('Full'))) importer = PywrHydraImporter(pywr_json_filename, template) # First the attributes must be added. attributes = [ JSONObject(a) for a in importer.add_attributes_request_data() ] # The response attributes have ids now. response_attributes = hydra_base.add_attributes(attributes) # Convert to a simple dict for local processing. attribute_ids = {a.name: a.id for a in response_attributes} # Now we try to create the network network = importer.add_network_request_data(attribute_ids, project.id) hydra_network = hydra_base.add_network(JSONObject(network), user_id=root_user_id) return hydra_network.id, pywr_json_filename
def create_attr(conn, name="Test attribute", dimension="dimensionless"): attr_i = conn.get_attribute({'name': name, 'dimension': dimension}) if attr_i is None or len(attr_i) == 0: attr = JSONObject({'name': name, 'dimension': dimension}) attr = JSONObject(conn.add_attribute({'attr': attr})) else: attr = JSONObject(attr_i) return attr
def create_dataframe(resource_attr): #A scenario attribute is a piece of data associated #with a resource attribute. val_1 = "df_a" val_2 = "df_b" val_3 = "df_c" ts_val = {"test_column": {'key1': val_1, 'key2': val_2, 'key3': val_3}} metadata = json.dumps({'created_by': 'Test user'}) dataset = dict( id=None, type='dataframe', name='my data frame', unit='m^3 s^-1', hidden='N', value=json.dumps(ts_val), ) scenario_attr = JSONObject( dict( attr_id=resource_attr.attr_id, resource_attr_id=resource_attr.id, dataset=dataset, )) return scenario_attr
def test_get_attributes_for_resource(self): """ Test to check leng's questions about this not working correctly. """ network = self.create_network_with_data() #Create the new scenario scenario = network.scenarios[0] node1 = network.nodes[0] ra_to_update = node1.attributes[0].id updated_val = None rs_to_update = [] for resourcescenario in scenario.resourcescenarios: ra_id = resourcescenario.resource_attr_id if ra_id == ra_to_update: updated_val = resourcescenario.value.value resourcescenario.value.name = 'I am an updated dataset name' rs_to_update.append(resourcescenario) hydra_base.get_attributes_for_resource(network.id, scenario.id, 'NODE', [node1.id], user_id=self.user_id) hydra_base.update_resourcedata(scenario.id, rs_to_update) new_node_data = [JSONObject(d) for d in hydra_base.get_attributes_for_resource(network.id, scenario.id, [node1.id], user_id=self.user_id)] for new_val in new_node_data: if new_val.resourcescenario.value.value == updated_val: assert new_val.resourcescenario.value.name == 'I am an updated dataset name'
def test_add_scenario(self): """ Test adding a new scenario to a network. """ network = self.create_network_with_data() new_scenario = copy.deepcopy(network.scenarios[0]) new_scenario.id = -1 new_scenario.name = 'Scenario 2' new_scenario.description = 'Scenario 2 Description' new_scenario.start_time = datetime.datetime.now() new_scenario.end_time = new_scenario.start_time + datetime.timedelta(hours=10) new_scenario.time_step = "1 day" node_attrs = network.nodes[0].attributes #This is an example of 3 diffent kinds of data #A simple string (Descriptor) #A time series, where the value may be a 1-D array #A multi-dimensional array. descriptor = self.create_descriptor(node_attrs[0], "new_descriptor") timeseries = self.create_timeseries(node_attrs[1]) for r in new_scenario.resourcescenarios: if r.resource_attr_id == node_attrs[0].id: r.value = descriptor['value'] elif r.resource_attr_id == node_attrs[1].id: r.value = timeseries['value'] scenario = JSONObject(hydra_base.add_scenario(network.id, new_scenario, user_id=self.user_id)) assert scenario is not None assert len(scenario.resourcegroupitems) > 0 assert len(scenario.resourcescenarios) > 0
def create_array(resource_attr): #A scenario attribute is a piece of data associated #with a resource attribute. #[[1, 2, 3], [4, 5, 6], [7, 8, 9]] arr = json.dumps([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]) metadata_array = json.dumps({'created_by': 'Test user'}) dataset = dict( id=None, type='array', name='my array', unit='bar', hidden='N', value=arr, metadata=metadata_array, ) scenario_attr = JSONObject( dict( attr_id=resource_attr.attr_id, resource_attr_id=resource_attr.id, dataset=dataset, )) return scenario_attr
def test_update_resourcedata_single_dataset_update_and_delete(self): """ Test to ensure update_resourcedata does not update other datasets that it should not. """ network = self.create_network_with_data() scenario_1 = network.scenarios[0] scenario_2 = self.clone_scenario(scenario_1.id) scenario_2 = self.get_scenario(scenario_2.id) new_value = json.dumps({"index": {"1.0":"test", "2.0":"update"}}) #Delete a timeseries from one scenario, so there's only 1 reference to that #dataset in tResourceSceanrio. ts_to_delete = [] ra_id = None ts_id = None for rs in scenario_1.resourcescenarios: if rs.value.type == 'timeseries': ra_id = rs.resource_attr_id ts_id = rs.value.id rs.value = None ts_to_delete.append(rs) break ts_to_update = [] for rs in scenario_2.resourcescenarios: if rs.resource_attr_id == ra_id: rs.value.value= new_value ts_to_update.append(rs) break deleted_rs = JSONObject(hydra_base.update_resourcedata(scenario_1.id, ts_to_delete, user_id=self.user_id)) updated_ts_rs = JSONObject(hydra_base.update_resourcedata(scenario_2.id, ts_to_update, user_id=self.user_id)) scenario_2_updated_1 = self.get_scenario(scenario_2.id) for rs in scenario_2_updated_1.resourcescenarios: if rs.resource_attr_id == ra_id: assert json.loads(rs.value.value) == json.loads(new_value) #Either the dataset is the same dataset, just updated or the dataset #has been removed and linked to a previous dataset, which must have a lower ID. assert rs.value.id <= ts_id break else: raise Exception("Couldn't find resource scenario. SOmething went wrong.")
def test_update_resourcedata(self): """ Test updating an existing scenario data. 2 main points to test: 1: setting a value to null should remove the resource scenario 2: changing the value should create a new dataset """ network = self.create_network_with_data() #Create the new scenario scenario = network.scenarios[0] num_old_rs = len(scenario.resourcescenarios) #Identify 2 nodes to play around with -- the first and last in the list. node1 = network.nodes[0] node2 = network.nodes[-1] descriptor = self.create_descriptor(node1.attributes[0], "updated_descriptor") val_to_delete = node2.attributes[0] rs_to_update = [] updated_dataset_id = None for resourcescenario in scenario.resourcescenarios: ra_id = resourcescenario.resource_attr_id if ra_id == descriptor['resource_attr_id']: updated_dataset_id = resourcescenario.value['id'] resourcescenario.value = descriptor['value'] rs_to_update.append(resourcescenario) elif ra_id == val_to_delete['id']: resourcescenario.value = None rs_to_update.append(resourcescenario) assert updated_dataset_id is not None new_resourcescenarios = [JSONObject(rs) for rs in hydra_base.update_resourcedata(scenario.id, rs_to_update, user_id=self.user_id)] assert len(new_resourcescenarios) == 1 for rs in new_resourcescenarios: if rs.resource_attr_id == descriptor['resource_attr_id']: assert rs.value.value == descriptor['value']['value'] updated_scenario = self.get_scenario(scenario.id) num_new_rs = len(updated_scenario.resourcescenarios) assert num_new_rs == num_old_rs - 1 for u_rs in updated_scenario.resourcescenarios: for rs in new_resourcescenarios: if u_rs.resource_attr_id == rs.resource_attr_id: assert str(u_rs.value) == str(rs.value) break
def create_groups(nodes, links, group_type): """ Create resource groups and their items A resource group is a container for nodes and links, used to represent political or social hierarchies, or logical groupings of nodes where a rule must be applied to them The contents of a group are scenario dependent, so the group configuration can be changed within a network. """ log.info('Creating Groups') # Put an attribute on a group group_ra = JSONObject( dict(ref_id=None, ref_key='GROUP', attr_is_var='N', attr_id=group_type.typeattrs[0].attr_id, id=-1)) group_attrs = [group_ra] groups = [] group = JSONObject( dict(id=-1, name="Test Group", description="Test group description")) group.attributes = group_attrs type_summary = JSONObject(dict(id=group_type.id, name=group_type.name)) type_summary_arr = [type_summary] group.types = type_summary_arr groups.append(group) group_items = [] group_item_1 = JSONObject( dict( ref_key='NODE', ref_id=nodes[0]['id'], group_id=group['id'], )) group_item_2 = JSONObject( dict( ref_key='NODE', ref_id=nodes[1]['id'], group_id=group['id'], )) group_items = [group_item_1, group_item_2] return groups, group_items
def test_update_resourcedata_consistency(self): """ Test to ensure update_resourcedata does not update other datasets that it should not. """ network = self.create_network_with_data() scenario_1 = network.scenarios[0] scenario_2 = self.clone_scenario(scenario_1.id) scenario_2 = self.get_scenario(scenario_2.id) #Identify 2 nodes to play around with -- the first and last in the list. node1 = network.nodes[0] descriptor = self.create_descriptor(node1.attributes[0], "updated_descriptor") rs_to_update = self._get_rs_to_update(scenario_1, descriptor) #Update the value new_resourcescenarios = [JSONObject(rs) for rs in hydra_base.update_resourcedata(scenario_1.id, rs_to_update, user_id=self.user_id)] rs_1_id = None updated_scenario_1 = self.get_scenario(scenario_1.id) for u_rs in updated_scenario_1.resourcescenarios: for rs in new_resourcescenarios: if u_rs.resource_attr_id == rs.resource_attr_id: assert str(u_rs.value) == str(rs.value) rs_1_id = u_rs.value break scalar = self.create_descriptor(node1.attributes[0], 200) rs_to_update = self._get_rs_to_update(scenario_2, scalar) new_resourcescenarios = hydra_base.update_resourcedata(scenario_2.id, rs_to_update, user_id=self.user_id) rs_2_id = None #Check that scenario 2 has been updated correctly. updated_scenario_2 = self.get_scenario(scenario_2.id) for u_rs in updated_scenario_2.resourcescenarios: for rs in new_resourcescenarios: if u_rs.resource_attr_id == rs.resource_attr_id: rs_2_id = u_rs.value assert str(u_rs.value) == str(rs.value) break log.critical("%s vs %s", rs_1_id, rs_2_id) #Check that this change has not affected scenario 1 for u_rs in updated_scenario_1.resourcescenarios: for rs in new_resourcescenarios: if u_rs.resource_attr_id == rs.resource_attr_id: assert str(u_rs.value) != str(rs.value) break
def test_clone(self): network = self.create_network_with_data() assert len(network.scenarios) == 1, "The network should have only one scenario!" #self.create_constraint(network) network = JSONObject(hydra_base.get_network(network.id, user_id=self.user_id)) scenario = network.scenarios[0] scenario_id = scenario.id clone = self.clone_scenario(scenario_id) new_scenario = self.get_scenario(clone.id) updated_network = JSONObject(hydra_base.get_network(new_scenario.network_id, user_id=self.user_id)) assert len(updated_network.scenarios) == 2, "The network should have two scenarios!" assert updated_network.scenarios[1].resourcescenarios is not None, "Data was not cloned!" scen_2_val = updated_network.scenarios[1].resourcescenarios[0].value.id scen_1_val = network.scenarios[0].resourcescenarios[0].value.id assert scen_2_val == scen_1_val, "Data was not cloned correctly" # scen_1_constraint = network.scenarios[0].constraints.Constraint[0].value #scen_2_constraint = updated_network.scenarios[1].constraints.Constraint[0].value # # assert scen_1_constraint == scen_2_constraint, "Constraints did not clone correctly!" scen_1_resourcegroupitems = network.scenarios[0].resourcegroupitems scen_2_resourcegroupitems = updated_network.scenarios[1].resourcegroupitems assert len(scen_1_resourcegroupitems) == len(scen_2_resourcegroupitems) return updated_network
def create_network_attributes(conn, network_type): log.info('Creating Network Attributes') net_attr = create_attr(conn, "net_attr_b", dimension='Pressure') net_ra_notmpl = JSONObject( dict( ref_id=None, ref_key='NETWORK', attr_is_var='N', attr_id=net_attr.id, )) net_ra_tmpl = JSONObject( dict( ref_id=None, ref_key='NETWORK', attr_is_var='N', attr_id=network_type.typeattrs[0].attr_id, )) return [net_ra_notmpl, net_ra_tmpl]
def test_update_scenario(self): """ Test updating an existing scenario. """ network = self.create_network_with_data() #Create the new scenario scenario = network.scenarios[0] scenario.name = 'Updated Scenario' scenario.description = 'Updated Scenario Description' scenario.start_time = datetime.datetime.now() scenario.end_time = scenario.start_time + datetime.timedelta(hours=10) scenario.time_step = "1 day" #Identify 2 nodes to play around with -- the first and last in the list. node1 = network.nodes[0] node2 = network.nodes[-1] #Identify 1 resource group item to edit (the last one in the list). item_to_edit = scenario.resourcegroupitems[-1] #Just checking that we're not changing an item that is already #assigned to this node.. assert scenario.resourcegroupitems[-1].node_id != node2.node_id scenario.resourcegroupitems[-1].node_id = node2.node_id descriptor = self.create_descriptor(node1.attributes[0], "updated_descriptor") for resourcescenario in scenario.resourcescenarios: if resourcescenario.attr_id == descriptor['attr_id']: resourcescenario.value = descriptor['value'] updated_scenario = JSONObject(hydra_base.update_scenario(scenario, user_id=self.user_id)) assert updated_scenario is not None assert updated_scenario.id == scenario.id assert updated_scenario.name == scenario.name assert updated_scenario.description == scenario.description assert "%.2f"%updated_scenario.start_time == "%.2f"%timestamp_to_ordinal(scenario.start_time) assert "%.2f"%updated_scenario.end_time == "%.2f"%timestamp_to_ordinal(scenario.end_time) assert updated_scenario.time_step == scenario.time_step assert len(updated_scenario.resourcegroupitems) > 0 for i in updated_scenario.resourcegroupitems: if i.item_id == item_to_edit.id: assert i.node_id == node2.node_id assert len(updated_scenario.resourcescenarios) > 0 for data in updated_scenario.resourcescenarios: if data.attr_id == descriptor['attr_id']: assert data.value.value == descriptor['value']['value']
def create_link(link_id, node_1_name, node_2_name, node_1_id, node_2_id): ra_array = [] link = JSONObject({ 'id': link_id, 'name': "%s_to_%s" % (node_1_name, node_2_name), 'description': 'A test link between two nodes.', 'layout': None, 'node_1_id': node_1_id, 'node_2_id': node_2_id, 'attributes': ra_array, }) return link
def create_node(node_id, attributes=None, node_name="test node name"): if attributes is None: attributes = [] #turn 0 into 1, -1 into 2, -2 into 3 etc.. coord = (node_id * -1) + 1 node = JSONObject({ 'id': node_id, 'name': node_name, 'description': "a node representing a water resource", 'layout': None, 'x': 10 * coord, 'y': 10 * coord - 1, 'attributes': attributes, }) return node
def test_purge_scenario(self): net = self.test_clone() scenarios_before = net.scenarios assert len(scenarios_before) == 2 hydra_base.purge_scenario(scenarios_before[1].id, user_id=self.user_id) updated_net = JSONObject(hydra_base.get_network(net.id, user_id=self.user_id)) scenarios_after = updated_net.scenarios assert len(scenarios_after) == 1 self.assertRaises(HydraError, self.get_scenario, scenarios_before[1].id) assert str(scenarios_after[0]) == str(scenarios_before[0])
def create_timeseries(resource_attr): #A scenario attribute is a piece of data associated #with a resource attribute. #[[[1, 2, "hello"], [5, 4, 6]], [[10, 20, 30], [40, 50, 60]]] fmt = "%Y-%m-%dT%H:%M:%S.%f000Z" t1 = datetime.datetime.now() t2 = t1 + datetime.timedelta(hours=1) t3 = t1 + datetime.timedelta(hours=2) val_1 = [10, 20, 30] val_2 = [1.0, 2.0, 3.0] val_3 = [3.0, 4.0, 5.0] ts_val = { "test_column": { t1.strftime(fmt): val_1, t2.strftime(fmt): val_2, t3.strftime(fmt): val_3 } } metadata = json.dumps({'created_by': 'Test user'}) dataset = dict( id=None, type='timeseries', name='my time series', unit= 'cm^3', # This does not match the type on purpose, to test validation hidden='N', value=json.dumps(ts_val), metadata=metadata) scenario_attr = JSONObject( dict( attr_id=resource_attr.attr_id, resource_attr_id=resource_attr.id, dataset=dataset, )) return scenario_attr
def create_scenario(nodes, links, groups, resourcegroupitems, node_type, link_type): log.info('Creating Scenario') #Create the scenario scenario = JSONObject() scenario.id = -1 scenario.name = 'Scenario 1' scenario.description = 'Scenario Description' scenario.layout = json.dumps({'app': ["Unit Test1", "Unit Test2"]}) scenario.resourcegroupitems = resourcegroupitems node_data, link_data, group_data = populate_network_with_data( nodes, links, groups, node_type, link_type) #Set the scenario's data to the array we have just populated scenario.resourcescenarios = node_data + link_data + group_data return scenario
def create_project(conn, name): user_projects = conn.get_project_by_name({'project_name': name}) if len(user_projects) == 0: log.info('Project "%s" not found, creating a new one', name) project = JSONObject() project.name = name project.description = "Project which contains all example networks" project = JSONObject(conn.add_project({'project': project})) return project else: return user_projects[0]
def create_scalar(resource_attr, val=1.234): #with a resource attribute. dataset = dict( id=None, type='scalar', name='Flow speed', unit='m s^-1', hidden='N', value=val, ) scenario_attr = JSONObject( dict( attr_id=resource_attr.attr_id, resource_attr_id=resource_attr.id, dataset=dataset, )) return scenario_attr
def create_descriptor(resource_attr, val="test"): #A scenario attribute is a piece of data associated #with a resource attribute. dataset = dict( id=None, type='descriptor', name='Flow speed', unit= 'm s^-1', # This does not match the type on purpose, to test validation hidden='N', value=val, ) scenario_attr = JSONObject( dict( attr_id=resource_attr.attr_id, resource_attr_id=resource_attr.id, dataset=dataset, )) return scenario_attr
def clone_scenario(self, scenario_id): """ Utility function wrapper for a function tat's called regularly. Introduced as the JSONObject wrapper can be controlled more easily """ return JSONObject(hydra_base.clone_scenario(scenario_id, user_id=self.user_id))
def test_compare(self): network = self.create_network_with_data() assert len(network.scenarios) == 1, "The network should have only one scenario!" # self.create_constraint(network) network = JSONObject(hydra_base.get_network(network.id, user_id=self.user_id)) scenario = network.scenarios[0] scenario_id = scenario.id clone = self.clone_scenario(scenario_id) new_scenario = self.get_scenario(clone.id) # self.create_constraint(network, constant=4) resource_scenario = new_scenario.resourcescenarios[0] resource_attr_id = resource_scenario.resource_attr_id dataset = Dataset() dataset = Dataset() dataset.type = 'descriptor' dataset.name = 'Max Capacity' dataset.unit = 'metres / second' dataset.dimension = 'number of units per time unit' dataset.value ='I am an updated test!' hydra_base.add_data_to_attribute(scenario_id, resource_attr_id, dataset, user_id=self.user_id) item_to_remove = new_scenario.resourcegroupitems[0].id hydra_base.delete_resourcegroupitem(item_to_remove, user_id=self.user_id) updated_network = JSONObject(hydra_base.get_network(new_scenario.network_id, user_id=self.user_id)) scenarios = updated_network.scenarios scenario_1 = None scenario_2 = None for s in scenarios: if s.id == new_scenario.id: scenario_1 = s else: scenario_2 = s scenario_diff = hydra_base.compare_scenarios(scenario_1.id, scenario_2.id, user_id=self.user_id) #print "Comparison result: %s"%(scenario_diff) assert len(scenario_diff.resourcescenariosDiff) == 1, "Data comparison was not successful!" # assert len(scenario_diff.constraints.common_constraints) == 1, "Constraint comparison was not successful!" # assert len(scenario_diff.constraints.scenario_2_constraints) == 1, "Constraint comparison was not successful!" assert len(scenario_diff.groups.scenario_2_items) == 1, "Group comparison was not successful!" assert scenario_diff.groups.scenario_1_items is None, "Group comparison was not successful!" return updated_network
def test_lock_scenario(self): network = self.create_network_with_data() network = hydra_base.get_network(network.id, user_id=self.user_id) scenario_to_lock = network.scenarios[0] scenario_id = scenario_to_lock.id log.info('Cloning scenario %s'%scenario_id) clone = self.clone_scenario(scenario_id) unlocked_scenario = self.get_scenario(clone.id) log.info("Locking scenario") hydra_base.lock_scenario(scenario_id, user_id=self.user_id) locked_scenario = self.get_scenario(scenario_id) assert locked_scenario.locked == 'Y' dataset = Dataset() dataset.type = 'descriptor' dataset.name = 'Max Capacity' dataset.unit = 'metres / second' dataset.dimension = 'number of units per time unit' dataset.value = 'I am an updated test!' locked_resource_scenarios = [] for rs in locked_scenario.resourcescenarios: if rs.value.type == 'descriptor': locked_resource_scenarios.append(rs) unlocked_resource_scenarios = [] for rs in unlocked_scenario.resourcescenarios: if rs.value.type == 'descriptor': unlocked_resource_scenarios.append(rs) resource_attr_id = unlocked_resource_scenarios[0].resource_attr_id locked_resource_scenarios_value = None for rs in locked_scenario.resourcescenarios: if rs.resource_attr_id == resource_attr_id: locked_resource_scenarios_value = rs.value unlocked_resource_scenarios_value = None for rs in unlocked_scenario.resourcescenarios: if rs.resource_attr_id == resource_attr_id: unlocked_resource_scenarios_value = rs.value log.info("Updating a shared dataset") ds = unlocked_resource_scenarios_value ds.dimension = 'updated_dimension' updated_ds = JSONObject(hydra_base.update_dataset(ds, user_id=self.user_id)) updated_unlocked_scenario = self.get_scenario(unlocked_scenario.id) #This should not have changed updated_locked_scenario = self.get_scenario(locked_scenario.id) locked_resource_scenarios_value = None for rs in updated_locked_scenario.resourcescenarios: if rs.resource_attr_id == resource_attr_id: locked_resource_scenarios_value = rs.value unlocked_resource_scenarios_value = None for rs in updated_unlocked_scenario.resourcescenarios: if rs.resource_attr_id == resource_attr_id: unlocked_resource_scenarios_value = rs.value self.assertRaises(HydraError, hydra_base.add_data_to_attribute, scenario_id, resource_attr_id, dataset, user_id=self.user_id) #THe most complicated situation is this: #Change a dataset in an unlocked scenario, which is shared by a locked scenario. #The original dataset should stay connected to the locked scenario and a new #dataset should be created for the edited scenario. hydra_base.add_data_to_attribute(unlocked_scenario.id, resource_attr_id, dataset, user_id=self.user_id) updated_unlocked_scenario = self.get_scenario(unlocked_scenario.id) #This should not have changed updated_locked_scenario = self.get_scenario(locked_scenario.id) locked_resource_scenarios_value = None for rs in updated_locked_scenario.resourcescenarios: if rs.resource_attr_id == resource_attr_id: locked_resource_scenarios_value = rs.value unlocked_resource_scenarios_value = None for rs in updated_unlocked_scenario.resourcescenarios: if rs.resource_attr_id == resource_attr_id: unlocked_resource_scenarios_value = rs.value assert locked_resource_scenarios_value.value != unlocked_resource_scenarios_value.value item_to_remove = locked_scenario.resourcegroupitems[0].id self.assertRaises(HydraError, hydra_base.delete_resourcegroupitem, item_to_remove, user_id=self.user_id) log.info("Locking scenario") hydra_base.unlock_scenario(scenario_id, user_id=self.user_id) locked_scenario = self.get_scenario(scenario_id) assert locked_scenario.locked == 'N'
def create_template(conn, name="Example Template"): log.info('Creating Template') existing_template = conn.get_template_by_name({'template_name': name}) if len(existing_template) > 0: log.info("Existing template found. Continuing") return JSONObject(existing_template) else: log.info("No existing template found. Making new one.") net_attr1 = create_attr(conn, "net_attr_a", dimension='Volume') net_attr2 = create_attr(conn, "net_attr_c", dimension='dimensionless') link_attr_1 = create_attr(conn, "link_attr_a", dimension='Pressure') link_attr_2 = create_attr(conn, "link_attr_b", dimension='Speed') link_attr_3 = create_attr(conn, "link_attr_c", dimension='Length') node_attr_1 = create_attr(conn, "node_attr_a", dimension='Volume') node_attr_2 = create_attr(conn, "node_attr_b", dimension='Speed') node_attr_3 = create_attr(conn, "node_attr_c", dimension='Monetary value') node_attr_4 = create_attr(conn, "node_attr_d", dimension='Volumetric flow rate') group_attr_1 = create_attr(conn, "grp_attr_1", dimension='Monetary Value') group_attr_2 = create_attr(conn, "grp_attr_2", dimension='Displacement') template = JSONObject() template['name'] = name types = [] #********************** #network type # #********************** net_type = JSONObject() net_type.name = "Default Network" net_type.alias = "Test type alias" net_type.resource_type = 'NETWORK' typeattrs = [] typeattr_1 = JSONObject() typeattr_1.attr_id = net_attr1.id typeattr_1.data_restriction = {'LESSTHAN': 10, 'NUMPLACES': 1} typeattr_1.unit = 'm^3' typeattrs.append(typeattr_1) typeattr_2 = JSONObject() typeattr_2.attr_id = net_attr2.id typeattrs.append(typeattr_2) net_type.typeattrs = typeattrs types.append(net_type) #********************** # node type # #********************** node_type = JSONObject() node_type.name = "Default Node" node_type.alias = "Test type alias" node_type.resource_type = 'NODE' typeattrs = [] typeattr_1 = JSONObject() typeattr_1.attr_id = node_attr_1.id typeattr_1.data_restriction = {'LESSTHAN': 10, 'NUMPLACES': 1} typeattr_1.unit = 'm^3' typeattrs.append(typeattr_1) typeattr_2 = JSONObject() typeattr_2.attr_id = node_attr_2.id typeattr_2.data_restriction = {'INCREASING': None} typeattrs.append(typeattr_2) typeattr_3 = JSONObject() typeattr_3.attr_id = node_attr_3.id typeattrs.append(typeattr_3) typeattr_4 = JSONObject() typeattr_4.attr_id = node_attr_4.id typeattr_4.unit = "m^3 s^-1" typeattrs.append(typeattr_4) node_type.typeattrs = typeattrs types.append(node_type) #********************** #link type # #********************** link_type = JSONObject() link_type.name = "Default Link" link_type.resource_type = 'LINK' typeattrs = [] typeattr_1 = JSONObject() typeattr_1.attr_id = link_attr_1.id typeattrs.append(typeattr_1) typeattr_2 = JSONObject() typeattr_2.attr_id = link_attr_2.id typeattrs.append(typeattr_2) typeattr_3 = JSONObject() typeattr_3.attr_id = link_attr_3.id typeattrs.append(typeattr_3) link_type.typeattrs = typeattrs types.append(link_type) #********************** #group type # #********************** group_type = JSONObject() group_type.name = "Default Group" group_type.resource_type = 'GROUP' typeattrs = [] typeattr_1 = JSONObject() typeattr_1.attr_id = group_attr_1.id typeattrs.append(typeattr_1) typeattr_2 = JSONObject() typeattr_2.attr_id = group_attr_2.id typeattrs.append(typeattr_2) group_type.typeattrs = typeattrs types.append(group_type) template.templatetypes = types new_template_i = conn.add_template({'tmpl': template}) new_template = JSONObject(new_template_i) assert new_template.name == template.name, "Names are not the same!" assert new_template.id is not None, "New Template has no ID!" assert new_template.id > 0, "New Template has incorrect ID!" assert len(new_template.templatetypes) == len( types), "Resource types did not add correctly" for t in new_template.templatetypes[1].typeattrs: assert t.attr_id in (node_attr_1.id, node_attr_2.id, node_attr_3.id, node_attr_4.id) "Node types were not added correctly!" for t in new_template.templatetypes[2].typeattrs: assert t.attr_id in (link_attr_1.id, link_attr_2.id, link_attr_3.id) "Link types were not added correctly!" return new_template
def create_nodes_and_links(node_type, link_type, num_nodes=10): log.info('Creating Nodes and Links') #keeps track of the last node looked at, as the first node can't be linked #to anything prev_node = None #resource attribute index. Used to assign IDs to nodes ra_index = 2 nodes = [] links = [] for n in range(num_nodes): node = create_node(n * -1, node_name="Node %s" % (n)) #From our attributes, create a resource attr for our node #We don't assign data directly to these resource attributes. This #is done when creating the scenario -- a scenario is just a set of #data for a given list of resource attributes. node_ra1 = JSONObject( dict( ref_key='NODE', ref_id=None, attr_id=node_type.typeattrs[0].attr_id, id=ra_index * -1, attr_is_var='N', )) ra_index = ra_index + 1 node_ra2 = JSONObject( dict( ref_key='NODE', ref_id=None, attr_id=node_type.typeattrs[1].attr_id, id=ra_index * -1, attr_is_var= 'Y', #Note that this is a 'var' meanint it's an OUTPUT, so is not assigned a value here )) ra_index = ra_index + 1 node_ra3 = JSONObject( dict( ref_key='NODE', ref_id=None, attr_id=node_type.typeattrs[2].attr_id, id=ra_index * -1, attr_is_var='N', )) ra_index = ra_index + 1 node_ra4 = JSONObject( dict( ref_key='NODE', ref_id=None, attr_id=node_type.typeattrs[3].attr_id, id=ra_index * -1, attr_is_var='N', )) ra_index = ra_index + 1 node.attributes = [node_ra1, node_ra2, node_ra3, node_ra4] type_summary = JSONObject(dict(id=node_type.id, name=node_type.name)) type_summary_arr = [type_summary] node.types = type_summary_arr nodes.append(node) if prev_node is not None: #Connect the two nodes with a link link = create_link(n * -1, node['name'], prev_node['name'], node['id'], prev_node['id']) link_ra1 = JSONObject( dict( ref_id=None, ref_key='LINK', id=ra_index * -1, attr_id=link_type.typeattrs[0].attr_id, attr_is_var='N', )) ra_index = ra_index + 1 link_ra2 = JSONObject( dict( ref_id=None, ref_key='LINK', attr_id=link_type.typeattrs[1].attr_id, id=ra_index * -1, attr_is_var='N', )) ra_index = ra_index + 1 link_ra3 = JSONObject( dict( ref_id=None, ref_key='LINK', attr_id=link_type.typeattrs[2].attr_id, id=ra_index * -1, attr_is_var='N', )) ra_index = ra_index + 1 link.attributes = [link_ra1, link_ra2, link_ra3] if link['id'] % 2 == 0: type_summary_arr = [] type_summary = JSONObject({ 'id': link_type.id, 'name': link_type.name }) type_summary_arr.append(type_summary) link.types = type_summary_arr links.append(link) prev_node = node return nodes, links