Added some initial documentation structure

Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
Kai Kreuzer 2014-06-24 18:40:46 +02:00
Родитель db2de6742c
Коммит fcc0754f1b
4 изменённых файлов: 201 добавлений и 0 удалений

11
docs/sources/.project Normal file
Просмотреть файл

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>docs</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>

Просмотреть файл

@ -0,0 +1,59 @@
# Overview
Eclipse SmartHome is a framework for building smart home solutions. As such, it consists of a rich set of OSGi bundles that serve different purposes. Not all solutions that build on top of Eclipse SmartHome will require all of those bundles - instead they can choose what parts are interesting for them.
There are the following categories of bundles:
- `config`: everything that is concerned with general configuration of the system like config files, xml parsing, etc.
- `core`: the main bundles for the logical operation of the system - based on the abstract item and event concepts.
- `io`: all kinds of optional functionality that have to do with i/o like console commands, audio support or http/rest communication
- `model`: support for domain specific languages (DSLs)
- `designer`: Eclipse RCP support for DSLs and other configuration files
- `ui`: user interface related bundles that provide services that can be used by different UIs, such as charting or icons
# General Concepts
## Items and Events
Eclipse SmartHome has a strict separation between the physical world (the "things", see below) and the application, which is built around the notion of "items" (also called the virtual layer).
Items represent functionality that is used by the application (mainly user interfaces or automation logic). Items have a state and are used through events.
The event bus is THE base service of Eclipse SmartHome. All bundles that do not require stateful behaviour should use it to inform other bundles about events and to be updated by other bundles on external events.
There are mainly two types of events:
- Commands, which trigger an action or a state change of some item.
- State updates, which inform about a state change of some item (often as a response to a command)
The following item types are currently available (alphabetical order):
<table>
<tr><td><b>Itemname</b></td><td><b>Description</b></td><td><b>Command Types</b></td></tr>
<tr><td>Color</td><td>Color information (RGB)</td><td>OnOff, IncreaseDecrease, Percent, HSB</td></tr>
<tr><td>Contact</td><td>Item storing status of e.g. door/window contacts</td><td>OpenClose</td></tr>
<tr><td>DateTime</td><td>Stores date and time</td><td></td></tr>
<tr><td>Dimmer</td><td>Item carrying a percentage value for dimmers</td><td>OnOff, IncreaseDecrease, Percent</td></tr>
<tr><td>Group</td><td>Item to nest other items / collect them in groups</td><td>-</td></tr>
<tr><td>Number</td><td>Stores values in number format</td><td>Decimal</td></tr>
<tr><td>Rollershutter</td><td>Typically used for blinds</td><td>UpDown, StopMove, Percent</td></tr>
<tr><td>String</td><td>Stores texts</td><td>String</td></tr>
<tr><td>Switch</td><td>Typically used for lights (on/off)</td><td>OnOff</td></tr>
</table>
Group Items can derive their own state depending on their member items.
- AVG displays the average of the item states in the group.
- OR displays an OR of the group, typically used to display whether any item in a group has been set.
- other aggregations: AND, SUM, MIN, MAX, NAND, NOR
It is important to note that Eclipse SmartHome is not meant to reside on (or near) actual hardware devices which would then have to remotely communicate with many other distributed instances. Instead, solutions based on Eclipse SmartHome serve as an integration hub between such devices and as a mediator between different protocols that are spoken between these devices. In a typical installation there will therefore be usually just one instance of Eclipse SmartHome running on some central server. Nonetheless, the events can also be exported through appropriate protocols such as MQTT, so that it is possible to connect several distributed Eclipse SmartHome instances.
## Things
t.b.d.
## Bindings
t.b.d.

Просмотреть файл

