Exemple #1
0
    def test_safe_manipulation(self):
        """
        test whether additions and deletions while a Group is being
        iterated is done lazy and only when the iterations are finished
        """
        a = Agent(name="a_name")
        b = Agent(name="b_name")
        c = Agent(name="c_name")
        # create group in Space
        my_group = self.testing_group([a, b])
        for i, j in enumerate(my_group):
            for k in my_group:
                if j is a:
                    # do  only once
                    my_group.discard(a)
                    res = my_group.add_as_child(c)
                    # shows that while in loop operation is delayed
                    self.assertIsNone(res)
            with self.subTest(i=i):
                # while in loop no changes are done
                self.assertTrue(a in my_group)
                self.assertTrue(c not in my_group)
        # changes are done after all loops are done
        self.assertTrue(a not in my_group)
        self.assertTrue(b in my_group)
        self.assertTrue(c in my_group)

        d = Agent(name="d_name")
        res = my_group.add_as_child(d)
        # shows that while in not in loop operation is not delayed
        self.assertIsNotNone(res)
Exemple #2
0
    def test_Group(self):
        """test group can check and retrieve correct objects"""
        a = Agent(name="a_name")
        b = Agent()
        not_in = Agent()
        # now objects are not in outer Space but
        # now are registered as inside the group
        my_group = self.testing_group([a, b])
        # test group inclusion and exclusion
        # by the object itself
        self.assertTrue(a in my_group)
        self.assertTrue(b in my_group)
        self.assertFalse(not_in in my_group)
        self.assertTrue(not_in not in my_group)
        # by their names
        self.assertTrue(a.name in my_group)
        self.assertTrue(b.name in my_group)
        self.assertFalse(not_in.name in my_group)
        self.assertTrue(not_in.name not in my_group)

        # change names and test again inclusion and exclusion
        b.name = b.name + "_changed"
        self.assertTrue(b in my_group)
        self.assertTrue(b.name in my_group)
        a_old_name = a.name
        a.name = a.name + "_changed"
        self.assertTrue(a in my_group)
        self.assertTrue(a.name in my_group)
        not_in.name = a_old_name
        self.assertFalse(not_in in my_group)
        self.assertFalse(not_in.name in my_group)

        # now objects are not only registered as inside the group
        # but the group is their parent
        my_group.update([a, b], as_parent=True)
        # by the object itself
        self.assertTrue(a in my_group)
        self.assertTrue(b in my_group)
        self.assertFalse(not_in in my_group)
        self.assertTrue(not_in not in my_group)
        # by their names
        self.assertTrue(a.name in my_group)
        self.assertTrue(b.name in my_group)
        self.assertFalse(not_in.name in my_group)
        self.assertTrue(not_in.name not in my_group)

        # now that "a" is a child of my_group
        # not_in which is a child of Space can have the same name as "a"
        not_in.name = a.name
        self.assertFalse(not_in in my_group)

        # there is no way to know by name that they are different objects
        self.assertTrue(not_in.name in my_group)
Exemple #3
0
    def test_hierarchy(self):
        """test group can form space hierarchies without risk of mangling
            names or not reflecting the space as it should be"""
        # both are in Space
        a = Agent(name="a_name")
        b = Agent()
        with self.assertRaises(KeyError):
            # name already exists in parent Space
            b.name = "a_name"

        # create group in Space
        my_group = self.testing_group()
        # b added as child, so moved in hierarchy
        my_group.add_as_child(b)

        with self.assertNotRaises(KeyError):
            # b can change to the same name like a
            # since it is in another hierarchy under Group
            b.name = "a_name"

        with self.assertRaises(KeyError):
            # a name already exists in parent Group since
            # b has the same name
            my_group.add_as_child(a)

        a.name = "a_name_changed"

        with self.assertNotRaises(KeyError):
            # a name has no conflict now
            my_group.add_as_child(a)

        with self.assertRaises(KeyError):
            # a name cannot change to a name that is in the Group
            a.name = b.name
