Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Link docker containers to allow unit testing #2628

Closed
jeff1evesque opened this issue Jul 4, 2016 · 26 comments
Closed

Link docker containers to allow unit testing #2628

jeff1evesque opened this issue Jul 4, 2016 · 26 comments

Comments

@jeff1evesque
Copy link
Owner

jeff1evesque commented Jul 4, 2016

This issue is a continuation of #2153. However, this issue will be more of a focus on accessing the environmental variables defined within the corresponding dockerfile. Specifically, we will use the environment variables to run the necessary docker logic. Then, we'll either conditionally run the unit tests (i.e. pytest), or the python application, based on the arguments supplied via the corresponding docker run command.

@jeff1evesque
Copy link
Owner Author

To start, we can list all available environment variables via the env argument. Specifically, changing the following from our .travis.yml:

...
  - docker run --link redis:container-redis --link database:container-database container-webserver bash -c "cd /var/machine-learning/test; py.test"
...

to the following implementation, with the env argument, should suffice:

...
  - docker run --link redis:container-redis --link database:container-database container-webserver bash -c "cd /var/machine-learning/test; py.test" env
...

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Jul 5, 2016

b4f68cf, 6c8e0c4: our pushed commits yield the following linked environment variables:

...
 docker run --link redis:container-redis --link database:container-database container-webserver env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=da20a026489b
CONTAINER_DATABASE_NAME=/admiring_brahmagupta/container-database
CONTAINER_REDIS_NAME=/admiring_brahmagupta/container-redis
HOME=/root
...

So, we see at least during the link within the webserver container, neither flask, nor mariadb is running, since no associated env variables exists.

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Jul 5, 2016

We need to look into caching within our travis ci implementation. This is important, because every travis statement exits with either 0, or 1. By design, a docker container will not persist, and therefore cannot be linked between multiple statements, within the .travis.yml.

Additionally, we still need to determine how to use docker locally:

$ docker -v
Docker version 1.11.2, build b9f10c9

$ ls
README.md    brain            hiera       log           test
Vagrantfile  build            hiera.yaml  puppet        
__init__.py  contributing.md  interface   settings.pyc
app.py       docker           license.md  src

$ ls -l docker
total 3
-rw-r--r--    1 Jeffrey     root      467 Jul  5 00:56 database.dockerfile
-rw-r--r--    1 Jeffrey     root     2348 Jul  5 00:56 default.dockerfile
-rw-r--r--    1 Jeffrey     root      387 Jul  4 20:09 redis.dockerfile
-rw-r--r--    1 Jeffrey     root      387 Jul  4 20:09 webserver.dockerfile

$ docker build docker/default.dockerfile
unable to prepare context: context must be a directory: C:\Users\Jeffrey\myprojects
\machine-learning\docker\default.dockerfile

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Jul 5, 2016

Our earlier troubles, can be remedied by running the Docker Quickstart Terminal, not the typical Git Bash, nor Command Prompt / Terminal:

docker-terminal

Once the above was determined, we knew we can implement a sql container locally:

$ docker build -f docker/database.dockerfile -t container-database .
Sending build context to Docker daemon 233.1 MB
Step 1 : FROM container-default
 ---> afed34cf406c
Step 2 : RUN /opt/puppetlabs/bin/puppet apply /var/machine-learning/puppet/envir
onment/development/manifests/setup_database.pp --modulepath=/var/machine-learnin
g/puppet/environment/development/modules_contrib:/var/machine-learning/puppet/en
vironment/development/modules --confdir=/var/machine-learning/test
 ---> Using cache
 ---> 20a15289dbd5
Step 3 : CMD mysqld
 ---> Using cache
 ---> a8ffeb6b9bd6
Successfully built a8ffeb6b9bd6
SECURITY WARNING: You are building a Docker image from Windows against a non-Win
dows Docker host. All files and directories added to build context will have '-r
wxr-xr-x' permissions. It is recommended to double check and reset permissions f
or sensitive files and directories.

$ docker run --name database container-database
160705 18:10:19 [Note] mysqld (mysqld 5.5.49-MariaDB-1ubuntu0.14.04.1) starting
as process 1 ...

Note: to be useful, the above command should be altered to run as a background process. This can be achieved via docker run -dt --name database container-database.

Additionally, we've determined how to debug docker locally, in context of the sql database container.

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Jul 5, 2016

We know we can implement a local redis implementation:

$ docker ps -a
CONTAINER ID        IMAGE                COMMAND             CREATED
 STATUS              PORTS               NAMES
f905b770f9a6        container-database   "mysqld"            2 hours ago
 Up 2 hours                              database

$ docker build -f docker/redis.dockerfile -t container-redis .
Sending build context to Docker daemon 233.1 MB
Step 1 : FROM container-default
 ---> afed34cf406c
Step 2 : RUN /opt/puppetlabs/bin/puppet apply /var/machine-learning/puppet/envir
onment/development/manifests/configure_redis.pp --modulepath=/var/machine-learni
ng/puppet/environment/development/modules_contrib:/var/machine-learning/puppet/e
nvironment/development/modules --confdir=/var/machine-learning/test
 ---> Using cache
 ---> 1eeaf1bfd14c
Step 3 : CMD redis-server
 ---> Using cache
 ---> f05badc69304
Successfully built f05badc69304
SECURITY WARNING: You are building a Docker image from Windows against a non-Win
dows Docker host. All files and directories added to build context will have '-r
wxr-xr-x' permissions. It is recommended to double check and reset permissions f
or sensitive files and directories.

$ docker run --name redis container-redis
[1] 05 Jul 17:50:51.131 # Warning: no config file specified, using the default c
onfig. In order to specify a config file use redis-server /path/to/redis.conf
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 2.8.4 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in stand alone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 1
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[1] 05 Jul 17:50:51.134 # Server started, Redis version 2.8.4
[1] 05 Jul 17:50:51.134 # WARNING overcommit_memory is set to 0! Background save
 may fail under low memory condition. To fix this issue add 'vm.overcommit_memor
y = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcom
mit_memory=1' for this to take effect.
[1] 05 Jul 17:50:51.134 * The server is now ready to accept connections on port
6379

$ docker ps -a
CONTAINER ID        IMAGE                COMMAND             CREATED
 STATUS              PORTS               NAMES
0fb1cbf7babf        container-redis      "redis-server"      5 minutes ago
 Up 5 minutes                            redis
f905b770f9a6        container-database   "mysqld"            3 hours ago
 Up 3 hours 

Note: our .travis.yml implements a background process via docker run -dt --name redis container-redis.

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Jul 6, 2016

Since link is deprecated, we'll need to implement docker network, which is supported by current docker version (currently 1.11.2).

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Jul 6, 2016

We need to implement the following kind of syntax:

docker network create -d bridge foobar && docker run --name web --net=foobar -d nginx:alpine && docker run --rm --net=foobar centos curl http://web/

The above notation, creates a network called foobar, starts up a container called web, and connects to the foobar network. Then, starts up a second container, called centos, having access to the web container. The curl http://web/ portion resolves the IP from the container named web, and connects to the second container.

Note: nginx:alpine is a specific nginx version provided by dockerhub.

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Jul 7, 2016

We removed all docker images, then attempted to create a network, as suggested above:

# stop all containers
$ docker stop $(docker ps -a -q)
0fb1cbf7babf

# delete all containers
$ docker rm $(docker ps -a -q)
0fb1cbf7babf

# delete all images
$ docker rmi $(docker images -q)

$ docker network rm app_nw

$ docker build -f docker/default.dockerfile -t container-default .
[TRACEBACK-OMITTED-DUE-TO-LENGTH]

$ docker build -f docker/database.dockerfile -t container-database .
Sending build context to Docker daemon 233.2 MB
Step 1 : FROM container-default
 ---> afed34cf406c
Step 2 : RUN /opt/puppetlabs/bin/puppet apply /var/machine-learning/puppet/envir
onment/development/manifests/setup_database.pp --modulepath=/var/machine-learnin
g/puppet/environment/development/modules_contrib:/var/machine-learning/puppet/en
vironment/development/modules --confdir=/var/machine-learning/test
 ---> Using cache
 ---> 20a15289dbd5
Step 3 : CMD mysqld
 ---> Using cache
 ---> a8ffeb6b9bd6
Successfully built a8ffeb6b9bd6
SECURITY WARNING: You are building a Docker image from Windows against a non-Win
dows Docker host. All files and directories added to build context will have '-r
wxr-xr-x' permissions. It is recommended to double check and reset permissions f
or sensitive files and directories.

$ docker build -f docker/webserver.dockerfile -t container-webserver .
Sending build context to Docker daemon 233.2 MB
Step 1 : FROM container-default
 ---> afed34cf406c
Step 2 : RUN /opt/puppetlabs/bin/puppet apply /var/machine-learning/puppet/envir
onment/development/manifests/start_webserver.pp --modulepath=/var/machine-learni
ng/puppet/environment/development/modules_contrib:/var/machine-learning/puppet/e
nvironment/development/modules --confdir=/var/machine-learning/test
 ---> Using cache
 ---> 9986e0df5137
Step 3 : WORKDIR /var/machine-learning
 ---> Using cache
 ---> 48b776a60a1f
Step 4 : CMD python app.py
 ---> Using cache
 ---> 946e02a63563
Successfully built 946e02a63563
SECURITY WARNING: You are building a Docker image from Windows against a non-Win
dows Docker host. All files and directories added to build context will have '-r
wxr-xr-x' permissions. It is recommended to double check and reset permissions f
or sensitive files and directories.

$ docker network create -d bridge app_nw && docker run --name default --net=app
_nw -d container-default && docker run --name database --net=app_nw -d containe
r-database && docker run --rm --net=app_nw container-webserver
cfb777eb3d9d5fa75451b9ce600e840324caa9f0c69d1fdd408055f8bf4733c8
829a02c1dee5ba5de4d9be7d76ec1f4e9f1cd7999bc0b90c360ae2445a82bf49
d5195d7c74c67b6fdb47f3b95fb0d557d2aee6e4dd26e20c10cfceb9f209b82b
Traceback (most recent call last):
  File "app.py", line 19, in <module>
    from interface import app
  File "/var/machine-learning/interface/__init__.py", line 16, in <module>
    import interface.views  # noqa
  File "/var/machine-learning/interface/views.py", line 11, in <module>
    from brain.load_data import Load_Data
  File "/var/machine-learning/brain/load_data.py", line 10, in <module>
    from brain.session.data_append import Data_Append
  File "/var/machine-learning/brain/session/data_append.py", line 15, in <module
>
    from brain.session.base_data import Base_Data
  File "/var/machine-learning/brain/session/base_data.py", line 13, in <module>
    from brain.session.data.save_feature_count import feature_count
  File "/var/machine-learning/brain/session/data/save_feature_count.py", line 11
, in <module>
    from brain.database.save_feature import Save_Feature
  File "/var/machine-learning/brain/database/save_feature.py", line 11, in <modu
le>
    from brain.database.db_query import SQL
  File "/var/machine-learning/brain/database/db_query.py", line 8, in <module>
    import MySQLdb as DB
ImportError: No module named MySQLdb

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Jul 7, 2016

The above ImportError helps bring to realization that the MySQLdb module in the database container, is not accessible within the webserver container. Therefore, we need to determine a mechanism that allows us to share file(s) between containers.

One consideration may involve data volumes. However, due to the current design of recycling puppet vagrant logic, we will likely have other similar issues. For example the redis container will have redis specific packages (including redis client), and modules that does not exist within the webserver container.

Alternatively, if it's not possible to implement FROM container1 container2 ... containerN, an alternative solution is to implement nested containers. Therefore, the webserver.dockerfile may implement FROM container-database, where database.dockerfile may be implement FROM container-redis, and redis.dockerfile may implement FROM container-default, then finally default.dockerfile would implement FROM ubuntu:14.04.

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Jul 7, 2016