@ -0,0 +1,125 @@
Testing Eclipse SmartHome
===
There are two different kinds of approaches for testing Eclipse SmartHome. One is to use plain JUnit tests for testing simple classes. The other is to execute JUnit tests within the OSGi environment to test OSGi services and dynamic behaviour. Both approaches are supported through a simple infrastructure, which allows to easily write and execute tests.
Test fragment
---
In OSGi tests are implemented in a separate fragment bundle, which host is the bundle, that should be tested. The name of the test fragment bundle should be the same as the bundle to test with a ".test" suffix. The MANIFEST.MF file must contain a `Fragment-Host` entry. Fragment bundles inherit all imported packages from the host bundle. In addition the fragment bundle must import the `org.junit` package with a minimum version of 4.0.0 specified. The following code snippet shows a manifest file of the test fragment for the `org.eclipse.smarthome.core.library` bundle.
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Tests for the Eclipse SmartHome Core Library
Bundle-SymbolicName: org.eclipse.smarthome.core.library.test
Bundle-Version: 0.7.0.qualifier
Bundle-Vendor: Eclipse.org/SmartHome
Fragment-Host: org.eclipse.smarthome.core.library
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: org.junit;version="4.0.0"
Tests are typically placed inside the folder `src/test/java`.
Unit tests
---
Each class inside the test folder, which has a public method with a `@Test` annotation will automatically be executed as a test. Inside the class one can refer to all classes from the host bundle and all imported classes. The following code snippet shows a simple JUnit test which tests the `toString` conversation of a PercentType.
public class PercentTypeTest {
@Test
public void DoubleValue() {
PercentType pt = new PercentType("0.0001");
assertEquals("0.0001", pt.toString());
}
}
Using the the [https://code.google.com/p/hamcrest/ hamcrest] matcher library is a good way to write expressive assertions. In contrast to the original assertion statements from JUnit the hamcrest matcher library allows to define the assertion in a more natural order:
PercentType pt = new PercentType("0.0001");
assertThat pt.toString(), is(equalTo("0.0001"))
To use the hamcrest library in your test project, you just have to add the following entry to the list of imported packages:
org.hamcrest;core=split
Tests can be executed from Eclipse by right-clicking the test file and clicking on `Run As => JUnit Test`. From maven one can execute the test with `mvn test` command in the folder of the test fragment bundle.
Groovy
---
Using the JVM language Groovy tests are very easy and efficient to write. Groovy supports mocking without any frameworks. Language features like closures, type-inference and native syntax for maps and lists allow to implement short and easy to understand tests. Thus Eclipse SmartHome comes with a out-of-the-boc-support for Groovy-testing in Eclipse and maven. Each test file which is placed under `src/test/groovy` will be automatically compiled and executed in Eclipse and maven. Moreover the Eclipse SmartHome Yoxos profile contains the Groovy-Eclipse-Plugin.
Even the following examples are presented in Groovy, unit and OSGi tests can also be implemented in Java. If the default mocking capabilities of Groovy do not fulfil the requirements, Groovy can also be combined with Java mocking frameworks like [https://code.google.com/p/mockito/ mockito].
== OSGi-Tests ==
Some components of Eclipse SmartHome are heavily bound to the OSGi runtime, because they use OSGi core services like the EventAdmin or the ConfigurationAdmin. That makes it hard to test those components outside of the OSGi container. Equinox provides a possibility to execute a JUnit tests inside the OSGi environment, where the test has access to OSGi services.
Eclipse SmartHome comes with an abstract base class `OSGiTest` for OSGi tests. The base class sets up a bundle context and has convenience methods for registering mocks as OSGi services and the retrieval of registered OSGi services. The following Groovy test class shows how to test the `ItemRegistry` by providing a mocked `ItemProvider`.
class ItemRegistryOSGiTest extends OSGiTest {
ItemRegistry itemRegistry
ItemProvider itemProvider
def ITEM_NAME = "switchItem"
@Before
void setUp() {
itemRegistry = getService(ItemRegistry)
itemProvider = [
getItems: {[new SwitchItem(ITEM_NAME)]},
addItemChangeListener: {def itemCHangeListener -> },
removeItemChangeListener: {def itemCHangeListener -> }] as ItemProvider
}
@Test
void 'assert getItems returns item from registered ItemProvider'() {
assertThat itemRegistry.getItems().size, is(0)
registerService itemProvider
def items = itemRegistry.getItems()
assertThat items.size, is(1)
assertThat items.first().name, is(equalTo(ITEM_NAME))
unregisterService itemProvider
assertThat itemRegistry.getItems().size, is(0)
}
}
In the `setUp` method the `ItemRegistry` OSGi service is retrieved through the method `getService` from the base class `OSGiTest` and assigned to a private variable. After it a new `ItemProvider` mock is created, which returns one item. The test method first checks that no item is inside the registry. Afterwards it registers the mocked `ItemProvider` as OSGi service with the method `registerService` and checks if the `ItemRegistry` returns one item now. At the end the mock is unregistered again.
In Eclipse the tests can be executed by right-clicking the test file and clicking on `Run As => JUnit Plug-In Test`. The launch config must be adapted, by selecting the bundle to test under the `Plug-Ins` tab and by clicking on `Add Required Plug-Ins`. Moreover you have to set the Auto-Start option to `true`. If the bundle that should be tested makes use of declarative services (has xml files in OSGI-INF folder), the bundle `org.eclipse.equinox.ds` must also be selected and also the required Plug-Ins of it. The `Validate Plug-Ins` button can be used to check if the launch config is valid. To avoid the manual selection of bundles, one can also choose `all workspace and enabled target plug-ins` with default `Default Auto-Start` set to `true`. The disadvantage is, that this will start all bundles, which makes the test execution really slow and will prodcue a lot of errors on the OSGi console. It is a good practice to store a launch configuration file, that launches all test cases for a test fragment.
From maven the test can be executed by calling `mvn integration-test`. For executing the test in maven, tycho calculates the list of depended bundles automatically from package imports. Only if there is no dependency to a bundle, the bundle must be added manually to the test execution environment. For example Eclipse SmartHome makes use of OSGi declarative services. That allows to define service components through XML files. In order to support declarative services in the test environment the according bundle must be added in the pom file within the `tycho-surefire-plugin` configuration section as followed:
...
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<dependencies>
<dependency>
<type>eclipse-plugin</type>
<artifactId>org.eclipse.equinox.ds</artifactId>
<version>0.0.0</version>
</dependency>
</dependencies>
<bundleStartLevel>
<bundle>
<id>org.eclipse.equinox.ds</id>
<level>1</level>
<autoStart>true</autoStart>
</bundle>
</bundleStartLevel>
</configuration>
</plugin>
</plugins>
</build>
...
In the dependency definition the `artifactId` is the name of the required bundle, where the version can always be `0.0.0`. Within the `bundleStartLevel` definition the start level and auto start of the depended bundles can be configured. The `org.eclipse.equinox.ds` bundle must have level 1 and must be started automatically.

Просмотреть файл

@ -0,0 +1,6 @@
# Introduction
This page gives you a starting point, if you intent to implement (and hopefully contribute) your own binding.
It guides you step by step through the implementation and explains the relevant concepts.
t.b.c.