Repository: Duke-GCB/DukeDSClient

Issue:
Importing DukeDS module checks config file
When a user imports the DukeDS module it reads and verifies the associated config file.

https://github.com/Duke-GCB/DukeDSClient/blob/0c15a9a50957abe806c7b2b6cad6a58f9d3aa61b/ddsc/sdk/client.py#L19

Importing a module shouldn't perform an action.

Discussion:

Patch:
diff --git a/ddsc/sdk/client.py b/ddsc/sdk/client.py
index e7b6e16..578c6d2 100644
--- a/ddsc/sdk/client.py
+++ b/ddsc/sdk/client.py
@@ -16,10 +16,12 @@ class Client(object):
     Client that connects to the DDSConnection base on ~/.ddsclient configuration.
     This configuration can be customized by passing in a ddsc.config.Config object
     """
-    def __init__(self, config=create_config()):
+    def __init__(self, config=None):
         """
         :param config: ddsc.config.Config: settings used to connect to DDSConnection
         """
+        if not config:
+            config = create_config()
         self.dds_connection = DDSConnection(config)
 
     def get_projects(self):
diff --git a/ddsc/sdk/dukeds.py b/ddsc/sdk/dukeds.py
index 7dc9418..3353cff 100644
--- a/ddsc/sdk/dukeds.py
+++ b/ddsc/sdk/dukeds.py
@@ -1,7 +1,6 @@
 from __future__ import absolute_import
 import logging
 from ddsc.sdk.client import Client, FileUpload, PathToFiles, ItemNotFound, DuplicateNameError
-from ddsc.config import create_config
 from ddsc.core.userutil import UserUtil
 
 
@@ -113,7 +112,7 @@ class Session(object):
     Contains methods for interacting with DukeDS using standard ddsclient config file and environment variables
     Same functionality as DukeDS but caches project list to improve performance.
     """
-    def __init__(self, config=create_config()):
+    def __init__(self, config=None):
         """
         :param config:  ddsc.config.Config: configuration specifying DukeDS endpoint and credential to use
         """


Test patch:
diff --git a/ddsc/sdk/tests/test_client.py b/ddsc/sdk/tests/test_client.py
index d103b2a..7a86bae 100644
--- a/ddsc/sdk/tests/test_client.py
+++ b/ddsc/sdk/tests/test_client.py
@@ -6,6 +6,19 @@ from mock import patch, Mock, ANY
 
 
 class TestClient(TestCase):
+    @patch('ddsc.sdk.client.create_config')
+    @patch('ddsc.sdk.client.DDSConnection', autospec=True)
+    def test_constructor_default_config(self, mock_dss_connection, mock_create_config):
+        Client()
+        mock_create_config.assert_called_with()
+
+    @patch('ddsc.sdk.client.create_config')
+    @patch('ddsc.sdk.client.DDSConnection', autospec=True)
+    def test_constructor_specify_config(self, mock_dss_connection, mock_create_config):
+        mock_config = Mock()
+        Client(mock_config)
+        mock_create_config.assert_not_called()
+
     @patch('ddsc.sdk.client.create_config')
     @patch('ddsc.sdk.client.DDSConnection')
     def test_get_projects(self, mock_dss_connection, mock_create_config):
diff --git a/ddsc/sdk/tests/test_dukeds.py b/ddsc/sdk/tests/test_dukeds.py
index eec8d06..91fd6a0 100644
--- a/ddsc/sdk/tests/test_dukeds.py
+++ b/ddsc/sdk/tests/test_dukeds.py
@@ -1,5 +1,5 @@
 from unittest import TestCase
-from ddsc import DukeDS, ItemNotFound, DuplicateNameError
+from ddsc import DukeDS, ItemNotFound, DuplicateNameError, Session
 from mock import patch, Mock, ANY
 
 
@@ -204,3 +204,16 @@ class TestDukeDS(TestCase):
         ]
         DukeDS.move_file_or_folder('myproject', '/data/file1.txt', '/data/file1_bak.txt')
         mock_project.move_file_or_folder.assert_called_with('/data/file1.txt', '/data/file1_bak.txt')
+
+
+class TestSession(TestCase):
+    @patch('ddsc.sdk.dukeds.Client', autospec=True)
+    def test_constructor_default_args(self, mock_client):
+        Session()
+        mock_client.assert_called_with(None)
+
+    @patch('ddsc.sdk.dukeds.Client', autospec=True)
+    def test_constructor_passing_config(self, mock_client):
+        mock_config = Mock()
+        Session(mock_config)
+        mock_client.assert_called_with(mock_config)