def test_concat(self):
        port = find_free_port()
        env = {
            'PYTHONPATH': '%s/tests/functions:$PYTHONPATH' % os.getcwd(),
            'GRPC_PORT': str(port),
            'FUNCTION_URI': 'file://%s/tests/functions/concat.py?handler=concat' % os.getcwd()
        }

        self.process = subprocess.Popen(self.command,
                                        cwd=self.workingdir,
                                        shell=True,
                                        env=env,
                                        preexec_fn=os.setsid,
                                        )

        channel = grpc.insecure_channel('localhost:%s' % port)
        wait_until_channel_ready(channel)
        self.stub = function.MessageFunctionStub(channel)

        def generate_messages():
            headers = {
                'Content-Type': message.Message.HeaderValue(values=['application/json']),
                'correlationId': message.Message.HeaderValue(values=[str(uuid.uuid4())])
            }

            messages = [
                message.Message(payload='{"foo":"bar","hello":"world"}', headers=headers),
            ]
            for msg in messages:
                yield msg

        responses = self.stub.Call(generate_messages())

        for response in responses:
            self.assertEquals('{"result": "foobarhelloworld"}', response.payload)
예제 #2
0
    def test_discrete_window_text(self):

        from itertools import count
        import json

        env = function_env('windows.py', 'discrete_window_text')

        func, interaction_model = invoker.function_invoker.install_function(
            env)

        threading.Thread(target=invoker.function_invoker.invoke_function,
                         args=([func, interaction_model, env])).start()

        channel = grpc.insecure_channel('localhost:%s' % env['GRPC_PORT'])
        testutils.wait_until_channel_ready(channel)
        '''
        unbounded generator of Messages converting int to bytes
        '''
        messages = (message.Message(
            payload=bytes("X%d" % i, 'UTF-8'),
            headers={
                'Content-Type':
                message.Message.HeaderValue(values=['text/plain'])
            }) for i in count())

        responses = function.MessageFunctionStub(channel).Call(messages)
        '''
        Check the first 10 responses. Each message is a json serialized tuple of size 3 containing the next sequence of ints.
        '''
        for _ in range(10):
            tpl = json.loads(next(responses).payload)

        invoker.function_invoker.stop()
    def test_upper(self):
        port = testutils.find_free_port()
        env = {
            'PYTHONPATH':
            self.PYTHONPATH,
            'GRPC_PORT':
            str(port),
            'FUNCTION_URI':
            'file://%s/tests/functions/upper.py?handler=handle' % os.getcwd()
        }

        self.process = subprocess.Popen(
            self.command,
            cwd=self.workingdir,
            shell=True,
            env=env,
            preexec_fn=os.setsid,
        )

        channel = grpc.insecure_channel('localhost:%s' % port)
        testutils.wait_until_channel_ready(channel)

        self.stub = function.MessageFunctionStub(channel)

        def generate_messages():
            headers = {
                'Content-Type':
                message.Message.HeaderValue(values=['text/plain']),
                'correlationId':
                message.Message.HeaderValue(values=[str(uuid.uuid4())])
            }

            messages = [
                message.Message(payload=bytes("hello", 'UTF-8'),
                                headers=headers),
                message.Message(payload=bytes("world", 'UTF-8'),
                                headers=headers),
                message.Message(payload=bytes("foo", 'UTF-8'),
                                headers=headers),
                message.Message(payload=bytes("bar", 'UTF-8'),
                                headers=headers),
            ]
            for msg in messages:
                yield msg

        responses = self.stub.Call(generate_messages())
        expected = [b'HELLO', b'WORLD', b'FOO', b'BAR']

        for response in responses:
            self.assertTrue(response.payload in expected)
            expected.remove(response.payload)

        self.assertEqual(0, len(expected))
    def test_accepts_not_supported(self):
        port = testutils.find_free_port()
        env = {
            'PYTHONPATH':
            self.PYTHONPATH,
            'GRPC_PORT':
            str(port),
            'FUNCTION_URI':
            'file://%s/tests/functions/concat.py?handler=concat' % os.getcwd()
        }

        self.process = subprocess.Popen(
            self.command,
            cwd=self.workingdir,
            shell=True,
            env=env,
            preexec_fn=os.setsid,
        )

        channel = grpc.insecure_channel('localhost:%s' % port)
        testutils.wait_until_channel_ready(channel)

        self.stub = function.MessageFunctionStub(channel)

        def generate_messages():
            headers = {
                'Content-Type':
                message.Message.HeaderValue(values=['application/json']),
                'Accept':
                message.Message.HeaderValue(values=['application/xml']),
                'correlationId':
                message.Message.HeaderValue(values=[str(uuid.uuid4())])
            }

            messages = [
                message.Message(payload=b'{"foo":"bar","hello":"world"}',
                                headers=headers),
            ]
            for msg in messages:
                yield msg

        try:
            responses = self.stub.Call(generate_messages())
            self.assertEqual(grpc._channel._Rendezvous, type(responses))
            # TODO: Investigate error handling
            # https://github.com/projectriff/python2-function-invoker/issues/5
        except RuntimeError:
            pass
