Пример #1
0
 def test_occupancy_and_state_destruction(self):
     for _ in range (0,100):
         c1 = argo.ServerConnection(argo.HttpProcess(f'http://localhost:{self.port}/'))
         # load a file
         hello_file = file_dir.joinpath('hello.txt')
         self.assertTrue(False if not hello_file.is_file() else True)
         uid1 = c1.send_command("load", {"file path": str(hello_file), "state": None})
         actual1 = c1.wait_for_reply_to(uid1)
         self.assertIn('result', actual1)
         self.assertIn('state', actual1['result'])
         state1 = actual1['result']['state']
class LowLevelCryptolApiTests(unittest.TestCase):
    c = None

    @classmethod
    def setUpClass(self):
        if (command := os.getenv('CRYPTOL_SERVER')) is not None and (
                command := find_executable(command)) is not None:
            self.c = argo.ServerConnection(
                argo.DynamicSocketProcess(command + " socket"))
        elif (url := os.getenv('CRYPTOL_SERVER_URL')) is not None:
            self.c = argo.ServerConnection(argo.HttpProcess(url))
Пример #3
0
    def setUpClass(self):
        p = subprocess.Popen(
            ["cabal", "run", "exe:file-echo-api", "--verbose=0", "--", "http", "/", "--port", self.port, "--log", HttpTests.server_log_file()],
            stdout=subprocess.PIPE,
            stdin=subprocess.DEVNULL,
            stderr=subprocess.PIPE,
            start_new_session=True)
        time.sleep(3)
        assert(p is not None)
        poll_result = p.poll()
        if poll_result is not None:
            print(poll_result)
            print(p.stdout.read())
            print(p.stderr.read())
        assert(poll_result is None)

        self.p = p
        self.c = argo.ServerConnection(argo.HttpProcess(f'http://localhost:{self.port}/'))
Пример #4
0
    def setUpClass(self):
        p = subprocess.Popen([
            "cabal", "run", "exe:mutable-file-echo-api", "--verbose=0", "--",
            "--max-occupancy", "2", "http", "/", "--port", "8080"
        ],
                             stdout=subprocess.PIPE,
                             stdin=subprocess.DEVNULL,
                             stderr=subprocess.PIPE,
                             start_new_session=True)
        time.sleep(3)
        assert (p is not None)
        poll_result = p.poll()
        if poll_result is not None:
            print(poll_result)
            print(p.stdout.read())
            print(p.stderr.read())
        assert (poll_result is None)

        self.p = p
        self.other_c = argo.ServerConnection(
            argo.HttpProcess('http://localhost:8080/'))
Пример #5
0
    def setUpClass(self):
        os.system('openssl req -nodes -newkey rsa:2048 -keyout server.key -out server.csr'\
                  + ' -subj "/C=GB/ST=London/L=London/O=Acme Widgets/OU=IT Department/CN=localhost"')
        os.system('openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt')
        p = subprocess.Popen(
            ["cabal", "run", "exe:file-echo-api", "--verbose=0", "--", "http", "/"
            , "--port", self.port, "--tls", "--log", TLSTests2.server_log_file()],
            stdout=subprocess.PIPE,
            stdin=subprocess.DEVNULL,
            stderr=subprocess.PIPE,
            start_new_session=True)
        time.sleep(3)
        assert(p is not None)
        poll_result = p.poll()
        if poll_result is not None:
            print(poll_result)
            print(p.stdout.read())
            print(p.stderr.read())
        assert(poll_result is None)

        self.p = p
        self.c = argo.ServerConnection(argo.HttpProcess(f'https://localhost:{self.port}', verify=False))
