Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 36a05f5a authored by Luke Huang's avatar Luke Huang Committed by Automerger Merge Worker
Browse files

Merge "Add more unit test for doh" am: 9310ca22

Original change: https://android-review.googlesource.com/c/platform/packages/modules/DnsResolver/+/1676245

Change-Id: Idf0a7f695c877bc5818ab5fc81133d35a38925dc
parents c7378dba 9310ca22
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -288,6 +288,13 @@ cc_library_static {
    min_sdk_version: "29",
}

filegroup {
    name: "resolv_rust_test_config_template",
    srcs: [
        "resolv_rust_test_config_template.xml",
    ],
}

filegroup {
    name: "resolv_test_config_template",
    srcs: [
@@ -368,6 +375,9 @@ rust_test {
    edition: "2018",
    test_suites: ["general-tests"],
    auto_gen_config: true,
    // Used to enable root permission for the test.
    // TODO: remove after 'require_root' is supported in rust_test.
    test_config_template: ":resolv_rust_test_config_template",
    rustlibs: [
        "libandroid_logger",
        "libanyhow",
+93 −1
Original line number Diff line number Diff line
@@ -475,10 +475,102 @@ pub unsafe extern "C" fn doh_query(

#[cfg(test)]
mod tests {
    use super::*;
    use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};

    const TEST_MARK: u32 = 0xD0033;
    const LOOPBACK_ADDR: &str = "127.0.0.1";

    #[test]
    fn dohdispatcher_invalid_args() {
        let test_args = [
            // Bad url
            ("foo", "bar"),
            ("https://1", "bar"),
            ("https:/", "bar"),
            // Bad ip
            ("https://dns.google", "bar"),
            ("https://dns.google", "256.256.256.256"),
        ];
        for args in &test_args {
            assert!(
                DohDispatcher::new(args.0, args.1, 0, None).is_err(),
                "doh dispatcher should not be created"
            )
        }
    }

    #[test]
    fn make_doh_udp_socket() {
        // Bad ip
        for ip in &["foo", "1", "333.333.333.333"] {
            assert!(super::make_doh_udp_socket(ip, 0).is_err(), "udp socket should not be created");
        }
        // Make a socket connecting to loopback with a test mark.
        let sk = super::make_doh_udp_socket(LOOPBACK_ADDR, TEST_MARK).unwrap();
        // Check if the socket is connected to loopback.
        assert_eq!(
            sk.peer_addr().unwrap(),
            SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), DOH_PORT))
        );

        // Check if the socket mark is correct.
        let fd: RawFd = sk.as_raw_fd();

        let mut mark: u32 = 50;
        let mut size = std::mem::size_of::<u32>() as libc::socklen_t;
        unsafe {
            // Safety: fd must be valid.
            assert_eq!(
                libc::getsockopt(
                    fd,
                    libc::SOL_SOCKET,
                    libc::SO_MARK,
                    &mut mark as *mut _ as *mut libc::c_void,
                    &mut size as *mut _ as *mut libc::socklen_t,
                ),
                0
            );
        }
        assert_eq!(mark, TEST_MARK);

        // Check if the socket is non-blocking.
        unsafe {
            // Safety: fd must be valid.
            assert_eq!(libc::fcntl(fd, libc::F_GETFL, 0) & libc::O_NONBLOCK, libc::O_NONBLOCK);
        }
    }

    #[test]
    fn create_quiche_config() {
        assert!(
            super::create_quiche_config(None).is_ok(),
            "quiche config without cert creating failed"
        );
        assert!(
            super::create_quiche_config(Some("data/local/tmp/")).is_ok(),
            "quiche config with cert creating failed"
        );
    }

    const GOOGLE_DNS_URL: &str = "https://dns.google/dns-query";
    const GOOGLE_DNS_IP: &str = "8.8.8.8";
    // qtype: A, qname: www.example.com
    const SAMPLE_QUERY: &str = "q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB";
    #[test]
    fn close_doh() {
        let doh = DohDispatcher::new(GOOGLE_DNS_URL, GOOGLE_DNS_IP, 0, None).unwrap();
        let (resp_tx, resp_rx) = oneshot::channel();
        let cmd = Command::DohQuery { query: SAMPLE_QUERY.as_bytes().to_vec(), resp: resp_tx };
        assert!(doh.query(cmd).is_ok(), "Send query failed");
        doh.abort_handler();
        assert!(RUNTIME_STATIC.block_on(resp_rx).is_err(), "channel should already be closed");
    }

    #[test]
    fn doh_init() {
        unsafe {
            // Safety: the returned pointer from doh_init() must be a null terminated string.
            // Safety: the returned pointer of doh_init() must be a null terminated string.
            assert_eq!(std::ffi::CStr::from_ptr(super::doh_init()).to_str().unwrap(), "1.0");
        }
    }
+26 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2020 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<configuration description="Configuration for {MODULE} Rust tests">
   <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
   <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
       <option name="cleanup" value="true" />
       <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
   </target_preparer>
   <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
       <option name="test-device-path" value="/data/local/tmp" />
       <option name="module-name" value="{MODULE}" />
   </test>
</configuration>