Exemple #4
0
    def test_space_deletions(self):
        no_agents = 5
        no_groups = 5
        agents = [Agent() for _ in range(no_agents)]
        groups = [self.testing_group(agents, as_contained=choice((False, True)),
                                     as_parent=choice((False, True)))
                  for _ in range(no_groups)]
        for a in agents:
            for g in groups:
                self.assertTrue(a in g, "failed a step to prove test")
            a._space_delete()
            for g in groups:
                self.assertFalse(a in g, "failed to delete agent in {}".format(g))
            remaining = len(a._space_name_handles)
            self.assertFalse(remaining, "still remain {} handles".format(remaining))

        # test all
        groups = [self.testing_group(agents, as_contained=choice((False, True)),
                                     as_parent=choice((False, True)))
                  for _ in range(no_groups)]
        groups[0].clear_in_space()
        for g in groups:
            self.assertFalse(len(g), "group '{}' is not empty".format(g))
Exemple #5
0
    def test_parenting(self):
        """test that there won't be name or parent corruption when
        the parent of an Agent is changed"""

        # all are in Space
        a = Agent(name="a_name")
        b = Agent(name="b_name")
        with self.assertRaises(ValueError):
            # parent cannot be itself
            a._space_parent = a

        b._space_parent = a
        bb = Agent(name="b_name")
        # test child of the same name in future parent
        with self.assertRaises(KeyError):
            # parent has child of the same name
            bb._space_parent = a
        with self.assertRaises(KeyError):
            # parent has child of the same name
            b._space_parent = None  # equivalent to Space

        del bb  # delete the cause of the conflict
        with self.assertNotRaises(KeyError):
            # parent has child of the same name
            b._space_parent = None  # equivalent to Space

        # test cross reference
        a._space_parent = b
        with self.assertRaises(ValueError):
            # a has already b as parent
            # so b cannot be child of a
            b._space_parent = a

        # test circular reference
        c = Agent()
        a._space_parent = b  # b is the parent of a
        b._space_parent = c  # c is the parent of b
        # c -> b -> a
        with self.assertRaises(ValueError):
            # a cannot be parent of one of its ancestors
            # a -> c
            c._space_parent = a  # a wants to be the parent of c

        d = Agent()
        d._space_parent = a  # a is the parent of d
        # c -> b -> a -> d
        with self.assertRaises(ValueError):
            # d -> b
            b._space_parent = d  # d wants to be the parent of c
