Skip to content

Commit

Permalink
rust: set up workspace for rust project
Browse files Browse the repository at this point in the history
  • Loading branch information
rizsotto committed Feb 10, 2024
1 parent 5654978 commit d1aea48
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 62 deletions.
101 changes: 39 additions & 62 deletions .github/workflows/build_on_push.yml
Original file line number Diff line number Diff line change
@@ -1,70 +1,47 @@
name: continuous integration

on: [push, pull_request]
on:
push:
pull_request:

jobs:
build:
runs-on: ${{ matrix.os }}
name: Build on ${{ matrix.os }} with multilib ${{ matrix.multilib }}
env:
CARGO_TERM_COLOR: always

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: rustup component add clippy && rustup update stable && rustup default stable
- run: cd source
- run: cargo clippy
compile:
name: Compile
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: rustup update stable && rustup default stable
- run: cd source
- run: cargo check --verbose
test:
name: Test
strategy:
matrix:
include:
- os: ubuntu-latest
multilib: true
- os: ubuntu-latest
multilib: false
- os: macos-latest
multilib: false

os:
- ubuntu-latest
- windows-latest
- macOS-latest
toolchain:
- stable
- beta
- nightly
runs-on: ${{ matrix.os }}
needs: [compile]
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Install package dependencies
if: startsWith( matrix.os, 'ubuntu' )
run: |
sudo apt-get update -y
sudo apt-get install -y cmake pkg-config gfortran nvidia-cuda-toolkit libtool-bin valgrind
- name: Install package dependencies
if: startsWith( matrix.os, 'macos' )
run: |
brew install cmake pkg-config fmt spdlog nlohmann-json grpc
echo "PKG_CONFIG_PATH=$(brew --prefix)/opt/[email protected]/lib/pkgconfig" >> $GITHUB_ENV
- uses: actions/setup-python@v2
with:
python-version: '3.x'
cache: 'pip'
cache-dependency-path: '**/requirements.txt'

- name: Prepare
run: |
pip install -r test/requirements.txt
mkdir "$HOME/work/bear_build"
mkdir "$HOME/work/bear_install"
echo "BUILD_DIR=$HOME/work/bear_build" >> $GITHUB_ENV
echo "INSTALL_DIR=$HOME/work/bear_install" >> $GITHUB_ENV
echo "ZLIB_SRC_DIR=$HOME/work/zlib" >> $GITHUB_ENV
echo "$HOME/work/bear_install/bin:$PATH" >> $GITHUB_PATH
- name: Build
env:
CTEST_OUTPUT_ON_FAILURE: 1
C_FLAGS: -Wall -Wextra -pedantic
CXX_FLAGS: -Wall -Wextra -pedantic
CMAKE_OPTIONS: -DENABLE_MULTILIB=${{ matrix.multilib }}
run: |
cmake -B "$BUILD_DIR" -S "$GITHUB_WORKSPACE" $CMAKE_OPTIONS -DCMAKE_INSTALL_PREFIX:PATH="$INSTALL_DIR" -DCMAKE_INSTALL_LIBDIR=lib/x86_64-linux-gnu
cmake --build "$BUILD_DIR" --parallel 4 --target install
- uses: actions/checkout@v3
- run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
- run: cd source
- run: cargo build --verbose
- run: cargo test --verbose

- name: Run [functional test]
run: |
git clone https://github.com/madler/zlib.git $ZLIB_SRC_DIR -b v1.2.11
mkdir $HOME/work/zlib_compilations && cd $HOME/work/zlib_compilations
bear --help
bear -- $ZLIB_SRC_DIR/configure
bear -- make
cat compile_commands.json
$GITHUB_WORKSPACE/test/bin/assert_compilation compile_commands.json count -gt 30
5 changes: 5 additions & 0 deletions source/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[workspace]
members = [
"citnames_rs",
"intercept_rs"
]
26 changes: 26 additions & 0 deletions source/intercept_rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "intercept"
version = "4.0.0"
authors = ["László Nagy <rizsotto at gmail dot com>"]
description = "Rust crate to intercept executed of commands."
keywords = ["clang", "clang-tooling", "compilation-database"]
repository = "https://github.com/rizsotto/Bear"
homepage = "https://github.com/rizsotto/Bear"
license = "GPL-3"
edition = "2021"

