Implemented 'update' option for rsync_ops.symlink and functional test

Change-Id: Ia9741e188f0c88bc5cca9b7db4b30578bcf84e6f
diff --git a/trsync/objects/rsync_ops.py b/trsync/objects/rsync_ops.py
index 5d4b0e0..794feb8 100644
--- a/trsync/objects/rsync_ops.py
+++ b/trsync/objects/rsync_ops.py
@@ -198,9 +198,13 @@
         return self.push(source=source, opts=opts)
 
     def symlink(self, symlink, target,
-                create_target_file=True, store_history=True):
+                create_target_file=True, store_history=True, update=True):
         '''Creates symlink targeted to target'''
 
+        # check that symlink already exists on remote
+        if not update:
+            if self.ls_symlinks(symlink):
+                raise RuntimeError('Symlink {} already exists'.format(symlink))
         temp_dir = self._tmp.get_temp_dir()
         remote_path, symlink = os.path.split(self.url.a_file(symlink))
         # check that target is exists on remote
diff --git a/trsync/tests/functional/test_rsync_ops.py b/trsync/tests/functional/test_rsync_ops.py
index 0c4bbb6..6d5336c 100644
--- a/trsync/tests/functional/test_rsync_ops.py
+++ b/trsync/tests/functional/test_rsync_ops.py
@@ -299,6 +299,11 @@
             self.assertRaises(RuntimeError,
                               ops.symlink, 'snapshots/symlink2', 'dir2')
 
+            # update existent symlink with update=False
+            self.assertRaises(RuntimeError,
+                              ops.symlink, 'snapshots/symlink1', 'dir2',
+                              update=False)
+
             # update existent symlink
             os.makedirs(os.path.join(remote.path, 'snapshots/dir2'))
             ops.symlink('snapshots/symlink1', 'dir2')