Beispiel #1
0
    async def test_update(self):
        source = fake_controller_source.FakeControllerSource()
        _FROM = "from"
        _TO = "to"
        allowed_transitions = {(_FROM, _TO), (_TO, _TO), (_FROM, _FROM)}

        def pod(name, check, final):
            labels = {"check": check}
            if final:
                labels["final"] = "true"
            return V1Pod(metadata=V1ObjectMeta(name=name, labels=labels))

        def delete_pod(p):
            return p.metadata.labels["final"] == "true"

        async def test(name):
            name = f"a-{name}"
            await source.add(pod(name, _FROM, False))
            await source.modify(pod(name, _TO, True))

        tests = [test]
        threads = 3
        size = threads * len(tests)
        test_done_queue = asyncio.Queue(maxsize=size)
        for _ in range(size):
            test_done_queue.put_nowait(None)

        watch_event = asyncio.Event()

        async def watch_func(options):
            try:
                return await source.watch(options)
            finally:
                watch_event.set()

        async def update_func(old_obj, new_obj):
            from_ = old_obj.metadata.labels["check"]
            to = new_obj.metadata.labels["check"]
            self.assertIn((from_, to), allowed_transitions)
            if delete_pod(new_obj):
                await source.delete(new_obj)

        async def delete_func(obj):
            test_done_queue.task_done()

        lw = TestLW(source.list, watch_func)
        h = ResourceEventHandlerFuncs(update_func=update_func, delete_func=delete_func)
        _, controller = new_informer(lw, V1Pod, 0, h)

        controller_task = asyncio.ensure_future(controller.run())
        await watch_event.wait()

        aws = [f(f"{i}-{j}") for i in range(threads) for j, f in enumerate(tests)]
        await asyncio.gather(*aws)
        await test_done_queue.join()
        controller_task.cancel()
        await asyncio.gather(controller_task, return_exceptions=True)
Beispiel #2
0
    async def test_initialization_race(self):
        source = fake_controller_source.FakeControllerSource()
        informer = new_shared_informer(source, V1Pod, 1)
        listener = TestListener("race_listener", 0)

        asyncio.ensure_future(
            informer.add_event_handler(listener,
                                       resync_period=listener._resync_period))
        task = asyncio.ensure_future(informer.run())
        task.cancel()
Beispiel #3
0
    async def test_listener_resync_periods(self):
        source = fake_controller_source.FakeControllerSource()
        await source.add(V1Pod(metadata=V1ObjectMeta(name="pod1")))
        await source.add(V1Pod(metadata=V1ObjectMeta(name="pod2")))

        informer = new_shared_informer(source, V1Pod, 1)

        clock_ = clock.FakeClock(time.time())
        informer._clock = clock_
        informer._processor._clock = clock_

        listener1 = TestListener("listener1", 0, "pod1", "pod2")
        await informer.add_event_handler(
            listener1, resync_period=listener1._resync_period)

        listener2 = TestListener("listener2", 2, "pod1", "pod2")
        await informer.add_event_handler(
            listener2, resync_period=listener2._resync_period)

        listener3 = TestListener("listener3", 3, "pod1", "pod2")
        await informer.add_event_handler(
            listener3, resync_period=listener3._resync_period)
        listeners = [listener1, listener2, listener3]

        try:
            task = asyncio.ensure_future(informer.run())

            for listener in listeners:
                self.assertTrue(await listener._ok())

            for listener in listeners:
                listener._received_item_names = []

            await clock_.step(2)
            self.assertTrue(await listener2._ok())

            await asyncio.sleep(1)
            self.assertEqual(len(listener1._received_item_names), 0)
            self.assertEqual(len(listener3._received_item_names), 0)

            for listener in listeners:
                listener._received_item_names = []

            await clock_.step(1)
            self.assertTrue(await listener3._ok())

            await asyncio.sleep(1)
            self.assertEqual(len(listener1._received_item_names), 0)
            self.assertEqual(len(listener2._received_item_names), 0)
        finally:
            task.cancel()
            await asyncio.gather(task, return_exceptions=True)
