def test_annex_filters(runner): r = runner N = 4 # Create some big data files for idx in range(N): util.mkrandfile(f"randfile{idx}", 200000) # 10x 200 MB files r.runcommand("gin", "upload", ".") # files should be links for idx in range(N): util.isannexed(r, f"randfile{idx}") status = util.zerostatus() status["OK"] = N util.assert_status(r, status=status) r.runcommand("gin", "remove-content", ".") status["OK"] = 0 status["NC"] = N util.assert_status(r, status=status) # TODO: Don't check on Windows # locking annexed files should turn them into symlinks r.runcommand("gin", "lock", ".") for idx in range(N): assert os.path.islink(f"randfile{idx}")
def test_rm_commit_offline(runner): r = runner # create files in root for idx in range(6): util.mkrandfile(f"root-{idx}.git", 5) util.mkrandfile(f"root-{idx}.annex", 2000) status = util.zerostatus() status["??"] += 12 util.assert_status(r, status=status) r.runcommand("gin", "commit", "root*") status["LC"] += 12 status["??"] -= 12 util.assert_status(r, status=status) r.runcommand("gin", "upload") status["LC"] -= 12 status["OK"] += 12 util.assert_status(r, status=status) for idx in range(2, 4): os.remove(f"root-{idx}.git") os.remove(f"root-{idx}.annex") status["OK"] -= 4 status["RM"] += 4 util.assert_status(r, status=status) r.runcommand("gin", "upload", ".") status["RM"] = 0 util.assert_status(r, status=status)
def read_flash(partition, addr, size): cmd = pack('<BBBHLL', 0x40, partition, 1, 0, addr, size) rsp = tls.cmd(cmd) assert_status(rsp) sz, = unpack('<xxLxx', rsp[:8]) return rsp[8:8 + sz]
def identify_sensor(): rsp = tls.cmd(b'\x75') assert_status(rsp) rsp = rsp[2:] zeroes, minor, major = unpack('<LHH', rsp) if zeroes != 0: raise Exception('This was not expected') return dev_info_lookup(major, minor)
def append_new_image(key=0, prev=b''): rsp = tls.app(pack('<BLL', 0x68, key, 0)) assert_status(rsp) new_key, = unpack('<L', rsp[2:]) usb.wait_int() rsp = tls.app(b'\x6b' + prev) assert_status(rsp) usb.wait_int() rsp = tls.app(b'\x6b' + prev) assert_status(rsp) res = rsp[2:] rsp = tls.app(unhexlify('6900000000')) assert_status(rsp) l, res = res[:2], res[2:] l, = unpack('<H', l) if l != len(res): raise Exception('Response size does not match %d != %d', l, len(res)) # FIXME check how it's done rather than using a hardcoded offsets res, new = res[:0x6c], res[0x6c:] return (new_key, res, new)
def get_fw_info(partition): rsp = tls.cmd(pack('<BB', 0x43, partition)) # don't want to throw exception here - it is normal not to have FW when we're about to upload it if len(rsp) == 2 and rsp[1] == 4 and rsp[0] == 0xb0: return None assert_status(rsp) rsp = rsp[2:] hdr = rsp[:0xa] rsp = rsp[0xa:] major, minor, modcnt, buildtime = unpack('<HHHL', hdr) modules = [rsp[i * 0xc:(i + 1) * 0xc] for i in range(0, modcnt)] modules = [unpack('<HHHHL', i) for i in modules] modules = [ModuleInfo(*i) for i in modules] return FirmwareInfo(major, minor, buildtime, modules)
def get_flash_info(): rsp = tls.cmd(unhex('3e')) assert_status(rsp) rsp = rsp[2:] hdr = rsp[:0xe] rsp = rsp[0xe:] jid0, jid1, blocks, unknown0, blocksize, unknown1, pcnt = unpack( '<HHHHHHH', hdr) ic = flash_ic_table_lookup(jid0, jid1, blocks * blocksize) if ic == None: raise Exception('Unknown flash IC. JEDEC id=%x:%x, size=%dx%d' % (jid0, jid1, blocks, blocksize)) partitions = [rsp[i * 0xc:(i + 1) * 0xc] for i in range(0, pcnt)] partitions = [unpack('<BBHLL', i) for i in partitions] partitions = [PartitionInfo(*i) for i in partitions] return FlashInfo(ic, blocks, unknown0, blocksize, unknown1, partitions)
def partition_flash(layout): info = get_flash_info() print('Detected Flash IC: %s, %d bytes' % (info.ic.name, info.ic.size)) if len(info.partitions) > 0: raise Exception('Flash is already partitioned') cmd = unhex('4f 0000 0000') cmd += with_hdr(0, serialize_flash_params(info.ic)) cmd += with_hdr(1, b''.join([serialize_partition(p) for p in layout])) cmd += with_hdr(5, make_cert()) cmd += with_hdr(3, crt_hardcoded) rsp = tls.cmd(cmd) assert_status(rsp) rsp = rsp[2:] crt_len, rsp = rsp[:4], rsp[4:] crt_len, = unpack('<L', crt_len) tls.handle_cert(rsp[:crt_len]) # ^ TODO - validate cert rsp = rsp[crt_len:]
def test_add_directory_remote(runner): r = runner r.runcommand("gin", "init") r.repositories[r.cmdloc] = None ngit = 3 nannex = 2 # create files in root for idx in range(ngit): util.mkrandfile(f"root-{idx}.git", 3) for idx in range(nannex): util.mkrandfile(f"root-{idx}.annex", 200) status = util.zerostatus() status["??"] = ngit + nannex util.assert_status(r, status=status) r.runcommand("gin", "commit", ".") status["LC"] += ngit + nannex status["??"] -= ngit + nannex util.assert_status(r, status=status) fsremotedir = os.path.join(r.testroot.name, "annexdata") r.runcommand("gin", "add-remote", "--create", "lanbackup", f"dir:{fsremotedir}") r.runcommand("gin", "git", "remote", "-v") r.repositories[fsremotedir] = None r.runcommand("gin", "upload") status["OK"] += ngit + nannex status["LC"] -= ngit + nannex util.assert_status(r, status=status)
def test_create_remote_on_add(runner): r = runner r.runcommand("gin", "init") r.repositories[r.cmdloc] = None ngit = 3 nannex = 2 # create files in root for idx in range(ngit): util.mkrandfile(f"root-{idx}.git", 3) for idx in range(nannex): util.mkrandfile(f"root-{idx}.annex", 200) status = util.zerostatus() status["??"] = nannex + ngit util.assert_status(r, status=status) r.runcommand("gin", "commit", ".") status["LC"] = ngit + nannex status["??"] = 0 util.assert_status(r, status=status) r.login() repopath = f"{r.username}/{r.reponame}" r.runcommand("gin", "add-remote", "--create", "origin", f"test:{repopath}") r.runcommand("gin", "upload") status["OK"] += status["LC"] status["LC"] = 0 util.assert_status(r, status=status)
def test_create_remote_prompt(runner): r = runner r.runcommand("gin", "init") r.repositories[r.cmdloc] = None ngit = 3 nannex = 2 # create files in root for idx in range(ngit): util.mkrandfile(f"root-{idx}.git", 3) for idx in range(nannex): util.mkrandfile(f"root-{idx}.annex", 200) status = util.zerostatus() status["??"] = nannex + ngit util.assert_status(r, status=status) r.runcommand("gin", "commit", ".") status["LC"] = ngit + nannex status["??"] = 0 util.assert_status(r, status=status) r.login() repopath = f"{r.username}/{r.reponame}" out, err = r.runcommand("gin", "add-remote", "origin", f"test:{repopath}", inp="abort") assert not err, f"Expected empty error, got\n{err}" assert out.endswith("aborted") out, err = r.runcommand("git", "remote", "-v") assert not out, f"Expected empty output, got\n{out}" assert not err, f"Expected empty error, got\n{err}" out, err = r.runcommand("gin", "add-remote", "origin", f"test:{repopath}", inp="add anyway") out, err = r.runcommand("git", "remote", "-v") assert len(out.splitlines()) == 2, "Unexpected output" assert not err, f"Expected empty error, got\n{err}" out, err = r.runcommand("gin", "upload", exit=False) assert err, "Expected error, got nothing" r.runcommand("git", "remote", "rm", "origin") out, err = r.runcommand("gin", "add-remote", "origin", f"test:{repopath}", inp="create") out, err = r.runcommand("gin", "upload") status["OK"] += ngit + nannex status["LC"] -= ngit + nannex util.assert_status(r, status=status)
def capture(prg): usb.purge_int_queue() start_scan(prg) b = usb.wait_int() if b[0] != 0: raise Exception('Unexpected interrupt type %s' % hexlify(b).decode()) try: wait_for_finger() wait_till_finished() finally: res = stop_prg() while True: b = usb.wait_int() if b[0] != 3: raise Exception('Unexpected interrupt type %s' % hexlify(b).decode()) if b[1] == 0x43: break assert_status(res) res = res[2:] l, res = res[:4], res[4:] l, = unpack('<L', l) if l != len(res): raise Exception('Response size does not match %d != %d', l, len(res)) x, y, w1, w2, error = unpack('<HHHHL', res) return error
def test_add_gin_remote(runner): r = runner r.runcommand("gin", "init") r.repositories[r.cmdloc] = None ngit = 3 nannex = 2 # create files in root for idx in range(ngit): util.mkrandfile(f"root-{idx}.git", 3) for idx in range(nannex): util.mkrandfile(f"root-{idx}.annex", 200) status = util.zerostatus() status["??"] = nannex + ngit util.assert_status(r, status=status) r.runcommand("gin", "commit", ".") status["LC"] = ngit + nannex status["??"] = 0 util.assert_status(r, status=status) r.login() r.runcommand("gin", "create", "--no-clone", r.reponame, "Test repository for add remote") r.repositories[r.cmdloc] = r.reponame repopath = f"{r.username}/{r.reponame}" r.runcommand("gin", "add-remote", "origin", f"test:{repopath}") r.runcommand("gin", "upload") status["OK"] += ngit + nannex status["LC"] -= ngit + nannex util.assert_status(r, status=status) # remove remote, add it with a different name (not origin) and see if it # works util.mkrandfile(f"final-file.annex", 500) r.runcommand("gin", "git", "remote", "rm", "origin") r.runcommand("gin", "git", "config", "--unset", "gin.remote") r.runcommand("gin", "add-remote", "notorigin", f"test:{repopath}") r.runcommand("gin", "upload", "final-file.annex") status["OK"] += 1 util.assert_status(r, status=status)
def send_init(self): #self.dev.set_configuration() # TODO analyse responses, detect hardware type assert_status(self.cmd(unhexlify('01'))) assert_status(self.cmd(unhexlify('19'))) # 43 -- get partition header(?) (02 -- fwext partition) # c28c745a in response is a FwextBuildtime = 0x5A748CC2 rsp = self.cmd(unhexlify('4302')) assert_status(self.cmd(init_hardcoded)) (err, ), rsp = unpack('<H', rsp[:2]), rsp[2:] if err != 0: # fwext is not loaded print('Clean slate') self.cmd(init_hardcoded_clean_slate)
def read_hw_reg32(addr): rsp = tls.cmd(pack('<BLB', 7, addr, 4)) assert_status(rsp) rsp, = unpack('<L', rsp[2:]) return rsp
def start_scan(cmd): assert_status(tls.app(cmd))
def identify(): glow_start_scan() try: err = capture(identify_prg) if err != 0: raise Exception('Capture failed: %08x' % err) # which finger? stg_id = 0 # match against any storage usr_id = 0 # match against any user cmd = pack('<BBBHHHHH', 0x5e, 2, 0xff, stg_id, usr_id, 1, 0, 0) rsp = tls.app(cmd) assert_status(rsp) b = usb.wait_int() if b[0] != 3: raise Exception('Identification failed: %s' % hexlify(b).decode()) rsp = tls.app(unhexlify('6000000000')) assert_status(rsp) rsp = rsp[2:] finally: # finish assert_status(tls.app(unhexlify('6200000000'))) (l, ), rsp = unpack('<H', rsp[:2]), rsp[2:] if l != len(rsp): raise Exception('Response size does not match') rsp = parse_dict(rsp) #for k in rsp: # print('%04x: %s (%d)' % (k, hexlify(rsp[k]).decode(), len(rsp[k]))) #0001: 09000000 (4) #0003: f500 (2) #0004: 8dee792532d3432d41c872fd4d6d590fbc855ad449cf2753cd919eb9c94675c6 (32) #0005: 0000000000000000000000000000000000000000000000000000000000000000 (32) #0008: 0a00 (2) #0002: 010b0000 (4) #0006: 00000000000000000000000000000000000000000000000000000000000000000000000000000000 (40) usrid, subtype, hsh, fingerid = rsp[1], rsp[3], rsp[4], rsp[8] usrid, = unpack('<L', usrid) subtype, = unpack('<H', subtype) fingerid, = unpack('<H', fingerid) usr = db.get_user(usrid) finger_record = db.get_record_children(fingerid) # Device won't let you add more than one data blob if len(finger_record.children) > 1: raise Exception('Expected only one child record for finger') print('Recognised finger %02x (%s) from user %s' % (subtype, subtype_to_string(subtype), repr(usr.identity))) print('Template hash: %s' % hexlify(hsh).decode()) if len(finger_record.children) > 0: if finger_record.children[0]['type'] != 8: raise Exception('Expected data blob as a finger child') blob_id = finger_record.children[0]['dbid'] blob = db.get_record_value(blob_id).value tag, sz = unpack('<HH', blob[:4]) val = blob[4:4 + sz] print('Data blob associated with the finger: %04x: %s' % (tag, hexlify(val).decode())) return rsp
def glow_end_enroll(): cmd = unhexlify( '39f4010000f401000001ff002000000000ffff0000000000000000000000000020000000000000000000000000f401000000ff0020000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' ) assert_status(tls.app(cmd))
def glow_start_scan(): cmd = unhexlify( '3920bf0200ffff0000019900200000000099990000000000000000000000000020000000000000000000000000ffff000000990020000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' ) assert_status(tls.app(cmd))
def test_create_from_local(runner): r = runner # create files in root for idx in range(51): util.mkrandfile(f"root-{idx}.git", 1) for idx in range(70, 91): util.mkrandfile(f"root-{idx}.annex", 100) # Create from local directory r.runcommand( "gin", "create", "--here", r.reponame, "Test repository for create --here. Created with test script") r.runcommand("gin", "upload", ".") util.assert_status(r, status={"OK": 72}) r.repositories[r.cmdloc] = r.reponame # gin upload command should not have created an extra commit out, err = r.runcommand("gin", "git", "rev-list", "--count", "HEAD") assert int(out) == 2, f"Expected 2 commits, got {out}" # Create more root files that will remain UNTRACKED for c in "abcdef": util.mkrandfile(f"root-file-{c}.untracked") # Create some subdirectories with files for idx in "abcdef": dirname = f"subdir-{idx}" os.mkdir(dirname) r.cdrel(dirname) for jdx in range(1, 11): util.mkrandfile(f"subfile-{jdx}.annex", 200) r.cdrel("..") # Upload all the files of the first subdirectory and 2 from the second r.runcommand("gin", "upload", "subdir-a", "subdir-b/subfile-5.annex", "subdir-b/subfile-10.annex") status = {"OK": 84, "??": 54} util.assert_status(r, status=status) # can also check each directory individually subb = {"??": 8} util.assert_status(r, path="subdir-b", status=subb) subcdef = {"??": 10} for p in "cdef": util.assert_status(r, path=f"subdir-{p}", status=subcdef) # Lock some files r.runcommand("gin", "lock", "root-70.annex", "root-75.annex", "root-84.annex") # Locked files should be marked TC util.assert_status(r, status={"TC": 3}) # Lock a whole directory r.runcommand("gin", "lock", "subdir-a") util.assert_status(r, status={"TC": 13}) # Check subdirectory only util.assert_status(r, path="subdir-a", status={"TC": 10}) # Check again but from within the subdir r.cdrel("subdir-a") util.assert_status(r, status={"TC": 10}) r.cdrel("..") # Re-unlock one of the files r.runcommand("gin", "unlock", "root-84.annex") util.assert_status(r, status={"TC": 12}) # check one of the remaining unlocked files explicitly util.assert_status(r, path="root-70.annex", status={"TC": 1}) # commit the type changes r.runcommand("gin", "commit") # no TCs left util.assert_status(r, status={"TC": 0}) # There should be no NC files so far util.assert_status(r, status={"NC": 0}) # drop some files and check the counts r.runcommand("gin", "rmc", "subdir-b/subfile-5.annex") util.assert_status(r, path="subdir-b", status={"NC": 1}) r.runcommand("gin", "rmc", "subdir-b") util.assert_status(r, path="subdir-b", status={"NC": 2}) r.runcommand("gin", "remove-content", "subdir-a") util.assert_status(r, path="subdir-b", status={"NC": 2}) util.assert_status(r, path="subdir-a", status={"NC": 10}) util.assert_status(r, status={"NC": 12}) print("Done!")
def test_annex_upgrade(runner): r = runner # checks if all files with suffix ".annex" are annexed files def assert_all_annex(): for root, dirs, files in os.walk("."): if ".git" in dirs: dirs.remove(".git") # don't visit .git directory for f in files: if f.endswith("annex"): fname = os.path.join(root, f) assert util.isannexed(r, fname) # add some file, commit, upload, then upgrade os.mkdir("first batch") fbfiles = 0 for idx in range(5): fname = os.path.join("first batch", f"small-{idx}.git") util.mkrandfile(fname, 5) fbfiles += 1 for idx in range(7, 9): fname = os.path.join("first batch", f"big-{idx}.annex") util.mkrandfile(fname, 2000) fbfiles += 1 status = util.zerostatus() status["??"] += fbfiles util.assert_status(r, status=status) r.runcommand("gin", "commit", "first batch") status["LC"] += status["??"] status["??"] = 0 util.assert_status(r, status=status) r.runcommand("gin", "upload") status["OK"] += status["LC"] status["LC"] = 0 util.assert_status(r, status=status) assert_all_annex() with open(os.path.join(".git", "config")) as gitconf: assert "version = 5" in gitconf.read() r.runcommand("gin", "annex", "upgrade") r.runcommand("gin", "init") util.assert_status(r, status=status) with open(os.path.join(".git", "config")) as gitconf: conf = gitconf.read() assert "version = 7" in conf assert "addunlocked" in conf assert_all_annex() os.mkdir("second batch") sbfiles = 0 for idx in range(20, 30): fname = os.path.join("second batch", f"small-{idx}.git") util.mkrandfile(fname, 5) sbfiles += 1 for idx in range(10, 15): fname = os.path.join("second batch", f"big-{idx}.annex") util.mkrandfile(fname, 2000) sbfiles += 1 status["??"] += sbfiles util.assert_status(r, status=status) r.runcommand("gin", "commit", ".") status["LC"] += status["??"] status["??"] = 0 util.assert_status(r, status=status) r.runcommand("gin", "upload") status["OK"] += status["LC"] status["LC"] = 0 util.assert_status(r, status=status) assert_all_annex()
def test_annex_filters(runner): r = runner # Create some big data files for idx in range(3): util.mkrandfile(f"randfile{idx}", 1000) r.runcommand("gin", "upload", ".") def isannexed(fname): return util.isannexed(r, fname) # annexed files should include path to annex objects in their git blob for idx in range(3): fname = f"randfile{idx}" assert isannexed(fname) # Create markdown, python, and 'foo' file # All these are extensions that are excluded from annex in the config # Make them "large" (bigger than annex threshold) excludedfiles = ["markdown.md", "python.py", "biscuits.foo"] for fname in excludedfiles: util.mkrandfile(fname, 500) r.runcommand("gin", "upload", *excludedfiles) for fname in excludedfiles: assert not isannexed(fname) # make a really big "script" util.mkrandfile("bigscript.py", 100000) # 100 MB r.runcommand("ls", "-lh") r.runcommand("gin", "upload", "bigscript.py") assert not isannexed("bigscript.py") # clear local directory and reclone r.runcommand("gin", "annex", "uninit") r.cdrel("..") shutil.rmtree(r.reponame, onerror=util.force_rm) repopath = f"{r.username}/{r.reponame}" r.runcommand("gin", "get", repopath) r.cdrel(r.reponame) # git files should be here status = util.zerostatus() status["OK"] = 4 status["NC"] = 3 util.assert_status(r, status=status) for fname in glob("randfile*"): assert isannexed(fname) # download first rand file r.runcommand("gin", "get-content", "randfile1") status["OK"] += 1 status["NC"] -= 1 util.assert_status(r, status=status) # download everything r.runcommand("gin", "getc", ".") status["OK"] += status["NC"] status["NC"] = 0 util.assert_status(r, status=status)
rsp = tls.cmd(cmd) assert_status(rsp) rsp = rsp[2:] crt_len, rsp = rsp[:4], rsp[4:] crt_len, = unpack('<L', crt_len) tls.handle_cert(rsp[:crt_len]) # ^ TODO - validate cert rsp = rsp[crt_len:] # ^ TODO - figure out what the rest of rsp means #usb.trace_enabled=True #tls.trace_enabled=True usb.open() assert_status(usb.cmd(reset_blob)) partition_flash(flash_layout_hardcoded) rsp = usb.cmd(unhex('01')) assert_status(rsp) # ^ get device info, contains firmware version which is needed to lookup pubkey for server cert validation rsp = usb.cmd(unhex('50')) # ^ TODO validate response # It should be signed by the firmware private key. # The corresponding pub key is hardcoded for each fw revision in the synaWudfBioUsb.dll. # for my device it is: x=f727653b4e16ce0665a6894d7f3a30d7d0a0be310d1292a743671fdf69f6a8d3, # y=a85538f8b6bec50d6eef8bd5f4d07a886243c58b2393948df761a84721a6ca94 assert_status(rsp) rsp = rsp[2:]
def write_fw_signature(partition, signature): rsp = tls.cmd(pack('<BBxH', 0x42, partition, len(signature)) + signature) assert_status(rsp)
def write_flash(partition, addr, buf): tls.cmd(db_write_enable) cmd = pack('<BBBHLL', 0x41, partition, 1, 0, addr, len(buf)) + buf rsp = tls.cmd(cmd) assert_status(rsp) flush_changes()
def write_hw_reg32(addr, val): rsp = tls.cmd(pack('<BLLB', 8, addr, val, 4)) assert_status(rsp)
def reboot(): assert_status(tls.cmd(unhex('050200')))
# 0800 0000 9400 0e00 0300 0080 07000000 7e7f807f808080808080808080808080808080808080818081808180818080808080818081808080818081808180818081808180818081808180808081808180808081807f80808180808081808180818080808180818081808180818081808080818081808180818081808180818081808180818081808180818081808080808080808080807f807f807f807f7f7e7e # a400 0000 0800 0e00 0200 0000 00000000 0d007100 # b400 0000 0800 0e00 0800 0080 db000000 00000000 # c400 0000 0400 0e00 0500 0080 1c6f0400 # d000 0000 9400 0e00 0700 0080 07000000 2b23203c2d182e1e30182e1c321d341d341e321c301e1e241e201f201d1c321a301e1c211e21341f1e202024201f1e20201f212221221d221e23341e1d1e1d20341f1d193b341c1d1e35201e201c20221f341c1e1e1c221f201d21201e1c1f34242221201f20221f201e241e241d2020221e2420231d221e211e1f1e1e341c321e3220301d2d302f2d2c2b23223a211c # 6c01 0000 1400 0e00 0f00 0080 05550007 7701002805720000080100020811e107 # 8801 0000 0c00 0e00 1200 0080 07000000 7002 7800 7002 7800 # # Empty reply: # >>> 6f 000a 000000000000 # <<< 0000 880d 0000 00000000 #Thread(target=wait_82).start() rsp = tls.cmd(calibrate_prg) assert_status(rsp) print(rsp.hex()) # ^ TODO check what the rest of the rsp means calib_data = usb.read_82() print('len=%d' % len(calib_data)) with open('calib-data.bin', 'wb') as f: f.write(calib_data) class Line(): def __init__(self, blob): # what's with the rest of fields? self.u0, self.u1, self.line, self.frame, self.u2, self.u3, self.u4, self.u5 = unpack( '<BBBBBBBB', blob[:8]) self.data = blob[8:]
def run_checks(r): # create files in root for idx in range(50): util.mkrandfile(f"root-{idx}.git", 5) for idx in range(70, 90): util.mkrandfile(f"root-{idx}.annex", 2000) status = util.zerostatus() status["??"] += 70 util.assert_status(r, status=status) r.runcommand("gin", "commit", "root*") status["LC"] += 70 status["??"] -= 70 util.assert_status(r, status=status) r.runcommand("gin", "upload") status["LC"] -= 70 status["OK"] += 70 util.assert_status(r, status=status) # gin upload command should not have created an extra commit assert util.getrevcount(r) == 2 # Create more root files that will remain UNTRACKED for idx in "abcdef": util.mkrandfile(f"root-file-{idx}.untracked", 1) status["??"] += 6 util.assert_status(r, status=status) # lock all annexed files r.runcommand("gin", "lock", ".") status["TC"] += 20 status["OK"] -= 20 util.assert_status(r, status=status) # commit typechange r.runcommand("gin", "commit") status["TC"] -= 20 status["OK"] += 20 util.assert_status(r, status=status) # modify all tracked files r.runcommand("gin", "unlock", ".") status["TC"] += 20 status["OK"] -= 20 util.assert_status(r, status=status) for idx in range(50): util.mkrandfile(f"root-{idx}.git", 4) for idx in range(70, 90): util.mkrandfile(f"root-{idx}.annex", 2100) status["OK"] = 0 status["TC"] = 0 status["MD"] = 70 util.assert_status(r, status=status) r.runcommand("gin", "commit", "*.git", "*.annex") status["LC"] += status["MD"] status["MD"] = 0 util.assert_status(r, status=status) # Upload all except untracked r.runcommand("gin", "upload", "*.annex", "*.git") status["LC"] = 0 status["MD"] = 0 status["OK"] = 70 util.assert_status(r, status=status) # Should have 4 commits so far assert util.getrevcount(r) == 4 # Create some subdirectories with files for idx in "abcdef": dirname = f"subdir-{idx}" os.mkdir(dirname) r.cdrel(dirname) for jdx in range(10): util.mkrandfile(f"subfile-{jdx}.annex", 1500) r.cdrel("..") status["??"] += 60 util.assert_status(r, status=status) # Upload the files in the first subdirectory only and a couple from the # second r.runcommand("gin", "upload", "subdir-a", os.path.join("subdir-b", "subfile-5.annex"), os.path.join("subdir-b", "subfile-9.annex")) status["OK"] += 12 status["??"] -= 12 util.assert_status(r, status=status) subb = util.zerostatus() subb["OK"] = 2 subb["??"] = 8 util.assert_status(r, path="subdir-b", status=subb) tenuntracked = util.zerostatus() tenuntracked["??"] = 10 for idx in "cdef": util.assert_status(r, path=f"subdir-{idx}", status=tenuntracked) # Lock some files r.runcommand("gin", "lock", "root-70.annex", "root-75.annex", "root-84.annex") status["TC"] += 3 status["OK"] -= 3 util.assert_status(r, status=status) # Lock a whole directory r.runcommand("gin", "lock", "subdir-a") status["TC"] += 10 status["OK"] -= 10 util.assert_status(r, status=status) # Check subdirectory only tenul = util.zerostatus() tenul["TC"] = 10 util.assert_status(r, path="subdir-a", status=tenul) # Check again from within the subdir r.cdrel("subdir-a") util.assert_status(r, status=tenul) r.cdrel("..") # Revert lock on one of the files r.runcommand("gin", "unlock", "root-84.annex") status["TC"] -= 1 status["OK"] += 1 util.assert_status(r, status=status) onetc = util.zerostatus() onetc["TC"] = 1 # Check one of the remaining locked files explicitly util.assert_status(r, status=onetc, path="root-70.annex") # There should be no NC files so far status["NC"] = 0 util.assert_status(r, status=status) # Drop some files r.runcommand("gin", "rmc", os.path.join("subdir-b", "subfile-5.annex")) status["NC"] += 1 status["OK"] -= 1 util.assert_status(r, status=status) # remove content in subdir-a r.runcommand("gin", "remove-content", "subdir-a") # removing content of TypeChanged files still shows them as unlocked until # the type change is committed util.assert_status(r, status=status) suba = util.zerostatus() suba["TC"] += 10 util.assert_status(r, status=suba, path="subdir-a") subb["OK"] -= 1 subb["NC"] += 1 util.assert_status(r, status=subb, path="subdir-b") # Upload everything and then rmc it r.runcommand("gin", "upload", ".") # subdir-a goes from TC to NC (unlocked, removed content, then commit) status["TC"] -= 10 status["NC"] += 10 # modified and untracked files become OK status["OK"] += status["TC"] + status["MD"] + status["LC"] + status["??"] # everything else becomes 0 status["TC"] = status["MD"] = status["LC"] = status["??"] = 0 util.assert_status(r, status=status) r.runcommand("gin", "rmc", ".") # annex files are now NC status["NC"] += 69 status["OK"] -= 69 util.assert_status(r, status=status) # remove a few files and check their status os.remove(os.path.join("subdir-a", "subfile-1.annex")) os.remove("root-10.git") shutil.rmtree("subdir-b", onerror=util.force_rm) status["RM"] += 12 status["NC"] -= 11 status["OK"] -= 1 util.assert_status(r, status=status) r.runcommand("gin", "commit", ".") status["RM"] = 0 util.assert_status(r, status=status) # Add new files, remove some existing ones, check status and upload util.mkrandfile("new-annex-file", 10021) util.mkrandfile("new-git-file", 10) shutil.rmtree("subdir-c", onerror=util.force_rm) status["RM"] += 10 status["??"] += 2 status["NC"] -= 10 util.assert_status(r, status=status) r.runcommand("gin", "upload", ".") status["RM"] = 0 status["OK"] += status["??"] status["??"] = 0 util.assert_status(r, status=status)
def flush_changes(): assert_status(tls.cmd(b'\x1a'))