update jenkinsfile
This commit is contained in:
parent
87c51ba8fc
commit
88c75e43ae
17
Makefile
17
Makefile
@ -1,4 +1,4 @@
|
|||||||
.PHONY: fmt fmt-check clippy test test-debugger-socket ci
|
.PHONY: fmt fmt-check clippy tes-local test-debugger-socket test ci cobertura
|
||||||
|
|
||||||
fmt:
|
fmt:
|
||||||
cargo fmt
|
cargo fmt
|
||||||
@ -9,10 +9,21 @@ fmt-check:
|
|||||||
clippy:
|
clippy:
|
||||||
cargo clippy --workspace --all-features
|
cargo clippy --workspace --all-features
|
||||||
|
|
||||||
test:
|
test-local:
|
||||||
cargo test --workspace --all-targets --all-features --no-fail-fast
|
cargo test --workspace --all-targets --all-features --no-fail-fast
|
||||||
|
|
||||||
test-debugger-socket:
|
test-debugger-socket:
|
||||||
cargo test -p prometeu-host-desktop-winit --lib -- --ignored
|
cargo test -p prometeu-host-desktop-winit --lib -- --ignored
|
||||||
|
|
||||||
ci: fmt-check clippy test
|
coverage:
|
||||||
|
cargo llvm-cov --workspace --all-features --html --output-dir target/llvm-cov/html --fail-under-lines 20 --fail-under-functions 20 --fail-under-regions 20
|
||||||
|
|
||||||
|
coverage-xml:
|
||||||
|
cargo llvm-cov report --workspace --all-features --cobertura --output-path target/llvm-cov/cobertura.xml
|
||||||
|
|
||||||
|
coverage-json:
|
||||||
|
cargo llvm-cov report --workspace --all-features --json --summary-only --output-path target/llvm-cov/summary.json
|
||||||
|
|
||||||
|
test: fmt-check clippy test-local test-debugger-socket
|
||||||
|
ci: fmt-check clippy coverage
|
||||||
|
cobertura: coverage-xml coverage-json
|
||||||
|
|||||||
@ -188,7 +188,8 @@ impl Audio {
|
|||||||
return AudioOpStatus::BankInvalid;
|
return AudioOpStatus::BankInvalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sample = bank_slot.and_then(|bank| bank.samples.get(sample_id as usize).map(Arc::clone));
|
let sample =
|
||||||
|
bank_slot.and_then(|bank| bank.samples.get(sample_id as usize).map(Arc::clone));
|
||||||
|
|
||||||
if let Some(s) = sample {
|
if let Some(s) = sample {
|
||||||
// println!(
|
// println!(
|
||||||
@ -322,8 +323,7 @@ mod tests {
|
|||||||
let sound_banks = Arc::clone(&banks) as Arc<dyn SoundBankPoolAccess>;
|
let sound_banks = Arc::clone(&banks) as Arc<dyn SoundBankPoolAccess>;
|
||||||
let mut audio = Audio::new(sound_banks);
|
let mut audio = Audio::new(sound_banks);
|
||||||
|
|
||||||
let status =
|
let status = audio.play_sample(sample(), MAX_CHANNELS, 255, 128, 1.0, 0, LoopMode::Off);
|
||||||
audio.play_sample(sample(), MAX_CHANNELS, 255, 128, 1.0, 0, LoopMode::Off);
|
|
||||||
|
|
||||||
assert_eq!(status, AudioOpStatus::VoiceInvalid);
|
assert_eq!(status, AudioOpStatus::VoiceInvalid);
|
||||||
assert!(!audio.voices.iter().any(|voice| voice.active));
|
assert!(!audio.voices.iter().any(|voice| voice.active));
|
||||||
|
|||||||
@ -872,16 +872,13 @@ impl Gfx {
|
|||||||
let glyph = glyph_for_char(c);
|
let glyph = glyph_for_char(c);
|
||||||
let raw = color.0;
|
let raw = color.0;
|
||||||
|
|
||||||
let row_start = (-y).max(0).min(5) as usize;
|
let row_start = (-y).clamp(0, 5) as usize;
|
||||||
let row_end = (screen_h - y).max(0).min(5) as usize;
|
let row_end = (screen_h - y).clamp(0, 5) as usize;
|
||||||
let col_start = (-x).max(0).min(3) as usize;
|
let col_start = (-x).clamp(0, 3) as usize;
|
||||||
let col_end = (screen_w - x).max(0).min(3) as usize;
|
let col_end = (screen_w - x).clamp(0, 3) as usize;
|
||||||
|
|
||||||
for (row_idx, row) in glyph
|
for (row_idx, row) in
|
||||||
.iter()
|
glyph.iter().enumerate().skip(row_start).take(row_end.saturating_sub(row_start))
|
||||||
.enumerate()
|
|
||||||
.skip(row_start)
|
|
||||||
.take(row_end.saturating_sub(row_start))
|
|
||||||
{
|
{
|
||||||
let py = (y + row_idx as i32) as usize;
|
let py = (y + row_idx as i32) as usize;
|
||||||
let base = py * self.w;
|
let base = py * self.w;
|
||||||
|
|||||||
@ -87,9 +87,12 @@ impl AssetsPayloadSource {
|
|||||||
pub fn open_slice(&self, offset: u64, size: u64) -> io::Result<AssetsPayloadSlice> {
|
pub fn open_slice(&self, offset: u64, size: u64) -> io::Result<AssetsPayloadSlice> {
|
||||||
match self {
|
match self {
|
||||||
Self::Memory(bytes) => {
|
Self::Memory(bytes) => {
|
||||||
let start = usize::try_from(offset).map_err(|_| invalid_input("asset offset overflow"))?;
|
let start =
|
||||||
let len = usize::try_from(size).map_err(|_| invalid_input("asset size overflow"))?;
|
usize::try_from(offset).map_err(|_| invalid_input("asset offset overflow"))?;
|
||||||
let end = start.checked_add(len).ok_or_else(|| invalid_input("asset range overflow"))?;
|
let len =
|
||||||
|
usize::try_from(size).map_err(|_| invalid_input("asset size overflow"))?;
|
||||||
|
let end =
|
||||||
|
start.checked_add(len).ok_or_else(|| invalid_input("asset range overflow"))?;
|
||||||
if end > bytes.len() {
|
if end > bytes.len() {
|
||||||
return Err(invalid_input("asset range out of bounds"));
|
return Err(invalid_input("asset range out of bounds"));
|
||||||
}
|
}
|
||||||
@ -97,7 +100,9 @@ impl AssetsPayloadSource {
|
|||||||
Ok(AssetsPayloadSlice::Memory { bytes: Arc::clone(bytes), start, len })
|
Ok(AssetsPayloadSlice::Memory { bytes: Arc::clone(bytes), start, len })
|
||||||
}
|
}
|
||||||
Self::File(source) => {
|
Self::File(source) => {
|
||||||
let end = offset.checked_add(size).ok_or_else(|| invalid_input("asset range overflow"))?;
|
let end = offset
|
||||||
|
.checked_add(size)
|
||||||
|
.ok_or_else(|| invalid_input("asset range overflow"))?;
|
||||||
if end > source.payload_len {
|
if end > source.payload_len {
|
||||||
return Err(invalid_input("asset range out of bounds"));
|
return Err(invalid_input("asset range out of bounds"));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -132,11 +132,9 @@ impl MemcardService {
|
|||||||
|
|
||||||
match self.load_committed(fs, app_id, slot) {
|
match self.load_committed(fs, app_id, slot) {
|
||||||
Ok(Some(committed)) => Self::slice_payload(&committed.payload, offset, max_bytes),
|
Ok(Some(committed)) => Self::slice_payload(&committed.payload, offset, max_bytes),
|
||||||
Ok(None) => MemcardReadResult {
|
Ok(None) => {
|
||||||
status: MemcardStatus::Empty,
|
MemcardReadResult { status: MemcardStatus::Empty, bytes: Vec::new(), bytes_read: 0 }
|
||||||
bytes: Vec::new(),
|
}
|
||||||
bytes_read: 0,
|
|
||||||
},
|
|
||||||
Err(status) => MemcardReadResult { status, bytes: Vec::new(), bytes_read: 0 },
|
Err(status) => MemcardReadResult { status, bytes: Vec::new(), bytes_read: 0 },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,7 +222,11 @@ impl MemcardService {
|
|||||||
|
|
||||||
fn slice_payload(payload: &[u8], offset: usize, max_bytes: usize) -> MemcardReadResult {
|
fn slice_payload(payload: &[u8], offset: usize, max_bytes: usize) -> MemcardReadResult {
|
||||||
if offset >= payload.len() || max_bytes == 0 {
|
if offset >= payload.len() || max_bytes == 0 {
|
||||||
return MemcardReadResult { status: MemcardStatus::Ok, bytes: Vec::new(), bytes_read: 0 };
|
return MemcardReadResult {
|
||||||
|
status: MemcardStatus::Ok,
|
||||||
|
bytes: Vec::new(),
|
||||||
|
bytes_read: 0,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
let end = payload.len().min(offset.saturating_add(max_bytes));
|
let end = payload.len().min(offset.saturating_add(max_bytes));
|
||||||
let bytes = payload[offset..end].to_vec();
|
let bytes = payload[offset..end].to_vec();
|
||||||
@ -276,11 +278,13 @@ fn make_save_uuid(app_id: u32, slot: u8) -> [u8; 16] {
|
|||||||
let mut out = [0u8; 16];
|
let mut out = [0u8; 16];
|
||||||
out[0..4].copy_from_slice(&app_id.to_le_bytes());
|
out[0..4].copy_from_slice(&app_id.to_le_bytes());
|
||||||
out[4] = slot;
|
out[4] = slot;
|
||||||
out[5..13].copy_from_slice(&(std::time::SystemTime::now()
|
out[5..13].copy_from_slice(
|
||||||
|
&(std::time::SystemTime::now()
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
.map(|d| d.as_nanos() as u64)
|
.map(|d| d.as_nanos() as u64)
|
||||||
.unwrap_or(0))
|
.unwrap_or(0))
|
||||||
.to_le_bytes());
|
.to_le_bytes(),
|
||||||
|
);
|
||||||
out[13] = 0x50;
|
out[13] = 0x50;
|
||||||
out[14] = 0x4D;
|
out[14] = 0x4D;
|
||||||
out[15] = 0x31;
|
out[15] = 0x31;
|
||||||
@ -312,8 +316,10 @@ fn decode_slot_file(bytes: &[u8]) -> Result<SlotImage, MemcardStatus> {
|
|||||||
|
|
||||||
let mut save_uuid = [0u8; 16];
|
let mut save_uuid = [0u8; 16];
|
||||||
save_uuid.copy_from_slice(&bytes[5..21]);
|
save_uuid.copy_from_slice(&bytes[5..21]);
|
||||||
let generation = u64::from_le_bytes(bytes[21..29].try_into().map_err(|_| MemcardStatus::Corrupt)?);
|
let generation =
|
||||||
let checksum = u32::from_le_bytes(bytes[29..33].try_into().map_err(|_| MemcardStatus::Corrupt)?);
|
u64::from_le_bytes(bytes[21..29].try_into().map_err(|_| MemcardStatus::Corrupt)?);
|
||||||
|
let checksum =
|
||||||
|
u32::from_le_bytes(bytes[29..33].try_into().map_err(|_| MemcardStatus::Corrupt)?);
|
||||||
let payload_size =
|
let payload_size =
|
||||||
u32::from_le_bytes(bytes[33..37].try_into().map_err(|_| MemcardStatus::Corrupt)?) as usize;
|
u32::from_le_bytes(bytes[33..37].try_into().map_err(|_| MemcardStatus::Corrupt)?) as usize;
|
||||||
if payload_size > MEMCARD_SLOT_CAPACITY_BYTES {
|
if payload_size > MEMCARD_SLOT_CAPACITY_BYTES {
|
||||||
|
|||||||
@ -197,7 +197,7 @@ impl NativeInterface for VirtualMachineRuntime {
|
|||||||
let pan_raw = expect_int(args, 3)?;
|
let pan_raw = expect_int(args, 3)?;
|
||||||
let pitch = expect_number(args, 4, "pitch")?;
|
let pitch = expect_number(args, 4, "pitch")?;
|
||||||
|
|
||||||
if voice_id_raw < 0 || voice_id_raw >= 16 {
|
if !(0..16).contains(&voice_id_raw) {
|
||||||
ret.push_int(AudioOpStatus::VoiceInvalid as i64);
|
ret.push_int(AudioOpStatus::VoiceInvalid as i64);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ impl NativeInterface for VirtualMachineRuntime {
|
|||||||
_ => prometeu_hal::LoopMode::On,
|
_ => prometeu_hal::LoopMode::On,
|
||||||
};
|
};
|
||||||
|
|
||||||
if voice_id_raw < 0 || voice_id_raw >= 16 {
|
if !(0..16).contains(&voice_id_raw) {
|
||||||
ret.push_int(AudioOpStatus::VoiceInvalid as i64);
|
ret.push_int(AudioOpStatus::VoiceInvalid as i64);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -558,7 +558,7 @@ fn hex_decode(s: &str) -> Result<Vec<u8>, VmFault> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let bytes = s.as_bytes();
|
let bytes = s.as_bytes();
|
||||||
if bytes.len() % 2 != 0 {
|
if !bytes.len().is_multiple_of(2) {
|
||||||
return Err(VmFault::Trap(TRAP_TYPE, "payload_hex must have even length".to_string()));
|
return Err(VmFault::Trap(TRAP_TYPE, "payload_hex must have even length".to_string()));
|
||||||
}
|
}
|
||||||
let mut out = Vec::with_capacity(bytes.len() / 2);
|
let mut out = Vec::with_capacity(bytes.len() / 2);
|
||||||
|
|||||||
51
files/config/Jenkinsfile
vendored
51
files/config/Jenkinsfile
vendored
@ -1,20 +1,57 @@
|
|||||||
pipeline {
|
pipeline {
|
||||||
agent any
|
agent any
|
||||||
|
|
||||||
|
environment {
|
||||||
|
CARGO_TERM_COLOR = 'always'
|
||||||
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
stage('CI') {
|
stage('Build') {
|
||||||
steps {
|
steps {
|
||||||
withChecks(name: 'Rust CI', includeStage: true) {
|
withChecks(name: 'Test', includeStage: true) {
|
||||||
sh '''
|
sh '''
|
||||||
set -e
|
set -eux
|
||||||
which rustc
|
|
||||||
which cargo
|
|
||||||
rustc --version
|
|
||||||
cargo --version
|
|
||||||
make ci
|
make ci
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
|
publishHTML(target: [
|
||||||
|
allowMissing: false,
|
||||||
|
alwaysLinkToLastBuild: true,
|
||||||
|
keepAll: true,
|
||||||
|
reportDir: 'target/llvm-cov/html',
|
||||||
|
reportFiles: 'index.html',
|
||||||
|
reportName: 'Rust Coverage HTML',
|
||||||
|
reportTitles: 'Coverage Report'
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
} // Test
|
||||||
|
stage('Coverage') {
|
||||||
|
steps {
|
||||||
|
sh '''
|
||||||
|
set -eux
|
||||||
|
make cobertura
|
||||||
|
'''
|
||||||
|
recordCoverage(
|
||||||
|
tools: [[parser: 'COBERTURA', pattern: 'target/llvm-cov/cobertura.xml']],
|
||||||
|
sourceCodeRetention: 'LAST_BUILD',
|
||||||
|
enabledForFailure: true,
|
||||||
|
failOnError: true,
|
||||||
|
checksAnnotationScope: 'MODIFIED_LINES',
|
||||||
|
checksName: 'Rust Coverage',
|
||||||
|
qualityGates: [
|
||||||
|
[metric: 'LINE', baseline: 'MODIFIED_LINES', threshold: 20.0],
|
||||||
|
[metric: 'LINE', baseline: 'PROJECT', threshold: 20.0],
|
||||||
|
[metric: 'BRANCH', baseline: 'PROJECT', threshold: 20.0]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} // Cobertura
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
archiveArtifacts artifacts: 'target/llvm-cov/**', fingerprint: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user