fn test_revset_and_stash()

in rust-create-cascade/src/main.rs [1166:1267]


    fn test_revset_and_stash() {
        let env = TestEnv::new();

        let issuer = env.add_issuer();
        for _ in 1..=1000 {
            env.add_serial(&issuer);
        }
        env.add_revoked_serial(&issuer, Reason::KeyCompromise);

        let filter_file = env.dir.path().join("filter");
        let stash_file = env.dir.path().join("filter.stash");
        let revset_file = env.dir.path().join("revset.bin");
        let prev_revset_file = env.dir.path().join("old-revset.bin");
        let delta_dir = env.dir.path().join("delta");

        let stats = count_all(&env.revoked_dir(), &env.known_dir(), ReasonSet::All, None);
        create_cascade(
            &filter_file,
            stats.exact_revoked_count,
            stats.approx_ok_count,
            &env.revoked_dir(),
            &env.known_dir(),
            HashAlgorithm::Sha256,
            ReasonSet::All,
        );

        write_revset_and_delta(
            &delta_dir,
            &revset_file,
            &prev_revset_file,
            &env.revoked_dir(),
            &env.known_dir(),
            ReasonSet::All,
            None,
        );

        std::fs::rename(&revset_file, &prev_revset_file).expect("could not move revset file");
        let first_revset_bytes = std::fs::read(&prev_revset_file).expect("could not read revset");
        let first_revset: HashSet<Vec<u8>> =
            bincode::deserialize(&first_revset_bytes).expect("could not parse revset");

        // Add a revoked serial after writing the first revset and stash
        let serial = env.add_revoked_serial(&issuer, Reason::Unspecified);

        write_revset_and_delta(
            &delta_dir,
            &revset_file,
            &prev_revset_file,
            &env.revoked_dir(),
            &env.known_dir(),
            ReasonSet::All,
            None,
        );

        write_stash(&stash_file, &delta_dir, ReasonSet::All, None);

        let second_revset_bytes = std::fs::read(&revset_file).expect("could not read revset");
        let second_revset: HashSet<Vec<u8>> =
            bincode::deserialize(&second_revset_bytes).expect("could not parse revset");

        let serial_bytes = decode_serial(&serial);
        let issuer_bytes = decode_issuer(&issuer);
        let key = crlite_key(&issuer_bytes, &serial_bytes);

        // The newly revoked serial should be in the second revset
        assert!(!first_revset.contains(&key));
        assert!(second_revset.contains(&key));

        // The stash should contain the newly revoked serial.
        let stash = std::fs::read(&stash_file).expect("could not read stash file");
        assert_eq!(u32::from_le_bytes(stash[0..4].try_into().unwrap()), 1);
        assert_eq!(stash[4] as usize, issuer_bytes.len());
        assert_eq!(stash[5..5 + issuer_bytes.len()], issuer_bytes);
        assert_eq!(stash[5 + issuer_bytes.len()] as usize, serial_bytes.len());
        assert_eq!(stash[5 + issuer_bytes.len() + 1..], serial_bytes);

        // Write the revset again using ReasonSet::Specified, so the newly revoked serial
        // will not be treated as revoked.
        write_revset_and_delta(
            &delta_dir,
            &revset_file,
            &prev_revset_file,
            &env.revoked_dir(),
            &env.known_dir(),
            ReasonSet::Specified,
            None,
        );

        write_stash(&stash_file, &delta_dir, ReasonSet::Specified, None);

        let third_revset_bytes = std::fs::read(&revset_file).expect("could not read revset");
        let third_revset: HashSet<Vec<u8>> =
            bincode::deserialize(&third_revset_bytes).expect("could not parse revset");

        // The newly revoked serial should not be in the third revset as it has
        // an unspecified reason code
        assert!(!third_revset.contains(&key));

        // The stash should be empty
        let stash = std::fs::read(&stash_file).expect("could not read stash file");
        assert_eq!(stash.len(), 0);
    }