test cases for state change and corresponding bug fixes
authorParichay Kapoor <pk.kapoor@samsung.com>
Wed, 27 Mar 2019 06:35:51 +0000 (15:35 +0900)
committerMyungJoo Ham <myungjoo.ham@samsung.com>
Tue, 2 Apr 2019 03:59:10 +0000 (12:59 +0900)
1. Created virtual iio device to test against
2. Added test case to test state change from NULL to PLAYING and backwards
3. Bug fixes-
  3.1 setting of fixated caps moved to _fixating() from _start()
  3.2 channel property list memory issue resolved
  3.3 missing sampling frequency file while setting it is now a warning
      skip to default frequency if file is not present
  3.4 More minor bug fixes
4. IIO base directories moved to header file
  These directories are modified to temporary location when testing with simulated device

V2:
- BugFix:
  - updated condition check for sampling_frequency
  - updated freeing channel list while filtering enabled channels
  - declaration following C89
- Moved fixating of caps to _fixate(). This removes unnecessary storage of fixated_caps
  and calculating fixated caps in _fixate() makes code more readable

V3:
- replaced stdio.h with glib/gprintf.h

Signed-off-by: Parichay Kapoor <pk.kapoor@samsung.com>
gst/nnstreamer/tensor_source/tensor_src_iio.c
gst/nnstreamer/tensor_source/tensor_src_iio.h
tests/nnstreamer_source/unittest_src_iio.cpp

index e42e5aa..469fb2f 100644 (file)
@@ -55,7 +55,6 @@
 #include <gst/gst.h>
 #include <glib.h>
 #include <string.h>
-#include <stdio.h>
 #include <endian.h>
 #include <unistd.h>
 #include <errno.h>
@@ -172,7 +171,7 @@ enum
 /**
  * @brief Default behavior on merging channels
  */
-#define DEFAULT_MERGE_CHANNELS FALSE
+#define DEFAULT_MERGE_CHANNELS TRUE
 
 /**
  * blocksize for buffer
@@ -206,12 +205,7 @@ enum
  */
 #define NAME_FILE "name"
 #define AVAIL_FREQUENCY_FILE "sampling_frequency_available"
-
-/**
- * @brief IIO system paths
- */
-#define IIO_BASE_DIR "/sys/bus/iio/devices/"
-#define IIO_DEV_DIR "/dev/"
+#define SAMPLING_FREQUENCY "sampling_frequency"
 
 /**
  * @brief Template for src pad.
@@ -354,6 +348,7 @@ gst_tensor_src_iio_channel_properties_free (gpointer data)
   g_free (prop->generic_name);
   g_free (prop->base_dir);
   g_free (prop->base_file);
+  g_free (prop);
 }
 
 /**
@@ -666,8 +661,8 @@ gst_tensor_channel_list_filter_enabled (gpointer data, gpointer user_data)
   list = *list_addr;
 
   if (!channel->enabled) {
+    *list_addr = g_list_remove (list, data);
     gst_tensor_src_iio_channel_properties_free (channel);
-    *list_addr = g_list_remove (list, channel);
   }
 }
 
@@ -692,6 +687,7 @@ gst_tensor_src_iio_get_all_channel_info (GstTensorSrcIIO * self,
   guint num_channels_enabled = 0;
   gboolean generic_val, specific_val;
   gchar *generic_type_filename;
+  GstTensorSrcIIOChannelProperties *channel_prop;
 
   if (!g_file_test (dir_name, G_FILE_TEST_IS_DIR)) {
     GST_ERROR_OBJECT (self, "No channels available.");
@@ -711,21 +707,21 @@ gst_tensor_src_iio_get_all_channel_info (GstTensorSrcIIO * self,
         continue;
       }
 
-      GstTensorSrcIIOChannelProperties channel_prop;
-      self->channels = g_list_prepend (self->channels, &channel_prop);
+      channel_prop = g_new (GstTensorSrcIIOChannelProperties, 1);
+      self->channels = g_list_prepend (self->channels, channel_prop);
 
       /** set the name and base_dir */