Beispiel #4
0
    async def test_resync_check_period(self):
        source = fake_controller_source.FakeControllerSource()
        informer = new_shared_informer(source, V1Pod, 12 * 3600)

        clock_ = clock.FakeClock(time.time())
        informer._clock = clock_
        informer._processor._clock = clock_

        listener1 = TestListener("listener1", 0)
        await informer.add_event_handler(
            listener1, resync_period=listener1._resync_period)
        self.assertEqual(informer._resync_check_period, 12 * 3600)
        self.assertEqual(informer._processor._listeners[0]._resync_period, 0)

        listener2 = TestListener("listener2", 60)
        await informer.add_event_handler(
            listener2, resync_period=listener2._resync_period)
        self.assertEqual(informer._resync_check_period, 60)
        self.assertEqual(informer._processor._listeners[0]._resync_period, 0)
        self.assertEqual(informer._processor._listeners[1]._resync_period, 60)

        listener3 = TestListener("listener3", 55)
        await informer.add_event_handler(
            listener3, resync_period=listener3._resync_period)
        self.assertEqual(informer._resync_check_period, 55)
        self.assertEqual(informer._processor._listeners[0]._resync_period, 0)
        self.assertEqual(informer._processor._listeners[1]._resync_period, 60)
        self.assertEqual(informer._processor._listeners[2]._resync_period, 55)

        listener4 = TestListener("listener4", 5)
        await informer.add_event_handler(
            listener4, resync_period=listener4._resync_period)
        self.assertEqual(informer._resync_check_period, 5)
        self.assertEqual(informer._processor._listeners[0]._resync_period, 0)
        self.assertEqual(informer._processor._listeners[1]._resync_period, 60)
        self.assertEqual(informer._processor._listeners[2]._resync_period, 55)
        self.assertEqual(informer._processor._listeners[3]._resync_period, 5)
Beispiel #5
0
    async def test_hammer(self):
        source = fake_controller_source.FakeControllerSource()
        output_set_lock = asyncio.Lock()
        output_set = defaultdict(list)

        async def record_func(event_type, obj):
            key = deletion_handling_meta_namespace_key_func(obj)
            async with output_set_lock:
                output_set[key].append(event_type)

        async def add_func(obj):
            await record_func("add", obj)

        async def update_func(old_obj, new_obj):
            await record_func("update", new_obj)

        async def delete_func(obj):
            await record_func("delete", obj)

        h = ResourceEventHandlerFuncs(
            add_func=add_func, update_func=update_func, delete_func=delete_func
        )
        _, controller = new_informer(source, V1Pod, 0.1, h)
        self.assertFalse(controller.has_synced())

        controller_task = asyncio.ensure_future(controller.run())

        async def condition():
            return controller.has_synced()

        await wait.poll(0.1, wait.FOREVER_TEST_TIMEOUT, condition)
        self.assertTrue(controller.has_synced())

        async def task():
            current_names = set()
            for _ in range(100):
                if not current_names or not random.randrange(3):
                    name = "".join(
                        random.choice(string.ascii_letters) for _ in range(16)
                    )
                    is_new = True
                else:
                    name = random.choice(list(current_names))
                    is_new = False
                # TODO: fuzz
                pod = V1Pod(metadata=V1ObjectMeta(name=name, namespace="default"))
                if is_new:
                    current_names.add(name)
                    await source.add(pod)
                    continue
                if random.randrange(2):
                    current_names.add(name)
                    await source.modify(pod)
                else:
                    current_names.remove(name)
                    await source.delete(pod)

        await asyncio.gather(*(task() for _ in range(3)))

        controller_task.cancel()
        await asyncio.gather(controller_task, return_exceptions=True)

        await output_set_lock.acquire()