To remediate the latter comment, we will create a new docker puppet environment, via #2632.

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Jul 9, 2016

We can debug our containers, by ssh'ing into them as follows:

# step 1: build container
$ docker build -f docker/redis.dockerfile -t <image-alias> .

# step 2: run container
$ docker run -dt --name <container-name> <image-alias>

# step 3: unix based
$ docker exec -it <container-name> bash
root@cdaa90138643:/#

# step 3: windows
$ winpty docker exec -it <container-name> bash
root@cdaa90138643:/#

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Jul 30, 2016

We temporarily removed the try / except, from the sql_connect method in db_query.py, then adjusted the indentation, within the sql_connect method, respectively. When we run the ./build_docker bash script, we get the following traceback:

$ cd /path/to/machine-learning
$ ./build_docker
...
9fc7c23522a84f707c0def1ee099d433a2cdb0ef67deaf84d672fb9ae4998dfb
5fd30a43d70e814d3dbf3ff25697732a82a9ac2f5f4d9173ebc12cb66201f010
8576b4dcccdb9c14c60df14e85c3763e8f947b1512d2641eb6092a6c092bf83b
c023de312efcc75075fe4273e1e1a64a35870e73d1a5150655396b0178b3363c
f173f712701cfb6ac9eb3fe4e1446c57df9fef16c9dfe332a2dd1413fdcff652
========================================= test session starts ==========================================
platform linux2 -- Python 2.7.6, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: /var/machine-learning/test, inifile: pytest.ini
plugins: flask-0.10.0
collected 6 items

test/programmatic_interface/pytest_svm_session.py F

=============================================== FAILURES ===============================================
____________________________________________ test_data_new _____________________________________________

client = <FlaskClient <Flask 'factory'>>, live_server = <LiveServer listening at http://localhost:41149>

    def test_data_new(client, live_server):
        '''@test_data_new

        This method tests the 'data_new' session.

        '''

        @live_server.app.route('/load-data/')
        def get_endpoint():
            return url_for('name.load_data', _external=True)

        live_server.start()

        res = client.post(
            get_endpoint(),
            headers={'Content-Type': 'application/json'},
>           data=get_sample_json('svm-data-new.json', 'svm')
        )

test/programmatic_interface/pytest_svm_session.py:71:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/lib/python2.7/dist-packages/werkzeug/test.py:788: in post
    return self.open(*args, **kw)
/usr/local/lib/python2.7/dist-packages/flask/testing.py:113: in open
    follow_redirects=follow_redirects)
/usr/local/lib/python2.7/dist-packages/werkzeug/test.py:751: in open
    response = self.run_wsgi_app(environ, buffered=buffered)
/usr/local/lib/python2.7/dist-packages/werkzeug/test.py:668: in run_wsgi_app
    rv = run_wsgi_app(self.application, environ, buffered=buffered)
/usr/local/lib/python2.7/dist-packages/werkzeug/test.py:871: in run_wsgi_app
    app_rv = app(environ, start_response)
/usr/local/lib/python2.7/dist-packages/flask/app.py:2000: in __call__
    return self.wsgi_app(environ, start_response)
/usr/local/lib/python2.7/dist-packages/flask/app.py:1991: in wsgi_app
    response = self.make_response(self.handle_exception(e))
/usr/local/lib/python2.7/dist-packages/flask/app.py:1567: in handle_exception
    reraise(exc_type, exc_value, tb)
/usr/local/lib/python2.7/dist-packages/flask/app.py:1988: in wsgi_app
    response = self.full_dispatch_request()
/usr/local/lib/python2.7/dist-packages/flask/app.py:1641: in full_dispatch_request
    rv = self.handle_user_exception(e)
/usr/local/lib/python2.7/dist-packages/flask/app.py:1544: in handle_user_exception
    reraise(exc_type, exc_value, tb)
/usr/local/lib/python2.7/dist-packages/flask/app.py:1639: in full_dispatch_request
    rv = self.dispatch_request()
/usr/local/lib/python2.7/dist-packages/flask/app.py:1625: in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
interface/views.py:84: in load_data
    response = loader.load_data_new()
brain/load_data.py:64: in load_data_new
    session_entity = session.save_entity('data_new')
brain/session/data_new.py:89: in save_entity
    db_return = db_save.save()
brain/database/save_entity.py:59: in save
    self.sql.sql_connect(self.db_ml)
brain/database/db_query.py:79: in sql_connect
    db=database,
