Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
jonlamb-gh committed Apr 4, 2024
1 parent 9d2d30f commit dc511e4
Show file tree
Hide file tree
Showing 25 changed files with 2,110 additions and 21 deletions.
1 change: 1 addition & 0 deletions .github/workflows/integration_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ jobs:
docker run \
--name reflector \
--network=host \
-e MODALITY_RUN_ID="$GITHUB_RUN_ID" \
-e RUST_LOG="modality_defmt=trace" \
-e INGEST_PROTOCOL_PARENT_URL="modality-ingest://127.0.0.1" \
-e MUTATION_PROTOCOL_PARENT_URL="modality-mutation://127.0.0.1" \
Expand Down
68 changes: 63 additions & 5 deletions src/event_record.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::Error;
use defmt_decoder::{Arg, Frame, Location};
use defmt_parser::{Fragment, ParserMode};
use modality_api::Uuid;
use modality_api::{AttrVal, BigInt, Nanoseconds, TimelineId};
use std::collections::BTreeMap;
use tracing::warn;
use tracing::{debug, warn};

pub type EventAttributes = BTreeMap<String, AttrVal>;

Expand Down Expand Up @@ -174,14 +175,18 @@ impl EventRecord {
formatted_string.clone().into(),
);

let mut deviant_event = None;

