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

Get unittest to 100% #212

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 src --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest (only on Python 3.11 to avoid concurrency issues)
if: ${{ (github.ref == 'refs/heads/master') && (matrix.primary-config == 'true') }}
if: ${{ matrix.primary-config == 'true' }}
env:
ONE_JOB_ONLY_TESTS: ${{ matrix.primary-config }}
WIOTP_API_KEY: ${{ secrets.WIOTP_API_KEY }}
Expand Down
10 changes: 5 additions & 5 deletions src/wiotp/sdk/api/dsc/connectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,16 @@ def __init__(self, apiClient):
def find(self, nameFilter=None, typeFilter=None, enabledFilter=None, serviceId=None):
"""
Gets the list of Historian connectors, they are used to configure the Watson IoT Platform to store IoT data in compatible services.

Parameters:

- nameFilter(string) - Filter the results by the specified name
- typeFilter(string) - Filter the results by the specified type, Available values : cloudant, eventstreams
- enabledFilter(boolean) - Filter the results by the enabled flag
- enabledFilter(boolean) - Filter the results by the enabled flag
- serviceId(string) - Filter the results by the service id
- limit(number) - Max number of results returned, defaults 25
- bookmark(string) - used for paging through results

Throws APIException on failure.
"""

Expand All @@ -106,7 +106,7 @@ def find(self, nameFilter=None, typeFilter=None, enabledFilter=None, serviceId=N

def create(self, name, type, serviceId, timezone=None, description=None, enabled=None, configuration=None):
"""
Create a connector for the organization in the Watson IoT Platform.
Create a connector for the organization in the Watson IoT Platform.
The connector must reference the target service that the Watson IoT Platform will store the IoT data in.
Parameters:
- name (string) - Name of the service
Expand Down
5 changes: 3 additions & 2 deletions src/wiotp/sdk/api/registry/diag.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
import json
from datetime import datetime
from collections import defaultdict

try:
from collections.abc import MutableSequence
from collections.abc import MutableSequence
except ImportError:
from collections import MutableSequence
from collections import MutableSequence
from wiotp.sdk.exceptions import ApiException


Expand Down
16 changes: 8 additions & 8 deletions src/wiotp/sdk/api/services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,16 +165,16 @@ def __init__(self, apiClient):

def find(self, nameFilter=None, typeFilter=None, bindingModeFilter=None, boundFilter=None):
"""
Gets the list of services that the Watson IoT Platform can connect to.
Gets the list of services that the Watson IoT Platform can connect to.
The list can include a mixture of services that are either bound or unbound.

Parameters:

- nameFilter(string) - Filter the results by the specified name
- typeFilter(string) - Filter the results by the specified type, Available values : cloudant, eventstreams
- bindingModeFilter(string) - Filter the results by the specified binding mode, Available values : automatic, manual
- boundFilter(boolean) - Filter the results by the bound flag
- boundFilter(boolean) - Filter the results by the bound flag

Throws APIException on failure.
"""

Expand All @@ -192,9 +192,9 @@ def find(self, nameFilter=None, typeFilter=None, bindingModeFilter=None, boundFi

def create(self, serviceBinding):
"""
Create a new external service.
The service must include all of the details required to connect
and authenticate to the external service in the credentials property.
Create a new external service.
The service must include all of the details required to connect
and authenticate to the external service in the credentials property.
Parameters:
- serviceName (string) - Name of the service
- serviceType (string) - must be either eventstreams or cloudant
Expand Down
2 changes: 2 additions & 0 deletions src/wiotp/sdk/api/state/deviceTypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from wiotp.sdk.api.state.logicalInterfaces import BaseLogicalInterface
from wiotp.sdk.api.state.physicalInterfaces import PhysicalInterface


# =========================================================================
# Physical Interface for the Device Type
# =========================================================================
Expand Down Expand Up @@ -166,6 +167,7 @@ def __init__(self, apiClient, deviceTypeId):
# Mappings for the Device Type
# =========================================================================


# define the common properties found on most Rest API Items
class DeviceTypeMapping(defaultdict):
def __init__(self, **kwargs):
Expand Down
1 change: 0 additions & 1 deletion src/wiotp/sdk/api/state/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ def __init__(self, apiClient):
super(DraftSchemas, self).__init__(apiClient, Schema, IterableSchemaList, "api/v0002/draft/schemas")

def create(self, name, schemaFileName, schemaContents, description):

"""
Create a schema for the org.
Returns: schemaId (string), response (object).
Expand Down
1 change: 1 addition & 0 deletions src/wiotp/sdk/api/state/thingTypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ def __init__(self, apiClient, thingTypeId):
# Mappings for the Thing Type
# =========================================================================


# define the common properties found on most Rest API Items
class ThingTypeMapping(defaultdict):
def __init__(self, **kwargs):
Expand Down
6 changes: 4 additions & 2 deletions src/wiotp/sdk/application/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

class ApplicationClientConfig(defaultdict):
def __init__(self, **kwargs):
if "auth" not in kwargs or kwargs["auth"] is None:
# previously quickstart supported unauthenticated connections but has been removed
if "auth" not in kwargs:
raise ConfigurationException("Missing auth from configuration")

if "key" not in kwargs["auth"] or kwargs["auth"]["key"] is None:
raise ConfigurationException("Missing auth.key from configuration")
if "token" not in kwargs["auth"] or kwargs["auth"]["token"] is None:
Expand Down Expand Up @@ -248,6 +248,8 @@ def parseEnvVars():
"auth": {"key": authKey, "token": authToken}
}

cfg["auth"] = {"key": authKey, "token": authToken}

return ApplicationClientConfig(**cfg)


Expand Down
4 changes: 3 additions & 1 deletion src/wiotp/sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,9 @@ def __init__(
# paho 2.0.0 has a breaking change for callbacks to support both 2.0.0 and 1.x we need
# to create a client in version1 mode if using 2.0.0
if pahoVersion >= "2.0.0":
self.client = paho.Client(paho.CallbackAPIVersion.VERSION1, self.clientId, transport=transport, clean_session=(not cleanStart))
self.client = paho.Client(
paho.CallbackAPIVersion.VERSION1, self.clientId, transport=transport, clean_session=(not cleanStart)
)
else:
self.client = paho.Client(self.clientId, transport=transport, clean_session=(not cleanStart))

Expand Down
10 changes: 5 additions & 5 deletions src/wiotp/sdk/device/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@
class Command:
"""
Represents a command sent to a device.

# Parameters
pahoMessage (?): ?
messageEncoderModules (dict): Dictionary of Python modules, keyed to the
message format the module should use.
messageEncoderModules (dict): Dictionary of Python modules, keyed to the
message format the module should use.

# Attributes
command (string): Identifies the command.
format (string): The format can be any string, for example JSON.
data (dict): The data for the payload. Maximum length is 131072 bytes.
timestamp (datetime): The date and time of the event.

# Raises
InvalidEventException: If the command was recieved on a topic that does
InvalidEventException: If the command was recieved on a topic that does
not match the regular expression `iot-2/cmd/(.+)/fmt/(.+)`
"""

Expand Down
2 changes: 2 additions & 0 deletions src/wiotp/sdk/device/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ def parseEnvVars():
"auth": {"token": authToken}
}

cfg["auth"] = {"token": authToken}

return DeviceClientConfig(**cfg)


Expand Down
9 changes: 9 additions & 0 deletions test/testUtils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,22 @@
import wiotp.sdk.application
import pytest
import os
import sys

oneJobOnlyTest = pytest.mark.skipif(
os.getenv("ONE_JOB_ONLY_TESTS", "true") == "false",
reason="Doesn't support running in multiple envs in parallel due to limits on # of service bindings allowed",
)


def isstring(s):
# if we use Python 3
if sys.version_info[0] >= 3:
return isinstance(s, str)
else:
return isinstance(s, basestring) # noqa: F821


class AbstractTest(object):

WIOTP_API_KEY = os.getenv("WIOTP_API_KEY")
Expand Down
10 changes: 2 additions & 8 deletions test/test_api_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,6 @@ class TestActions(testUtils.AbstractTest):
testActionName = "test-action-new"
updated_action_name = testActionName + "-updated"

def isstring(self, s):
# if we use Python 3
if sys.version_info[0] >= 3:
basestring = str
return isinstance(s, basestring)

# =========================================================================
# Set up services
# =========================================================================
Expand Down Expand Up @@ -125,9 +119,9 @@ def checkAction(self, action, name, type, description, configuration, enabled):
assert action.configuration[configElement] is not None
assert action.enabled == enabled
assert isinstance(action.created, datetime)
assert self.isstring(action.createdBy)
assert testUtils.isstring(action.createdBy)
assert isinstance(action.updated, datetime)
assert self.isstring(action.updatedBy)
assert testUtils.isstring(action.updatedBy)

def doesActionNameExist(self, name):
for a in self.appClient.actions.find({"name": name}):
Expand Down
4 changes: 3 additions & 1 deletion test/test_api_dsc_cloudant.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
import testUtils
import time
import pytest
import os
from wiotp.sdk.api.services import CloudantServiceBindingCredentials, CloudantServiceBindingCreateRequest
from wiotp.sdk.exceptions import ApiException


@testUtils.oneJobOnlyTest
@pytest.mark.skipif(os.getenv("CLOUDANT_HOST", None) is None, reason="Cloudant host not specified")
class TestDscCloudant(testUtils.AbstractTest):

# =========================================================================
Expand Down Expand Up @@ -153,7 +155,7 @@ def testCreateService2(self):
assert rule1.logicalInterfaceId == None
assert rule1.columnMappings == None
assert rule1.enabled == True
assert isinstance(rule1.id, str)
assert testUtils.isstring(rule1.id)
assert isinstance(rule1.updated, datetime)
assert isinstance(rule1.created, datetime)

Expand Down
4 changes: 3 additions & 1 deletion test/test_api_dsc_db2.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import testUtils
import time
import pytest
import os
from wiotp.sdk.api.services import (
CloudantServiceBindingCredentials,
CloudantServiceBindingCreateRequest,
Expand All @@ -20,6 +21,7 @@
from wiotp.sdk.exceptions import ApiException


@pytest.mark.skipif(os.getenv("DB2_PASSWORD") is None, reason="DB2 settings not provided")
@testUtils.oneJobOnlyTest
class TestDscDb2(testUtils.AbstractTest):
def checkDB2Service(self, service, name, description):
Expand Down Expand Up @@ -170,7 +172,7 @@ def checkDB2ForwardingRule(self, createdRule, name, destination, description, lo
assert createdRule.columnMappings == columnMappings
assert createdRule.typeId == None
assert createdRule.eventId == None
assert isinstance(createdRule.id, str)
assert testUtils.isstring(createdRule.id)
assert isinstance(createdRule.updated, datetime)
assert isinstance(createdRule.created, datetime)

Expand Down
2 changes: 2 additions & 0 deletions test/test_api_dsc_eventstreams.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
import pytest
import testUtils
import time
import os

from wiotp.sdk.api.services import EventStreamsServiceBindingCredentials, EventStreamsServiceBindingCreateRequest
from wiotp.sdk.exceptions import ApiException


@pytest.mark.skipif(os.getenv("EVENTSTREAMS_API_KEY") is None, reason="Eventstreams details not test")
@testUtils.oneJobOnlyTest
class TestDscEventStreams(testUtils.AbstractTest):

Expand Down
4 changes: 3 additions & 1 deletion test/test_api_dsc_postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import testUtils
import time
import pytest
import os
from wiotp.sdk.api.services import (
CloudantServiceBindingCredentials,
CloudantServiceBindingCreateRequest,
Expand All @@ -21,6 +22,7 @@
from wiotp.sdk.exceptions import ApiException


@pytest.mark.skipif(os.getenv("POSTGRES_DATABASE") is None, reason="postgres database not specified")
@testUtils.oneJobOnlyTest
class TestDscPostgres(testUtils.AbstractTest):
def checkPostgresService(self, service, name, description):
Expand Down Expand Up @@ -173,7 +175,7 @@ def checkPostgresForwardingRule(
assert createdRule.columnMappings == columnMappings
assert createdRule.typeId == None
assert createdRule.eventId == None
assert isinstance(createdRule.id, str)
assert testUtils.isstring(createdRule.id)
assert isinstance(createdRule.updated, datetime)
assert isinstance(createdRule.created, datetime)

Expand Down
2 changes: 1 addition & 1 deletion test/test_api_registry_devicetypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,4 @@ def testDeleteTypeId(self, device, deviceType):
{"id": typeId, "description": "This is still a test", "metadata": {"test": "test"}}
)
self.appClient.registry.devicetypes.delete(typeId)
assert typeId not in deviceType.devices
assert typeId not in deviceType.devices
8 changes: 1 addition & 7 deletions test/test_api_state_device_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import string
import json
import sys
from test_state_utils import TestStateUtils
import test_state_utils as TestStateUtils


@testUtils.oneJobOnlyTest
Expand Down Expand Up @@ -87,12 +87,6 @@ def testCleanup(self):
self.appClient, (TestDeviceTypes.testEventSchemaName, TestDeviceTypes.testLiSchemaName)
)

def isstring(self, s):
# if we use Python 3
if sys.version_info[0] >= 3:
basestring = str
return isinstance(s, basestring)

def createAndCheckDT(
self, name, description, deviceInfo=None, metadata=None, edgeConfiguration=None, classId="Device"
):
Expand Down
4 changes: 2 additions & 2 deletions test/test_api_state_eventTypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ def checkEventType(self, eventType, name, description, schemaId):
assert eventType.version == "draft"

assert isinstance(eventType.created, datetime)
assert isinstance(eventType.createdBy, str)
assert testUtils.isstring(eventType.createdBy)
assert isinstance(eventType.updated, datetime)
assert isinstance(eventType.updatedBy, str)
assert testUtils.isstring(eventType.updatedBy)

def doesSchemaNameExist(self, name):
for a in self.appClient.state.draft.schemas.find({"name": name}):
Expand Down
4 changes: 2 additions & 2 deletions test/test_api_state_logical_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ def checkLI(self, logicalInterface, name, description, schemaId, version, alias)
assert logicalInterface.alias == alias

assert isinstance(logicalInterface.created, datetime)
assert isinstance(logicalInterface.createdBy, str)
assert testUtils.isstring(logicalInterface.createdBy)
assert isinstance(logicalInterface.updated, datetime)
assert isinstance(logicalInterface.updatedBy, str)
assert testUtils.isstring(logicalInterface.updatedBy)

def doesSchemaNameExist(self, name):
for a in self.appClient.state.draft.schemas.find({"name": name}):
Expand Down
4 changes: 2 additions & 2 deletions test/test_api_state_physical_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ def checkPI(self, physicalInterface, name, description):
assert physicalInterface.description == description

assert isinstance(physicalInterface.created, datetime)
assert isinstance(physicalInterface.createdBy, str)
assert testUtils.isstring(physicalInterface.createdBy)
assert isinstance(physicalInterface.updated, datetime)
assert isinstance(physicalInterface.updatedBy, str)
assert testUtils.isstring(physicalInterface.updatedBy)

def doesSchemaNameExist(self, name):
for a in self.appClient.state.draft.schemas.find({"name": name}):
Expand Down
4 changes: 2 additions & 2 deletions test/test_api_state_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ def checkRule(self, rule, name, description, logicalInterfaceId, condition, noti
assert rule.notificationStrategy == notificationStrategy

assert isinstance(rule.created, datetime)
assert isinstance(rule.createdBy, str)
assert testUtils.isstring(rule.createdBy)
assert isinstance(rule.updated, datetime)
assert isinstance(rule.updatedBy, str)
assert testUtils.isstring(rule.updatedBy)

def doesSchemaNameExist(self, name):
for a in self.appClient.state.draft.schemas.find({"name": name}):
Expand Down
Loading
Loading