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