-      channel_prop.name = g_strndup (dir_entry->d_name,
+      channel_prop->name = g_strndup (dir_entry->d_name,
           strlen (dir_entry->d_name) - strlen (EN_SUFFIX));
-      channel_prop.base_dir = g_strdup (dir_name);
-      channel_prop.base_file =
-          g_build_filename (dir_name, channel_prop.name, NULL);
-      channel_prop.generic_name =
-          gst_tensor_src_iio_get_generic_name (channel_prop.name);
-      silent_debug ("Generic name = %s", channel_prop.generic_name);
+      channel_prop->base_dir = g_strdup (dir_name);
+      channel_prop->base_file =
+          g_build_filename (dir_name, channel_prop->name, NULL);
+      channel_prop->generic_name =
+          gst_tensor_src_iio_get_generic_name (channel_prop->name);
+      silent_debug ("Generic name = %s", channel_prop->generic_name);
 
       /** find and set the current state */
-      filename = g_strdup_printf ("%s%s", channel_prop.base_file, EN_SUFFIX);
+      filename = g_strdup_printf ("%s%s", channel_prop->base_file, EN_SUFFIX);
       if (!g_file_get_contents (filename, &file_contents, NULL, &error)) {
         GST_ERROR_OBJECT (self, "Unable to read %s, error: %s.\n", filename,
             error->message);
@@ -736,20 +732,21 @@ gst_tensor_src_iio_get_all_channel_info (GstTensorSrcIIO * self,
       value = g_ascii_strtoull (file_contents, NULL, 10);
       g_free (file_contents);
       if (value == 1) {
-        channel_prop.enabled = TRUE;
+        channel_prop->enabled = TRUE;
         num_channels_enabled += 1;
       } else if (value == 0) {
-        channel_prop.enabled = FALSE;
+        channel_prop->enabled = FALSE;
       } else {
         GST_ERROR_OBJECT
             (self,
             "Enable bit %u (out of range) in current state of channel %s.\n",
-            value, channel_prop.name);
+            value, channel_prop->name);
         goto error_cleanup_list;
       }
 
       /** find and set the index */
-      filename = g_strdup_printf ("%s%s", channel_prop.base_file, INDEX_SUFFIX);
+      filename =
+          g_strdup_printf ("%s%s", channel_prop->base_file, INDEX_SUFFIX);
       if (!g_file_get_contents (filename, &file_contents, NULL, &error)) {
         GST_ERROR_OBJECT (self, "Unable to read %s, error: %s.\n", filename,
             error->message);
@@ -759,17 +756,17 @@ gst_tensor_src_iio_get_all_channel_info (GstTensorSrcIIO * self,
 
       value = g_ascii_strtoull (file_contents, NULL, 10);
       g_free (file_contents);
-      channel_prop.index = value;
+      channel_prop->index = value;
 
       /** find and set the type information */
-      filename = g_strdup_printf ("%s%s", channel_prop.base_file, TYPE_SUFFIX);
+      filename = g_strdup_printf ("%s%s", channel_prop->base_file, TYPE_SUFFIX);
       if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
         /** if specific type info unavailable, use generic type info */
         g_free (filename);
         generic_type_filename =
-            g_strdup_printf ("%s%s", channel_prop.generic_name, TYPE_SUFFIX);
+            g_strdup_printf ("%s%s", channel_prop->generic_name, TYPE_SUFFIX);
         filename =
-            g_build_filename (channel_prop.base_dir, generic_type_filename,
+            g_build_filename (channel_prop->base_dir, generic_type_filename,
             NULL);
         g_free (generic_type_filename);
       }
@@ -780,37 +777,37 @@ gst_tensor_src_iio_get_all_channel_info (GstTensorSrcIIO * self,
       }
       g_free (filename);
 
-      if (!gst_tensor_src_iio_set_channel_type (&channel_prop, file_contents)) {
+      if (!gst_tensor_src_iio_set_channel_type (channel_prop, file_contents)) {
         GST_ERROR_OBJECT (self,
             "Error while setting up channel type for channel %s.\n",
-            channel_prop.name);
+            channel_prop->name);
         g_free (file_contents);
         goto error_cleanup_list;
       }
       g_free (file_contents);
 
       /** find and setup offset info */
-      channel_prop.scale = 1.0;
+      channel_prop->scale = 1.0;
 
       specific_val =
           gst_tensor_src_iio_get_float_from_file (self->device.base_dir,
-          channel_prop.name, SCALE_SUFFIX, &channel_prop.scale);
+          channel_prop->name, SCALE_SUFFIX, &channel_prop->scale);
       generic_val =
           gst_tensor_src_iio_get_float_from_file (self->device.base_dir,
-          channel_prop.generic_name, SCALE_SUFFIX, &channel_prop.scale);
+          channel_prop->generic_name, SCALE_SUFFIX, &channel_prop->scale);
       if (!specific_val || !generic_val) {
         goto error_cleanup_list;
       }
 
       /** find and setup scale info */
-      channel_prop.offset = 0.0;
+      channel_prop->offset = 0.0;
 
       specific_val =
           gst_tensor_src_iio_get_float_from_file (self->device.base_dir,
-          channel_prop.name, OFFSET_SUFFIX, &channel_prop.offset);
+          channel_prop->name, OFFSET_SUFFIX, &channel_prop->offset);
       generic_val =
           gst_tensor_src_iio_get_float_from_file (self->device.base_dir,
-          channel_prop.generic_name, OFFSET_SUFFIX, &channel_prop.offset);
+          channel_prop->generic_name, OFFSET_SUFFIX, &channel_prop->offset);
       if (!specific_val || !generic_val) {
         goto error_cleanup_list;
       }
@@ -842,9 +839,10 @@ error_cleanup_list:
  * @param[in] base_dir Device base directory (containing sampling freq file)
  * @param[in] frequency Frequency specified by user (else 0)
  * @return >0 if OK, represents sampling frequency to be set
- *         0  if any cannot find the matching frequency
+ *         0  if sampling frequency file does not exist, dont change anything
+ *         -1 if any error occurs
  */
