def test_grant(self): view = View(self.log, self.root_key) view.build() home_path = os.path.join(os.sep, utils.random_ascii()) view.mkdir(home_path) key = Key.generate() view.grant(home_path, 'user', key) prev = str(view.root) view.build() self.assertEqual(len(prev), len(str(view.root))) # Change key view = View(self.log, key) view.build() content = utils.random_ascii() file_path = os.path.join(os.sep, utils.random_ascii()) with self.assertRaises(exceptions.PermissionDenied): view.write(file_path, content) user_path = os.path.join(home_path, utils.random_ascii()) view.mkdir(user_path) self.assertEqual(LogEntry.MKDIR, view.get(user_path).entry.action) file_path = os.path.join(user_path, utils.random_ascii()) content = utils.random_ascii() view.write(file_path, content) self.assertEqual(content.encode(), view.get(file_path).content) view = View(self.log, self.root_key) view.build() view.write(file_path, content) self.assertEqual(content.encode(), view.get(file_path).content) file_path = os.path.join(user_path, utils.random_ascii()) content = utils.random_ascii() view.write(file_path, content) self.assertEqual(content.encode(), view.get(file_path).content) self.rebuild(view)
def test_permission(self): key = Key.generate() view = View(self.log, key) view.build() path = os.path.join(os.sep, utils.random_ascii()) with self.assertRaises(exceptions.PermissionDenied): view.mkdir(path)
def test_revoke(self): root_view = View(self.log, self.root_key) root_view.build() home_path = os.path.join(os.sep, 'home-' + utils.random_ascii()) root_view.mkdir(home_path) key = Key.generate() root_view.grant(home_path, 'user', key) view = View(self.log, key) view.build() user_path = os.path.join(home_path, 'user-' + utils.random_ascii()) view.mkdir(user_path) root_view.build() file_path = os.path.join(user_path, 'file2-' + utils.random_ascii()) file_content = ('content1-' + utils.random_ascii(1024))*32 root_view.write(file_path, file_content) self.assertEqual(file_content.encode(), root_view.get(file_path).content) root_view.revoke(home_path, 'user') self.assertEqual(file_content.encode(), root_view.get(file_path).content) self.assertEqual(file_path, root_view.get(file_path).path) view.build() # with open(self.logpath, 'r') as r: # print(r.read()) print(self.log.print_tree(view=view, color=True)) root_view.build() # TODO tree eq after build, except the revoke brancj # TODO test maintain current state (file writen by revoked user) print(self.log.print_tree(view=root_view, color=True)) alt_file_content = 'content2-' + utils.random_ascii() with self.assertRaises(exceptions.DoesNotExist): view.write(file_path, alt_file_content)
def test_branch_conflict(self): view = View(self.log, self.root_key) view.build() home_path = os.path.join(os.sep, 'home-' + utils.random_ascii()) view.mkdir(home_path) key = Key.generate() view.grant(home_path, 'user', key) view = View(self.log, key) view.build() parent_node = view.get(home_path) user_path = os.path.join(home_path, 'user-' + utils.random_ascii()) max_hash = None enc_content = '' for ix in range(12): content = 'content-' + utils.random_ascii(32) prev = enc_content enc_content = bsdiff4.diff(enc_content, content) entry = self.log.write(parent_node.entry, user_path, key, attachment=enc_content) max_hash = max(max_hash, entry.hash) if max_hash else entry.hash view = View(self.log, self.root_key) view.build() self.assertEqual( bsdiff4.patch(prev, self.log.entries[max_hash].get_content()), view.get(user_path).content) # Admin branch more power admin_content = 'content-' + utils.random_ascii(32) content = bsdiff4.diff(enc_content, admin_content) self.log.write(parent_node.entry, user_path, self.root_key, attachment=content) view.build() self.assertEqual(admin_content.encode(), view.get(user_path).content) alt_content = bsdiff4.diff(content, ('content-' + utils.random_ascii(32)).encode()) self.log.write(parent_node.entry, user_path, key, attachment=alt_content) self.assertEqual(admin_content.encode(), view.get(user_path).content) # Grant consistency with prev state view.grant(os.sep, 'user', key) self.assertEqual(admin_content.encode(), view.get(user_path).content) view.build() self.assertEqual(admin_content.encode(), view.get(user_path).content) # Test prints self.log.print_tree(view=view, color=True) self.log.print_tree(view=view, ascii=True)
def test_permission(self): self.assertEqual(0o750, stat.S_IMODE(os.stat(self.mountpoint).st_mode)) self.assertEqual(0o640, stat.S_IMODE(os.stat(self.full_path('.cluster')).st_mode)) self.process.terminate() self.process.join() __, self.keypath = tempfile.mkstemp() self.addCleanup(os.remove, self.keypath) self.key = Key.generate() self.key.save(self.keypath) self.fs = FileSystem(self.logpath, self.keypath, serf=False) self.process = Process(target=lambda: FUSE(self.fs, self.mountpoint, nothreads=True, foreground=True)) self.process.start() time.sleep(0.01) self.assertEqual(0o550, stat.S_IMODE(os.stat(self.mountpoint).st_mode)) self.assertEqual(0o440, stat.S_IMODE(os.stat(self.full_path('.cluster')).st_mode)) home_path = 'home-' + utils.random_ascii() with self.assertRaises(PermissionError): os.mkdir(self.full_path(home_path))
def setUp(self): __, self.logpath = tempfile.mkstemp() __, self.logpath_b = tempfile.mkstemp() self.addCleanup(os.remove, self.logpath) self.addCleanup(os.remove, self.logpath_b) __, self.keypath = tempfile.mkstemp() self.addCleanup(os.remove, self.keypath) self.port = random.randint(40000, 50000-1) self.port_b = random.randint(50000, 60000) log = Log(self.logpath) root_key = Key.generate() log.bootstrap([root_key], ['127.0.0.1:%i' % self.port]) root_key.save(self.keypath) shutil.copy2(self.logpath, self.logpath_b) self.hostname = utils.random_ascii(10) self.hostname_b = utils.random_ascii(10) self.mountpath = tempfile.mkdtemp() self.mountpath_b = tempfile.mkdtemp() context = { 'mountpath': self.mountpath, 'logpath': self.logpath, 'keypath': self.keypath, 'port': self.port, 'hostname': self.hostname, } cmd = 'basefs mount %(logpath)s %(mountpath)s -k %(keypath)s -p %(port)s -n %(hostname)s' proc = subprocess.Popen(cmd % context, shell=True) self.addCleanup(proc.kill) time.sleep(1) self.addCleanup(proc.kill) context.update({ 'mountpath': self.mountpath_b, 'logpath': self.logpath_b, 'port': self.port_b, 'hostname': self.hostname_b, }) proc = subprocess.Popen(cmd % context, shell=True) self.addCleanup(proc.kill) self.addCleanup(time.sleep, 1) self.addCleanup(proc.kill) self.addCleanup(shutil.rmtree, self.mountpath) self.addCleanup(shutil.rmtree, self.mountpath_b) time.sleep(1)
def test_permission(self): self.assertEqual(0o750, stat.S_IMODE(os.stat(self.mountpoint).st_mode)) self.assertEqual( 0o640, stat.S_IMODE(os.stat(self.full_path('.cluster')).st_mode)) self.process.terminate() self.process.join() __, self.keypath = tempfile.mkstemp() self.addCleanup(os.remove, self.keypath) self.key = Key.generate() self.key.save(self.keypath) self.fs = FileSystem(self.logpath, self.keypath, serf=False) self.process = Process(target=lambda: FUSE( self.fs, self.mountpoint, nothreads=True, foreground=True)) self.process.start() time.sleep(0.01) self.assertEqual(0o550, stat.S_IMODE(os.stat(self.mountpoint).st_mode)) self.assertEqual( 0o440, stat.S_IMODE(os.stat(self.full_path('.cluster')).st_mode)) home_path = 'home-' + utils.random_ascii() with self.assertRaises(PermissionError): os.mkdir(self.full_path(home_path))
def test_branch_conflict(self): view = View(self.log, self.root_key) view.build() home_path = os.path.join(os.sep, 'home-' + utils.random_ascii()) view.mkdir(home_path) key = Key.generate() view.grant(home_path, 'user', key) view = View(self.log, key) view.build() parent_node = view.get(home_path) user_path = os.path.join(home_path, 'user-' + utils.random_ascii()) max_hash = None enc_content = '' for ix in range(12): content = 'content-' + utils.random_ascii(32) prev = enc_content enc_content = bsdiff4.diff(enc_content, content) entry = self.log.write(parent_node.entry, user_path, key, attachment=enc_content) max_hash = max(max_hash, entry.hash) if max_hash else entry.hash view = View(self.log, self.root_key) view.build() self.assertEqual(bsdiff4.patch(prev, self.log.entries[max_hash].get_content()), view.get(user_path).content) # Admin branch more power admin_content = 'content-' + utils.random_ascii(32) content = bsdiff4.diff(enc_content, admin_content) self.log.write(parent_node.entry, user_path, self.root_key, attachment=content) view.build() self.assertEqual(admin_content.encode(), view.get(user_path).content) alt_content = bsdiff4.diff(content, ('content-' + utils.random_ascii(32)).encode()) self.log.write(parent_node.entry, user_path, key, attachment=alt_content) self.assertEqual(admin_content.encode(), view.get(user_path).content) # Grant consistency with prev state view.grant(os.sep, 'user', key) self.assertEqual(admin_content.encode(), view.get(user_path).content) view.build() self.assertEqual(admin_content.encode(), view.get(user_path).content) # Test prints self.log.print_tree(view=view, color=True) self.log.print_tree(view=view, ascii=True)
def test_revoke(self): root_view = View(self.log, self.root_key) root_view.build() home_path = os.path.join(os.sep, 'home-' + utils.random_ascii()) root_view.mkdir(home_path) key = Key.generate() root_view.grant(home_path, 'user', key) view = View(self.log, key) view.build() user_path = os.path.join(home_path, 'user-' + utils.random_ascii()) view.mkdir(user_path) root_view.build() file_path = os.path.join(user_path, 'file2-' + utils.random_ascii()) file_content = ('content1-' + utils.random_ascii(1024)) * 32 root_view.write(file_path, file_content) self.assertEqual(file_content.encode(), root_view.get(file_path).content) root_view.revoke(home_path, 'user') self.assertEqual(file_content.encode(), root_view.get(file_path).content) self.assertEqual(file_path, root_view.get(file_path).path) view.build() # with open(self.logpath, 'r') as r: # print(r.read()) print(self.log.print_tree(view=view, color=True)) root_view.build() # TODO tree eq after build, except the revoke brancj # TODO test maintain current state (file writen by revoked user) print(self.log.print_tree(view=root_view, color=True)) alt_file_content = 'content2-' + utils.random_ascii() with self.assertRaises(exceptions.DoesNotExist): view.write(file_path, alt_file_content)
def bootstrap(logpath): log = Log(logpath) root_key = Key.generate() ip = '127.0.0.1' log.bootstrap([root_key], [ip]) return log, root_key