예제 #5
0
    def test_upper(self):
        env = function_env('upper.py', 'handle')

        func, interaction_model = invoker.function_invoker.install_function(
            env)
        self.assertEqual('handle', func.__name__)
        self.assertIsNone(interaction_model)

        threading.Thread(target=invoker.function_invoker.invoke_function,
                         args=([func, interaction_model, env])).start()

        channel = grpc.insecure_channel('localhost:%s' % env['GRPC_PORT'])
        testutils.wait_until_channel_ready(channel)

        def generate_messages():
            headers = {
                'Content-Type':
                message.Message.HeaderValue(values=['text/plain']),
                'correlationId':
                message.Message.HeaderValue(values=[str(uuid.uuid4())])
            }

            messages = [
                message.Message(payload=bytes("hello", 'UTF-8'),
                                headers=headers),
                message.Message(payload=bytes("world", 'UTF-8'),
                                headers=headers),
                message.Message(payload=bytes("foo", 'UTF-8'),
                                headers=headers),
                message.Message(payload=bytes("bar", 'UTF-8'),
                                headers=headers),
            ]

            for msg in messages:
                yield msg

        responses = function.MessageFunctionStub(channel).Call(
            generate_messages())
        expected = [b'HELLO', b'WORLD', b'FOO', b'BAR']

        for response in responses:
            self.assertTrue(response.payload in expected)
            expected.remove(response.payload)

        self.assertEqual(0, len(expected))
        invoker.function_invoker.stop()
    def test_upper_no_correlation(self):
        port = find_free_port()
        env = {
            'PYTHONPATH': '%s/tests/functions:$PYTHONPATH' % os.getcwd(),
            'GRPC_PORT': str(port),
            'FUNCTION_URI': 'file://%s/tests/functions/upper.py?handler=handle' % os.getcwd()
        }

        self.process = subprocess.Popen(self.command,
                                        cwd=self.workingdir,
                                        shell=True,
                                        env=env,
                                        preexec_fn=os.setsid,
                                        )

        channel = grpc.insecure_channel('localhost:%s' % port)
        wait_until_channel_ready(channel)

        self.stub = function.MessageFunctionStub(channel)

        def generate_messages():
            headers = {}

            messages = [
                message.Message(payload="hello", headers=headers),
                message.Message(payload="world", headers=headers),
                message.Message(payload="foo", headers=headers),
                message.Message(payload="bar", headers=headers),
            ]
            for msg in messages:
                yield msg


        responses = self.stub.Call(generate_messages())
        expected = ['HELLO', 'WORLD', 'FOO', 'BAR']

        for response in responses:
            self.assertTrue(response.payload in expected)
            self.assertEquals([], response.headers['correlationId'].values)
            expected.remove(response.payload)

        self.assertEquals(0, len(expected))
예제 #7
0
    def test_source(self):
        env = function_env('streamer.py', 'source')

        func, interaction_model = invoker.function_invoker.install_function(
            env)

        threading.Thread(target=invoker.function_invoker.invoke_function,
                         args=([func, interaction_model, env])).start()

        channel = grpc.insecure_channel('localhost:%s' % env['GRPC_PORT'])
        testutils.wait_until_channel_ready(channel)

        def messages():
            yield message.Message()

        responses = function.MessageFunctionStub(channel).Call(messages())

        for i in range(10):
            self.assertEqual(bytes(str(i), 'utf-8'), next(responses).payload)

        invoker.function_invoker.stop()
예제 #8
0
    def test_bidirectional(self):
        env = function_env('streamer.py', 'bidirectional')
        func, interaction_model = invoker.function_invoker.install_function(
            env)
        self.assertEqual('bidirectional', func.__name__)
        self.assertEqual('stream', interaction_model)

        threading.Thread(target=invoker.function_invoker.invoke_function,
                         args=([func, interaction_model, env])).start()

        channel = grpc.insecure_channel('localhost:%s' % env['GRPC_PORT'])
        testutils.wait_until_channel_ready(channel)

        stub = function.MessageFunctionStub(channel)

        def generate_messages():
            headers = {
                'Content-Type':
                message.Message.HeaderValue(values=['text/plain']),
            }

            messages = [
                message.Message(payload=b'foo', headers=headers),
                message.Message(payload=b'bar', headers=headers),
                message.Message(payload=b'baz', headers=headers),
                message.Message(payload=b'faz', headers=headers),
            ]
            for msg in messages:
                yield msg

        responses = stub.Call(generate_messages())

        expected = [b'FOO', b'BAR', b'BAZ', b'FAZ']

        for response in responses:
            self.assertTrue(response.payload in expected)
            expected.remove(response.payload)

        self.assertEqual(0, len(expected))
        invoker.function_invoker.stop()
예제 #9
0
    def test_sliding_window(self):
        from itertools import count
        import struct
        import json

        env = function_env('windows.py', 'sliding_window')

        func, interaction_model = invoker.function_invoker.install_function(
            env)

        threading.Thread(target=invoker.function_invoker.invoke_function,
                         args=([func, interaction_model, env])).start()

        channel = grpc.insecure_channel('localhost:%s' % env['GRPC_PORT'])
        testutils.wait_until_channel_ready(channel)
        '''
        unbounded generator of Messages converting int to bytes
        '''
        messages = (message.Message(
            payload=struct.pack(">I", i),
            headers={
                'Content-Type':
                message.Message.HeaderValue(
                    values=['application/octet-stream'])
            }) for i in count())

        responses = function.MessageFunctionStub(channel).Call(messages)
        '''
        Check the first 10 responses. Each message is a json serialized tuple of size 3 containing the next sequence 
        of ints: ((0,1,2),(1,2,3),(2,3,4))
        '''
        for i in range(10):
            tpl = json.loads(next(responses).payload)
            self.assertEqual(3, len(tpl))
            for j in range(len(tpl)):
                self.assertEqual(i + j, tpl[j])

        invoker.function_invoker.stop()