require_relative './test_config' require 'helix_web_services_client' describe 'HelixWebServicesClient Helix Sync' do my_project_id = 'My~20Project' context 'create_helix_sync_device_client' do it 'should create a new device client for a user' do client_as_jdoe do |c| c.add_setting('HVE_PROJECTS_PATH', '//depot/main') info = c.create_helix_sync_device_client(my_project_id, 'client_user_test', '/dev/null') expect(info.client).to include(my_project_id) expect(info.client).to include('client_user_test') expect(info.client).to include('jdoe') end end end context 'create_helix_sync_shelf_client' do it 'should create a new shelf client for a user' do client_as_jdoe do |c| c.add_setting('HVE_PROJECTS_PATH', '//depot/main') info = c.create_helix_sync_shelf_client(my_project_id) expect(info.client).to include(my_project_id) expect(info.client).to include('jdoe') end end end context 'fetch_helix_sync_latest_changelist' do it 'should return a latest changelist for a user' do client_as_jdoe do |c| c.add_setting('HVE_PROJECTS_PATH', '//depot/main') info = c.fetch_helix_sync_latest_changelist(my_project_id) expect(info.change.to_i).to be > 1 end end end context 'preview_helix_sync_pending_change' do create_cloud_project('preview_test_add') if cloud_test? context 'simple add' do it 'indicates a new file should be added' do client_as_jdoe do |c| c.add_setting('HVE_PROJECTS_PATH', '//depot/main') begin p4 = p4_as_jdoe info = create_sync_project('preview_test_add', c, p4) sync_root = info[0] device_client = info[1] depot_path = info[2] new_file_name = create_new_file_under(sync_root) run_device_sync('preview_test_add', sync_root, c, device_client) preview = c.preview_helix_sync_pending_change('preview_test_add') puts "preview: #{preview}" if ENV['HELIX_SYNC_DEBUG'] expect(preview.length).to eq(1) expect(preview.first.depotFile).to eq("#{depot_path}/#{new_file_name}") expect(preview.first.action).to eq('add') # Cleanup change = c.fetch_helix_sync_pending_changelist('preview_test_add').change shelf_client = c.create_helix_sync_shelf_client('preview_test_add') p4.client = shelf_client.client client_spec = p4.fetch_client client_spec._root = sync_root p4.save_client(client_spec) shelve_out = p4.run_shelve('-d', '-c', change) puts "shelve_out: #{shelve_out}" if ENV['HELIX_SYNC_DEBUG'] change_out = p4.run_change('-d', change) puts "change_out: #{change_out}" if ENV['HELIX_SYNC_DEBUG'] client_out = p4.run_client('-d', shelf_client.client) puts "client_out: #{client_out}" if ENV['HELIX_SYNC_DEBUG'] ensure p4.disconnect if !p4.nil? and p4.connected? FileUtils.rmtree(sync_root) if sync_root && Dir.exist?(sync_root) end end end end # This is a scenario where we've deleted a file on a shelf, that was also # already deleted by someone else. So the "resolution" is to just remove # the file from the shelf, no further action is needed. context 'remove from shelf' do # This test depends on the file added above create_cloud_project('preview_test_remove') if cloud_test? it 'just removes the file from the shelf' do upload_test_file('preview_test_remove', 'to_delete', 'First state!') client_as_jdoe do |c| c.add_setting('HVE_PROJECTS_PATH', '//depot/main') begin p4 = p4_as_jdoe info = create_sync_project('preview_test_remove', c, p4) sync_root = info[0] device_client = info[1] depot_path = info[2] file_path = File.join(sync_root, 'to_delete') File.delete(file_path) run_device_sync('preview_test_remove', sync_root, c, device_client) delete_test_file('preview_test_remove', 'to_delete') preview = c.preview_helix_sync_pending_change('preview_test_remove') puts "preview remove from shelf: #{preview}" if ENV['HELIX_SYNC_DEBUG'] expect(preview.length).to eq(1) expect(preview.first.depotFile).to eq("#{depot_path}/to_delete") expect(preview.first.action).to eq('delete') # Cleanup change = c.fetch_helix_sync_pending_changelist('preview_test_remove').change shelf_client = c.create_helix_sync_shelf_client('preview_test_remove') p4.client = shelf_client.client client_spec = p4.fetch_client client_spec._root = sync_root p4.save_client(client_spec) shelve_out = p4.run_shelve('-d', '-c', change) puts "shelve_out: #{shelve_out}" if ENV['HELIX_SYNC_DEBUG'] change_out = p4.run_change('-d', change) puts "change_out: #{change_out}" if ENV['HELIX_SYNC_DEBUG'] client_out = p4.run_client('-d', shelf_client.client) puts "client_out: #{client_out}" if ENV['HELIX_SYNC_DEBUG'] ensure p4.disconnect if !p4.nil? and p4.connected? FileUtils.rmtree(sync_root) if sync_root && Dir.exist?(sync_root) end end end end # This is a scenario where user A edited a file that user B has deleted, # and user A submits the changes. The resolution is to "re-add". context 'readd' do it 'adds file content that the user has edited but someone else removed' do create_cloud_project('preview_readd_test') if cloud_test? upload_test_file('preview_readd_test', "README", 'First state!') client_as_jdoe do |c| c.add_setting('HVE_PROJECTS_PATH', '//depot/main') begin p4 = p4_as_jdoe info = create_sync_project('preview_readd_test', c, p4) sync_root = info[0] device_client = info[1] depot_path = info[2] readme_path = File.join(sync_root, 'README') IO.write(readme_path, 'Second state') run_device_sync('preview_readd_test', sync_root, c, device_client) delete_test_file('preview_readd_test','README') preview = c.preview_helix_sync_pending_change('preview_readd_test') expect(preview.first.depotFile).to eq("#{depot_path}/README") expect(preview.first.action).to eq('edit') # Cleanup c.delete_helix_sync_pending_changelist('preview_readd_test') c.delete_helix_sync_device_client('preview_readd_test', 'test-machine') c.delete_helix_sync_shelf_client('preview_readd_test') ensure p4.disconnect if !p4.nil? and p4.connected? FileUtils.rmtree(sync_root) if sync_root && Dir.exist?(sync_root) end end end end end context 'submit_helix_sync_pending_change' do new_file_name = nil create_cloud_project('synctest') if cloud_test? context 'no resolves needed' do it 'creates a new file' do client_as_jdoe do |c| c.add_setting('HVE_PROJECTS_PATH', '//depot/main') begin p4 = p4_as_jdoe info = create_sync_project('synctest', c, p4) sync_root = info[0] device_client = info[1] depot_path = info[2] new_file_name = create_new_file_under(sync_root) run_device_sync('synctest', sync_root, c, device_client) c.submit_helix_sync_pending_change('synctest') changes = p4.run_changes('-s', 'pending', '-u', 'jdoe') puts "no resolves needed changes: #{changes}" if ENV['HELIX_SYNC_DEBUG'] files = c.files(depot_path) expect(files.map(&:depotFile)).to include("#{depot_path}/#{new_file_name}") ensure p4.disconnect if !p4.nil? and p4.connected? FileUtils.rmtree(sync_root) if sync_root && Dir.exist?(sync_root) end end end end # This is a scenario where we've deleted a file on a shelf, that was also # already deleted by someone else. So the "resolution" is to just remove # the file from the shelf, no further action is needed. context 'remove from shelf' do # This test depends on the file added above it 'just removes the file from the shelf' do client_as_jdoe do |c| c.add_setting('HVE_PROJECTS_PATH', '//depot/main') begin p4 = p4_as_jdoe info = create_sync_project('synctest', c, p4) sync_root = info[0] device_client = info[1] depot_path = info[2] new_file_path = File.join(sync_root, new_file_name) File.delete(new_file_path) run_device_sync('synctest', sync_root, c, device_client) delete_test_file('synctest',new_file_name) c.submit_helix_sync_pending_change('synctest') ensure p4.disconnect if !p4.nil? and p4.connected? FileUtils.rmtree(sync_root) if sync_root && Dir.exist?(sync_root) end end end end # This is a scenario where user A edited a file that user B has deleted, # and user A submits the changes. The resolution is to "re-add". context 'readd' do it 'adds file content that the user has edited but someone else removed' do create_cloud_project('readd_test') if cloud_test? upload_test_file('readd_test', "README", 'First state!') client_as_jdoe do |c| c.add_setting('HVE_PROJECTS_PATH', '//depot/main') begin p4 = p4_as_jdoe info = create_sync_project('readd_test', c, p4) sync_root = info[0] device_client = info[1] depot_path = info[2] readme_path = File.join(sync_root, 'README') IO.write(readme_path, 'Second state') run_device_sync('readd_test', sync_root, c, device_client) delete_test_file('readd_test', 'README') c.submit_helix_sync_pending_change('readd_test') files = c.files(depot_path) shelf_client = c.create_helix_sync_shelf_client('readd_test').client changes = p4.run_changes('-s', 'pending', '-u', 'jdoe', '-c', shelf_client) puts "post readd changes: #{changes}" if ENV['HELIX_SYNC_DEBUG'] expect(changes.empty?).to be(true) file = c.file("#{depot_path}/README") expect(file.Content).to eq('Second state') ensure p4.disconnect if !p4.nil? and p4.connected? FileUtils.rmtree(sync_root) if sync_root && Dir.exist?(sync_root) end end end end context 'lock' do it 'renames a locked file from the submit' do randstr = (0...8).map { (65 + rand(26)).chr }.join lock_file_name = "test_#{randstr}" project_id = "lock_test_#{randstr}" create_cloud_project(project_id) if cloud_test? upload_test_file(project_id, lock_file_name, 'Current State') client_as_jdoe do |c| c.add_setting('HVE_PROJECTS_PATH', '//depot/main') begin p4 = p4_as_jdoe info = create_sync_project("#{project_id}", c, p4) sync_root = info[0] device_client = info[1] depot_path = info[2] new_file_name = create_new_file_under(sync_root) IO.write("#{sync_root}/#{lock_file_name}", 'Edited state') # The server seems to run into problems if we run device sync too fast # I'm adding 1-second sleeps to ensure there's at least a wee bit # of time between operations. Otherwise fstat just doesn't report # the locks are actually locks sleep(1) run_device_sync(project_id, sync_root, c, device_client) sleep(1) edit_and_lock(project_id, lock_file_name) sleep(1) pending = c.fetch_helix_sync_pending_changelist(project_id).change puts "pending change #{pending}" if ENV['HELIX_SYNC_DEBUG'] c.submit_helix_sync_pending_change(project_id) changes = p4.run_changes('-s', 'pending', '-u', 'jdoe') puts "no resolves needed changes: #{changes}" if ENV['HELIX_SYNC_DEBUG'] files = c.files(depot_path) expect(files.map(&:depotFile)).to include("#{depot_path}/#{lock_file_name}.#{pending}.locked") lock_file = c.file("#{depot_path}/#{lock_file_name}") expect(lock_file.Content).to eq('Current State') renamed_file = c.file("#{depot_path}/#{lock_file_name}.#{pending}.locked") expect(renamed_file.Content).to eq('Edited state') ensure p4.disconnect if !p4.nil? and p4.connected? FileUtils.rmtree(sync_root) if sync_root && Dir.exist?(sync_root) end end end end end end