for (frag_idx, frag) in fragments.iter().enumerate() {
match frag {
Fragment::Literal(l) => {
let mut s: &str = l.as_ref();
// Look for <event_name>:: convention
if frag_idx == 0 {
if let Some((n, rem)) = s.split_once("::") {
name = n.trim().to_owned().into();
let ev_name = n.trim();
deviant_event = DeviantEventKind::from_event_name(ev_name);
name = ev_name.to_owned().into();
s = rem;
}
}
Expand Down Expand Up @@ -219,16 +224,40 @@ impl EventRecord {
// SAFETY: decoder/frame already checks args and params
let arg = &f.args()[p.index];
match arg_to_attr_val(arg) {
None => {
Some(val) => {
attributes.insert(Self::attr_key(&key), val);
}
None if deviant_event.is_none() => {
warn!(
formatted_string,
attr_key = key,
ty = ?p.ty,
"Unsupported arg type"
);
}
Some(val) => {
attributes.insert(Self::attr_key(&key), val);
None => {
// We have a deviant event, special case handle the UUID slices
match key.as_ref() {
"mutator.id" | "mutation.id" => {
if let Arg::Slice(uuid_bytes) = arg {
if let Ok(uuid) = Uuid::try_from(uuid_bytes.clone()) {
debug!(attr_key = key, attr_val = %uuid, "Found Deviant attribute");
attributes.insert(
Self::attr_key(&key),
uuid_to_integer_attr_val(&uuid),
);
} else {
warn!(attr_key = key, "Invalid UUID bytes");
}
} else {
warn!(
attr_key = key,
"Unsupported argument type for Deviant event"
);
}
}
_ => (),
}
}
}
}
Expand Down Expand Up @@ -375,6 +404,35 @@ fn ts_from_arg(arg: &Arg<'_>) -> Option<u64> {
})
}

#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub enum DeviantEventKind {
MutatorAnnounced,
MutatorRetired,
MutationCmdCommunicated,
MutationClearCommunicated,
MutationTriggered,
MutationInjected,
}

impl DeviantEventKind {
fn from_event_name(event_name: &str) -> Option<Self> {
use DeviantEventKind::*;
Some(match event_name {
"modality.mutator.announced" => MutatorAnnounced,
"modality.mutator.retired" => MutatorRetired,
"modality.mutation.command_communicated" => MutationCmdCommunicated,
"modality.mutation.clear_communicated" => MutationClearCommunicated,
"modality.mutation.triggered" => MutationTriggered,
"modality.mutation.injected" => MutationInjected,
_ => return None,
})
}
}

fn uuid_to_integer_attr_val(u: &Uuid) -> AttrVal {
i128::from_le_bytes(*u.as_bytes()).into()
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
7 changes: 7 additions & 0 deletions test_system/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
/target
.gdb_history
log.html
logs/
report.html
robot_output.xml
snapshots/
results-tests.robot.xml
.runids
13 changes: 11 additions & 2 deletions test_system/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version = "0.1.0"
edition = "2021"
authors = ["Jon Lamb"]
build = "build.rs"
exclude = ["tools/mutator-server"]

[[bin]]
name = "atsamd-rtic-firmware"
Expand Down Expand Up @@ -40,7 +41,7 @@ defmt = { git = "https://github.com/knurling-rs/defmt.git", rev = "4db33ca5df8d7
[profile.release]
codegen-units = 1
debug = 2
lto = true
lto = false

[package.metadata.renode]
name = 'atsamd-rtic'
Expand All @@ -50,6 +51,7 @@ machine-name = 'atsamd'
using-sysbus = true
init-commands = [
'include @renode/RttReader.cs',
'include @renode/commands.py',
]
platform-descriptions = [
'renode/atsamd51g19a.repl',
Expand Down Expand Up @@ -77,7 +79,14 @@ pre-start-commands = [
'logLevel -1 RttReader',
'RttReader Start',
]
start = 'emulation RunFor "00:00:20"'
# Includes the Deviant staged mutation related
#'write_staged_mutation "88b565a8-455b-4993-9779-9f6d4004d6d5" "d135b4b9-64c9-4d0d-b2bb-621e37ca29f7"',
reset = '''
sysbus LoadELF $bin
clear_deviant_noint_vars
'''
start = 'emulation RunFor "00:00:12"'
post-start-commands = [
'RttReader Stop',
'quit'
]
3 changes: 3 additions & 0 deletions test_system/config/reflector-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ additional-timeline-attributes = [
"ci_commit='${GITHUB_SHA-local}'",
"ci_git_commit='${GIT_COMMIT-local}'",
]
override-timeline-attributes = [
"run_id='${MODALITY_RUN_ID-1}'",
]

[plugins.ingest.importers.defmt]
additional-timeline-attributes = [
Expand Down
2 changes: 1 addition & 1 deletion test_system/config/workspace.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[[segmentation-rule]]
name = "by-run-id"
attributes = ["run_id"]
segment-name-template = "Run {timeline.run_id}"
segment-name-template = "{timeline.run_id}"
causally-partition-segments = true
1 change: 0 additions & 1 deletion test_system/memory.x
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ MEMORY
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K
}
_stack_start = ORIGIN(RAM) + LENGTH(RAM);

9 changes: 7 additions & 2 deletions test_system/renode/RttReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@ public void Start() {
this.NoisyLog("Starting RTT reading");
pollTimer.Enabled = true;
}


public void Stop() {
this.NoisyLog("Stopping RTT reading");
pollTimer.Enabled = false;
}

private void TimerLimitReachedCallback()
{
if(controlBlockAddress == 0)
Expand Down Expand Up @@ -135,7 +140,7 @@ private void readRttBuffer()
{
break;
}

uint addr = chBufferPtr + read;
machine.SystemBus.ReadBytes((ulong) addr, (int) count, buffer, (int) total);

Expand Down
26 changes: 26 additions & 0 deletions test_system/renode/commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from Antmicro import Renode
import uuid

def mc_clear_deviant_noint_vars():
sysbus = self.Machine["sysbus"]
var_mutation_staged_addr = sysbus.GetSymbolAddress("DEVIANT_MUTATION_STAGED")
sysbus.WriteDoubleWord(var_mutation_staged_addr, 0)

def mc_write_staged_mutation(mutator_uuid_str, mutation_uuid_str):
print("Writing staged mutation, mutator_id = %s, mutation_id = %s" % (mutator_uuid_str, mutation_uuid_str))
mutator_uuid = uuid.UUID(mutator_uuid_str)
mutation_uuid = uuid.UUID(mutation_uuid_str)

sysbus = self.Machine["sysbus"]
var_mutation_staged_addr = sysbus.GetSymbolAddress("DEVIANT_MUTATION_STAGED")
var_mutator_id_addr = sysbus.GetSymbolAddress("DEVIANT_MUTATOR_ID");
var_mutation_id_addr = sysbus.GetSymbolAddress("DEVIANT_MUTATION_ID");

for offset, b in enumerate(mutator_uuid.bytes):
val = int(b.encode('hex'), 16)
sysbus.WriteByte(var_mutator_id_addr + offset, val)
for offset, b in enumerate(mutation_uuid.bytes):
val = int(b.encode('hex'), 16)
sysbus.WriteByte(var_mutation_id_addr + offset, val)

sysbus.WriteDoubleWord(var_mutation_staged_addr, 1)
41 changes: 41 additions & 0 deletions test_system/renode/robot_frameworkd_setup.resc
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
:name: atsamd-rtic
:description: Runs the example firmware in Renode

using sysbus

mach create "atsamd"

include @renode/RttReader.cs
include @renode/commands.py

$bin = @target/thumbv7em-none-eabihf/release/atsamd-rtic-firmware

machine LoadPlatformDescription @renode/atsamd51g19a.repl
machine LoadPlatformDescriptionFromString
"""
sercom0: UART.SAMD5_UART @ sysbus 0x40003000
->nvic@48
"""

sysbus.nvic Frequency 10000000000
emulation CreateUARTHub "uarthub"
connector Connect sercom0 uarthub
connector Connect sercom3 uarthub
machine CreateRttReader
RttReader CreateFileBackend @/tmp/rtt_log.bin true
logLevel 3 sercom0
logLevel 3 sercom3
logLevel 3 sysbus
logLevel 3 nvic
logLevel 3 dwt
logLevel -1 RttReader
RttReader Start

macro reset
"""
sysbus LoadELF $bin
"""

runMacro $reset

clear_deviant_noint_vars
9 changes: 9 additions & 0 deletions test_system/scripts/get_test_run_id.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -euo pipefail

dir=".runids"

mkdir -p "$dir"

exit 0
7 changes: 7 additions & 0 deletions test_system/scripts/run_robot_framework.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

set -euo pipefail

renode-test --kill-stale-renode-instances tests.robot

exit 0
13 changes: 13 additions & 0 deletions test_system/scripts/setup_modality.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash

set -euo pipefail

modality user create --use admin

modality workspace create --use ci-tests config/workspace.toml

modality segment use --latest

conform spec create --file specs/tests.speqtr tests

exit 0
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
#!/usr/bin/env bash

set -euo pipefail

rustfmt --emit stdout target/rtic-expansion.rs | vim +':setlocal buftype=nofile filetype=rust' -

exit 0
7 changes: 7 additions & 0 deletions test_system/scripts/view_report.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

set -euo pipefail

firefox $PWD/report.html

exit 0
6 changes: 6 additions & 0 deletions test_system/view_rtt.sh → test_system/scripts/view_rtt.sh
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
#!/usr/bin/env bash

set -euo pipefail

cat /tmp/rtt_log.bin | defmt-print -e target/thumbv7em-none-eabihf/release/atsamd-rtic-firmware

exit 0
11 changes: 7 additions & 4 deletions test_system/specs/tests.speqtr
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
# @rtos_mode = "rtic1"
behavior "Basic Checks"
prohibited case "Start event comes first"
AUXON_TRACE_START@init <- *@*
AUXON_TRACE_START @ init <- *@*
end

nominal case "Start event checks"
AUXON_TRACE_START@init (exists(_.version) AND exists(_.task) AND _.level = "trace") aggregate count() = 1
AUXON_TRACE_START @ init (exists(_.version) AND exists(_.task) AND _.level = "trace") aggregate count() = 1
end
end

Expand Down Expand Up @@ -40,13 +40,16 @@ behavior "Context Switching"
-> AUXON_TASK_EXIT @ blinky
# back on the ISR
-> AUXON_CONTEXT_RETURN @ FREQM
end

recovery case "Mutation causes panic"
init -> panic @ consumer (_.msg = "*Message corruption!")
end
end

behavior "System Shutdown"
behavior "Nominal System Shutdown"
nominal case "System panics when done"
panic @ consumer (_.level = "error") aggregate count() = 1
panic @ consumer (_.level = "error" AND _.msg = "*data == 6") aggregate count() = 1
end
end

Expand Down
Loading

0 comments on commit dc511e4

Please sign in to comment.