_rust_cpp_test_lib_rustc_static/
lib.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use fidl_fuchsia_kernel::{
6    CpuStats, MemoryStats, MemoryStatsCompression, MemoryStatsExtended, StatsProxyInterface,
7};
8use stalls::{MemoryStallRate, StallProvider};
9use std::future::{self, Ready};
10use std::pin::pin;
11use std::sync::atomic::{AtomicU64, Ordering};
12use std::sync::{Arc, Once};
13use tokio::sync::watch::{self};
14use traces::watcher::Watcher;
15
16struct FakeStallProvider {}
17
18impl StallProvider for FakeStallProvider {
19    fn get_stall_info(&self) -> Result<zx::MemoryStall, anyhow::Error> {
20        Ok(zx::MemoryStall { stall_time_some: 1, stall_time_full: 2 })
21    }
22
23    fn get_stall_rate(&self) -> Option<MemoryStallRate> {
24        unimplemented!();
25    }
26}
27struct FakeStatsProxy {
28    counter: Arc<AtomicU64>,
29}
30impl FakeStatsProxy {
31    fn new() -> FakeStatsProxy {
32        FakeStatsProxy { counter: Arc::new(AtomicU64::new(0)) }
33    }
34}
35
36impl StatsProxyInterface for FakeStatsProxy {
37    type GetMemoryStatsResponseFut = Ready<Result<MemoryStats, fidl::Error>>;
38    fn get_memory_stats(&self) -> <Self as StatsProxyInterface>::GetMemoryStatsResponseFut {
39        let base = self.counter.fetch_add(1000, Ordering::Relaxed);
40        future::ready(Ok(MemoryStats {
41            total_bytes: Some(base + 1),
42            free_bytes: Some(base + 2),
43            wired_bytes: Some(base + 3),
44            total_heap_bytes: Some(base + 4),
45            free_heap_bytes: Some(base + 5),
46            vmo_bytes: Some(base + 6),
47            mmu_overhead_bytes: Some(base + 7),
48            ipc_bytes: Some(base + 8),
49            other_bytes: Some(base + 9),
50            free_loaned_bytes: Some(base + 10),
51            cache_bytes: Some(base + 11),
52            slab_bytes: Some(base + 12),
53            zram_bytes: Some(base + 13),
54            vmo_reclaim_total_bytes: Some(base + 14),
55            vmo_reclaim_newest_bytes: Some(base + 15),
56            vmo_reclaim_oldest_bytes: Some(base + 16),
57            vmo_reclaim_disabled_bytes: Some(base + 17),
58            vmo_discardable_locked_bytes: Some(base + 18),
59            vmo_discardable_unlocked_bytes: Some(base + 19),
60            ..Default::default()
61        }))
62    }
63    type GetMemoryStatsExtendedResponseFut = Ready<Result<MemoryStatsExtended, fidl::Error>>;
64    fn get_memory_stats_extended(
65        &self,
66    ) -> <Self as StatsProxyInterface>::GetMemoryStatsExtendedResponseFut {
67        unimplemented!();
68    }
69    type GetMemoryStatsCompressionResponseFut = Ready<Result<MemoryStatsCompression, fidl::Error>>;
70    fn get_memory_stats_compression(
71        &self,
72    ) -> <Self as StatsProxyInterface>::GetMemoryStatsCompressionResponseFut {
73        let base = self.counter.fetch_add(1000, Ordering::Relaxed);
74        future::ready(Ok(MemoryStatsCompression {
75            uncompressed_storage_bytes: Some(base + 100),
76            compressed_storage_bytes: Some(base + 101),
77            compressed_fragmentation_bytes: Some(base + 102),
78            compression_time: Some((base + 103).try_into().unwrap()),
79            decompression_time: Some((base + 104).try_into().unwrap()),
80            total_page_compression_attempts: Some(base + 105),
81            failed_page_compression_attempts: Some(base + 106),
82            total_page_decompressions: Some(base + 107),
83            compressed_page_evictions: Some(base + 108),
84            eager_page_compressions: Some(base + 109),
85            memory_pressure_page_compressions: Some(base + 110),
86            critical_memory_page_compressions: Some(base + 111),
87            pages_decompressed_unit_ns: Some(base + 112),
88            pages_decompressed_within_log_time: Some([
89                base + 113,
90                114,
91                115,
92                116,
93                117,
94                118,
95                119,
96                120,
97            ]),
98            ..Default::default()
99        }))
100    }
101    type GetCpuStatsResponseFut = Ready<Result<CpuStats, fidl::Error>>;
102    fn get_cpu_stats(&self) -> <Self as StatsProxyInterface>::GetCpuStatsResponseFut {
103        unimplemented!();
104    }
105    type GetCpuLoadResponseFut = Ready<Result<Vec<f32>, fidl::Error>>;
106    fn get_cpu_load(&self, _: i64) -> <Self as StatsProxyInterface>::GetCpuLoadResponseFut {
107        unimplemented!();
108    }
109}
110
111async fn actual_main(watcher: Watcher) {
112    let stall_provider = FakeStallProvider {};
113    let kernel_stats = FakeStatsProxy::new();
114    traces::kernel::serve_forever(watcher, kernel_stats, stall_provider.into()).await;
115}
116
117static LOGGER_ONCE: Once = Once::new();
118
119#[no_mangle]
120pub extern "C" fn rs_init_logs() {
121    LOGGER_ONCE.call_once(|| {
122        diagnostics_log::initialize_sync(diagnostics_log::PublishOptions::default());
123    });
124}
125
126#[no_mangle]
127pub extern "C" fn rs_test_trace_two_records() {
128    let (sender, _) = watch::channel(());
129    let mut executor = fuchsia_async::TestExecutor::new_with_fake_time();
130    let start_time = executor.now();
131    let mut fut = pin!(actual_main(Watcher::new(sender.subscribe())));
132    assert!(
133        executor.run_until_stalled(&mut fut).is_pending(),
134        "Task should be waiting for the timer"
135    );
136    // One record has been written, the watcher is waiting for the timer.
137    executor.set_fake_time(start_time + fuchsia_async::MonotonicDuration::from_millis(980));
138    assert_eq!(false, executor.wake_expired_timers(), "Time should not wake until 1 second passed");
139
140    executor.set_fake_time(start_time + fuchsia_async::MonotonicDuration::from_millis(1000));
141    assert_eq!(true, executor.wake_expired_timers(), "Time should wake now");
142    assert!(
143        executor.run_until_stalled(&mut fut).is_pending(),
144        "Task should be waiting for the timers"
145    );
146    // Assertion on the traced record in ./test_runner.cc test_trace_two_records
147}
148#[no_mangle]
149pub extern "C" fn rs_test_trace_no_record() {
150    let (sender, _) = watch::channel(());
151    let mut executor = fuchsia_async::TestExecutor::new_with_fake_time();
152    let start_time = executor.now();
153    let mut fut = pin!(actual_main(Watcher::new(sender.subscribe())));
154    assert!(
155        executor.run_until_stalled(&mut fut).is_pending(),
156        "Task should be waiting for the watcher"
157    );
158
159    executor.set_fake_time(start_time + fuchsia_async::MonotonicDuration::from_millis(10000));
160    assert_eq!(
161        false,
162        executor.wake_expired_timers(),
163        "No time should be involved as we are waiting on the watcher"
164    );
165
166    sender.send(()).expect("There should be a watcher receiving this notification");
167    assert!(
168        executor.run_until_stalled(&mut fut).is_pending(),
169        "Task should be waiting for the watcher"
170    );
171    // Assertion on the traced record in ./test_runner.cc test_trace_no_record
172}