Пример #6
0
    def test_interrupts(self):
        c1 = argo.ServerConnection(argo.HttpProcess(f'http://localhost:{self.port}/'))
        c2 = argo.ServerConnection(argo.HttpProcess(f'http://localhost:{self.port}/'))
        # load a file
        hello_file = file_dir.joinpath('hello.txt')
        self.assertTrue(False if not hello_file.is_file() else True)
        uid1 = c1.send_command("load", {"file path": str(hello_file), "state": None})
        uid2 = c2.send_command("load", {"file path": str(hello_file), "state": None})
        actual1 = c1.wait_for_reply_to(uid1)
        self.assertIn('result', actual1)
        self.assertIn('state', actual1['result'])
        state1 = actual1['result']['state']
        actual2 = c2.wait_for_reply_to(uid2)
        self.assertIn('result', actual2)
        self.assertIn('state', actual2['result'])
        state2 = actual2['result']['state']

        # simple sleep for 3 seconds
        t1 = time.time()
        three_seconds = 3000000
        uid1 = c1.send_query("sleep query", {"microseconds": three_seconds, "state": state1})
        actual1 = c1.wait_for_reply_to(uid1)
        t2 = time.time()
        self.assertIn('result', actual1)
        if 'result' in actual1:
            self.assertIn('state', actual1['result'])
            self.assertIn('answer', actual1['result'])
            if 'answer' in actual1['result']:
                self.assertIn('value', actual1['result']['answer'])
                if 'value' in actual1['result']['answer']:
                    self.assertGreater(actual1['result']['answer']['value'], 2.9)
        self.assertGreater(t2 - t1, 2.9)


        # Sleep for 100 seconds, but then interrupt!
        newpid = os.fork()
        if newpid == 0:
            time.sleep(3)
            uid2 = c2.send_notification("interrupt", {})
            os._exit(0)
        else:
            one_hundred_sec = 100000000
            t1 = time.time()
            uid1 = c1.send_query("sleep query", {"microseconds": one_hundred_sec, "state": state1})
            actual1 = c1.wait_for_reply_to(uid1)
            expected = {'error':{'data':{'stdout':None,'stderr':None},'code':24,'message':'Request interrupted'},'jsonrpc':'2.0','id':uid1}
            self.assertEqual(actual1, expected)


        # check contents...?
        uid1 = assertShow(self, c1, state=state1, expected='Hello World!\n')
        uid2 = assertShow(self, c2, state=state2, expected='Hello World!\n')

        # mutation/interrupt test
        newpid = os.fork()
        if newpid != 0:
            # parent tries to clean up
            two_sec = 2000000
            t1 = time.time()
            uid1 = c1.send_command("slow clear", {"pause microseconds": two_sec, "state": state1})
            actual1 = c1.wait_for_reply_to(uid1)
            expected = {'error':{'data':{'stdout':None,'stderr':None},'code':24,'message':'Request interrupted'},'jsonrpc':'2.0','id':uid1}
            self.assertEqual(actual1, expected)
        else:
            # child allows cleanup to start but not finish
            time.sleep(4)
            uid2 = c2.send_notification("interrupt", {})
            os._exit(0)

        # check contents (N.B., there is no mutable state, so interrupts which stop a command mean
        # the state is not updated by the argo server backend).
        uid1 = assertShow(self, c1, state=state1, expected='Hello World!\n')
        uid2 = assertShow(self, c2, state=state2, expected='Hello World!\n')



        # Ensure sleeping notification delays the subsequent request
        # (i.e., requests can't interrupt or be interleaved with notification handling)
        six_seconds = three_seconds * 2
        newpid = os.fork()
        if newpid == 0:
            uid2 = c1.send_notification("sleep notification", {"microseconds": six_seconds})
            time.sleep(2)
            os._exit(0)
        else:
            t1 = time.time()
            time.sleep(2)
            uid2 = assertShow(self, c2, state=state2, expected='Hello World!\n')
            t2 = time.time()
            self.assertGreater(t2 - t1, 5.9)
