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:
|
||||
cargo fmt
|
||||
@ -9,10 +9,21 @@ fmt-check:
|
||||
clippy:
|
||||
cargo clippy --workspace --all-features
|
||||
|
||||
test:
|
||||
test-local:
|
||||
cargo test --workspace --all-targets --all-features --no-fail-fast
|
||||
|
||||
test-debugger-socket:
|
||||
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;
|
||||
}
|
||||
|
||||
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 {
|
||||
// println!(
|
||||
@ -322,8 +323,7 @@ mod tests {
|
||||
let sound_banks = Arc::clone(&banks) as Arc<dyn SoundBankPoolAccess>;
|
||||
let mut audio = Audio::new(sound_banks);
|
||||
|
||||
let status =
|
||||
audio.play_sample(sample(), MAX_CHANNELS, 255, 128, 1.0, 0, LoopMode::Off);
|
||||
let status = audio.play_sample(sample(), MAX_CHANNELS, 255, 128, 1.0, 0, LoopMode::Off);
|
||||
|
||||
assert_eq!(status, AudioOpStatus::VoiceInvalid);
|
||||
assert!(!audio.voices.iter().any(|voice| voice.active));
|
||||
|
||||
@ -872,16 +872,13 @@ impl Gfx {
|
||||
let glyph = glyph_for_char(c);
|
||||
let raw = color.0;
|
||||
|
||||
let row_start = (-y).max(0).min(5) as usize;
|
||||
let row_end = (screen_h - y).max(0).min(5) as usize;
|
||||
let col_start = (-x).max(0).min(3) as usize;
|
||||
let col_end = (screen_w - x).max(0).min(3) as usize;
|
||||
let row_start = (-y).clamp(0, 5) as usize;
|
||||
let row_end = (screen_h - y).clamp(0, 5) as usize;
|
||||
let col_start = (-x).clamp(0, 3) as usize;
|
||||
let col_end = (screen_w - x).clamp(0, 3) as usize;
|
||||
|
||||
for (row_idx, row) in glyph
|
||||
.iter()
|
||||
.enumerate()
|
||||
.skip(row_start)
|
||||
.take(row_end.saturating_sub(row_start))
|
||||
for (row_idx, row) in
|
||||
glyph.iter().enumerate().skip(row_start).take(row_end.saturating_sub(row_start))
|
||||
{
|
||||
let py = (y + row_idx as i32) as usize;
|
||||
let base = py * self.w;
|
||||
|
||||
@ -87,9 +87,12 @@ impl AssetsPayloadSource {
|
||||
pub fn open_slice(&self, offset: u64, size: u64) -> io::Result<AssetsPayloadSlice> {
|
||||
match self {
|
||||
Self::Memory(bytes) => {
|
||||
let start = usize::try_from(offset).map_err(|_| invalid_input("asset offset 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"))?;
|
||||
let start =
|
||||
usize::try_from(offset).map_err(|_| invalid_input("asset offset 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() {
|
||||
return Err(invalid_input("asset range out of bounds"));
|
||||
}
|
||||
@ -97,7 +100,9 @@ impl AssetsPayloadSource {
|
||||
Ok(AssetsPayloadSlice::Memory { bytes: Arc::clone(bytes), start, len })
|
||||
}
|
||||
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 {
|
||||
return Err(invalid_input("asset range out of bounds"));
|
||||
}
|
||||
|
||||
@ -132,11 +132,9 @@ impl MemcardService {
|
||||
|
||||
match self.load_committed(fs, app_id, slot) {
|
||||
Ok(Some(committed)) => Self::slice_payload(&committed.payload, offset, max_bytes),
|
||||
Ok(None) => MemcardReadResult {
|
||||
status: MemcardStatus::Empty,
|
||||
bytes: Vec::new(),
|
||||
bytes_read: 0,
|
||||
},
|
||||
Ok(None) => {
|
||||
MemcardReadResult { status: MemcardStatus::Empty, 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 {
|
||||
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 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];
|
||||
out[0..4].copy_from_slice(&app_id.to_le_bytes());
|
||||
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)
|
||||
.map(|d| d.as_nanos() as u64)
|
||||
.unwrap_or(0))
|
||||
.to_le_bytes());
|
||||
.to_le_bytes(),
|
||||
);
|
||||
out[13] = 0x50;
|
||||
out[14] = 0x4D;
|
||||
out[15] = 0x31;
|
||||
@ -312,8 +316,10 @@ fn decode_slot_file(bytes: &[u8]) -> Result<SlotImage, MemcardStatus> {
|
||||
|
||||
let mut save_uuid = [0u8; 16];
|
||||
save_uuid.copy_from_slice(&bytes[5..21]);
|
||||
let generation = 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 generation =
|
||||
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 =
|
||||
u32::from_le_bytes(bytes[33..37].try_into().map_err(|_| MemcardStatus::Corrupt)?) as usize;
|
||||
if payload_size > MEMCARD_SLOT_CAPACITY_BYTES {
|
||||
|
||||
@ -197,7 +197,7 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
let pan_raw = expect_int(args, 3)?;
|
||||
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);
|
||||
return Ok(());
|
||||
}
|
||||
@ -238,7 +238,7 @@ impl NativeInterface for VirtualMachineRuntime {
|
||||
_ => 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);
|
||||
return Ok(());
|
||||
}
|
||||
@ -558,7 +558,7 @@ fn hex_decode(s: &str) -> Result<Vec<u8>, VmFault> {
|
||||
}
|
||||
|
||||
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()));
|
||||
}
|
||||
let mut out = Vec::with_capacity(bytes.len() / 2);
|
||||
|
||||
51
files/config/Jenkinsfile
vendored
51
files/config/Jenkinsfile
vendored
@ -1,20 +1,57 @@
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
environment {
|
||||
CARGO_TERM_COLOR = 'always'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('CI') {
|
||||
stage('Build') {
|
||||
steps {
|
||||
withChecks(name: 'Rust CI', includeStage: true) {
|
||||
withChecks(name: 'Test', includeStage: true) {
|
||||
sh '''
|
||||
set -e
|
||||
which rustc
|
||||
which cargo
|
||||
rustc --version
|
||||
cargo --version
|
||||
set -eux
|
||||
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