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