File: cross-sync.rs

package info (click to toggle)
rust-taskchampion 2.0.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 812 kB
  • sloc: python: 49; makefile: 2
file content (91 lines) | stat: -rw-r--r-- 3,131 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use chrono::Utc;
use pretty_assertions::assert_eq;
use taskchampion::{Operations, Replica, ServerConfig, Status, StorageConfig, Uuid};
use tempfile::TempDir;

#[test]
fn cross_sync() -> anyhow::Result<()> {
    // set up two replicas, and demonstrate replication between them
    let mut rep1 = Replica::new(StorageConfig::InMemory.into_storage()?);
    let mut rep2 = Replica::new(StorageConfig::InMemory.into_storage()?);

    let tmp_dir = TempDir::new().expect("TempDir failed");
    let server_config = ServerConfig::Local {
        server_dir: tmp_dir.path().to_path_buf(),
    };
    let mut server = server_config.into_server()?;

    let (uuid1, uuid2) = (Uuid::new_v4(), Uuid::new_v4());
    let mut ops = Operations::new();

    // add some tasks on rep1
    let mut t1 = rep1.create_task(uuid1, &mut ops)?;
    t1.set_description("test 1".into(), &mut ops)?;
    t1.set_status(Status::Pending, &mut ops)?;
    t1.set_entry(Some(Utc::now()), &mut ops)?;
    let mut t2 = rep1.create_task(uuid2, &mut ops)?;
    t2.set_description("test 2".into(), &mut ops)?;
    t2.set_status(Status::Pending, &mut ops)?;
    t2.set_entry(Some(Utc::now()), &mut ops)?;

    // modify t1
    t1.start(&mut ops)?;

    rep1.commit_operations(ops)?;

    rep1.sync(&mut server, false)?;
    rep2.sync(&mut server, false)?;

    // those tasks should exist on rep2 now
    let mut t12 = rep2.get_task(uuid1)?.expect("expected task 1 on rep2");
    let t22 = rep2.get_task(uuid2)?.expect("expected task 2 on rep2");

    assert_eq!(t12.get_description(), "test 1");
    assert_eq!(t12.is_active(), true);
    assert_eq!(t22.get_description(), "test 2");
    assert_eq!(t22.is_active(), false);

    // make non-conflicting changes on the two replicas
    let mut ops = Operations::new();
    t2.set_status(Status::Completed, &mut ops)?;
    rep2.commit_operations(ops)?;

    let mut ops = Operations::new();
    t12.set_status(Status::Completed, &mut ops)?;
    rep2.commit_operations(ops)?;

    // sync those changes back and forth
    rep1.sync(&mut server, false)?; // rep1 -> server
    rep2.sync(&mut server, false)?; // server -> rep2, rep2 -> server
    rep1.sync(&mut server, false)?; // server -> rep1

    let t1 = rep1.get_task(uuid1)?.expect("expected task 1 on rep1");
    assert_eq!(t1.get_status(), Status::Completed);

    let mut t22 = rep2.get_task(uuid2)?.expect("expected task 2 on rep2");
    assert_eq!(t22.get_status(), Status::Completed);

    rep1.rebuild_working_set(true)?;
    rep2.rebuild_working_set(true)?;

    // Make task 2 pending again, and observe that it is in the working set in both replicas after
    // sync.
    let mut ops = Operations::new();
    t22.set_status(Status::Pending, &mut ops)?;
    rep2.commit_operations(ops)?;

    let ws = rep2.working_set()?;
    assert_eq!(ws.by_index(1), Some(uuid2));

    // Pending status is not sync'd to rep1 yet.
    let ws = rep1.working_set()?;
    assert_eq!(ws.by_index(1), None);

    rep2.sync(&mut server, false)?;
    rep1.sync(&mut server, false)?;

    let ws = rep1.working_set()?;
    assert_eq!(ws.by_index(1), Some(uuid2));

    Ok(())
}