Пример #7
0
    def test_occupancy_and_state_destruction(self):
        c1 = argo.ServerConnection(argo.HttpProcess(f'http://localhost:{self.port}/'))
        c2 = argo.ServerConnection(argo.HttpProcess(f'http://localhost:{self.port}/'))
        # load a file
        hello_file = file_dir.joinpath('hello.txt')
        self.assertTrue(False if not hello_file.is_file() else True)
        uid1 = c1.send_command("load", {"file path": str(hello_file), "state": None})
        uid2 = c2.send_command("load", {"file path": str(hello_file), "state": None})
        actual1 = c1.wait_for_reply_to(uid1)
        self.assertIn('result', actual1)
        self.assertIn('state', actual1['result'])
        state1 = actual1['result']['state']
        actual2 = c2.wait_for_reply_to(uid2)
        self.assertIn('result', actual2)
        self.assertIn('state', actual2['result'])
        state2 = actual2['result']['state']

        # check the next (3rd) connection is rejected
        c3 = argo.ServerConnection(argo.HttpProcess(f'http://localhost:{self.port}/'))
        uid3 = c3.send_command("load", {"file path": str(hello_file), "state": None})
        actual3 = c3.wait_for_reply_to(uid3)
        expected = {'error':{'data':{'stdout':None,'stderr':None},'code':22,'message':'Server at max capacity'},'jsonrpc':'2.0','id':uid3}
        self.assertEqual(actual3, expected)

        # kill connection 1's state
        c1.send_notification("destroy state", {"state to destroy": state1})
        # ensure connection 1's state is dead
        uid1 = c1.send_query("show", {"state": state1})
        actual1 = c1.wait_for_reply_to(uid1)
        expected = {'error':{'data':{'stdout':None,'data':state1,'stderr':None},'code':20,'message':'Unknown state ID'},'jsonrpc':'2.0','id':uid1}
        self.assertEqual(actual1, expected)

        # now connection 3 should succeed
        uid3 = c3.send_command("load", {"file path": str(hello_file), "state": None})
        actual3 = c3.wait_for_reply_to(uid3)
        self.assertIn('result', actual3)
        self.assertIn('state', actual3['result'])
        state3 = actual3['result']['state']

        # kill all the connection's state
        c1.send_notification("destroy all states", {})

        # ensure connection 2's state is dead
        uid2 = c2.send_query("show", {"state": state2})
        actual2 = c2.wait_for_reply_to(uid2)
        expected = {'error':{'data':{'stdout':None,'data':state2,'stderr':None},'code':20,'message':'Unknown state ID'},'jsonrpc':'2.0','id':uid2}
        self.assertEqual(actual2, expected)

        # ensure connection 3's state is dead
        uid3 = c3.send_query("show", {"state": state3})
        actual3 = c3.wait_for_reply_to(uid3)
        expected = {'error':{'data':{'stdout':None,'data':state3,'stderr':None},'code':20,'message':'Unknown state ID'},'jsonrpc':'2.0','id':uid3}
        self.assertEqual(actual3, expected)

        # now ensure there's room for two more new connections
        uid1 = c1.send_command("load", {"file path": str(hello_file), "state": None})
        uid2 = c2.send_command("load", {"file path": str(hello_file), "state": None})
        actual1 = c1.wait_for_reply_to(uid1)
        self.assertIn('result', actual1)
        self.assertIn('state', actual1['result'])
        state1 = actual1['result']['state']
        actual2 = c2.wait_for_reply_to(uid2)
        self.assertIn('result', actual2)
        self.assertIn('state', actual2['result'])
        state2 = actual2['result']['state']

        # check again that the next (3rd) connection is rejected
        c3 = argo.ServerConnection(argo.HttpProcess(f'http://localhost:{self.port}/'))
        uid3 = c3.send_command("load", {"file path": str(hello_file), "state": None})
        actual3 = c3.wait_for_reply_to(uid3)
        expected = {'error':{'data':{'stdout':None,'stderr':None},'code':22,'message':'Server at max capacity'},'jsonrpc':'2.0','id':uid3}
        self.assertEqual(actual3, expected)
Пример #8
0
    def test_interrupts(self):
        c1 = argo.ServerConnection(argo.HttpProcess('http://localhost:8083/'))
        c2 = argo.ServerConnection(argo.HttpProcess('http://localhost:8083/'))
        # load a file
        hello_file = file_dir.joinpath('hello.txt')
        self.assertTrue(False if not hello_file.is_file() else True)
        uid1 = c1.send_command("load", {
            "file path": str(hello_file),
            "state": None
        })
        uid2 = c2.send_command("load", {
            "file path": str(hello_file),
            "state": None
        })
        actual1 = c1.wait_for_reply_to(uid1)
        self.assertIn('result', actual1)
        self.assertIn('state', actual1['result'])
        state1 = actual1['result']['state']
        actual2 = c2.wait_for_reply_to(uid2)
        self.assertIn('result', actual2)
        self.assertIn('state', actual2['result'])
        state2 = actual2['result']['state']

        # simple sleep for 3 seconds
        t1 = time.time()
        uid1 = c1.send_query("sleep query", {
            "microseconds": 3000000,
            "state": state1
        })
        actual1 = c1.wait_for_reply_to(uid1)
        t2 = time.time()
        self.assertIn('result', actual1)
        if 'result' in actual1:
            self.assertIn('state', actual1['result'])
            self.assertIn('answer', actual1['result'])
            if 'answer' in actual1['result']:
                self.assertIn('value', actual1['result']['answer'])
                if 'value' in actual1['result']['answer']:
                    self.assertGreater(actual1['result']['answer']['value'],
                                       2.9)
        self.assertGreater(t2 - t1, 2.9)

        # sleep/interrupt test
        newpid = os.fork()
        if newpid != 0:
            # parent tries to sleep
            one_hundred_sec = 100000000
            t1 = time.time()
            uid1 = c1.send_query("sleep query", {
                "microseconds": one_hundred_sec,
                "state": state1
            })
            t2 = time.time()
        else:
            # child does not allow sleep
            time.sleep(3)
            uid2 = c2.send_notification("interrupt", {})
            os._exit(0)
        # check interrupt actually interrupted 100sec sleep
        self.assertLess(t2 - t1, 10)

        # mutation/interrupt test
        newpid = os.fork()
        if newpid != 0:
            # parent tries to clean up
            two_sec = 2000000
            t1 = time.time()
            uid1 = c1.send_command("slow clear", {
                "pause microseconds": two_sec,
                "state": state1
            })
        else:
            # child allows cleanup to start but not finish
            time.sleep(4)
            uid2 = c2.send_notification("interrupt", {})
            os._exit(0)

        # check contents (N.B., the mutable server uses an IORef for the
        # contents, so the interrupt doesn't prevent effects.)
        (uid1, state1) = assertShow(self,
                                    c1,
                                    state=state1,
                                    expected='Hello World!\n',
                                    expected_equal=False)
        (uid1, state1) = assertShow(self,
                                    c1,
                                    state=state1,
                                    expected='',
                                    expected_equal=False)
        (uid2, state2) = assertShow(self,
                                    c2,
                                    state=state2,
                                    expected='Hello World!\n')
Пример #9
0
    def test_subsequent_connection(self):
        c = argo.ServerConnection(argo.HttpProcess('http://localhost:8080/'))
        ## Positive tests -- make sure the server behaves as we expect with valid RPCs

        # [c] Check that their is nothing to show if we haven't loaded a file yet
        (prev_uid, state) = assertShow(self, c, state=None, expected='')

        # [c] load a file
        hello_file = file_dir.joinpath('hello.txt')
        self.assertTrue(False if not hello_file.is_file() else True)
        uid = c.send_command("load", {
            "file path": str(hello_file),
            "state": state
        })
        actual = c.wait_for_reply_to(uid)
        self.assertTrue('result' in actual and 'state' in actual['result'])
        state = actual['result']['state']
        expected = {
            'result': {
                'state': state,
                'stdout': '',
                'stderr': '',
                'answer': []
            },
            'jsonrpc': '2.0',
            'id': uid
        }
        self.assertEqual(actual, expected)
        self.assertNotEqual(uid, prev_uid)
        self.assertNotEqual(state, None)
        prev_uid = uid

        # [c] check the contents of the loaded file
        (prev_uid, state) = assertShow(self,
                                       c,
                                       state=state,
                                       expected='Hello World!\n')

        # [other_c] start a subsequent connection
        other_c = argo.ServerConnection(
            argo.HttpProcess('http://localhost:8080/'))

        # [other_c] check that the other connection has nothing to show if we haven't loaded our own file yet
        (other_prev_uid, other_state) = assertShow(self,
                                                   other_c,
                                                   state=None,
                                                   expected='')

        # [other_c] load a file
        base_file = file_dir.joinpath('base.txt')
        other_uid = other_c.send_command("load", {
            "file path": str(base_file),
            "state": other_state
        })
        actual = other_c.wait_for_reply_to(other_uid)
        self.assertTrue('result' in actual and 'state' in actual['result'])
        other_state = actual['result']['state']
        expected = {
            'result': {
                'state': other_state,
                'stdout': '',
                'stderr': '',
                'answer': []
            },
            'jsonrpc': '2.0',
            'id': other_uid
        }
        self.assertEqual(actual, expected)
        self.assertNotEqual(other_uid, other_prev_uid)
        self.assertNotEqual(other_state, None)
        other_prev_uid = other_uid

        # [other_c] clear the loaded file
        other_uid = other_c.send_command("clear", {"state": other_state})
        actual = other_c.wait_for_reply_to(other_uid)
        self.assertTrue('result' in actual and 'state' in actual['result'])
        cleared_state = actual['result']['state']
        expected = {
            'result': {
                'state': cleared_state,
                'stdout': '',
                'stderr': '',
                'answer': []
            },
            'jsonrpc': '2.0',
            'id': other_uid
        }
        self.assertEqual(actual, expected)
        self.assertNotEqual(cleared_state, other_state)
        self.assertNotEqual(other_uid, other_prev_uid)

        # [c] check the contents of the loaded file again in the original connection
        (prev_uid, state) = assertShow(self,
                                       c,
                                       state=state,
                                       expected='Hello World!\n')