Skip to content

Commit

Permalink
Remove taskchampion-sync-server (#3380)
Browse files Browse the repository at this point in the history
This crate has been moved to
https://github.com/GothenburgBitFactory/taskchampion-sync-server.

The integration-tests repo used the sync server to test integration
between taskchampion and the sync-server. We should do that again, but
after taskchampion moves to its own repo (#3209). In the interim, the
cross-sync integration test can simply test syncing between local
servers, but the snapshot test is no longer useful as the local server
does not support snapshots.
  • Loading branch information
djmitche authored Apr 20, 2024
1 parent 304b84e commit f054a40
Show file tree
Hide file tree
Showing 20 changed files with 73 additions and 3,601 deletions.
536 changes: 1 addition & 535 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 0 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

members = [
"taskchampion/taskchampion",
"taskchampion/sync-server",
"taskchampion/lib",
"taskchampion/integration-tests",
"taskchampion/xtask",
Expand All @@ -16,17 +15,12 @@ exclude = [ "src/tc/rust" ]
# All Rust dependencies are defined here, and then referenced by the
# Cargo.toml's in the members with `foo.workspace = true`.
[workspace.dependencies]
actix-rt = "2"
actix-web = "^4.3.1"
anyhow = "1.0"
byteorder = "1.5"
cc = "1.0.73"
chrono = { version = "^0.4.22", features = ["serde"] }
clap = { version = "^4.3.0", features = ["string"] }
env_logger = "^0.10.2"
ffizz-header = "0.5"
flate2 = "1"
futures = "^0.3.25"
google-cloud-storage = { version = "0.15.0", default-features = false, features = ["rustls-tls", "auth"] }
lazy_static = "1"
libc = "0.2.136"
Expand Down
12 changes: 2 additions & 10 deletions doc/man/task-sync.5.in
Original file line number Diff line number Diff line change
Expand Up @@ -144,16 +144,8 @@ Users are identified by a client ID, and users with different client IDs are
entirely independent. Task data is encrypted by Taskwarrior, and the sync
server never sees un-encrypted data.

To start the server, run it in your preferred HTTP hosting environment, using
`--port` to set the TCP port on which it should listen. It is recommended to
use TLS to protect communications with the server, but this is not required.

The server stores its data in a database, the path to which is given by the
`--data-dir` argument, defaulting to "/var/lib/taskchampion-sync-server".

For example:

$ taskchampion-sync-server --port 8443 --data-dir /storage/taskdata
The server is developed in
https://github.com/GothenburgBitFactory/taskchampion-sync-server.

.SS Adding a New User

Expand Down
13 changes: 5 additions & 8 deletions taskchampion/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,8 @@ Other ideas;

TaskChampion is a typical Rust application.
To work on TaskChampion, you'll need to [install the latest version of Rust](https://www.rust-lang.org/tools/install).
Once you've done that, run `cargo build` at the top level of this repository to build the binaries.
This will build `task` and `taskchampion-sync-server` executables in the `./target/debug` directory.
You can build optimized versions of these binaries with `cargo build --release`, but the performance difference in the resulting binaries is not noticeable, and the build process will take a long time, so this is not recommended.

## Running Test
## Running Tests

It's always a good idea to make sure tests run before you start hacking on a project.
Run `cargo test` from the top-level of this repository to run the tests.
Expand All @@ -39,13 +36,13 @@ Aside from that, start reading the docs and the source to learn more!
The book documentation explains lots of the concepts in the design of TaskChampion.
It is linked from the README.

There are three crates in this repository.
There are three important crates in this repository.
You may be able to limit the scope of what you need to understand to just one crate.
* `taskchampion` is the core functionality of the application, implemented as a library
* `taskchampion-cli` implements the command-line interface (in `cli/`)
* `taskchampion-sync-server` implements the synchronization server (in `sync-server/`)
* `taskchampion-lib` implements a C API for `taskchampion`, used by Taskwarrior
* `integration-tests` contains some tests for integrations between multiple crates.

You can generate the documentation for the `taskchampion` crate with `cargo doc --release --open -p taskchampion`.
You can generate the documentation for the `taskchampion` crate with `cargo doc --release --open -p taskchampion`.

## Making a Pull Request

Expand Down
5 changes: 2 additions & 3 deletions taskchampion/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ Until that is complete, the information here may be out-of-date.

## Structure

There are five crates here:
There are four crates here:

* [taskchampion](./taskchampion) - the core of the tool
* [taskchampion-sync-server](./sync-server) - the server against which `task sync` operates
* [taskchampion-lib](./lib) - glue code to use _taskchampion_ from C
* [integration-tests](./integration-tests) (private) - integration tests covering _taskchampion-cli_, _taskchampion-sync-server_, and _taskchampion-lib_.
* [integration-tests](./integration-tests) (private) - integration tests covering _taskchampion_ and _taskchampion-lib_.
* [xtask](./xtask) (private) - implementation of the `cargo xtask codegen` command

## Code Generation
Expand Down
7 changes: 1 addition & 6 deletions taskchampion/integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,13 @@ publish = false
build = "build.rs"

[dependencies]
taskchampion = { path = "../taskchampion", features = ["server-sync"] }
taskchampion = { path = "../taskchampion" }
taskchampion-lib = { path = "../lib" }
taskchampion-sync-server = { path = "../sync-server" }

[dev-dependencies]
anyhow.workspace = true
actix-web.workspace = true
actix-rt.workspace = true
tempfile.workspace = true
pretty_assertions.workspace = true
log.workspace = true
env_logger.workspace = true
lazy_static.workspace = true

[build-dependencies]
Expand Down
155 changes: 62 additions & 93 deletions taskchampion/integration-tests/tests/cross-sync.rs
Original file line number Diff line number Diff line change
@@ -1,97 +1,66 @@
use actix_web::{App, HttpServer};
use pretty_assertions::assert_eq;
use taskchampion::{Replica, ServerConfig, Status, StorageConfig, Uuid};
use taskchampion_sync_server::{storage::InMemoryStorage, Server};
use taskchampion::{Replica, ServerConfig, Status, StorageConfig};
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()?;

// add some tasks on rep1
let t1 = rep1.new_task(Status::Pending, "test 1".into())?;
let t2 = rep1.new_task(Status::Pending, "test 2".into())?;

// modify t1
let mut t1 = t1.into_mut(&mut rep1);
t1.start()?;
let t1 = t1.into_immut();

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

// those tasks should exist on rep2 now
let t12 = rep2
.get_task(t1.get_uuid())?
.expect("expected task 1 on rep2");
let t22 = rep2
.get_task(t2.get_uuid())?
.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 t2 = t2.into_mut(&mut rep1);
t2.set_status(Status::Completed)?;
let t2 = t2.into_immut();

let mut t12 = t12.into_mut(&mut rep2);
t12.set_status(Status::Completed)?;

// 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(t1.get_uuid())?
.expect("expected task 1 on rep1");
assert_eq!(t1.get_status(), Status::Completed);

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

#[actix_rt::test]
async fn cross_sync() -> anyhow::Result<()> {
async fn server() -> anyhow::Result<u16> {
let _ = env_logger::builder()
.is_test(true)
.filter_level(log::LevelFilter::Trace)
.try_init();

let server = Server::new(Default::default(), Box::new(InMemoryStorage::new()));
let httpserver = HttpServer::new(move || App::new().configure(|sc| server.config(sc)))
.bind("0.0.0.0:0")?;

// bind was to :0, so the kernel will have selected an unused port
let port = httpserver.addrs()[0].port();
actix_rt::spawn(httpserver.run());
Ok(port)
}

fn client(port: u16) -> 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 client_id = Uuid::new_v4();
let encryption_secret = b"abc123".to_vec();
let make_server = || {
ServerConfig::Remote {
origin: format!("http://127.0.0.1:{}", port),
client_id,
encryption_secret: encryption_secret.clone(),
}
.into_server()
};

let mut serv1 = make_server()?;
let mut serv2 = make_server()?;

// add some tasks on rep1
let t1 = rep1.new_task(Status::Pending, "test 1".into())?;
let t2 = rep1.new_task(Status::Pending, "test 2".into())?;

// modify t1
let mut t1 = t1.into_mut(&mut rep1);
t1.start()?;
let t1 = t1.into_immut();

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

// those tasks should exist on rep2 now
let t12 = rep2
.get_task(t1.get_uuid())?
.expect("expected task 1 on rep2");
let t22 = rep2
.get_task(t2.get_uuid())?
.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 t2 = t2.into_mut(&mut rep1);
t2.set_status(Status::Completed)?;
let t2 = t2.into_immut();

let mut t12 = t12.into_mut(&mut rep2);
t12.set_status(Status::Completed)?;

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

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

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

Ok(())
}

let port = server().await?;
actix_rt::task::spawn_blocking(move || client(port)).await??;
Ok(())
}
98 changes: 0 additions & 98 deletions taskchampion/integration-tests/tests/snapshots.rs

This file was deleted.

27 changes: 0 additions & 27 deletions taskchampion/sync-server/Cargo.toml

This file was deleted.

Loading

0 comments on commit f054a40

Please sign in to comment.