Exemple #6
0
    def test_compare(self):
        """
        typical output:

        updating Group with 1000 items: 0.066299 seconds
        Group size 1.84 MB, program 82.00 MB, 1.03% of total memory
        getting agent by index 100 times in Group: 0.005021 seconds which are: i0=0.142 ms, i10=0.049 ms, i20=0.047 ms, i30=0.047 ms, i40=0.047 ms, i50=0.047 ms, i60=0.046 ms, i70=0.047 ms, i80=0.046 ms, i90=0.046 ms, i100=0.047 ms, i110=0.046 ms, i120=0.046 ms, i130=0.046 ms, i140=0.046 ms, i150=0.046 ms, i160=0.046 ms, i170=0.047 ms, i180=0.046 ms, i190=0.057 ms, i200=0.057 ms, i210=0.056 ms, i220=0.057 ms, i230=0.047 ms, i240=0.047 ms, i250=0.046 ms, i260=0.046 ms, i270=0.046 ms, i280=0.046 ms, i290=0.046 ms, i300=0.056 ms, i310=0.057 ms, i320=0.047 ms, i330=0.046 ms, i340=0.046 ms, i350=0.046 ms, i360=0.048 ms, i370=0.046 ms, i380=0.047 ms, i390=0.046 ms, i400=0.046 ms, i410=0.059 ms, i420=0.050 ms, i430=0.066 ms, i440=0.047 ms, i450=0.047 ms, i460=0.046 ms, i470=0.046 ms, i480=0.046 ms, i490=0.046 ms, i500=0.046 ms, i510=0.046 ms, i520=0.046 ms, i530=0.046 ms, i540=0.046 ms, i550=0.046 ms, i560=0.046 ms, i570=0.046 ms, i580=0.046 ms, i590=0.046 ms, i600=0.046 ms, i610=0.046 ms, i620=0.046 ms, i630=0.046 ms, i640=0.046 ms, i650=0.046 ms, i660=0.046 ms, i670=0.046 ms, i680=0.046 ms, i690=0.046 ms, i700=0.046 ms, i710=0.046 ms, i720=0.046 ms, i730=0.046 ms, i740=0.046 ms, i750=0.046 ms, i760=0.097 ms, i770=0.081 ms, i780=0.072 ms, i790=0.052 ms, i800=0.051 ms, i810=0.051 ms, i820=0.073 ms, i830=0.079 ms, i840=0.061 ms, i850=0.047 ms, i860=0.046 ms, i870=0.046 ms, i880=0.047 ms, i890=0.047 ms, i900=0.046 ms, i910=0.046 ms, i920=0.046 ms, i930=0.046 ms, i940=0.046 ms, i950=0.046 ms, i960=0.046 ms, i970=0.046 ms, i980=0.046 ms, i990=0.046 ms
        getting agent by value 100 times in Group: 0.000555 seconds
        getting agent by name 100 times in Group: 0.000281 seconds
        iterating 1000 items in Group 0.000134 seconds
        changing agent name 100 times when Group is used: 0.039076 seconds
        reversing 1000 items in Group 0.000331 seconds
        discarding 100 items by value in Group 0.000508 seconds
        discarding 100 items by name in Group 0.000491 seconds
        discarding 100 items by index in Group 0.005079 seconds
        clearing 700 items in Group 0.000507 seconds

        updating CompleteGroup with 1000 items: 0.129765 seconds
        CompleteGroup size 1.93 MB, program 82.11 MB, 1.04% of total memory
        getting agent by index 100 times in CompleteGroup: 0.000164 seconds which are: i0=0.010 ms, i10=0.002 ms, i20=0.002 ms, i30=0.002 ms, i40=0.001 ms, i50=0.002 ms, i60=0.002 ms, i70=0.002 ms, i80=0.002 ms, i90=0.002 ms, i100=0.001 ms, i110=0.001 ms, i120=0.002 ms, i130=0.002 ms, i140=0.002 ms, i150=0.002 ms, i160=0.002 ms, i170=0.002 ms, i180=0.001 ms, i190=0.001 ms, i200=0.001 ms, i210=0.002 ms, i220=0.001 ms, i230=0.002 ms, i240=0.001 ms, i250=0.001 ms, i260=0.002 ms, i270=0.001 ms, i280=0.001 ms, i290=0.001 ms, i300=0.002 ms, i310=0.001 ms, i320=0.002 ms, i330=0.002 ms, i340=0.002 ms, i350=0.001 ms, i360=0.002 ms, i370=0.002 ms, i380=0.001 ms, i390=0.001 ms, i400=0.001 ms, i410=0.002 ms, i420=0.001 ms, i430=0.001 ms, i440=0.001 ms, i450=0.001 ms, i460=0.001 ms, i470=0.002 ms, i480=0.002 ms, i490=0.001 ms, i500=0.001 ms, i510=0.002 ms, i520=0.001 ms, i530=0.001 ms, i540=0.002 ms, i550=0.002 ms, i560=0.002 ms, i570=0.001 ms, i580=0.001 ms, i590=0.002 ms, i600=0.001 ms, i610=0.001 ms, i620=0.002 ms, i630=0.002 ms, i640=0.001 ms, i650=0.002 ms, i660=0.002 ms, i670=0.001 ms, i680=0.001 ms, i690=0.001 ms, i700=0.002 ms, i710=0.001 ms, i720=0.001 ms, i730=0.002 ms, i740=0.002 ms, i750=0.002 ms, i760=0.002 ms, i770=0.001 ms, i780=0.002 ms, i790=0.001 ms, i800=0.001 ms, i810=0.002 ms, i820=0.002 ms, i830=0.002 ms, i840=0.002 ms, i850=0.001 ms, i860=0.001 ms, i870=0.001 ms, i880=0.001 ms, i890=0.001 ms, i900=0.002 ms, i910=0.002 ms, i920=0.002 ms, i930=0.001 ms, i940=0.001 ms, i950=0.001 ms, i960=0.002 ms, i970=0.001 ms, i980=0.002 ms, i990=0.001 ms
        getting agent by value 100 times in CompleteGroup: 0.000199 seconds
        getting agent by name 100 times in CompleteGroup: 0.000131 seconds
        iterating 1000 items in CompleteGroup 0.000125 seconds
        changing agent name 100 times when CompleteGroup is used: 0.003896 seconds
        reversing 1000 items in CompleteGroup 0.000127 seconds
        discarding 100 items by value in CompleteGroup 0.015910 seconds
        discarding 100 items by name in CompleteGroup 0.014403 seconds
        discarding 100 items by index in CompleteGroup 0.014663 seconds
        clearing 700 items in CompleteGroup 0.002078 seconds

        medium data:

        updating Group with 10000 items: 0.734338 seconds
        Group size 18.20 MB, program 100.61 MB, 1.27% of total memory
        getting agent by index 1000 times in Group: 1.686387 seconds
        getting agent by value 1000 times in Group: 0.006331 seconds
        getting agent by name 1000 times in Group: 0.002857 seconds
        iterating 10000 items in Group 0.002547 seconds
        changing agent name 1000 times when Group is used: 12.072925 seconds
        reversing 10000 items in Group 0.007429 seconds
        discarding 1000 items by value in Group 0.005666 seconds
        discarding 1000 items by name in Group 0.005351 seconds
        discarding 1000 items by index in Group 1.279876 seconds
        clearing 7000 items in Group 0.007442 seconds

        updating CompleteGroup with 10000 items: 7.216077 seconds
        CompleteGroup size 18.85 MB, program 114.74 MB, 1.45% of total memory
        getting agent by index 1000 times in CompleteGroup: 0.003818 seconds
        getting agent by value 1000 times in CompleteGroup: 0.003106 seconds
        getting agent by name 1000 times in CompleteGroup: 0.004088 seconds
        iterating 10000 items in CompleteGroup 0.002455 seconds
        changing agent name 1000 times when CompleteGroup is used: 0.058381 seconds
        reversing 10000 items in CompleteGroup 0.002732 seconds
        discarding 1000 items by value in CompleteGroup 3.114873 seconds
        discarding 1000 items by name in CompleteGroup 2.070081 seconds
        discarding 1000 items by index in CompleteGroup 1.607720 seconds
        clearing 7000 items in CompleteGroup 0.135715 seconds

        big data:

        updating Group with 100000 items: 5.975632 seconds
        Group size 172.69 MB, program 312.57 MB, 3.94% of total memory
        getting agent by index 5 times in Group: 0.126789 seconds
        getting agent by value 5 times in Group: 0.000072 seconds
        getting agent by name 5 times in Group: 0.000022 seconds
        iterating 100000 items in Group 0.032963 seconds
        reversing 100000 items in Group 0.118575 seconds
        getting agent by value 5 times in Group: 0.000088 seconds
        discarding 10000 items in Group 0.101913 seconds
        clearing 90000 items in Group 0.096648 seconds

        updating CompleteGroup with 100000 items: 721.883513 seconds
        CompleteGroup size 183.48 MB, program 382.79 MB, 4.83% of total memory
        getting agent by index 5 times in CompleteGroup: 0.000023 seconds
        getting agent by value 5 times in CompleteGroup: 0.000021 seconds
        getting agent by name 5 times in CompleteGroup: 0.000027 seconds
        iterating 100000 items in CompleteGroup 0.010987 seconds
        reversing 100000 items in CompleteGroup 0.022679 seconds
        getting agent by value 5 times in CompleteGroup: 0.090463 seconds
        discarding 10000 items in CompleteGroup 333.245388 seconds
        clearing 90000 items in CompleteGroup 0.058000 seconds
        """

        no_insertions = 1000
        agents_base = [Agent() for _ in range(no_insertions)]
        for g in self.groups:
            agents = agents_base.copy()
            name = g.__class__.__name__
            with TimeCode("updating {} with {} items: ".format(name, len(agents))):
                g.update(agents, as_parent=True, as_contained=True)
            my_size = bytes2MB(pympler.asizeof.asizeof(g))
            percentage, used = memory_usage_psutil()
            print("{} size {:.2f} MB, program {:.2f} MB, {:.2f}% of total "
                  "memory".format(name, my_size, used, percentage))

            step = 10
            indices = list(range(0, no_insertions, step))
            a_rev = [agents[i] for i in indices]
            retrieval_times = []
            printed = []
            pf = lambda x: printed.append(x)
            with TimeCode("getting agent by index {} times in {}: ".format(len(indices), name), printfunc=pf) as tc:
                # retrieval time test
                for i in indices:
                    tc.start_cummulative()
                    g[i]
                    tc.end_cummulative()
                    retrieval_times.append((i, tc.time_end))
            printed[-1] = printed[-1].strip()
            #printed.append(" which are:")
            #printed.append(",".join(" i{}={}".format(i, Magnitude(j, unit="s", factor="m", precision=3)) for i, j in retrieval_times))
            printed.append("\n")
            for i in printed:
                print(i, end="")
            # real retrieval test
            for i, (j, a) in enumerate(zip(indices, a_rev)):
                #with self.subTest(i=i):
                self.assertIs(a, g[j], "failed retrieval by index in {}".format(name))
                self.assertTrue(j==g.index(a), "failed retrieval of index in {}".format(name))

            with TimeCode("getting agent by value {} times in {}: ".format(len(indices), name)):
                # object inside time test
                for a in a_rev:
                    g[a]
            # real object inside test
            for i, a in enumerate(a_rev):
                #with self.subTest(i=i):
                self.assertIs(a, g[a], "failed retrieval by object in {}".format(name))

            with TimeCode("getting agent by name {} times in {}: ".format(len(indices), name)):
                # retrieval by name time test
                for a in a_rev:
                    g[a.name]
            # real retrieval by name test
            for i, a in enumerate(a_rev):
                #with self.subTest(i=i):
                self.assertIs(a, g[a.name], "failed retrieval by name in {}".format(name))

            with TimeCode("iterating {} items in {} ".format(len(agents), name)):
                for i in g:
                    i

            with TimeCode("changing agent name {} times when {} is used: ".format(len(indices), name)):
                # retrieval by name time test
                for a in a_rev:
                    a.name = a.name + "_changed"
            # real retrieval by name test
            for i, (j, a) in enumerate(zip(indices, a_rev)):
                #with self.subTest(i=i):
                self.assertIs(a, g[a.name], "failed retrieval by name when name changed in {}".format(name))
                self.assertIs(agents[j], g[j], "failed retrieval by index when name changed in {}".format(name))
                self.assertTrue(j==g.index(a), "failed retrieval of index when name changed in {}".format(name))

            with TimeCode("reversing {} items in {} ".format(len(agents), name)):
                g.reverse()

            agents.reverse()  # reflect the changes in the group
            # test reverse values
            for i, a in enumerate(g):
                #with self.subTest(i=i):
                cmp_a = agents[i]
                self.assertIs(a, cmp_a, "failed reverse comparison by iteration in {}".format(name))
                self.assertTrue(g.index(a) == i, "failed reverse comparison by index in {}".format(name))

            # real object discarding test
            to_discard = int(no_insertions*0.1)  # delete 10%
            indices_discard = range(to_discard)
            with TimeCode("discarding {} items by value in {} ".format(to_discard, name)) as tc:
                for i, j in enumerate(indices_discard):
                    a = agents[j]
                    del agents[j]  # reflect the changes in the group
                    tc.start_cummulative()
                    g.discard(a)
                    tc.end_cummulative()
                    #with self.subTest(i=i):
                    self.assertFalse(a in g, "failed discarding of object by value in {}".format(name))

            # real object discarding test
            to_discard = int(no_insertions*0.1)  # delete 10%
            indices_discard = range(to_discard)
            with TimeCode("discarding {} items by name in {} ".format(to_discard, name)) as tc:
                for i, j in enumerate(indices_discard):
                    a = agents[j]
                    del agents[j]  # reflect the changes in the group
                    tc.start_cummulative()
                    g.discard(a.name)
                    tc.end_cummulative()
                    #with self.subTest(i=i):
                    self.assertFalse(a in g, "failed discarding of object by name in {}".format(name))

            # real object discarding test
            to_discard = int(no_insertions*0.1)  # delete 10%
            indices_discard = range(to_discard)
            with TimeCode("discarding {} items by index in {} ".format(to_discard, name)) as tc:
                for i, j in enumerate(indices_discard):
                    a = agents[j]
                    del agents[j]  # reflect the changes in the group
                    tc.start_cummulative()
                    g.discard(g[j])  # discard only accept name or object
                    tc.end_cummulative()
                    #with self.subTest(i=i):
                    self.assertFalse(a in g, "failed discarding of object by index in {}".format(name))

            with TimeCode("clearing {} items in {} ".format(len(agents), name)):
                g.clear()
            self.assertTrue(len(g) == 0, "failed to clear {}".format(name))
            print("")