/usr/lib/python2.7/dist-packages/MySQLdb/__init__.py:81: in Connect
    return Connection(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <_mysql.connection closed at e1f9b0>, args = ('database', 'authenticated', 'password')
kwargs = {'db': 'db_machine_learning'}
CLIENT = <module 'MySQLdb.constants.CLIENT' from '/usr/lib/python2.7/dist-packages/MySQLdb/constants/CLI
ENT.pyc'>
FIELD_TYPE = <module 'MySQLdb.constants.FIELD_TYPE' from '/usr/lib/python2.7/dist-packages/MySQLdb/const
ants/FIELD_TYPE.pyc'>
conversions = {0: <class 'decimal.Decimal'>, 1: <type 'int'>, 2: <type 'int'>, 3: <type 'long'>, ...}
proxy = <built-in function proxy>
WeakValueDictionary = <class weakref.WeakValueDictionary at 0x7f1dcf484530>
types = <module 'types' from '/usr/lib/python2.7/types.pyc'>
kwargs2 = {'client_flag': 196608, 'conv': {0: <class 'decimal.Decimal'>, 1: <type 'int'>, 2: <type 'int'
>, 3: <type 'long'>, ...}, 'db': 'db_machine_learning'}
conv = {0: <class 'decimal.Decimal'>, 1: <type 'int'>, 2: <type 'int'>, 3: <type 'long'>, ...}
conv2 = {0: <class 'decimal.Decimal'>, 1: <type 'int'>, 2: <type 'int'>, 3: <type 'long'>, ...}, k = 254

    def __init__(self, *args, **kwargs):
        """

            Create a connection to the database. It is strongly recommended
            that you only use keyword parameters. Consult the MySQL C API
            documentation for more information.

            host
              string, host to connect

            user
              string, user to connect as

            passwd
              string, password to use

            db
              string, database to use

            port
              integer, TCP/IP port to connect to

            unix_socket
              string, location of unix_socket to use

            conv
              conversion dictionary, see MySQLdb.converters

            connect_timeout
              number of seconds to wait before the connection attempt
              fails.

            compress
              if set, compression is enabled

            named_pipe
              if set, a named pipe is used to connect (Windows only)

            init_command
              command which is run once the connection is created

            read_default_file
              file from which default client values are read

            read_default_group
              configuration group to use from the default file

            cursorclass
              class object, used to create cursors (keyword only)

            use_unicode
              If True, text-like columns are returned as unicode objects
              using the connection's character set.  Otherwise, text-like
              columns are returned as strings.  columns are returned as
              normal strings. Unicode objects will always be encoded to
              the connection's character set regardless of this setting.

            charset
              If supplied, the connection character set will be changed
              to this character set (MySQL-4.1 and newer). This implies
              use_unicode=True.

            sql_mode
              If supplied, the session SQL mode will be changed to this
              setting (MySQL-4.1 and newer). For more details and legal
              values, see the MySQL documentation.

            client_flag
              integer, flags to use or 0
              (see MySQL docs or constants/CLIENTS.py)

            ssl
              dictionary or mapping, contains SSL connection parameters;
              see the MySQL documentation for more details
              (mysql_ssl_set()).  If this is set, and the client does not
              support SSL, NotSupportedError will be raised.

            local_infile
              integer, non-zero enables LOAD LOCAL INFILE; zero disables

            There are a number of undocumented, non-standard methods. See the
            documentation for the MySQL C API for some hints on what they do.

            """
        from constants import CLIENT, FIELD_TYPE
        from converters import conversions
        from weakref import proxy, WeakValueDictionary

        import types

        kwargs2 = kwargs.copy()

        if kwargs.has_key('conv'):
            conv = kwargs['conv']
        else:
            conv = conversions

        conv2 = {}
        for k, v in conv.items():
            if isinstance(k, int) and isinstance(v, list):
                conv2[k] = v[:]
            else:
                conv2[k] = v
        kwargs2['conv'] = conv2

        self.cursorclass = kwargs2.pop('cursorclass', self.default_cursor)
        charset = kwargs2.pop('charset', '')

        if charset:
            use_unicode = True
        else:
            use_unicode = False

        use_unicode = kwargs2.pop('use_unicode', use_unicode)
        sql_mode = kwargs2.pop('sql_mode', '')

        client_flag = kwargs.get('client_flag', 0)
        client_version = tuple([ numeric_part(n) for n in _mysql.get_client_info().split('.')[:2] ])
        if client_version >= (4, 1):
            client_flag |= CLIENT.MULTI_STATEMENTS
        if client_version >= (5, 0):
            client_flag |= CLIENT.MULTI_RESULTS

        kwargs2['client_flag'] = client_flag

>       super(Connection, self).__init__(*args, **kwargs2)
E       OperationalError: (2003, "Can't connect to MySQL server on 'database' (111)")

/usr/lib/python2.7/dist-packages/MySQLdb/connections.py:187: OperationalError
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
======================================= 1 failed in 1.38 seconds =======================================

So, we need to ensure that we've properly defined the DB.connect() parameters, and that the corresponding mysqld service, is properly running within the database instance, of the container-database.

@jeff1evesque
Copy link
Owner Author

When we inspect our docker network, we get the following:

$ docker network inspect app_nw
[
    {
        "Name": "app_nw",
        "Id": "ce70c0a7d99e9be8e62b7b42ab8626ff730e1419696bce2e80ff86460903ebdc",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "xxx.yy.0.0/16",
                    "Gateway": "xxx.yy.0.1/16"
                }
            ]
        },
        "Internal": false,
        "Containers": {
            "122713abf4c40d239fbc9e956834dc76e9604a70b9ce34417cc1b05bc9789023": {
                "Name": "redis",
                "EndpointID": "d9a68884704d0cb9783c00602600984032e6769e089d4eb8b0d990f2187a260a",
                "MacAddress": "xx:bb:aa:12:00:02",
                "IPv4Address": "xxx.yy.0.2/16",
                "IPv6Address": ""
            },
            "42f867aaa4481b22250c4a8728686b3a602cd420962ea755700f4eed9bf96d4f": {
                "Name": "database",
                "EndpointID": "ece9c51ba910504204ee35ef1d5d297fd47b762ba2c035a1dc3cd43d1ae38e17",
                "MacAddress": "xx:bb:aa:12:00:04",
                "IPv4Address": "xxx.yy.0.4/16",
                "IPv6Address": ""
            },
            "a61ded157c3a3b36f9f0659e78452b4019c4419f35d52213d021a8205d11c020": {
                "Name": "webserver",
                "EndpointID": "8414d4d6301b68651e5545a9405d857f6c0aea06e0ef916cbbbb430811aba320",
                "MacAddress": "xx:bb:aa:12:00:03",
                "IPv4Address": "xxx.yy.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

@jeff1evesque
Copy link
Owner Author

A bind-address = 0.0.0.0, defined within the /etc/mysql/my.cnf, allows the mysqld service to be exposed within the common bridged app_nw network. Luckily, the docker implementation, restricts this exposed service to be contained within the common network, unless explicitly exposed to the host, or routed to another network.

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Jul 31, 2016

When we rebuild our docker container, we get the following traceback:

...
307ce89a912f812ff1b2a0c1280bbb10b6b49f297650b943786c7d62f9893754
a9b0ff66057ca73ff82be5d530a8ce4cc22859e6945a153c870d75784f12b85a
7b23e1ced764972600dec704cad4554bf8aa897d00484140842684438bf15209
0d644f970e1554318c0f395377eac80f3444a7bfc1c8022c0ee06b4357446a51
097f6b3092ae3f760885b3b9abdf314f4d6cff4aed407e5744df8f5ee1d13b5e
======================================== test session starts ========================================
platform linux2 -- Python 2.7.6, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: /var/machine-learning/test, inifile: pytest.ini
plugins: flask-0.10.0
collected 6 items

test/programmatic_interface/pytest_svm_session.py F

============================================= FAILURES ==============================================
___________________________________________ test_data_new ___________________________________________

client = <FlaskClient <Flask 'factory'>>
live_server = <LiveServer listening at http://localhost:50010>

    def test_data_new(client, live_server):
        '''@test_data_new

        This method tests the 'data_new' session.

        '''

        @live_server.app.route('/load-data/')
        def get_endpoint():
            return url_for('name.load_data', _external=True)

        live_server.start()

        res = client.post(
            get_endpoint(),
            headers={'Content-Type': 'application/json'},
>           data=get_sample_json('svm-data-new.json', 'svm')
        )

test/programmatic_interface/pytest_svm_session.py:71:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/lib/python2.7/dist-packages/werkzeug/test.py:788: in post
    return self.open(*args, **kw)
/usr/local/lib/python2.7/dist-packages/flask/testing.py:113: in open
    follow_redirects=follow_redirects)
/usr/local/lib/python2.7/dist-packages/werkzeug/test.py:751: in open
    response = self.run_wsgi_app(environ, buffered=buffered)
/usr/local/lib/python2.7/dist-packages/werkzeug/test.py:668: in run_wsgi_app
    rv = run_wsgi_app(self.application, environ, buffered=buffered)
/usr/local/lib/python2.7/dist-packages/werkzeug/test.py:871: in run_wsgi_app
    app_rv = app(environ, start_response)
/usr/local/lib/python2.7/dist-packages/flask/app.py:2000: in __call__
    return self.wsgi_app(environ, start_response)
/usr/local/lib/python2.7/dist-packages/flask/app.py:1991: in wsgi_app
    response = self.make_response(self.handle_exception(e))
/usr/local/lib/python2.7/dist-packages/flask/app.py:1567: in handle_exception
    reraise(exc_type, exc_value, tb)
/usr/local/lib/python2.7/dist-packages/flask/app.py:1988: in wsgi_app
    response = self.full_dispatch_request()
/usr/local/lib/python2.7/dist-packages/flask/app.py:1641: in full_dispatch_request
    rv = self.handle_user_exception(e)
/usr/local/lib/python2.7/dist-packages/flask/app.py:1544: in handle_user_exception
    reraise(exc_type, exc_value, tb)
/usr/local/lib/python2.7/dist-packages/flask/app.py:1639: in full_dispatch_request
    rv = self.dispatch_request()
/usr/local/lib/python2.7/dist-packages/flask/app.py:1625: in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
interface/views.py:84: in load_data
    response = loader.load_data_new()
brain/load_data.py:64: in load_data_new
    session_entity = session.save_entity('data_new')
brain/session/data_new.py:89: in save_entity
    db_return = db_save.save()
brain/database/save_entity.py:59: in save
    self.sql.sql_connect(self.db_ml)
brain/database/db_query.py:79: in sql_connect
    db=database,
/usr/lib/python2.7/dist-packages/MySQLdb/__init__.py:81: in Connect
    return Connection(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <_mysql.connection closed at 26b41e0>, args = ('database', 'authenticated', 'password')
kwargs = {'db': 'db_machine_learning'}
CLIENT = <module 'MySQLdb.constants.CLIENT' from '/usr/lib/python2.7/dist-packages/MySQLdb/constants/
CLIENT.pyc'>
FIELD_TYPE = <module 'MySQLdb.constants.FIELD_TYPE' from '/usr/lib/python2.7/dist-packages/MySQLdb/co
nstants/FIELD_TYPE.pyc'>
conversions = {0: <class 'decimal.Decimal'>, 1: <type 'int'>, 2: <type 'int'>, 3: <type 'long'>, ...}
proxy = <built-in function proxy>
WeakValueDictionary = <class weakref.WeakValueDictionary at 0x7f6a9916a530>
types = <module 'types' from '/usr/lib/python2.7/types.pyc'>
kwargs2 = {'client_flag': 196608, 'conv': {0: <class 'decimal.Decimal'>, 1: <type 'int'>, 2: <type 'i
nt'>, 3: <type 'long'>, ...}, 'db': 'db_machine_learning'}
conv = {0: <class 'decimal.Decimal'>, 1: <type 'int'>, 2: <type 'int'>, 3: <type 'long'>, ...}
conv2 = {0: <class 'decimal.Decimal'>, 1: <type 'int'>, 2: <type 'int'>, 3: <type 'long'>, ...}
k = 254

    def __init__(self, *args, **kwargs):
        """

            Create a connection to the database. It is strongly recommended
            that you only use keyword parameters. Consult the MySQL C API
            documentation for more information.

            host
              string, host to connect

            user
              string, user to connect as

            passwd
              string, password to use

            db
              string, database to use

            port
              integer, TCP/IP port to connect to

            unix_socket
              string, location of unix_socket to use

            conv
              conversion dictionary, see MySQLdb.converters

            connect_timeout
              number of seconds to wait before the connection attempt
              fails.

            compress
              if set, compression is enabled

            named_pipe
              if set, a named pipe is used to connect (Windows only)

            init_command
              command which is run once the connection is created

            read_default_file
              file from which default client values are read

            read_default_group
              configuration group to use from the default file

            cursorclass
              class object, used to create cursors (keyword only)

            use_unicode
              If True, text-like columns are returned as unicode objects
              using the connection's character set.  Otherwise, text-like
              columns are returned as strings.  columns are returned as
              normal strings. Unicode objects will always be encoded to
              the connection's character set regardless of this setting.

            charset
              If supplied, the connection character set will be changed
              to this character set (MySQL-4.1 and newer). This implies
              use_unicode=True.

            sql_mode
              If supplied, the session SQL mode will be changed to this
              setting (MySQL-4.1 and newer). For more details and legal
              values, see the MySQL documentation.

            client_flag
              integer, flags to use or 0
              (see MySQL docs or constants/CLIENTS.py)

            ssl
              dictionary or mapping, contains SSL connection parameters;
              see the MySQL documentation for more details
              (mysql_ssl_set()).  If this is set, and the client does not
              support SSL, NotSupportedError will be raised.

            local_infile
              integer, non-zero enables LOAD LOCAL INFILE; zero disables

            There are a number of undocumented, non-standard methods. See the
            documentation for the MySQL C API for some hints on what they do.

            """
        from constants import CLIENT, FIELD_TYPE
        from converters import conversions
        from weakref import proxy, WeakValueDictionary

        import types

        kwargs2 = kwargs.copy()

        if kwargs.has_key('conv'):
            conv = kwargs['conv']
        else:
            conv = conversions

        conv2 = {}
        for k, v in conv.items():
            if isinstance(k, int) and isinstance(v, list):
                conv2[k] = v[:]
            else:
                conv2[k] = v
        kwargs2['conv'] = conv2

        self.cursorclass = kwargs2.pop('cursorclass', self.default_cursor)
        charset = kwargs2.pop('charset', '')

        if charset:
            use_unicode = True
        else:
            use_unicode = False

        use_unicode = kwargs2.pop('use_unicode', use_unicode)
        sql_mode = kwargs2.pop('sql_mode', '')

        client_flag = kwargs.get('client_flag', 0)
        client_version = tuple([ numeric_part(n) for n in _mysql.get_client_info().split('.')[:2] ])
        if client_version >= (4, 1):
            client_flag |= CLIENT.MULTI_STATEMENTS
        if client_version >= (5, 0):
            client_flag |= CLIENT.MULTI_RESULTS

        kwargs2['client_flag'] = client_flag

>       super(Connection, self).__init__(*args, **kwargs2)
E       OperationalError: (1130, "Host 'webserver-pytest.app_nw' is not allowed to connect to this Ma
riaDB server")

/usr/lib/python2.7/dist-packages/MySQLdb/connections.py:187: OperationalError
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
===================================== 1 failed in 1.46 seconds ======================================

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Jul 31, 2016

We notice the bind-address was correctly adjusted within /etc/mysql/my.cnf:

### MANAGED BY PUPPET ###

[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock

[isamchk]
key_buffer_size = 16M

[mysqld]
basedir = /usr
bind-address = 0.0.0.0
datadir = /var/lib/mysql
expire_logs_days = 10
key_buffer_size = 16M
log-error = /var/log/mysql/error.log
max_allowed_packet = 16M
max_binlog_size = 100M
max_connections = 151
myisam_recover = BACKUP
pid-file = /var/run/mysqld/mysqld.pid
port = 3306
query_cache_limit = 1M
query_cache_size = 16M
skip-external-locking
socket = /var/run/mysqld/mysqld.sock
ssl = false
ssl-ca = /etc/mysql/cacert.pem
ssl-cert = /etc/mysql/server-cert.pem
ssl-key = /etc/mysql/server-key.pem
thread_cache_size = 8
thread_stack = 256K
tmpdir = /tmp
user = mysql
...

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Aug 2, 2016

After running ./build_docker bash script, we can verify the container-database retains the py.test dataset (from the svm test case):

$ docker ps -a
CONTAINER ID        IMAGE                 COMMAND                CREATED             STATUS                      PORTS               NAMES
39c64f3b7c7a        container-webserver   "python app.py test"   27 minutes ago      Exited (0) 27 minutes ago                       webserver-pytest
793a2ff6ec67        container-database    "mysqld"               27 minutes ago      Up 27 minutes                                   database
5725c4040967        container-webserver   "python app.py run"    27 minutes ago      Up 27 minutes                                   webserver
d341fa4dbd44        container-redis       "redis-server"         27 minutes ago      Up 27 minutes                                   redis
5ec1f0e29334        container-default     "/bin/bash"            27 minutes ago      Exited (0) 27 minutes ago                       base

$ winpty docker exec -it database bash
root@793a2ff6ec67:/# mysql -u root -p db_machine_learning
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 84
Server version: 5.5.49-MariaDB-1ubuntu0.14.04.1 (Ubuntu)

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [db_machine_learning]> show tables;
+-------------------------------+
| Tables_in_db_machine_learning |
+-------------------------------+
| tbl_dataset_entity            |
| tbl_feature_count             |
| tbl_feature_value             |
| tbl_model_type                |
| tbl_observation_label         |
+-------------------------------+
5 rows in set (0.00 sec)

MariaDB [db_machine_learning]> select * from tbl_dataset_entity;
+-----------+------------------+------------+-------------+---------------------+--------------+---------------------+
| id_entity | title            | model_type | uid_created | datetime_created    | uid_modified | datetime_modified   |
+-----------+------------------+------------+-------------+---------------------+--------------+---------------------+
|         1 | sample_svm_title |          1 |           1 | 2016-08-02 00:54:07 |            1 | 2016-08-02 00:54:09 |
+-----------+------------------+------------+-------------+---------------------+--------------+---------------------+
1 row in set (0.00 sec)

MariaDB [db_machine_learning]> select * from tbl_feature_count;
+---------+-----------+----------------+
| id_size | id_entity | count_features |
+---------+-----------+----------------+
|       1 |         1 |              7 |
+---------+-----------+----------------+
1 row in set (0.00 sec)

MariaDB [db_machine_learning]> select * from tbl_observation_label;
+----------+-----------+--------------------+
| id_label | id_entity | dep_variable_label |
+----------+-----------+--------------------+
|        1 |         1 | dep-variable-5     |
|        2 |         1 | dep-variable-4     |
|        3 |         1 | dep-variable-1     |
|        4 |         1 | dep-variable-3     |
|        5 |         1 | dep-variable-2     |
+----------+-----------+--------------------+
5 rows in set (0.00 sec)

MariaDB [db_machine_learning]> select * from tbl_model_type;
+----------+----------------+
| id_model | model          |
+----------+----------------+
|        1 | classification |
|        2 | regression     |
+----------+----------------+
2 rows in set (0.00 sec)

MariaDB [db_machine_learning]> select * from tbl_feature_value;
+----------+-----------+--------------------+-----------+----------------------+----------------------+
| id_value | id_entity | dep_variable_label | criterion | indep_variable_label | indep_variable_value |
+----------+-----------+--------------------+-----------+----------------------+----------------------+
|        1 |         1 | dep-variable-5     |      NULL | indep-variable-6     |                0.001 |
|        2 |         1 | dep-variable-5     |      NULL | indep-variable-7     |                   27 |
|        3 |         1 | dep-variable-5     |      NULL | indep-variable-4     |                  295 |
|        4 |         1 | dep-variable-5     |      NULL | indep-variable-5     |                55.83 |
|        5 |         1 | dep-variable-5     |      NULL | indep-variable-2     |                95.03 |
|        6 |         1 | dep-variable-5     |      NULL | indep-variable-3     |                0.488 |
|        7 |         1 | dep-variable-5     |      NULL | indep-variable-1     |                23.27 |
|        8 |         1 | dep-variable-5     |      NULL | indep-variable-6     |                0.001 |
|        9 |         1 | dep-variable-5     |      NULL | indep-variable-7     |                   27 |
|       10 |         1 | dep-variable-5     |      NULL | indep-variable-4     |                  295 |
|       11 |         1 | dep-variable-5     |      NULL | indep-variable-5     |                55.83 |
|       12 |         1 | dep-variable-5     |      NULL | indep-variable-2     |                95.03 |
|       13 |         1 | dep-variable-5     |      NULL | indep-variable-3     |                0.488 |
|       14 |         1 | dep-variable-5     |      NULL | indep-variable-1     |                23.27 |
|       15 |         1 | dep-variable-5     |      NULL | indep-variable-6     |                0.001 |
|       16 |         1 | dep-variable-5     |      NULL | indep-variable-7     |                   29 |
|       17 |         1 | dep-variable-5     |      NULL | indep-variable-4     |                  303 |
|       18 |         1 | dep-variable-5     |      NULL | indep-variable-5     |                58.88 |
|       19 |         1 | dep-variable-5     |      NULL | indep-variable-2     |                97.78 |
|       20 |         1 | dep-variable-5     |      NULL | indep-variable-3     |                0.638 |
|       21 |         1 | dep-variable-5     |      NULL | indep-variable-1     |                19.99 |
|       22 |         1 | dep-variable-4     |      NULL | indep-variable-6     |                0.001 |
|       23 |         1 | dep-variable-4     |      NULL | indep-variable-7     |                   32 |
|       24 |         1 | dep-variable-4     |      NULL | indep-variable-4     |                  342 |
|       25 |         1 | dep-variable-4     |      NULL | indep-variable-5     |                66.67 |
|       26 |         1 | dep-variable-4     |      NULL | indep-variable-2     |                95.96 |
|       27 |         1 | dep-variable-4     |      NULL | indep-variable-3     |                0.743 |
|       28 |         1 | dep-variable-4     |      NULL | indep-variable-1     |                 22.1 |
|       29 |         1 | dep-variable-4     |      NULL | indep-variable-6     |                0.001 |
|       30 |         1 | dep-variable-4     |      NULL | indep-variable-7     |                   30 |
|       31 |         1 | dep-variable-4     |      NULL | indep-variable-4     |                  342 |
|       32 |         1 | dep-variable-4     |      NULL | indep-variable-5     |                75.67 |
|       33 |         1 | dep-variable-4     |      NULL | indep-variable-2     |                99.33 |
|       34 |         1 | dep-variable-4     |      NULL | indep-variable-3     |                0.648 |
|       35 |         1 | dep-variable-4     |      NULL | indep-variable-1     |                20.71 |
|       36 |         1 | dep-variable-1     |      NULL | indep-variable-6     |                0.002 |
|       37 |         1 | dep-variable-1     |      NULL | indep-variable-7     |                   23 |
|       38 |         1 | dep-variable-1     |      NULL | indep-variable-4     |                  325 |
|       39 |         1 | dep-variable-1     |      NULL | indep-variable-5     |                54.64 |
|       40 |         1 | dep-variable-1     |      NULL | indep-variable-2     |                98.01 |
|       41 |         1 | dep-variable-1     |      NULL | indep-variable-3     |                0.432 |
|       42 |         1 | dep-variable-1     |      NULL | indep-variable-1     |                23.45 |
|       43 |         1 | dep-variable-3     |      NULL | indep-variable-6     |                0.002 |
|       44 |         1 | dep-variable-3     |      NULL | indep-variable-7     |                   26 |
|       45 |         1 | dep-variable-3     |      NULL | indep-variable-4     |                  427 |
|       46 |         1 | dep-variable-3     |      NULL | indep-variable-5     |                75.45 |
|       47 |         1 | dep-variable-3     |      NULL | indep-variable-2     |               101.21 |
|       48 |         1 | dep-variable-3     |      NULL | indep-variable-3     |                0.832 |
|       49 |         1 | dep-variable-3     |      NULL | indep-variable-1     |                22.67 |
|       50 |         1 | dep-variable-1     |      NULL | indep-variable-6     |                0.002 |
|       51 |         1 | dep-variable-1     |      NULL | indep-variable-7     |                   25 |
|       52 |         1 | dep-variable-1     |      NULL | indep-variable-4     |                  325 |
|       53 |         1 | dep-variable-1     |      NULL | indep-variable-5     |                54.64 |
|       54 |         1 | dep-variable-1     |      NULL | indep-variable-2     |                98.01 |
|       55 |         1 | dep-variable-1     |      NULL | indep-variable-3     |                0.432 |
|       56 |         1 | dep-variable-1     |      NULL | indep-variable-1     |                23.45 |
|       57 |         1 | dep-variable-3     |      NULL | indep-variable-6     |                0.002 |
|       58 |         1 | dep-variable-3     |      NULL | indep-variable-7     |                   24 |
|       59 |         1 | dep-variable-3     |      NULL | indep-variable-4     |                  427 |
|       60 |         1 | dep-variable-3     |      NULL | indep-variable-5     |                75.45 |
|       61 |         1 | dep-variable-3     |      NULL | indep-variable-2     |               101.21 |
|       62 |         1 | dep-variable-3     |      NULL | indep-variable-3     |                0.832 |
|       63 |         1 | dep-variable-3     |      NULL | indep-variable-1     |                22.67 |
|       64 |         1 | dep-variable-2     |      NULL | indep-variable-6     |                0.001 |
|       65 |         1 | dep-variable-2     |      NULL | indep-variable-7     |                   31 |
|       66 |         1 | dep-variable-2     |      NULL | indep-variable-4     |                  235 |
|       67 |         1 | dep-variable-2     |      NULL | indep-variable-5     |                64.45 |
|       68 |         1 | dep-variable-2     |      NULL | indep-variable-2     |                92.22 |
|       69 |         1 | dep-variable-2     |      NULL | indep-variable-3     |                0.356 |
|       70 |         1 | dep-variable-2     |      NULL | indep-variable-1     |                24.32 |
+----------+-----------+--------------------+-----------+----------------------+----------------------+
70 rows in set (0.00 sec)

However, we notice nothing is stored in the redis-server, in the corresponding redis container, after the py.test is executed (from the svm test case):

$ winpty docker exec -it redis bash
root@9fcc9deeab14:/# redis-cli
127.0.0.1:6379> keys *
(empty list or set)

@jeff1evesque
Copy link
Owner Author

jeff1evesque commented Aug 2, 2016

Currently, 3/4 tests pass, for the svm case:

$ ./build_docker
...
346d0f4fbebf6f6eb2563a29e8c8d4ddfd663490f50316d4202d39843cbd1cfd
15b03a63743866162d47b97f5c936b05a6df65ed2487e773f75b569428aedf47
a97ca81c257ba36806429df44b59fd44d9a421bda85d645900293df21b4e8b19
60ef578c87e0a114d114899daf6f3d71b861b402aa7ec7727d9a9a5337ffec71
801bb4250a2d97676d5bd6ed1529220d79e026e4cc982e041886170e968f772f
================================================== test session starts ==================================================
platform linux2 -- Python 2.7.6, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: /var/machine-learning/test, inifile: pytest.ini
plugins: flask-0.10.0
collected 6 items

test/programmatic_interface/pytest_svm_session.py ...F

======================================================= FAILURES ========================================================
__________________________________________________ test_model_predict ___________________________________________________

client = <FlaskClient <Flask 'factory'>>, live_server = <LiveServer listening at http://localhost:42339>

    def test_model_predict(client, live_server):
        '''@test_model_predict

        This method tests the 'model_predict' session.

        '''

        @live_server.app.route('/load-data/')
        def get_endpoint():
            return url_for('name.load_data', _external=True)

        live_server.start()

        res = client.post(
            get_endpoint(),
            headers={'Content-Type': 'application/json'},
>           data=get_sample_json('svm-model-predict.json', 'svm')
        )

test/programmatic_interface/pytest_svm_session.py:137:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/lib/python2.7/dist-packages/werkzeug/test.py:788: in post
    return self.open(*args, **kw)
/usr/local/lib/python2.7/dist-packages/flask/testing.py:113: in open
    follow_redirects=follow_redirects)
/usr/local/lib/python2.7/dist-packages/werkzeug/test.py:751: in open
    response = self.run_wsgi_app(environ, buffered=buffered)
/usr/local/lib/python2.7/dist-packages/werkzeug/test.py:668: in run_wsgi_app
    rv = run_wsgi_app(self.application, environ, buffered=buffered)
/usr/local/lib/python2.7/dist-packages/werkzeug/test.py:871: in run_wsgi_app
    app_rv = app(environ, start_response)
/usr/local/lib/python2.7/dist-packages/flask/app.py:2000: in __call__
    return self.wsgi_app(environ, start_response)
/usr/local/lib/python2.7/dist-packages/flask/app.py:1991: in wsgi_app
    response = self.make_response(self.handle_exception(e))
/usr/local/lib/python2.7/dist-packages/flask/app.py:1567: in handle_exception
    reraise(exc_type, exc_value, tb)
/usr/local/lib/python2.7/dist-packages/flask/app.py:1988: in wsgi_app
    response = self.full_dispatch_request()
/usr/local/lib/python2.7/dist-packages/flask/app.py:1641: in full_dispatch_request
    rv = self.handle_user_exception(e)
/usr/local/lib/python2.7/dist-packages/flask/app.py:1544: in handle_user_exception
    reraise(exc_type, exc_value, tb)
/usr/local/lib/python2.7/dist-packages/flask/app.py:1639: in full_dispatch_request
    rv = self.dispatch_request()
/usr/local/lib/python2.7/dist-packages/flask/app.py:1625: in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
interface/views.py:90: in load_data
    response = loader.load_model_predict()
brain/load_data.py:165: in load_model_predict
    my_prediction = session.predict()
brain/session/model_predict.py:66: in predict
    return svm_prediction('svm', 'rbf', self.model_id, self.predictors)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

model = 'svm', kernel = 'rbf', model_id = '1', predictors = ['22.22', '96.24', '338', '72.55', '0.001', '28', ...]

    def svm_prediction(model, kernel, model_id, predictors):
        '''@svm_prediction

        This method generates an svm prediction using the provided prediction
        feature input(s), and the stored corresponding model, within the NoSQL
        datastore.

        @predictors, a list of arguments (floats) required to make an SVM
            prediction, against the respective svm model.

        '''

        # get necessary model
        title = Cache_Hset().uncache(
            model + '_' + kernel + '_title',
            model_id
        )['result']
        clf = Cache_Model().uncache(
            model + '_' + kernel + '_model',
>           model_id + '_' + title
        )
E       TypeError: coercing to Unicode: need string or buffer, NoneType found

brain/session/predict/svm.py:32: TypeError
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================== 1 failed, 3 passed in 5.32 seconds ===========================================

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant