Merge pull request #5 from apache/develop

[MARVIN-19] Init PR to Master
diff --git a/.travis.yml b/.travis.yml
index 4d0de99..08689ac 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,7 +30,7 @@
       before_script:
         - cd engine-executor
         - unset SBT_OPTS
-      script: sbt ++$TRAVIS_SCALA_VERSION coverage test coverageReport
+      script: travis_retry sbt ++$TRAVIS_SCALA_VERSION coverage test coverageReport
     # Python Toolbox
     # Python Toolbox - Linux
     - language: python
@@ -40,7 +40,7 @@
         - 3.6
       before_install:
         - cd python-toolbox
-        - curl https://d3kbcqa49mib13.cloudfront.net/spark-2.1.1-bin-hadoop2.6.tgz -o ./spark-2.1.1-bin-hadoop2.6.tgz
+        - travis_retry curl https://d3kbcqa49mib13.cloudfront.net/spark-2.1.1-bin-hadoop2.6.tgz -o ./spark-2.1.1-bin-hadoop2.6.tgz
         - sudo tar -xf ./spark-2.1.1-bin-hadoop2.6.tgz
         - mkdir -p marvin_data
         - mkdir -p marvin_home
@@ -52,12 +52,12 @@
         - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update                    ; fi
         - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openssl graphviz  ; fi
         - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install libsasl2-dev python-pip graphviz -y    ; fi
-        - sudo pip install --upgrade pip
-        - sudo pip install virtualenvwrapper --ignore-installed six
+        - travis_retry sudo pip install --upgrade pip
+        - travis_retry sudo pip install virtualenvwrapper --ignore-installed six
         - source virtualenvwrapper.sh
         - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mkvirtualenv marvin-env        ; fi
       install:
-        - pip install codecov
+        - travis_retry pip install codecov
         - make marvin
       script:
         - marvin test
@@ -67,7 +67,7 @@
       os: osx
       before_install:
         - cd python-toolbox
-        - curl https://d3kbcqa49mib13.cloudfront.net/spark-2.1.1-bin-hadoop2.6.tgz -o ./spark-2.1.1-bin-hadoop2.6.tgz
+        - travis_retry curl https://d3kbcqa49mib13.cloudfront.net/spark-2.1.1-bin-hadoop2.6.tgz -o ./spark-2.1.1-bin-hadoop2.6.tgz
         - sudo tar -xf ./spark-2.1.1-bin-hadoop2.6.tgz
         - mkdir -p marvin_data
         - mkdir -p marvin_home
@@ -79,12 +79,12 @@
         - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update                    ; fi
         - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openssl graphviz  ; fi
         - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install libsasl2-dev python-pip graphviz -y    ; fi
-        - sudo pip install --upgrade pip
-        - sudo pip install virtualenvwrapper --ignore-installed six
+        - travis_retry sudo pip install --upgrade pip
+        - travis_retry sudo pip install virtualenvwrapper --ignore-installed six
         - source virtualenvwrapper.sh
         - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mkvirtualenv marvin-env        ; fi
       install:
-        - pip install codecov
+        - travis_retry pip install codecov
         - make marvin
       script:
         - marvin test
diff --git a/README.md b/README.md
index 8fd01ab..bc4dcf0 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,48 @@
-# Apache Marvin AI Platform
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
 