Exemple #7
0
    def test_safe_manipulation_with_statement(self):
        """
        This tests the with context with Groups. It demonstrates
        that Groups is thread safe.
        This method sleeps randomly and do not reflect the
         real performance of the Group
        """
        def iterate(group, l):
            if choice((True, False)):
                # sleep enough time to let the other process advance
                sleep(random()/3)
            for i in group:
                l.append(i)

        no_tests = 10
        for no_t in range(no_tests):
            test_order = []
            max_first_insertion = no_t
            insertions = [Agent() for _ in
                          range(int(1 + random() * max_first_insertion))]
            my_group = self.testing_group(insertions)
            first_len = len(my_group)
            t = Thread(target=iterate, args=(my_group, test_order))
            t.start()
            with my_group:
                # in this context the Group should ensure that any operation
                # will be executed when there is not iteration with the
                # Group and that it is secure to do proceed with deletions and
                # additions

                second_len = len(test_order)

                # add operations here
                maping = {}
                no_insertions = int(random() * max_first_insertion)
                for i in range(no_insertions):
                    # ensure method returns something besides None
                    new_agent = Agent()
                    # this can be anything and hopefully except None
                    res = my_group.add(new_agent)
                    with self.subTest(i=i):
                        self.assertIsNotNone(res)
                    test_order.append(res)
                    maping[new_agent] = res  # map custom results

                no_deletions = no_insertions / 2
                for _ in range(int(random() * no_deletions)):
                    # a = choice(insertions)
                    # ensure method returns something besides None
                    a = my_group.pop()
                    with self.assertNotRaises(ValueError,
                        msg="list.remove(x): x not in list, x={}".format(a)):
                        test_order.remove(maping.pop(a))

                # calculate how many operations
                insertion_len = len(test_order) - second_len

            t.join()  # wait until thread finishes
            if len(test_order) == first_len + insertion_len:
                # operations after iteration
                self.assertFalse([i for i in test_order if i is None])
            elif len(test_order) == first_len + insertion_len*2:
                # operations before iteration
                self.assertFalse([i for i in test_order if i is None])
            else:
                self.assertTrue(False, msg="Test lock failed in try {}".format(no_t+1))
Exemple #8
0
    def test_hierarchy(self):
        """test that there won't be name corruption in hierarchy
        when a name is introduced or changed no matter the place
        or where the name is being changed from"""

        # both are in Space
        a = Agent(name="a_name")
        b = Agent()
        with self.assertRaises(KeyError):
            # name already exists in parent Space
            b.name = "a_name"

        # created group in Sapce
        my_group = Agent()  # my_group = Group()
        # b added as child, so moved in hierarchy
        b._space_parent = my_group  # my_group.add_as_child(b)

        with self.assertNotRaises(KeyError):
            # b can change to the same name like a
            # since it is in another hierarchy under Group
            b.name = "a_name"

        with self.assertRaises(KeyError):
            # a name already exists in parent Group since
            # b has the same name
            a._space_parent = my_group  # my_group.add_as_child(a)

        a.name = "a_name_changed"

        with self.assertNotRaises(KeyError):
            # a name has no conflict now
            a._space_parent = my_group  # my_group.add_as_child(a)

        with self.assertRaises(KeyError):
            # a name cannot change to a name that is in the Group
            a.name = b.name