def test_attr_after_storing(self): a = Node() a._set_attr('none', None) a._set_attr('bool', self.boolval) a._set_attr('integer', self.intval) a._set_attr('float', self.floatval) a._set_attr('string', self.stringval) a._set_attr('dict', self.dictval) a._set_attr('list', self.listval) a.store() # Now I check if I can retrieve them, before the storage self.assertIsNone(a.get_attr('none')) self.assertEquals(self.boolval, a.get_attr('bool')) self.assertEquals(self.intval, a.get_attr('integer')) self.assertEquals(self.floatval, a.get_attr('float')) self.assertEquals(self.stringval, a.get_attr('string')) self.assertEquals(self.dictval, a.get_attr('dict')) self.assertEquals(self.listval, a.get_attr('list')) # And now I try to edit/delete the keys; I should not be able to do it # after saving. I try only for a couple of attributes with self.assertRaises(ModificationNotAllowed): a._del_attr('bool') with self.assertRaises(ModificationNotAllowed): a._set_attr('integer', 13)
def test_very_deep_attributes(self): """ Test attributes where the total length of the key, including the separators, would be longer than the field length in the DB. """ from aiida.backends.djsite.db import models n = Node() semi_long_string = "abcdefghijklmnopqrstuvwxyz" value = "some value" attribute = {semi_long_string: value} key_len = len(semi_long_string) max_len = models.DbAttribute._meta.get_field_by_name( 'key')[0].max_length while key_len < 2 * max_len: # Create a deep, recursive attribute attribute = {semi_long_string: attribute} key_len += len(semi_long_string) + len(models.DbAttribute._sep) n._set_attr(semi_long_string, attribute) n.store() all_keys = models.DbAttribute.objects.filter( dbnode=n.dbnode).values_list('key', flat=True) print max(len(i) for i in all_keys)
def test_attr_with_reload(self): a = Node() a._set_attr('none', None) a._set_attr('bool', self.boolval) a._set_attr('integer', self.intval) a._set_attr('float', self.floatval) a._set_attr('string', self.stringval) a._set_attr('dict', self.dictval) a._set_attr('list', self.listval) a.store() b = Node.get_subclass_from_uuid(a.uuid) self.assertIsNone(a.get_attr('none')) self.assertEquals(self.boolval, b.get_attr('bool')) self.assertEquals(self.intval, b.get_attr('integer')) self.assertEquals(self.floatval, b.get_attr('float')) self.assertEquals(self.stringval, b.get_attr('string')) self.assertEquals(self.dictval, b.get_attr('dict')) self.assertEquals(self.listval, b.get_attr('list')) # Reload directly b = Node(dbnode=a.dbnode) self.assertIsNone(a.get_attr('none')) self.assertEquals(self.boolval, b.get_attr('bool')) self.assertEquals(self.intval, b.get_attr('integer')) self.assertEquals(self.floatval, b.get_attr('float')) self.assertEquals(self.stringval, b.get_attr('string')) self.assertEquals(self.dictval, b.get_attr('dict')) self.assertEquals(self.listval, b.get_attr('list')) with self.assertRaises(ModificationNotAllowed): a._set_attr('i', 12)
def test_comments(self): # This is the best way to compare dates with the stored ones, instead of # directly loading datetime.datetime.now(), or you can get a # "can't compare offset-naive and offset-aware datetimes" error user = get_automatic_user() a = Node() with self.assertRaises(ModificationNotAllowed): a.add_comment('text', user=user) self.assertEquals(a.get_comments(), []) a.store() before = timezone.now() time.sleep(1) # I wait 1 second because MySql time precision is 1 sec a.add_comment('text', user=user) a.add_comment('text2', user=user) time.sleep(1) after = timezone.now() comments = a.get_comments() times = [i['mtime'] for i in comments] for t in times: self.assertTrue(t > before) self.assertTrue(t < after) self.assertEquals([(i['user__email'], i['content']) for i in comments], [ (user.email, 'text'), (user.email, 'text2'), ])
def fill_repo(self): from aiida.orm import JobCalculation, CalculationFactory, Data, DataFactory extra_name = self.__class__.__name__ + "/test_with_subclasses" calc_params = { 'computer': self.computer, 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 } } TemplateReplacerCalc = CalculationFactory( 'simpleplugins.templatereplacer') ParameterData = DataFactory('parameter') a1 = JobCalculation(**calc_params).store() # To query only these nodes later a1.set_extra(extra_name, True) a2 = TemplateReplacerCalc(**calc_params).store() # To query only these nodes later a2.set_extra(extra_name, True) a3 = Data().store() a3.set_extra(extra_name, True) a4 = ParameterData(dict={'a': 'b'}).store() a4.set_extra(extra_name, True) a5 = Node().store() a5.set_extra(extra_name, True) # I don't set the extras, just to be sure that the filtering works # The filtering is needed because other tests will put stuff int he DB a6 = JobCalculation(**calc_params) a6.store() a7 = Node() a7.store()
def test_with_subclasses(self, computer): extra_name = self.__class__.__name__ + "/test_with_subclasses" calc_params = { 'computer': computer, 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 } } TemplateReplacerCalc = CalculationFactory( 'simpleplugins.templatereplacer') ParameterData = DataFactory('parameter') a1 = JobCalculation(**calc_params).store() # To query only these nodes later a1.set_extra(extra_name, True) a2 = TemplateReplacerCalc(**calc_params).store() # To query only these nodes later a2.set_extra(extra_name, True) a3 = Data().store() a3.set_extra(extra_name, True) a4 = ParameterData(dict={'a': 'b'}).store() a4.set_extra(extra_name, True) a5 = Node().store() a5.set_extra(extra_name, True) # I don't set the extras, just to be sure that the filtering works # The filtering is needed because other tests will put stuff int he DB a6 = JobCalculation(**calc_params) a6.store() a7 = Node() a7.store() # Query by calculation results = list(JobCalculation.query(dbextras__key=extra_name)) # a3, a4, a5 should not be found because they are not JobCalculations. # a6, a7 should not be found because they have not the attribute set. self.assertEquals(set([i.pk for i in results]), set([a1.pk, a2.pk])) # Same query, but by the generic Node class results = list(Node.query(dbextras__key=extra_name)) self.assertEquals(set([i.pk for i in results]), set([a1.pk, a2.pk, a3.pk, a4.pk, a5.pk])) # Same query, but by the Data class results = list(Data.query(dbextras__key=extra_name)) self.assertEquals(set([i.pk for i in results]), set([a3.pk, a4.pk])) # Same query, but by the ParameterData subclass results = list(ParameterData.query(dbextras__key=extra_name)) self.assertEquals(set([i.pk for i in results]), set([a4.pk])) # Same query, but by the TemplateReplacerCalc subclass results = list(TemplateReplacerCalc.query(dbextras__key=extra_name)) self.assertEquals(set([i.pk for i in results]), set([a2.pk]))
def test_load_nodes(self): """ Test for load_node() function. """ from aiida.orm import load_node from aiida.common.exceptions import NotExistent import aiida.backends.sqlalchemy from aiida.backends.sqlalchemy import get_scoped_session a = Node() a.store() self.assertEquals(a.pk, load_node(node_id=a.pk).pk) self.assertEquals(a.pk, load_node(node_id=a.uuid).pk) self.assertEquals(a.pk, load_node(pk=a.pk).pk) self.assertEquals(a.pk, load_node(uuid=a.uuid).pk) session = get_scoped_session() try: session.begin_nested() with self.assertRaises(ValueError): load_node(node_id=a.pk, pk=a.pk) finally: session.rollback() try: session.begin_nested() with self.assertRaises(ValueError): load_node(pk=a.pk, uuid=a.uuid) finally: session.rollback() try: session.begin_nested() with self.assertRaises(ValueError): load_node(pk=a.uuid) finally: session.rollback() try: session.begin_nested() with self.assertRaises(ValueError): load_node(uuid=a.pk) finally: session.rollback() try: session.begin_nested() with self.assertRaises(ValueError): load_node() finally: session.rollback()
def test_session_wfdata(self): """ This test checks that the aiida.backends.sqlalchemy.models.workflow.DbWorkflowData#set_value method works as expected. There were problems with the DbNode object that was added as a value to a DbWorkflowData object. If there was an older version of the dbnode in the session than the one given to to the DbWorkflowData#set_value then there was a collision in the session and SQLA identity map. """ from aiida.orm.node import Node from aiida.workflows.test import WFTestSimpleWithSubWF from aiida.backends.sqlalchemy import get_scoped_session from aiida.orm.utils import load_node # Create a node and store it n = Node() n.store() # Keep some useful information n_id = n.id old_dbnode = n._dbnode # Get the session sess = get_scoped_session() # Remove everything from the session sess.expunge_all() # Create a workflow and store it wf = WFTestSimpleWithSubWF() wf.store() # Load a new version of the node n_reloaded = load_node(n_id) # Remove everything from the session sess.expunge_all() # Add the dbnode that was originally added to the session sess.add(old_dbnode) # Add as attribute the node that was added after the first cleanup # of the session # At this point the following command should not fail wf.add_attribute('a', n_reloaded)
def test_load_nodes(self): """ """ from aiida.orm import load_node from aiida.common.exceptions import NotExistent, InputValidationError a = Node() a.store() self.assertEquals(a.pk, load_node(pk=a.pk).pk) self.assertEquals(a.pk, load_node(uuid=a.uuid).pk) with self.assertRaises(InputValidationError): load_node(node_id=a.pk, pk=a.pk) with self.assertRaises(InputValidationError): load_node(pk=a.pk, uuid=a.uuid) with self.assertRaises(TypeError): load_node(pk=a.uuid) with self.assertRaises(TypeError): load_node(uuid=a.pk) with self.assertRaises(InputValidationError): load_node()
def test_attr_and_extras(self): a = Node() a._set_attr('bool', self.boolval) a._set_attr('integer', self.intval) a._set_attr('float', self.floatval) a._set_attr('string', self.stringval) a._set_attr('dict', self.dictval) a._set_attr('list', self.listval) with self.assertRaises(ModificationNotAllowed): # I did not store, I cannot modify a.set_extra('bool', 'blablabla') a.store() a_string = 'some non-boolean value' # I now set an extra with the same name of an attr a.set_extra('bool', a_string) # and I check that there is no name clash self.assertEquals(self.boolval, a.get_attr('bool')) self.assertEquals(a_string, a.get_extra('bool'))
def test_load_nodes(self): """ Test for load_node() function. """ a = Node() a.store() self.assertEquals(a.pk, load_node(node_id=a.pk).pk) self.assertEquals(a.pk, load_node(node_id=a.uuid).pk) self.assertEquals(a.pk, load_node(pk=a.pk).pk) self.assertEquals(a.pk, load_node(uuid=a.uuid).pk) with self.assertRaises(ValueError): load_node(node_id=a.pk, pk=a.pk) with self.assertRaises(ValueError): load_node(pk=a.pk, uuid=a.uuid) with self.assertRaises(ValueError): load_node(pk=a.uuid) with self.assertRaises(NotExistent): load_node(uuid=a.pk) with self.assertRaises(ValueError): load_node()
def test_datetime_attribute(self): from aiida.utils.timezone import (get_current_timezone, is_naive, make_aware, now) a = Node() date = now() a._set_attr('some_date', date) a.store() retrieved = a.get_attr('some_date') if is_naive(date): date_to_compare = make_aware(date, get_current_timezone()) else: date_to_compare = date # Do not compare microseconds (they are not stored in the case of MySQL) date_to_compare = date_to_compare.replace(microsecond=0) retrieved = retrieved.replace(microsecond=0) self.assertEquals(date_to_compare, retrieved)
def test_attr_listing(self): """ Checks that the list of attributes and extras is ok. """ a = Node() attrs_to_set = { 'none': None, 'bool': self.boolval, 'integer': self.intval, 'float': self.floatval, 'string': self.stringval, 'dict': self.dictval, 'list': self.listval, } for k, v in attrs_to_set.iteritems(): a._set_attr(k, v) a.store() # I now set extras extras_to_set = { 'bool': 'some non-boolean value', 'some_other_name': 987 } for k, v in extras_to_set.iteritems(): a.set_extra(k, v) self.assertEquals(set(a.attrs()), set(attrs_to_set.keys())) self.assertEquals(set(a.extras()), set(extras_to_set.keys())) returned_internal_attrs = {k: v for k, v in a.iterattrs()} self.assertEquals(returned_internal_attrs, attrs_to_set) returned_attrs = {k: v for k, v in a.iterextras()} self.assertEquals(returned_attrs, extras_to_set)
def test_folders(self): """ Similar as test_files, but I manipulate a tree of folders """ import tempfile import os, shutil import random, string a = Node() # Since Node uses the same method of Folder(), # for this test I create a test folder by hand # For any non-test usage, use SandboxFolder()! directory = os.path.realpath(os.path.join('/', 'tmp', 'tmp_try')) while os.path.exists(os.path.join(directory)): # I append a random letter/number until it is unique directory += random.choice(string.ascii_uppercase + string.digits) # create a folder structure to copy around tree_1 = os.path.join(directory, 'tree_1') os.makedirs(tree_1) file_content = 'some text ABCDE' file_content_different = 'other values 12345' with open(os.path.join(tree_1, 'file1.txt'), 'w') as f: f.write(file_content) os.mkdir(os.path.join(tree_1, 'dir1')) os.mkdir(os.path.join(tree_1, 'dir1', 'dir2')) with open(os.path.join(tree_1, 'dir1', 'file2.txt'), 'w') as f: f.write(file_content) os.mkdir(os.path.join(tree_1, 'dir1', 'dir2', 'dir3')) # add the tree to the node a.add_path(tree_1, 'tree_1') # verify if the node has the structure I expect self.assertEquals(set(a.get_folder_list()), set(['tree_1'])) self.assertEquals(set(a.get_folder_list('tree_1')), set(['file1.txt', 'dir1'])) self.assertEquals( set(a.get_folder_list(os.path.join('tree_1', 'dir1'))), set(['dir2', 'file2.txt'])) with open(a.get_abs_path(os.path.join('tree_1', 'file1.txt'))) as f: self.assertEquals(f.read(), file_content) with open(a.get_abs_path(os.path.join('tree_1', 'dir1', 'file2.txt'))) as f: self.assertEquals(f.read(), file_content) # try to exit from the folder with self.assertRaises(ValueError): a.get_folder_list('..') # copy into a new node b = a.copy() self.assertNotEquals(a.uuid, b.uuid) # Check that the content is there self.assertEquals(set(b.get_folder_list('.')), set(['tree_1'])) self.assertEquals(set(b.get_folder_list('tree_1')), set(['file1.txt', 'dir1'])) self.assertEquals( set(b.get_folder_list(os.path.join('tree_1', 'dir1'))), set(['dir2', 'file2.txt'])) with open(b.get_abs_path(os.path.join('tree_1', 'file1.txt'))) as f: self.assertEquals(f.read(), file_content) with open(b.get_abs_path(os.path.join('tree_1', 'dir1', 'file2.txt'))) as f: self.assertEquals(f.read(), file_content) # I overwrite a file and create a new one in the copy only dir3 = os.path.join(directory, 'dir3') os.mkdir(dir3) b.add_path(dir3, os.path.join('tree_1', 'dir3')) # no absolute path here with self.assertRaises(ValueError): b.add_path('dir3', os.path.join('tree_1', 'dir3')) with tempfile.NamedTemporaryFile() as f: f.write(file_content_different) f.flush() b.add_path(f.name, 'file3.txt') # I check the new content, and that the old one has not changed # old self.assertEquals(set(a.get_folder_list('.')), set(['tree_1'])) self.assertEquals(set(a.get_folder_list('tree_1')), set(['file1.txt', 'dir1'])) self.assertEquals( set(a.get_folder_list(os.path.join('tree_1', 'dir1'))), set(['dir2', 'file2.txt'])) with open(a.get_abs_path(os.path.join('tree_1', 'file1.txt'))) as f: self.assertEquals(f.read(), file_content) with open(a.get_abs_path(os.path.join('tree_1', 'dir1', 'file2.txt'))) as f: self.assertEquals(f.read(), file_content) # new self.assertEquals(set(b.get_folder_list('.')), set(['tree_1', 'file3.txt'])) self.assertEquals(set(b.get_folder_list('tree_1')), set(['file1.txt', 'dir1', 'dir3'])) self.assertEquals( set(b.get_folder_list(os.path.join('tree_1', 'dir1'))), set(['dir2', 'file2.txt'])) with open(b.get_abs_path(os.path.join('tree_1', 'file1.txt'))) as f: self.assertEquals(f.read(), file_content) with open(b.get_abs_path(os.path.join('tree_1', 'dir1', 'file2.txt'))) as f: self.assertEquals(f.read(), file_content) # This should in principle change the location of the files, # so I recheck a.store() # I now copy after storing c = a.copy() # I overwrite a file, create a new one and remove a directory # in the copy only with tempfile.NamedTemporaryFile() as f: f.write(file_content_different) f.flush() c.add_path(f.name, os.path.join('tree_1', 'file1.txt')) c.add_path(f.name, os.path.join('tree_1', 'dir1', 'file4.txt')) c.remove_path(os.path.join('tree_1', 'dir1', 'dir2')) # check old self.assertEquals(set(a.get_folder_list('.')), set(['tree_1'])) self.assertEquals(set(a.get_folder_list('tree_1')), set(['file1.txt', 'dir1'])) self.assertEquals( set(a.get_folder_list(os.path.join('tree_1', 'dir1'))), set(['dir2', 'file2.txt'])) with open(a.get_abs_path(os.path.join('tree_1', 'file1.txt'))) as f: self.assertEquals(f.read(), file_content) with open(a.get_abs_path(os.path.join('tree_1', 'dir1', 'file2.txt'))) as f: self.assertEquals(f.read(), file_content) # check new self.assertEquals(set(c.get_folder_list('.')), set(['tree_1'])) self.assertEquals(set(c.get_folder_list('tree_1')), set(['file1.txt', 'dir1'])) self.assertEquals( set(c.get_folder_list(os.path.join('tree_1', 'dir1'))), set(['file2.txt', 'file4.txt'])) with open(c.get_abs_path(os.path.join('tree_1', 'file1.txt'))) as f: self.assertEquals(f.read(), file_content_different) with open(c.get_abs_path(os.path.join('tree_1', 'dir1', 'file2.txt'))) as f: self.assertEquals(f.read(), file_content) # garbage cleaning shutil.rmtree(directory)
def test_links_and_queries(self): from aiida.backends.djsite.db.models import DbNode, DbLink a = Node() a._set_attr('myvalue', 123) a.store() a2 = Node().store() a3 = Node() a3._set_attr('myvalue', 145) a3.store() a4 = Node().store() a2.add_link_from(a) a3.add_link_from(a2) a4.add_link_from(a2) a4.add_link_from(a3) b = Node.query(pk=a2) self.assertEquals(len(b), 1) # It is a aiida.orm.Node instance self.assertTrue(isinstance(b[0], Node)) self.assertEquals(b[0].uuid, a2.uuid) going_out_from_a2 = Node.query(inputs__in=b) # Two nodes going out from a2 self.assertEquals(len(going_out_from_a2), 2) self.assertTrue(isinstance(going_out_from_a2[0], Node)) self.assertTrue(isinstance(going_out_from_a2[1], Node)) uuid_set = set([going_out_from_a2[0].uuid, going_out_from_a2[1].uuid]) # I check that I can query also directly the django DbNode # class passing a aiida.orm.Node entity going_out_from_a2_db = DbNode.objects.filter(inputs__in=b) self.assertEquals(len(going_out_from_a2_db), 2) self.assertTrue(isinstance(going_out_from_a2_db[0], DbNode)) self.assertTrue(isinstance(going_out_from_a2_db[1], DbNode)) uuid_set_db = set( [going_out_from_a2_db[0].uuid, going_out_from_a2_db[1].uuid]) # I check that doing the query with a Node or DbNode instance, # I get the same nodes self.assertEquals(uuid_set, uuid_set_db) # This time I don't use the __in filter, but I still pass a Node instance going_out_from_a2_bis = Node.query(inputs=b[0]) self.assertEquals(len(going_out_from_a2_bis), 2) self.assertTrue(isinstance(going_out_from_a2_bis[0], Node)) self.assertTrue(isinstance(going_out_from_a2_bis[1], Node)) # Query for links starting from b[0]==a2 using again the Node class output_links_b = DbLink.objects.filter(input=b[0]) self.assertEquals(len(output_links_b), 2) self.assertTrue(isinstance(output_links_b[0], DbLink)) self.assertTrue(isinstance(output_links_b[1], DbLink)) uuid_set_db_link = set( [output_links_b[0].output.uuid, output_links_b[1].output.uuid]) self.assertEquals(uuid_set, uuid_set_db_link) # Query for related fields using django syntax # Note that being myvalue an attribute, it is internally stored starting # with an underscore nodes_with_given_attribute = Node.query(dbattributes__key='myvalue', dbattributes__ival=145) # should be entry a3 self.assertEquals(len(nodes_with_given_attribute), 1) self.assertTrue(isinstance(nodes_with_given_attribute[0], Node)) self.assertEquals(nodes_with_given_attribute[0].uuid, a3.uuid)
def test_links_and_queries(self): a = Node() a._set_attr('myvalue', 123) a.store() a2 = Node().store() a3 = Node() a3._set_attr('myvalue', 145) a3.store() a4 = Node().store() a2.add_link_from(a) a3.add_link_from(a2) a4.add_link_from(a2) a4.add_link_from(a3) b = Node.query(id=a2.id).all() self.assertEquals(len(b), 1) # It is a aiida.orm.Node instance self.assertTrue(isinstance(b[0], Node)) self.assertEquals(b[0].uuid, a2.uuid) going_out_from_a2 = Node.query(inputs__id__in=[_.id for _ in b]).all() # Two nodes going out from a2 self.assertEquals(len(going_out_from_a2), 2) self.assertTrue(isinstance(going_out_from_a2[0], Node)) self.assertTrue(isinstance(going_out_from_a2[1], Node)) uuid_set = set([going_out_from_a2[0].uuid, going_out_from_a2[1].uuid]) # I check that I can query also directly the django DbNode # class passing a aiida.orm.Node entity # # XXX SP: we can't do this using SqlAlchemy => pass a Node instance and # # expect a filter on the DbNode id # going_out_from_a2_db = DbNode.query.filter(DbNode.inputs.in_(b)).all() # self.assertEquals(len(going_out_from_a2_db), 2) # self.assertTrue(isinstance(going_out_from_a2_db[0], DbNode)) # self.assertTrue(isinstance(going_out_from_a2_db[1], DbNode)) # uuid_set_db = set([going_out_from_a2_db[0].uuid, # going_out_from_a2_db[1].uuid]) # # # I check that doing the query with a Node or DbNode instance, # # I get the same nodes # self.assertEquals(uuid_set, uuid_set_db) # # # This time I don't use the __in filter, but I still pass a Node instance # going_out_from_a2_bis = Node.query(inputs=b[0]).all() # self.assertEquals(len(going_out_from_a2_bis), 2) # self.assertTrue(isinstance(going_out_from_a2_bis[0], Node)) # self.assertTrue(isinstance(going_out_from_a2_bis[1], Node)) # # # Query for links starting from b[0]==a2 using again the Node class # output_links_b = DbLink.query.filter_by(input=b[0]) # self.assertEquals(len(output_links_b), 2) # self.assertTrue(isinstance(output_links_b[0], DbLink)) # self.assertTrue(isinstance(output_links_b[1], DbLink)) # uuid_set_db_link = set([output_links_b[0].output.uuid, # output_links_b[1].output.uuid]) # self.assertEquals(uuid_set, uuid_set_db_link) # Query for related fields using django syntax # Note that being myvalue an attribute, it is internally stored starting # with an underscore nodes_with_given_attribute = Node.query(dbattributes__key='myvalue', dbattributes__ival=145).all() # should be entry a3 self.assertEquals(len(nodes_with_given_attribute), 1) self.assertTrue(isinstance(nodes_with_given_attribute[0], Node)) self.assertEquals(nodes_with_given_attribute[0].uuid, a3.uuid)
def test_attributes_on_copy(self): import copy a = Node() attrs_to_set = { 'none': None, 'bool': self.boolval, 'integer': self.intval, 'float': self.floatval, 'string': self.stringval, 'dict': self.dictval, 'list': self.listval, 'emptydict': {}, 'emptylist': [], } for k, v in attrs_to_set.iteritems(): a._set_attr(k, v) a.store() # I now set extras extras_to_set = { 'bool': 'some non-boolean value', 'some_other_name': 987 } for k, v in extras_to_set.iteritems(): a.set_extra(k, v) # I make a copy b = a.copy() # I modify an attribute and add a new one; I mirror it in the dictionary # for later checking b_expected_attributes = copy.deepcopy(attrs_to_set) b._set_attr('integer', 489) b_expected_attributes['integer'] = 489 b._set_attr('new', 'cvb') b_expected_attributes['new'] = 'cvb' # I check before storing that the attributes are ok self.assertEquals({k: v for k, v in b.iterattrs()}, b_expected_attributes) # Note that during copy, I do not copy the extras! self.assertEquals({k: v for k, v in b.iterextras()}, {}) # I store now b.store() # and I finally add a extras b.set_extra('meta', 'textofext') b_expected_extras = {'meta': 'textofext'} # Now I check for the attributes # First I check that nothing has changed self.assertEquals({k: v for k, v in a.iterattrs()}, attrs_to_set) self.assertEquals({k: v for k, v in a.iterextras()}, extras_to_set) # I check then on the 'b' copy self.assertEquals({k: v for k, v in b.iterattrs()}, b_expected_attributes) self.assertEquals({k: v for k, v in b.iterextras()}, b_expected_extras)
def test_files(self): import tempfile a = Node() file_content = 'some text ABCDE' file_content_different = 'other values 12345' with tempfile.NamedTemporaryFile() as f: f.write(file_content) f.flush() a.add_path(f.name, 'file1.txt') a.add_path(f.name, 'file2.txt') self.assertEquals(set(a.get_folder_list()), set(['file1.txt', 'file2.txt'])) with open(a.get_abs_path('file1.txt')) as f: self.assertEquals(f.read(), file_content) with open(a.get_abs_path('file2.txt')) as f: self.assertEquals(f.read(), file_content) b = a.copy() self.assertNotEquals(a.uuid, b.uuid) # Check that the content is there self.assertEquals(set(b.get_folder_list()), set(['file1.txt', 'file2.txt'])) with open(b.get_abs_path('file1.txt')) as f: self.assertEquals(f.read(), file_content) with open(b.get_abs_path('file2.txt')) as f: self.assertEquals(f.read(), file_content) # I overwrite a file and create a new one in the copy only with tempfile.NamedTemporaryFile() as f: f.write(file_content_different) f.flush() b.add_path(f.name, 'file2.txt') b.add_path(f.name, 'file3.txt') # I check the new content, and that the old one has not changed self.assertEquals(set(a.get_folder_list()), set(['file1.txt', 'file2.txt'])) with open(a.get_abs_path('file1.txt')) as f: self.assertEquals(f.read(), file_content) with open(a.get_abs_path('file2.txt')) as f: self.assertEquals(f.read(), file_content) self.assertEquals(set(b.get_folder_list()), set(['file1.txt', 'file2.txt', 'file3.txt'])) with open(b.get_abs_path('file1.txt')) as f: self.assertEquals(f.read(), file_content) with open(b.get_abs_path('file2.txt')) as f: self.assertEquals(f.read(), file_content_different) with open(b.get_abs_path('file3.txt')) as f: self.assertEquals(f.read(), file_content_different) # This should in principle change the location of the files, # so I recheck a.store() # I now copy after storing c = a.copy() # I overwrite a file and create a new one in the copy only with tempfile.NamedTemporaryFile() as f: f.write(file_content_different) f.flush() c.add_path(f.name, 'file1.txt') c.add_path(f.name, 'file4.txt') self.assertEquals(set(a.get_folder_list()), set(['file1.txt', 'file2.txt'])) with open(a.get_abs_path('file1.txt')) as f: self.assertEquals(f.read(), file_content) with open(a.get_abs_path('file2.txt')) as f: self.assertEquals(f.read(), file_content) self.assertEquals(set(c.get_folder_list()), set(['file1.txt', 'file2.txt', 'file4.txt'])) with open(c.get_abs_path('file1.txt')) as f: self.assertEquals(f.read(), file_content_different) with open(c.get_abs_path('file2.txt')) as f: self.assertEquals(f.read(), file_content) with open(c.get_abs_path('file4.txt')) as f: self.assertEquals(f.read(), file_content_different)