-static guint64
+static gint64
 gst_tensor_src_iio_set_frequency (const gchar * base_dir,
     const guint64 frequency)
 {
@@ -852,13 +850,20 @@ gst_tensor_src_iio_set_frequency (const gchar * base_dir,
   gchar *filename = NULL;
   gchar *file_contents = NULL;
   gint i = 0;
-  guint64 ret = 0, val = 0;
+  guint64 val = 0;
+  gint64 ret = 0;
 
   /** get frequency list supported by the device */
   filename = g_build_filename (base_dir, AVAIL_FREQUENCY_FILE, NULL);
+  if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
+    GST_WARNING ("Sampling frequency file does not exist for the file %s.\n",
+        base_dir);
+    goto del_filename;
+  }
   if (!g_file_get_contents (filename, &file_contents, NULL, &error)) {
     GST_ERROR ("Unable to read sampling frequency for device %s.\n", base_dir);
     g_error_free (error);
+    ret = -1;
     goto del_filename;
   }
 
@@ -866,6 +871,7 @@ gst_tensor_src_iio_set_frequency (const gchar * base_dir,
   gint num = g_strv_length (freq_list);
   if (num == 0) {
     GST_ERROR ("No sampling frequencies for device %s.\n", base_dir);
+    ret = -1;
     goto del_freq_list;
   }
   /**
@@ -1043,7 +1049,7 @@ gst_tensor_write_sysfs_string (GstTensorSrcIIO * self, const gchar * file,
     GST_ERROR_OBJECT (self, "Unable to write to file %s.\n", filename);
     goto error_close_file;
   }
-  if (!fclose (fd)) {
+  if (fclose (fd)) {
     GST_ERROR_OBJECT (self, "Unable to close file %s after write.\n", filename);
     goto error_free_filename;
   }
@@ -1055,6 +1061,7 @@ gst_tensor_write_sysfs_string (GstTensorSrcIIO * self, const gchar * file,
     if (!g_file_get_contents (filename, &file_contents, NULL, &error)) {
       GST_ERROR_OBJECT (self, "Unable to read file %s with error %s.\n",
           filename, error->message);
+      g_error_free (error);
       goto error_free_filename;
     } else {
       if (!g_strcmp0 (contents, file_contents)) {
@@ -1071,7 +1078,6 @@ error_close_file:
   fclose (fd);
 
 error_free_filename:
-  g_error_free (error);
   g_free (filename);
   return ret;
 }
@@ -1175,7 +1181,7 @@ gst_tensor_src_iio_create_config (GstTensorSrcIIO * tensor_src_iio)
 
   /** compile tensor info data */
   for (list = tensor_src_iio->channels; list != NULL; list = list->next) {
-    channel_prop = (GstTensorSrcIIOChannelProperties *) list;
+    channel_prop = (GstTensorSrcIIOChannelProperties *) list->data;
     if (!channel_prop->enabled)
       continue;
     info[info_idx].name = channel_prop->name;
@@ -1244,9 +1250,10 @@ gst_tensor_src_iio_start (GstBaseSrc * src)
   GstTensorSrcIIO *self;
   self = GST_TENSOR_SRC_IIO_CAST (src);
   gint id;
-  guint64 sampling_frequency;
+  gint64 sampling_frequency;
   gchar *dirname = NULL;
   gchar *filename = NULL;
+  gint num_channels_enabled;
 
   /** Find the device */
   id = gst_tensor_src_iio_get_id_by_name (IIO_BASE_DIR, self->device.name,
@@ -1312,24 +1319,35 @@ gst_tensor_src_iio_start (GstBaseSrc * src)
   sampling_frequency =
       gst_tensor_src_iio_set_frequency (self->device.base_dir,
       self->sampling_frequency);
-  if (0 == sampling_frequency) {
-    GST_ERROR_OBJECT (self, "IIO device does not support %lu frequency.\n",
-        (gulong) self->sampling_frequency);
+  if (-1 == sampling_frequency) {
+    GST_ERROR_OBJECT (self, "Error in setting frequency for device %s.\n",
+        self->device.name);
     goto error_trigger_free;
+  } else if (0 == sampling_frequency) {
+    /** if sampling frequency file does not exist, no error */
+    GST_WARNING_OBJECT (self, "Cannot verify against sampling frequency list.");
   } else {
-    self->sampling_frequency = sampling_frequency;
-    /** interface of frequency is kept long for outside but uint64 inside */
-    gchar *sampling_frequency_char =
-        g_strdup_printf ("%lu", (gulong) self->sampling_frequency);
-    if (G_UNLIKELY (!gst_tensor_write_sysfs_string (self, "sampling_frequency",
-                self->device.base_dir, sampling_frequency_char))) {
-      GST_ERROR_OBJECT (self,
-          "Cannot set the sampling frequency for device: %s.\n",
-          self->device.name);
+    /** check if sampling frequency can be set */
+    filename =
+        g_build_filename (self->device.base_dir, SAMPLING_FREQUENCY, NULL);
+    if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
+      GST_WARNING_OBJECT (self, "Cannot set sampling frequency.");
+    } else {
+      self->sampling_frequency = sampling_frequency;
+      /** interface of frequency is kept long for outside but uint64 inside */
+      gchar *sampling_frequency_char =
+          g_strdup_printf ("%lu", (gulong) self->sampling_frequency);
+      if (G_UNLIKELY (!gst_tensor_write_sysfs_string (self, SAMPLING_FREQUENCY,
+                  self->device.base_dir, sampling_frequency_char))) {
+        GST_ERROR_OBJECT (self,
+            "Cannot set the sampling frequency for device: %s.\n",
+            self->device.name);
+        g_free (sampling_frequency_char);
+        goto error_trigger_free;
+      }
       g_free (sampling_frequency_char);
-      goto error_trigger_free;
     }
-    g_free (sampling_frequency_char);
+    g_free (filename);
   }
 
   /** once all these are set, set the buffer related thingies */
@@ -1346,7 +1364,7 @@ gst_tensor_src_iio_start (GstBaseSrc * src)
 
   /** get all the channels that exist and then set enable on them */
   dirname = g_build_filename (self->device.base_dir, CHANNELS, NULL);
-  guint num_channels_enabled =
+  num_channels_enabled =
       gst_tensor_src_iio_get_all_channel_info (self, dirname);
   g_free (dirname);
   if (G_UNLIKELY (num_channels_enabled == -1)) {
@@ -1365,74 +1383,23 @@ gst_tensor_src_iio_start (GstBaseSrc * src)
       gst_tensor_set_all_channels (self, 0);
       goto error_channels_free;
     }
-    /** filter out disabled channels */
-    g_list_foreach (self->channels, gst_tensor_channel_list_filter_enabled,
-        &self->channels);
-    self->scan_size = gst_tensor_get_size_from_channels (self->channels);
   }
 
-  /** set source pad */
-  GstCaps *prev_caps, *caps, *updated_caps;
-  GstPad *pad;
+  /** filter out disabled channels */
+  g_list_foreach (self->channels, gst_tensor_channel_list_filter_enabled,
+      &self->channels);
+  self->scan_size = gst_tensor_get_size_from_channels (self->channels);
+  self->num_channels_enabled = g_list_length (self->channels);
 
-  pad = src->srcpad;
-  gst_pad_use_fixed_caps (pad);
+  /** set fixed caps for the src pad */
+  gst_pad_use_fixed_caps (src->srcpad);
 
-  /**
-   * We can update the caps of the pad in current NULL state
-   * as the pad is activated in READY->PAUSED trainsition.
-   */
+  /** create tensor_config */
   if (!gst_tensor_src_iio_create_config (self)) {
     GST_ERROR_OBJECT (self, "Error creating config.\n");
     goto error_channels_free;
   }
 
-  if (self->is_tensor) {
-    GstTensorConfig tensor_config;
-    gst_tensor_info_copy (&tensor_config.info,
-        &(self->tensors_config->info.info[0]));
-    tensor_config.rate_n = self->tensors_config->rate_n;
-    tensor_config.rate_d = self->tensors_config->rate_d;
-    caps = gst_tensor_caps_from_config (&tensor_config);
-    gst_tensor_info_free (&tensor_config.info);
-  } else {
-    caps = gst_tensors_caps_from_config (self->tensors_config);
-  }
-  if (caps == NULL) {
-    GST_ERROR_OBJECT (self, "Error creating caps from config.\n");
-    goto error_config_free;
-  }
-
-  /** get current caps, take intersection with it and then set the new ones */
-  if (gst_pad_has_current_caps (pad)) {
-    prev_caps = gst_pad_get_current_caps (pad);
-    if (gst_caps_can_intersect (caps, prev_caps)) {
-      updated_caps = gst_caps_intersect (caps, prev_caps);
-    } else {
-      GST_ERROR_OBJECT (self,
-          "No intersection between new and current caps.\n");
-      gst_caps_unref (prev_caps);
-      gst_caps_unref (caps);
-      goto error_config_free;
-    }
-    gst_caps_unref (caps);
-    gst_caps_unref (prev_caps);
-  } else {
-    updated_caps = caps;
-  }
-
-  if (!gst_pad_set_caps (pad, updated_caps)) {
-    GST_ERROR_OBJECT (self, "Unable to set caps for the pad.\n");
-    gst_caps_unref (updated_caps);
-    goto error_config_free;
-    /** free this in stop as well */
-  }
-
-  silent_debug ("Finalization of caps while starting device");
-  silent_debug ("caps = %" GST_PTR_FORMAT, updated_caps);
-
-  gst_caps_unref (updated_caps);
-
   /** enable the buffer for the data to be captured */
   dirname = g_build_filename (self->device.base_dir, BUFFER, NULL);
   if (G_UNLIKELY (!gst_tensor_write_sysfs_int (self, "enable", dirname, 1))) {
@@ -1585,12 +1552,12 @@ gst_tensor_src_iio_set_caps (GstBaseSrc * src, GstCaps * caps)
 
   if (DBG) {
     GstCaps *cur_caps = gst_pad_get_current_caps (pad);
-    if (!gst_caps_is_subset (caps, cur_caps)) {
+    if (cur_caps != NULL && !gst_caps_is_subset (caps, cur_caps)) {
       silent_debug ("Setting caps in source mismatch");
       silent_debug ("caps = %" GST_PTR_FORMAT, caps);
       silent_debug ("cur_caps = %" GST_PTR_FORMAT, cur_caps);
+      gst_caps_unref (cur_caps);
     }
-    gst_caps_unref (cur_caps);
   }
 
   if (!gst_pad_set_caps (pad, caps)) {
@@ -1636,9 +1603,42 @@ gst_tensor_src_iio_fixate (GstBaseSrc * src, GstCaps * caps)
 {
   /**
    * Caps are fixated based on the device source in _start().
-   * Nothing to be handled here.
    */
-  return gst_caps_fixate (caps);
+  GstTensorSrcIIO *self;
+  self = GST_TENSOR_SRC_IIO_CAST (src);
+  GstCaps *updated_caps, *fixated_caps;
+
+  if (self->is_tensor) {
+    GstTensorConfig tensor_config;
+    gst_tensor_info_copy (&tensor_config.info,
+        &(self->tensors_config->info.info[0]));
+    tensor_config.rate_n = self->tensors_config->rate_n;
+    tensor_config.rate_d = self->tensors_config->rate_d;
+    fixated_caps = gst_tensor_caps_from_config (&tensor_config);
+    gst_tensor_info_free (&tensor_config.info);
+  } else {
+    fixated_caps = gst_tensors_caps_from_config (self->tensors_config);
+  }
+
+  if (fixated_caps == NULL) {
+    GST_ERROR_OBJECT (self, "Error creating fixated caps from config.");
+    return NULL;
+  }
+  silent_debug ("Fixated caps from device = %" GST_PTR_FORMAT, fixated_caps);
+
+  if (gst_caps_can_intersect (caps, fixated_caps)) {
+    updated_caps = gst_caps_intersect (caps, fixated_caps);
+  } else {
+    GST_ERROR_OBJECT (self,
+        "No intersection while fixating caps of the element.");
+    gst_caps_unref (caps);
+    gst_caps_unref (fixated_caps);
+    return NULL;
+  }
+
+  gst_caps_unref (caps);
+  gst_caps_unref (fixated_caps);
+  return gst_caps_fixate (updated_caps);
 }
 
 /**
index d6de7d4..42d6b32 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <gst/gst.h>
 #include <gst/base/gstbasesrc.h>
+#include <glib/gprintf.h>
 #include <tensor_common.h>
 #include <poll.h>
 
@@ -48,6 +49,12 @@ typedef struct _GstTensorSrcIIO GstTensorSrcIIO;
 typedef struct _GstTensorSrcIIOClass GstTensorSrcIIOClass;
 
 /**
+ * @brief IIO system paths
+ */
+gchar *IIO_BASE_DIR = "/sys/bus/iio/devices/";
+gchar *IIO_DEV_DIR = "/dev/";
+
+/**
  * @brief iio device channel enabled mode
  */
 typedef enum
index a149da5..618fdb7 100644 (file)
 #include <gtest/gtest.h>
 #include <gst/gst.h>
 #include <gst/check/gstharness.h>
+#include <fcntl.h>
+#include <unistd.h>
 
+/**
+ * @brief element name to be tested
+ */
 #define ELEMENT_NAME "tensor_src_iio"
 
-const guint DEFAULT_BUFFER_CAPACITY = 1;
-const gulong DEFAULT_FREQUENCY = 0;
-const gboolean DEFAULT_SILENT = TRUE;
-const gboolean DEFAULT_MERGE_CHANNELS = FALSE;
+/**
+ * @brief original location of iio to be modified for testing
+ */
+extern gchar *IIO_BASE_DIR;
+extern gchar *IIO_DEV_DIR;
+
+/**
+ * @brief to store the original location for iio
+ */
+gchar *PREV_IIO_BASE_DIR;
+gchar *PREV_IIO_DEV_DIR;
+
+/**
+ * @brief iio default and test values
+ */
+#define DEFAULT_BUFFER_CAPACITY 1
+#define DEFAULT_FREQUENCY 0
+#define DEFAULT_SILENT TRUE
+#define DEFAULT_MERGE_CHANNELS TRUE
+#define DEVICE_NAME "test-device-1"
+#define TRIGGER_NAME "test-trigger-1"
+#define SCALE  10.1
+#define OFFSET 1.1
+
+/**
+ * @brief iio states and values
+ */
 
 const gchar *mode[] = { "one-shot", "continuous" };
 const gchar *channels[] = { "auto", "all" };
+const gchar *samp_freq_avail[] = { "1000", "2000", "3000", NULL };
+
+/**
+ * @brief structure for iio device file/folder names
+ */
+typedef struct _iio_dev_dir_struct
+{
+  gchar *base_dir;
+  gchar *sys_dir;
+  gchar *bus_dir;
+  gchar *iio_dir;
+  gchar *iio_base_dir_sim;
+
+  gchar *device;
+  gchar *name;
+
+  gchar *trigger_dev;
+  gchar *trigger_name;
+
+  gchar *trigger;
+  gchar *cur_trig;
+
+  gchar *samp_freq;
+  gchar *samp_freq_avail;
+  gchar *buffer;
+  gchar *buf_en;
+  gchar *buf_length;
+  gchar *scale;
+  gchar *offset;
+
+  static const int num_scan_elements = 8;
+  gchar *scan_el;
+  gchar *scan_el_en[num_scan_elements];
+  gchar *scan_el_index[num_scan_elements];
+  gchar *scan_el_type[num_scan_elements];
+  gchar *scan_el_raw[num_scan_elements];
+  gchar *scan_el_time_en;
+  gchar *scan_el_time_index;
+  gchar *scan_el_time_type;
+
+  gchar *dev_dir;
+  gchar *dev_device_dir;
+} iio_dev_dir_struct;
+
+/**
+ * @brief make structure for iio device with all file names
+ * @param[in] num number assigned to the device
+ * @returns made structure (owned by the caller)
+ */
+static iio_dev_dir_struct *
+make_iio_dev_structure (int num)
+{
+  gchar *device_folder_name;
+  gchar *trigger_folder_name;
+  gchar *scan_element_name;
+  const gchar *_tmp_dir = g_get_tmp_dir ();
+  const gchar *_dirname = "nnst-src-XXXXXX";
+
+  iio_dev_dir_struct *iio_dev = g_new (iio_dev_dir_struct, 1);
+  iio_dev->base_dir = g_build_filename (_tmp_dir, _dirname, NULL);
+  iio_dev->base_dir = g_mkdtemp_full (iio_dev->base_dir, 0777);
+  rmdir (iio_dev->base_dir);
+
+  iio_dev->sys_dir = g_build_filename (iio_dev->base_dir, "sys", NULL);
+  iio_dev->bus_dir = g_build_filename (iio_dev->sys_dir, "bus", NULL);
+  iio_dev->iio_dir = g_build_filename (iio_dev->bus_dir, "iio", NULL);
+  iio_dev->iio_base_dir_sim =
+      g_build_filename (iio_dev->iio_dir, "devices", NULL);
+
+  PREV_IIO_BASE_DIR = IIO_BASE_DIR;
+  IIO_BASE_DIR = g_strdup (iio_dev->iio_base_dir_sim);
+
+  device_folder_name = g_strdup_printf ("%s%d", "iio:device", num);
+  iio_dev->device = g_build_filename (IIO_BASE_DIR, device_folder_name, NULL);
+  iio_dev->name = g_build_filename (iio_dev->device, "name", NULL);
+
+  trigger_folder_name = g_strdup_printf ("%s%d", "iio:trigger", num);
+  iio_dev->trigger_dev =
+      g_build_filename (IIO_BASE_DIR, trigger_folder_name, NULL);
+  iio_dev->trigger_name = g_build_filename (iio_dev->trigger_dev, "name", NULL);
+
+  iio_dev->trigger = g_build_filename (iio_dev->device, "trigger", NULL);
+  iio_dev->cur_trig =
+      g_build_filename (iio_dev->trigger, "current_trigger", NULL);
+
+  iio_dev->samp_freq =
+      g_build_filename (iio_dev->device, "sampling_frequency", NULL);
+  iio_dev->samp_freq_avail =
+      g_build_filename (iio_dev->device, "sampling_frequency_available", NULL);
+
+  iio_dev->buffer = g_build_filename (iio_dev->device, "buffer", NULL);
+  iio_dev->buf_en = g_build_filename (iio_dev->buffer, "enable", NULL);
+  iio_dev->buf_length = g_build_filename (iio_dev->buffer, "length", NULL);
+
+  iio_dev->scale = g_build_filename (iio_dev->device, "in_voltage_scale", NULL);
+  iio_dev->offset =
+      g_build_filename (iio_dev->device, "in_voltage_offset", NULL);
+
+  iio_dev->scan_el = g_build_filename (iio_dev->device, "scan_elements", NULL);
+  for (int idx = 0; idx < iio_dev->num_scan_elements; idx++) {
+    scan_element_name = g_strdup_printf ("%s%d%s", "in_voltage", idx, "_en");
+    iio_dev->scan_el_en[idx] =
+        g_build_filename (iio_dev->scan_el, scan_element_name, NULL);
+    g_free (scan_element_name);
+    scan_element_name = g_strdup_printf ("%s%d%s", "in_voltage", idx, "_index");
+    iio_dev->scan_el_index[idx] =
+        g_build_filename (iio_dev->scan_el, scan_element_name, NULL);
+    g_free (scan_element_name);
+    scan_element_name = g_strdup_printf ("%s%d%s", "in_voltage", idx, "_type");
+    iio_dev->scan_el_type[idx] =
+        g_build_filename (iio_dev->scan_el, scan_element_name, NULL);
+    g_free (scan_element_name);
+    scan_element_name = g_strdup_printf ("%s%d%s", "in_voltage", idx, "_raw");
+    iio_dev->scan_el_raw[idx] =
+        g_build_filename (iio_dev->scan_el, scan_element_name, NULL);
+    g_free (scan_element_name);
+  }
+  iio_dev->scan_el_time_en =
+      g_build_filename (iio_dev->scan_el, "timestamp_en", NULL);
+  iio_dev->scan_el_time_index =
+      g_build_filename (iio_dev->scan_el, "timestamp_index", NULL);
+  iio_dev->scan_el_time_type =
+      g_build_filename (iio_dev->scan_el, "timestamp_type", NULL);
+
+  iio_dev->dev_dir = g_build_filename (iio_dev->base_dir, "dev", NULL);
+  iio_dev->dev_device_dir =
+      g_build_filename (iio_dev->dev_dir, device_folder_name, NULL);
+
+  PREV_IIO_DEV_DIR = IIO_DEV_DIR;
+  IIO_DEV_DIR = g_strdup (iio_dev->dev_dir);
+
+  g_free (device_folder_name);
+  g_free (trigger_folder_name);
+
+  return iio_dev;
+}
+
+/**
+ * @brief write string in to the file
+ * @param[in] filename Destination file for the data
+ * @param[in] contents Data to be written to the file
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+write_file_string (const gchar * filename, const gchar * contents)
+{
+  if (!g_file_set_contents (filename, contents, -1, NULL)) {
+    return -1;
+  }
+  return 0;
+}
+
+/**
+ * @brief write int in to the file
+ * @param[in] filename Destination file for the data
+ * @param[in] contents Data to be written to the file
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+write_file_int (const gchar * filename, const gint contents)
+{
+  g_autofree gchar *contents_char = NULL;
+  contents_char = g_strdup_printf ("%d", contents);
+
+  return write_file_string (filename, contents_char);
+}
+
+/**
+ * @brief write float in to the file
+ * @param[in] filename Destination file for the data
+ * @param[in] contents Data to be written to the file
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+write_file_float (const gchar * filename, const gfloat contents)
+{
+  g_autofree gchar *contents_char = NULL;
+  contents_char = g_strdup_printf ("%f", contents);
+
+  return write_file_string (filename, contents_char);
+}
+
+/**
+ * @brief create a file
+ * @param[in] filename name of the file to be created
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+touch_file (const gchar * filename)
+{
+  return write_file_string (filename, "");
+}
+
+/**
+ * @brief build base dir for iio device simulation
+ * @param[in] iio_dev struct of iio device
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+build_dev_dir_base (const iio_dev_dir_struct * iio_dev)
+{
+  gint status = 0;
+
+  status += g_mkdir_with_parents (iio_dev->device, 0777);
+  status += write_file_string (iio_dev->name, DEVICE_NAME);
+
+  return status;
+}
+
+/**
+ * @brief build dev data dir and fills it for iio device simulation
+ * @param[in] iio_dev struct of iio device
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+build_dev_dir_dev_data (const iio_dev_dir_struct * iio_dev)
+{
+  gint status = 0;
+
+  status += g_mkdir_with_parents (iio_dev->dev_dir, 0777);
+  /** @todo fill in proper data */
+  status += write_file_string (iio_dev->dev_device_dir, "FIXME");
+
+  return status;
+}
+
+/**
+ * @brief build buffer dir for iio device simulation
+ * @param[in] iio_dev struct of iio device
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+build_dev_dir_buffer (const iio_dev_dir_struct * iio_dev)
+{
+  gint status = 0;
+
+  status += g_mkdir_with_parents (iio_dev->buffer, 0777);
+  status += touch_file (iio_dev->buf_en);
+  status += touch_file (iio_dev->buf_length);
+
+  return status;
+}
+
+/**
+ * @brief build trigger dir for iio device simulation
+ * @param[in] iio_dev struct of iio device
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+build_dev_dir_trigger (const iio_dev_dir_struct * iio_dev)
+{
+  gint status = 0;
+
+  status += g_mkdir_with_parents (iio_dev->trigger, 0777);
+  status += touch_file (iio_dev->cur_trig);
+
+  return status;
+}
+
+/**
+ * @brief build trigger device dir for iio device simulation
+ * @param[in] iio_dev struct of iio device
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+build_dev_dir_trigger_dev (const iio_dev_dir_struct * iio_dev)
+{
+  gint status = 0;
+
+  status += g_mkdir_with_parents (iio_dev->trigger_dev, 0777);
+  status += write_file_string (iio_dev->trigger_name, TRIGGER_NAME);
+
+  return status;
+}
+
+/**
+ * @brief build sampling frequency for iio device simulation
+ * @param[in] iio_dev struct of iio device
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+build_dev_dir_samp_freq (const iio_dev_dir_struct * iio_dev)
+{
+  gint status = 0;
+
+  status += touch_file (iio_dev->samp_freq);
+
+  return status;
+}
+
+/**
+ * @brief build list of sampling frequency for iio device simulation
+ * @param[in] iio_dev struct of iio device
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+build_dev_dir_samp_freq_avail (const iio_dev_dir_struct * iio_dev)
+{
+  gint status = 0;
+  gchar *samp_freq_avail_string = g_strjoinv (",", (char **) samp_freq_avail);
+
+  status +=
+      write_file_string (iio_dev->samp_freq_avail, samp_freq_avail_string);
+
+  g_free (samp_freq_avail_string);
+  return status;
+}
+
+/**
+ * @brief build scale and offset for iio device simulation
+ * @param[in] iio_dev struct of iio device
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+build_dev_dir_scale_offset (const iio_dev_dir_struct * iio_dev)
+{
+  gint status = 0;
+
+  status += write_file_float (iio_dev->scale, SCALE);
+  status += write_file_float (iio_dev->offset, OFFSET);
+
+  return status;
+}
+
+/**
+ * @brief build raw data elements for iio device simulation
+ * @param[in] iio_dev struct of iio device
+ * @param[in] skip skip some of the elements
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+build_dev_dir_raw_elements (const iio_dev_dir_struct * iio_dev, gboolean skip =
+    FALSE)
+{
+  gint status = 0;
+
+  for (int idx = 0; idx < iio_dev->num_scan_elements; idx++) {
+    if (idx % 2 && skip) {
+      continue;
+    }
+    /** todo: verify what is the dtype of this data */
+    status += write_file_int (iio_dev->scan_el_raw[idx], 1000);
+  }
+
+  return status;
+}
+
+/**
+ * @brief build scan data elements dir for iio device simulation
+ * @param[in] iio_dev struct of iio device
+ * @param[in] num_bits num of bits for storage of data
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+build_dev_dir_scan_elements (const iio_dev_dir_struct * iio_dev,
+    const guint num_bits)
+{
+  gint status = 0;
+  gchar *type_data;
+  gchar endianchar, signchar;
+  gint storage, used, shift;
+
+  if (!g_file_test (iio_dev->scan_el, G_FILE_TEST_IS_DIR)) {
+    status += g_mkdir_with_parents (iio_dev->scan_el, 0777);
+  }
+  /** total 8 possible cases */
+  for (int idx = 0; idx < iio_dev->num_scan_elements; idx++) {
+    status += write_file_int (iio_dev->scan_el_en[idx], idx % 2);
+    status += write_file_int (iio_dev->scan_el_index[idx], idx);
+    /** form 4 possible combinations */
+    endianchar = 'b';
+    signchar = 's';
+    switch (idx % (iio_dev->num_scan_elements / 2)) {
+      case 0:
+        break;
+      case 1:
+        endianchar = 'l';
+      case 2:
+        signchar = 'u';
+        break;
+      case 3:
+        endianchar = 'l';
+        break;
+    }
+    storage = num_bits;
+    used = storage - 2 * (idx / (iio_dev->num_scan_elements / 2));
+    if (used <= 0) {
+      used = 1;
+    }
+    /** shift will be 0 or non-zero (2 in this case) */
+    shift = storage - used;
+    type_data =
+        g_strdup_printf ("%ce:%c%u/%u>>%u", endianchar, signchar, used, storage,
+        shift);
+    status += write_file_string (iio_dev->scan_el_type[idx], type_data);
+    g_free (type_data);
+  }
+
+  return status;
+}
+
+/**
+ * @brief build timestamp in scan data elements dir for iio device simulation
+ * @param[in] iio_dev struct of iio device
+ * @returns 0 on success, non-zero on failure
+ */
+static gint
+build_dev_dir_timestamp (const iio_dev_dir_struct * iio_dev)
+{
+  gint status = 0;
+  gchar *type_data;
+  gchar endianchar, signchar;
+  gint storage, used, shift;
+
+  if (!g_file_test (iio_dev->scan_el, G_FILE_TEST_IS_DIR)) {
+    status += g_mkdir_with_parents (iio_dev->scan_el, 0777);
+  }
+  /** total 8 possible cases */
+  status += write_file_int (iio_dev->scan_el_time_en, 1);
+  status +=
+      write_file_int (iio_dev->scan_el_time_index, iio_dev->num_scan_elements);
+  endianchar = 'b';
+  signchar = 's';
+  storage = 64;
+  used = 64;
+  /** shift will be 0 or non-zero (2 in this case) */
+  shift = storage - used;
+  type_data =
+      g_strdup_printf ("%ce:%c%u/%u>>%u", endianchar, signchar, used, storage,
+      shift);
+  status += write_file_string (iio_dev->scan_el_time_type, type_data);
+  g_free (type_data);
+
+  return status;
+}
+
+/**
+ * @brief cleans memory of iio device structure
+ * @param[in] iio_dev struct of iio device
+ */
+static void
+clean_iio_dev_structure (iio_dev_dir_struct * iio_dev)
+{
+  g_free (IIO_BASE_DIR);
+  g_free (IIO_DEV_DIR);
+
+  IIO_BASE_DIR = PREV_IIO_BASE_DIR;
+  IIO_DEV_DIR = PREV_IIO_DEV_DIR;
+
+  g_free (iio_dev->base_dir);
+  g_free (iio_dev->sys_dir);
+  g_free (iio_dev->bus_dir);
+  g_free (iio_dev->iio_dir);
+  g_free (iio_dev->iio_base_dir_sim);
+  g_free (iio_dev->device);
+  g_free (iio_dev->name);
+  g_free (iio_dev->trigger_dev);
+  g_free (iio_dev->trigger_name);
+  g_free (iio_dev->trigger);
+  g_free (iio_dev->cur_trig);
+  g_free (iio_dev->samp_freq);
+  g_free (iio_dev->samp_freq_avail);
+  g_free (iio_dev->buffer);
+  g_free (iio_dev->buf_en);
+  g_free (iio_dev->buf_length);
+  g_free (iio_dev->scale);
+  g_free (iio_dev->offset);
+  g_free (iio_dev->scan_el);
+  g_free (iio_dev->scan_el_time_en);
+  g_free (iio_dev->scan_el_time_index);
+  g_free (iio_dev->scan_el_time_type);
+
+  for (int idx = 0; idx < iio_dev->num_scan_elements; idx++) {
+    g_free (iio_dev->scan_el_en[idx]);
+    g_free (iio_dev->scan_el_index[idx]);
+    g_free (iio_dev->scan_el_type[idx]);
+    g_free (iio_dev->scan_el_raw[idx]);
+  }
+
+  g_free (iio_dev->dev_dir);
+  g_free (iio_dev->dev_device_dir);
+
+  g_free (iio_dev);
+  return;
+}
+
+/**
+ * @brief destroy dir for iio device simulation
+ * @param[in] iio_dev struct of iio device
+ */
+static void
+destroy_dev_dir (const iio_dev_dir_struct * iio_dev)
+{
+  for (int idx = 0; idx < iio_dev->num_scan_elements; idx++) {
+    remove (iio_dev->scan_el_en[idx]);
+    remove (iio_dev->scan_el_index[idx]);
+    remove (iio_dev->scan_el_type[idx]);
+    remove (iio_dev->scan_el_raw[idx]);
+  }
+  remove (iio_dev->scan_el_time_en);
+  remove (iio_dev->scan_el_time_index);
+  remove (iio_dev->scan_el_time_type);
+  rmdir (iio_dev->scan_el);
+
+  remove (iio_dev->buf_en);
+  remove (iio_dev->buf_length);
+  rmdir (iio_dev->buffer);
+
+  remove (iio_dev->cur_trig);
+  rmdir (iio_dev->trigger);
+
+  remove (iio_dev->scale);
+  remove (iio_dev->offset);
+  remove (iio_dev->samp_freq);
+  remove (iio_dev->samp_freq_avail);
+  remove (iio_dev->name);
+
+  remove (iio_dev->trigger_name);
+
+  rmdir (iio_dev->trigger_dev);
+  rmdir (iio_dev->device);
+  rmdir (iio_dev->iio_base_dir_sim);
+  rmdir (iio_dev->iio_dir);
+  rmdir (iio_dev->bus_dir);
+  rmdir (iio_dev->sys_dir);
+
+  remove (iio_dev->dev_device_dir);
+  rmdir (iio_dev->dev_dir);
+
+  rmdir (iio_dev->base_dir);
+}
 
 /**
  * @brief tests properties of tensor source IIO
@@ -26,8 +585,6 @@ const gchar *channels[] = { "auto", "all" };
 TEST (test_tensor_src_iio, properties)
 {
   const gchar default_name[] = "tensorsrciio0";
-  const gchar device[] = "test-device-1";
-  const gchar trigger[] = "test-trigger-1";
 
   GstHarness *hrnss = NULL;
   GstElement *src_iio = NULL;
@@ -78,14 +635,14 @@ TEST (test_tensor_src_iio, properties)
   EXPECT_STREQ (ret_mode, mode[1]);
 
   /** setting device test */
-  g_object_set (src_iio, "device", device, NULL);
+  g_object_set (src_iio, "device", DEVICE_NAME, NULL);
   g_object_get (src_iio, "device", &ret_device, NULL);
-  EXPECT_STREQ (ret_device, device);
+  EXPECT_STREQ (ret_device, DEVICE_NAME);
 
   /** setting trigger test */
-  g_object_set (src_iio, "trigger", trigger, NULL);
+  g_object_set (src_iio, "trigger", TRIGGER_NAME, NULL);
   g_object_get (src_iio, "trigger", &ret_trigger, NULL);
-  EXPECT_STREQ (ret_trigger, trigger);
+  EXPECT_STREQ (ret_trigger, TRIGGER_NAME);
 
   /** setting channels test */
   g_object_get (src_iio, "channels", &ret_channels, NULL);
@@ -121,11 +678,106 @@ TEST (test_tensor_src_iio, properties)
   g_object_get (src_iio, "merge-channels-data", &ret_merge_channels, NULL);
   EXPECT_EQ (ret_merge_channels, merge_channels);
 
-  /* teardown */
+  /** teardown */
   gst_harness_teardown (hrnss);
 }
 
 /**
+ * @brief tests state change of tensor source IIO
+ */
+TEST (test_tensor_src_iio, start_stop)
+{
+  iio_dev_dir_struct *dev0;
+  GstHarness *hrnss = NULL;
+  GstElement *src_iio = NULL;
+  GstStateChangeReturn status;
+  GstState state;
+
+  /** build iio dummy device */
+  dev0 = make_iio_dev_structure (0);
+  ASSERT_EQ (build_dev_dir_base (dev0), 0);
+
+  /** build iio dummy trigger */
+  ASSERT_EQ (build_dev_dir_trigger_dev (dev0), 0);
+
+  /** add trigger support in device */
+  ASSERT_EQ (build_dev_dir_trigger (dev0), 0);
+
+  /** dir for continuous mode */
+  ASSERT_EQ (build_dev_dir_buffer (dev0), 0);
+  ASSERT_EQ (build_dev_dir_scan_elements (dev0, 32), 0);
+  ASSERT_EQ (build_dev_dir_timestamp (dev0), 0);
+  ASSERT_EQ (build_dev_dir_dev_data (dev0), 0);
+
+  /** dir for single-shot mode */
+  ASSERT_EQ (build_dev_dir_raw_elements (dev0), 0);
+
+  /** other attributes */
+  ASSERT_EQ (build_dev_dir_samp_freq (dev0), 0);
+  ASSERT_EQ (build_dev_dir_samp_freq_avail (dev0), 0);
+  ASSERT_EQ (build_dev_dir_scale_offset (dev0), 0);
+
+  /** setup */
+  hrnss = gst_harness_new_empty ();
+  ASSERT_TRUE (hrnss != NULL);
+  gst_harness_add_parse (hrnss, ELEMENT_NAME);
+  src_iio = gst_harness_find_element (hrnss, ELEMENT_NAME);
+  ASSERT_TRUE (src_iio != NULL);
+
+  /** setup properties */
+  g_object_set (src_iio, "device", DEVICE_NAME, NULL);
+  g_object_set (src_iio, "silent", FALSE, NULL);
+  g_object_set (src_iio, "trigger", TRIGGER_NAME, NULL);
+
+  /** silent mode test */
+  status = gst_element_set_state (src_iio, GST_STATE_NULL);
+  EXPECT_EQ (status, GST_STATE_CHANGE_SUCCESS);
+  status = gst_element_get_state (src_iio, &state, NULL, GST_CLOCK_TIME_NONE);
+  EXPECT_EQ (status, GST_STATE_CHANGE_SUCCESS);
+  EXPECT_EQ (state, GST_STATE_NULL);
+
+  status = gst_element_set_state (src_iio, GST_STATE_READY);
+  EXPECT_EQ (status, GST_STATE_CHANGE_SUCCESS);
+  status = gst_element_get_state (src_iio, &state, NULL, GST_CLOCK_TIME_NONE);
+  EXPECT_EQ (status, GST_STATE_CHANGE_SUCCESS);
+  EXPECT_EQ (state, GST_STATE_READY);
+
+  status = gst_element_set_state (src_iio, GST_STATE_PAUSED);
+  EXPECT_EQ (status, GST_STATE_CHANGE_NO_PREROLL);
+  status = gst_element_get_state (src_iio, &state, NULL, GST_CLOCK_TIME_NONE);
+  EXPECT_EQ (status, GST_STATE_CHANGE_NO_PREROLL);
+  EXPECT_EQ (state, GST_STATE_PAUSED);
+
+  status = gst_element_set_state (src_iio, GST_STATE_PLAYING);
+  EXPECT_EQ (status, GST_STATE_CHANGE_SUCCESS);
+  status = gst_element_get_state (src_iio, &state, NULL, GST_CLOCK_TIME_NONE);
+  EXPECT_EQ (status, GST_STATE_CHANGE_SUCCESS);
+  EXPECT_EQ (state, GST_STATE_PLAYING);
+
+  /** let a frames load */
+  g_usleep (50000);
+
+  /** this will be resolved once correct data has been fed */
+  status = gst_element_get_state (src_iio, &state, NULL, GST_CLOCK_TIME_NONE);
+  EXPECT_EQ (status, GST_STATE_CHANGE_SUCCESS);
+  EXPECT_EQ (state, GST_STATE_PLAYING);
+
+  status = gst_element_set_state (src_iio, GST_STATE_NULL);
+  EXPECT_EQ (status, GST_STATE_CHANGE_SUCCESS);
+  status = gst_element_get_state (src_iio, &state, NULL, GST_CLOCK_TIME_NONE);
+  EXPECT_EQ (status, GST_STATE_CHANGE_SUCCESS);
+  EXPECT_EQ (state, GST_STATE_NULL);
+
+  /** teardown */
+  gst_harness_teardown (hrnss);
+
+  /** delete device structure */
+  destroy_dev_dir (dev0);
+  clean_iio_dev_structure (dev0);
+}
+
+
+/**
  * @brief Main function for unit test.
  */
 int