Ejemplo n.º 1
0
    def test_remove_inactive_containers_succeeds(self):
        container_name = "clipper/noop-container:{}".format(clipper_version)
        input_type = "doubles"
        model_name = "remove-inactive-test-model"
        self.clipper_conn.build_and_deploy_model(model_name,
                                                 1,
                                                 input_type,
                                                 fake_model_data,
                                                 container_name,
                                                 num_replicas=2)
        docker_client = get_docker_client()
        containers = docker_client.containers.list(
            filters={"ancestor": container_name})
        self.assertEqual(len(containers), 2)

        self.clipper_conn.build_and_deploy_model(model_name,
                                                 2,
                                                 input_type,
                                                 fake_model_data,
                                                 container_name,
                                                 num_replicas=3)
        containers = docker_client.containers.list(
            filters={"ancestor": container_name})
        self.assertEqual(len(containers), 5)

        self.clipper_conn.stop_inactive_model_versions([model_name])
        containers = docker_client.containers.list(
            filters={"ancestor": container_name})
        self.assertEqual(len(containers), 3)
Ejemplo n.º 2
0
 def get_containers(self, container_name):
     return get_docker_client().containers.list(
         filters={
             "ancestor":
             container_name,
             "label":
             "{key}={val}".format(key=CLIPPER_DOCKER_LABEL,
                                  val=self.clipper_conn.cm.cluster_name)
         })
Ejemplo n.º 3
0
    def test_register_py_endpoint(self):
        name = "py-closure-test"
        expected_version = 1

        def predict_func(inputs):
            return ["0" for x in inputs]

        input_type = "doubles"

        create_py_endpoint(self.clipper_conn, name, input_type, predict_func)

        registered_applications = self.clipper_conn.get_all_apps()
        self.assertEqual(len(registered_applications), 1)
        self.assertTrue(name in registered_applications)

        registered_model_info = self.clipper_conn.get_model_info(
            name, expected_version)
        self.assertIsNotNone(registered_model_info)

        linked_models = self.clipper_conn.get_linked_models(name)
        self.assertIsNotNone(linked_models)

        docker_client = get_docker_client()
        py_minor_version = (sys.version_info.major, sys.version_info.minor)
        if py_minor_version < (3, 0):
            containers = docker_client.containers.list(
                filters={
                    "ancestor":
                    "clipper/python-closure-container:{}".format(
                        clipper_version)
                })

        elif py_minor_version == (3, 5):
            containers = docker_client.containers.list(
                filters={
                    "ancestor":
                    "clipper/python35-closure-container:{}".format(
                        clipper_version)
                })
        elif py_minor_version == (3, 6):
            containers = docker_client.containers.list(
                filters={
                    "ancestor":
                    "clipper/python36-closure-container:{}".format(
                        clipper_version)
                })
        else:
            msg = (
                "Python closure deployer only supports Python 2.7, 3.5, and 3.6. "
                "Detected {major}.{minor}").format(
                    major=sys.version_info.major, minor=sys.version_info.minor)
            logger.error(msg)
        self.assertEqual(len(containers), 1)
Ejemplo n.º 4
0
 def test_model_deploys_successfully(self):
     model_name = "m"
     version = "v1"
     container_name = "clipper/noop-container:{}".format(clipper_version)
     input_type = "doubles"
     self.clipper_conn.build_and_deploy_model(model_name, version,
                                              input_type, fake_model_data,
                                              container_name)
     model_info = self.clipper_conn.get_model_info(model_name, version)
     self.assertIsNotNone(model_info)
     self.assertEqual(type(model_info), dict)
     docker_client = get_docker_client()
     containers = docker_client.containers.list(
         filters={"ancestor": container_name})
     self.assertEqual(len(containers), 1)
Ejemplo n.º 5
0
    def test_python_closure_deploys_successfully(self):
        model_name = "m2"
        model_version = 1

        def predict_func(inputs):
            return ["0" for x in inputs]

        input_type = "doubles"
        deploy_python_closure(self.clipper_conn, model_name, model_version,
                              input_type, predict_func)
        model_info = self.clipper_conn.get_model_info(model_name,
                                                      model_version)
        self.assertIsNotNone(model_info)

        docker_client = get_docker_client()
        py_minor_version = (sys.version_info.major, sys.version_info.minor)
        if py_minor_version < (3, 0):
            containers = docker_client.containers.list(
                filters={
                    "ancestor":
                    "clipper/python-closure-container:{}".format(
                        clipper_version)
                })

        elif py_minor_version == (3, 5):
            containers = docker_client.containers.list(
                filters={
                    "ancestor":
                    "clipper/python35-closure-container:{}".format(
                        clipper_version)
                })
        elif py_minor_version == (3, 6):
            containers = docker_client.containers.list(
                filters={
                    "ancestor":
                    "clipper/python36-closure-container:{}".format(
                        clipper_version)
                })
        else:
            msg = (
                "Python closure deployer only supports Python 2.7, 3.5, and 3.6. "
                "Detected {major}.{minor}").format(
                    major=sys.version_info.major, minor=sys.version_info.minor)
            logger.error(msg)

        self.assertGreaterEqual(len(containers), 1)