-![](https://images-americanas.b2w.io/img/_staging/marvin/marvin.png)
+    http://www.apache.org/licenses/LICENSE-2.0
 
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# [Apache Marvin AI Platform](https://marvin.apache.org/)
+
+![](https://github.com/apache/incubator-marvin-website/blob/master/site/assets/themes/apache/img/logo.png?raw=true)
+
+[![Build Status](https://travis-ci.org/apache/incubator-marvin.svg?branch=master)](https://travis-ci.org/apache/incubator-marvin)
 
 **Marvin** is an open-source Artificial Intelligence platform that focuses on helping data scientists deliver meaningful solutions to complex problems. Supported by a standardized large-scale, language-agnostic architecture, Marvin simplifies the process of exploration and modeling.
+
+## Getting Started
+
+[Website!](https://marvin.apache.org)
+
+## Bug Reports and Feature Requests
+
+[Apache JIRA](https://issues.apache.org/jira/projects/MARVIN/issues/)
+
+## Community
+
+ - Subscribe to the [user mailing list](mailto:user-subscribe@marvin.apache.org)!
+
+ - Subscribe to the [dev mailing list](mailto:dev-subscribe@marvin.apache.org)!
+
+## Contributing
+
+Please follow the [Contribution Guidelines](https://issues.apache.org/jira/projects/MARVIN/issues/MARVIN-8)
+
+For website and documentation contribution, check our [Website Repository](https://github.com/apache/incubator-marvin)
+
+## License
+
+Apache Marvin-AI is under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0.html).
diff --git a/python-toolbox/README.md b/python-toolbox/README.md
index 2bbce65..eb1d459 100644
--- a/python-toolbox/README.md
+++ b/python-toolbox/README.md
@@ -13,9 +13,9 @@
 **Marvin** is an open-source Artificial Intelligence platform that focuses on helping data scientists deliver meaningful solutions to complex problems. Supported by a standardized large-scale, language-agnostic architecture, Marvin simplifies the process of exploration and modeling.
 
 ## Getting Started
-* [Installing Marvin (Ubuntu)](https://www.marvin-ai.org/book/installing-marvin/ubuntu-debian-installation)
-* [Installing Marvin (MacOS)](https://www.marvin-ai.org/book/installing-marvin/macos-installation)
-* [Installing Marvin (Other OS) Vagrant](https://www.marvin-ai.org/book/installing-marvin/vagrant-installation)
+* [Installing Marvin (Ubuntu)](https://www.marvin-ai.org/book/overview-1/ubuntu)
+* [Installing Marvin (MacOS)](https://www.marvin-ai.org/book/overview-1/mac)
+* [Installing Marvin (Other OS) Vagrant](https://www.marvin-ai.org/book/overview-1/vagrant)
 * [Creating a new engine](#creating-a-new-engine)
 * [Working in an existing engine](#working-in-an-existing-engine)
 * [Command line interface](#command-line-interface)
diff --git a/python-toolbox/marvin_python_toolbox/engine_base/engine_base_action.py b/python-toolbox/marvin_python_toolbox/engine_base/engine_base_action.py
index daead75..fcabdb1 100644
--- a/python-toolbox/marvin_python_toolbox/engine_base/engine_base_action.py
+++ b/python-toolbox/marvin_python_toolbox/engine_base/engine_base_action.py
@@ -95,6 +95,7 @@
             self._local_saved_objects[object_reference] = object_file_path
 
     def _load_obj(self, object_reference, force=False):
+        object_reference = object_reference if object_reference.startswith('_') else '_%s' % object_reference
         if (getattr(self, object_reference, None) is None and self._persistence_mode == 'local') or force:
             object_file_path = self._get_object_file_path(object_reference)
             logger.info("Loading object from {}".format(object_file_path))
diff --git a/python-toolbox/tests/engine_base/test_engine_base_prediction.py b/python-toolbox/tests/engine_base/test_engine_base_prediction.py
index bba43a3..4e3c3fe 100644
--- a/python-toolbox/tests/engine_base/test_engine_base_prediction.py
+++ b/python-toolbox/tests/engine_base/test_engine_base_prediction.py
@@ -16,6 +16,10 @@
 # limitations under the License.
 
 import pytest
+try:
+    import mock
+except ImportError:
+    import unittest.mock as mock
 
 from marvin_python_toolbox.engine_base import EngineBasePrediction
 
@@ -26,7 +30,10 @@
         def execute(self, **kwargs):
             return 1
 
-    return EngineAction(default_root_path="/tmp/.marvin")
+    return EngineAction(
+        default_root_path="/tmp/.marvin",
+        persistence_mode="local"
+    )
 
 
 class TestEngineBasePrediction:
@@ -38,3 +45,32 @@
     def test_metrics(self, engine_action):
         engine_action.marvin_metrics = [3]
         assert engine_action.marvin_metrics == engine_action._metrics == [3]
+
+
+class TestEnsureReloadActionReplaceObjectAttr:
+
+    @mock.patch('marvin_python_toolbox.engine_base.engine_base_action.EngineBaseAction._serializer_load')
+    def test_first_load_from_artifact_works(self, mock_serializer, engine_action):
+        mock_serializer.return_value = "MOCKED"
+
+        assert engine_action._model == None
+
+        engine_action._load_obj(object_reference="model")
+        
+        assert engine_action._model == engine_action.marvin_model == "MOCKED"
+
+    @mock.patch('marvin_python_toolbox.engine_base.engine_base_action.EngineBaseAction._serializer_load')
+    def test_reload_works_before_first_load(self, mock_serializer, engine_action):
+        mock_serializer.return_value = "MOCKED"
+
+        assert engine_action._model == None
+
+        engine_action._load_obj(object_reference="model")
+
+        assert engine_action._model == engine_action.marvin_model == "MOCKED"
+
+        mock_serializer.return_value = "NEW MOCKED"
+
+        engine_action._load_obj(object_reference="model", force=True)
+
+        assert engine_action._model == engine_action.marvin_model == "NEW MOCKED"
\ No newline at end of file