[dependencies]
anyhow = "1.0"
lazy_static = "1.4"
serde = { version = "1.0", default-features = false, features = ["derive"] }
serde_json = { version = "1.0", default-features = false, features = ["std"] }
log = "0.4"
simple_logger = { version = "4.2", default-features = false, features = ["timestamps"]}
clap = { version = "4.4", default-features = false, features = ["std", "cargo", "help", "usage", "suggestions"] }
crossbeam = "0.8"
crossbeam-channel = "0.5"
rand = "0.8.5"
chrono = "0.4.33"

[[bin]]
name = "intercept"
150 changes: 150 additions & 0 deletions source/intercept_rs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
pub mod ipc {
use std::collections::HashMap;
use std::path::PathBuf;

use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct SessionLocator(String);

// Reporter id is a unique identifier for a reporter.
//
// It is used to identify the process that sends the execution report.
// Because the OS PID is not unique across a single build (PIDs are
// recycled), we need to use a new unique identifier to identify the process.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct ReporterId(pub u64);

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct ProcessId(u32);

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct Execution {
pub executable: PathBuf,
pub arguments: Vec<String>,
pub working_dir: PathBuf,
pub environment: HashMap<String, String>,
}

// Represent a relevant life cycle event of a process.
//
// Currently, it's only the process life cycle events (start, signal,
// terminate), but can be extended later with performance related
// events like monitoring the CPU usage or the memory allocation if
// this information is available.
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub enum Event {
Started {
pid: ProcessId,
ppid: ProcessId,
execution: Execution,
},
Terminated {
status: i64
},
Signaled {
signal: i32,
},
}

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct Envelope {
pub rid: ReporterId,
pub timestamp: u64,
pub event: Event,
}
}

mod client {
use std::net::UdpSocket;

use super::ipc::{Envelope, Event, ReporterId};

use rand::Rng;

impl ReporterId {
pub fn new() -> Self {
let id = rand::thread_rng().gen::<u64>();
ReporterId(id)
}
}

impl Envelope {
pub fn new(rid: &ReporterId, event: super::ipc::Event) -> Self {
let timestamp = chrono::Utc::now().timestamp_millis() as u64;
Envelope { rid: rid.clone(), timestamp, event }
}
}

// Represents the remote sink of supervised process events.
//
// Events from a process execution can be sent from many actors (mostly
// supervisor processes). The events are collected in a common place
// in order to reconstruct of final report of a build process.
trait Report {
fn report(&self, event: Event);
}

struct UdpReporter {
socket: UdpSocket,
destination: String,
reporter_id: ReporterId,
}

impl Report for UdpReporter {
fn report(&self, event: Event) {
let envelope = Envelope::new(&self.reporter_id, event);
let serialized_envelope = match serde_json::to_string(&envelope) {
Ok(s) => s,
Err(e) => {
eprintln!("Failed to serialize envelope: {}", e);
return;
}
};

match self.socket.send_to(serialized_envelope.as_bytes(), &self.destination) {
Ok(_) => (),
Err(e) => eprintln!("Failed to send envelope: {}", e),
};
}
}
}

mod server {
use std::net::UdpSocket;

use crossbeam::channel::Sender;
use serde_json::Result;

use super::ipc::Envelope;

struct UdpServer {
socket: UdpSocket,
sender: Sender<Envelope>,
}

impl UdpServer {
fn listen(&self) {
let mut buf = [0; 4096];

loop {
match self.socket.recv_from(&mut buf) {
Ok((amt, _src)) => {
let data = &mut buf[..amt];
let envelope: Result<Envelope> = serde_json::from_slice(data);

match envelope {
Ok(envelope) => {
if let Err(e) = self.sender.send(envelope) {
eprintln!("Failed to send envelope to channel: {}", e);
}
}
Err(e) => eprintln!("Failed to deserialize envelope: {}", e),
}
}
Err(e) => eprintln!("Failed to receive data: {}", e),
}
}
}
}
}
7 changes: 7 additions & 0 deletions source/intercept_rs/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use anyhow::Result;

use intercept::ipc::Execution;

fn main() -> Result<()> {
Ok(())
}

0 comments on commit d1aea48

Please sign in to comment.