Ejemplo n.º 6
0
    def test_stop_models(self):
        container_name = "clipper/noop-container:{}".format(clipper_version)
        input_type = "doubles"
        mnames = ["jimmypage", "robertplant", "jpj", "johnbohnam"]
        versions = ["i", "ii", "iii", "iv"]
        for model_name in mnames:
            for version in versions:
                self.clipper_conn.deploy_model(model_name,
                                               version,
                                               input_type,
                                               container_name,
                                               num_replicas=1)

        docker_client = get_docker_client()
        containers = docker_client.containers.list(
            filters={"ancestor": container_name})
        self.assertEqual(len(containers), len(mnames) * len(versions))

        # stop all versions of models jimmypage, robertplant
        self.clipper_conn.stop_models(mnames[:2])
        containers = docker_client.containers.list(
            filters={"ancestor": container_name})
        self.assertEqual(len(containers), len(mnames[2:]) * len(versions))

        # After calling this method, the remaining models should be:
        # jpj:i, jpj:iii, johnbohman:ii
        self.clipper_conn.stop_versioned_models({
            "jpj": ["ii", "iv"],
            "johnbohnam": ["i", "iv", "iii"],
        })
        containers = docker_client.containers.list(
            filters={"ancestor": container_name})
        self.assertEqual(len(containers), 3)

        self.clipper_conn.stop_all_model_containers()
        containers = docker_client.containers.list(
            filters={"ancestor": container_name})
        self.assertEqual(len(containers), 0)
Ejemplo n.º 7
0
    def test_remove_inactive_container(self):
        container_name = "clipper/noop-container:{}".format(clipper_version)
        self.clipper_conn.build_and_deploy_model(self.model_name_5,
                                                 1,
                                                 self.input_type,
                                                 fake_model_data,
                                                 container_name,
                                                 num_replicas=2)
        docker_client = get_docker_client()
        containers = docker_client.containers.list(
            filters={"ancestor": container_name})
        self.assertEqual(len(containers), 2)

        self.clipper_conn.link_model_to_app(self.app_name_5, self.model_name_5)
        time.sleep(30)

        # We now have 2 replicas running, both the same model name and Version
        # send predictions, assert that we are getting correct response

        addr = self.clipper_conn.get_query_addr()
        test_input = [101.1, 99.5, 107.2]
        req_json = json.dumps({'input': test_input})
        headers = {'Content-type': 'application/json'}
        for i in range(2):
            response = requests.post("http://%s/%s/predict" %
                                     (addr, self.app_name_5),
                                     headers=headers,
                                     data=req_json)
            result = response.json()
            self.assertEqual(response.status_code, requests.codes.ok)
            #print(result["default_explanation"])
            self.assertEqual(result["default"], False)

        # one of the containers should go inactive

        self.clipper_conn.set_num_replicas(name=self.model_name_5,
                                           version=1,
                                           num_replicas=1)
        time.sleep(100)

        containers = docker_client.containers.list(
            filters={"ancestor": container_name})
        self.assertEqual(len(containers), 1)

        test_input = [101.1, 99.9]
        req_json = json.dumps({'input': test_input})

        #send predictions, should still be working
        for i in range(2):
            response = requests.post("http://%s/%s/predict" %
                                     (addr, self.app_name_5),
                                     headers=headers,
                                     data=req_json)
            result = response.json()
            self.assertEqual(response.status_code, requests.codes.ok)
            self.assertEqual(result["default"], False)

        #2nd container should go inactive
        self.clipper_conn.set_num_replicas(name=self.model_name_5,
                                           version=1,
                                           num_replicas=0)
        time.sleep(100)

        containers = docker_client.containers.list(
            filters={"ancestor": container_name})
        self.assertEqual(len(containers), 0)

        test_input = [101.1]
        req_json = json.dumps({'input': test_input})

        #send predictions, should be getting response with message 'no connected models'
        for i in range(2):
            response = requests.post("http://%s/%s/predict" %
                                     (addr, self.app_name_5),
                                     headers=headers,
                                     data=req_json)
            result = response.json()
            self.assertEqual(result["default"], True)
            self.assertEqual(result["default_explanation"],
                             "No connected models found for query")