Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita21896f

Browse files
authored
feat: Improve integration tests (#214)
1 parent29bfb06 commita21896f

File tree

14 files changed

+966
-228
lines changed

14 files changed

+966
-228
lines changed

‎Cargo.lock

Lines changed: 321 additions & 2 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎examples/http-server/tests/integration.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fn test_php() {
3939

4040
let client =Client::new();
4141
for _in0..5{
42-
let response = client.get("http://127.0.0.1:9000/").send().unwrap();
42+
let response = client.get("http://127.0.0.1:9010/").send().unwrap();
4343
assert_eq!(response.status(),StatusCode::OK);
4444
let content_type = response.headers().get(CONTENT_TYPE).unwrap();
4545
assert_eq!(content_type,"text/plain");

‎examples/http-server/tests/php/test.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
ini_set("display_startup_errors","On");
1818
error_reporting(E_ALL);
1919

20-
$server =newHttpServer("127.0.0.1",9000);
20+
$server =newHttpServer("127.0.0.1",9010);
2121
$server->onRequest(function ($request,$response) {
2222
echo"HEADERS:\n";
2323
foreach ($request->headersas$key =>$value) {
@@ -30,6 +30,6 @@
3030
$response->end("Hello World\n");
3131
});
3232

33-
echo"Listening http://127.0.0.1:9000\n\n";
33+
echo"Listening http://127.0.0.1:9010\n\n";
3434

3535
$server->start();

‎phper-test/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ repository = { workspace = true }
2020
license = {workspace =true }
2121

2222
[dependencies]
23+
cargo_metadata ="0.20.0"
2324
fastcgi-client ="0.9.0"
2425
libc ="0.2.169"
26+
log = {version ="0.4.27",features = ["kv"] }
2527
phper-macros = {workspace =true }
2628
tempfile ="3.17.1"
27-
tokio = {version ="1.43.0",features = ["full"] }
29+
tokio = {version ="1.43.0",features = ["net"] }
2830

2931
[package.metadata.docs.rs]
3032
rustdoc-args = ["--cfg","docsrs"]

‎phper-test/src/cargo.rs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright (c) 2022 PHPER Framework Team
2+
// PHPER is licensed under Mulan PSL v2.
3+
// You can use this software according to the terms and conditions of the Mulan
4+
// PSL v2. You may obtain a copy of Mulan PSL v2 at:
5+
// http://license.coscl.org.cn/MulanPSL2
6+
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
7+
// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
8+
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
9+
// See the Mulan PSL v2 for more details.
10+
11+
//! Cargo build utilities for building and analyzing Rust libraries.
12+
13+
use cargo_metadata::Message;
14+
use log::{debug, trace};
15+
use std::{
16+
io::{self,BufReader},
17+
path::{Path,PathBuf},
18+
process::{Command,Stdio},
19+
};
20+
21+
/// Builder for running cargo build commands with JSON output
22+
pubstructCargoBuilder{
23+
command:Command,
24+
}
25+
26+
/// Result of a cargo build operation
27+
pubstructCargoBuildResult{
28+
messages:Vec<Message>,
29+
}
30+
31+
implCargoBuilder{
32+
/// Create a new CargoBuilder instance
33+
pubfnnew() ->Self{
34+
letmut args =vec!["build","--lib","--message-format","json"];
35+
if !cfg!(debug_assertions){
36+
args.push("--release");
37+
}
38+
letmut command =Command::new(env!("CARGO"));
39+
command
40+
.args(&args)
41+
.stdin(Stdio::null())
42+
.stdout(Stdio::piped())
43+
.stderr(Stdio::null());
44+
Self{ command}
45+
}
46+
47+
/// Add additional arguments to the cargo command
48+
pubfnarg<S:AsRef<std::ffi::OsStr>>(&mutself,arg:S) ->&mutSelf{
49+
self.command.arg(arg);
50+
self
51+
}
52+
53+
/// Set the current directory for the cargo command
54+
pubfncurrent_dir<P:AsRef<Path>>(&mutself,dir:P) ->&mutSelf{
55+
self.command.current_dir(dir);
56+
self
57+
}
58+
59+
/// Execute the cargo build command and return the result
60+
pubfnbuild(&mutself) -> io::Result<CargoBuildResult>{
61+
debug!(command:% ={
62+
let program =self.command.get_program();
63+
let args =self.command.get_args();
64+
letmut command = vec![program];
65+
command.extend(args);
66+
command.join(" ".as_ref()).to_string_lossy().to_string()
67+
};"run cargo build command");
68+
69+
letmut child =self.command.spawn()?;
70+
let stdout = child
71+
.stdout
72+
.take()
73+
.ok_or_else(|| io::Error::new(io::ErrorKind::Other,"Failed to capture stdout"))?;
74+
let reader =BufReader::new(stdout);
75+
letmut messages =Vec::new();
76+
for messagein cargo_metadata::Message::parse_stream(reader){
77+
trace!(message:?;"cargo build message");
78+
let message = message?;
79+
messages.push(message);
80+
}
81+
let exit_status = child.wait()?;
82+
if !exit_status.success(){
83+
returnErr(io::Error::new(
84+
io::ErrorKind::Other,
85+
format!("Cargo build failed with exit status: {}", exit_status),
86+
));
87+
}
88+
Ok(CargoBuildResult{ messages})
89+
}
90+
}
91+
92+
implDefaultforCargoBuilder{
93+
fndefault() ->Self{
94+
Self::new()
95+
}
96+
}
97+
98+
implCargoBuildResult{
99+
/// Get the cdylib file path from the last compiler-artifact message
100+
pubfnget_cdylib(&self) ->Option<PathBuf>{
101+
self.messages.iter().rev().find_map(|msg|{
102+
ifletMessage::CompilerArtifact(artifact) = msg{
103+
artifact.filenames.iter().find_map(|filename|{
104+
let ext = filename.extension();
105+
ifmatches!(ext,Some("so") |Some("dylib") |Some("dll")){
106+
Some(PathBuf::from(filename.as_std_path()))
107+
}else{
108+
None
109+
}
110+
})
111+
}else{
112+
None
113+
}
114+
})
115+
}
116+
}

‎phper-test/src/cli.rs

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//! Test tools for php cli program.
1212
1313
usecrate::context::Context;
14+
use log::debug;
1415
use std::{
1516
panic::{UnwindSafe, catch_unwind, resume_unwind},
1617
path::Path,
@@ -22,9 +23,23 @@ use std::{
2223
///
2324
/// - `lib_path` is the path of extension lib.
2425
///
25-
/// - `scripts` is the path of your php test scripts.
26+
/// - `script` is the path of your php test script.
27+
pubfntest_php_script(lib_path:implAsRef<Path>,scripts:implAsRef<Path>){
28+
let condition = |output:Output| output.status.success();
29+
let scripts =Some(scripts);
30+
let scripts = scripts
31+
.iter()
32+
.map(|s|(sas_,&conditionas_))
33+
.collect::<Vec<_>>();
34+
test_php_scripts_with_condition(lib_path,&scripts);
35+
}
36+
37+
/// Check your extension by executing the php script, if the all executing
38+
/// return success, than the test is pass.
39+
///
40+
/// - `lib_path` is the path of extension lib.
2641
///
27-
///See [example hello integrationtest](https://github.com/phper-framework/phper/blob/master/examples/hello/tests/integration.rs).
42+
///- `scripts` is the path of your phptest scripts.
2843
pubfntest_php_scripts(lib_path:implAsRef<Path>,scripts:&[&dynAsRef<Path>]){
2944
let condition = |output:Output| output.status.success();
3045
let scripts = scripts
@@ -58,31 +73,32 @@ pub fn test_php_scripts_with_condition(
5873
let output = cmd.output().unwrap();
5974
let path = script.as_ref().to_str().unwrap();
6075

61-
letmut stdout =String::from_utf8(output.stdout.clone()).unwrap();
76+
letmut stdout =String::from_utf8_lossy(&output.stdout).to_string();
6277
if stdout.is_empty(){
6378
stdout.push_str("<empty>");
6479
}
6580

66-
letmut stderr =String::from_utf8(output.stderr.clone()).unwrap();
81+
letmut stderr =String::from_utf8_lossy(&output.stderr).to_string();
6782
if stderr.is_empty(){
6883
stderr.push_str("<empty>");
69-
}
84+
};
7085

71-
eprintln!(
72-
"===== command =====\n{} {}\n===== stdout ======\n{}\n===== stderr ======\n{}",
73-
&context.php_bin,
74-
cmd.get_args().join(" "),
75-
stdout,
76-
stderr,
77-
);
78-
#[cfg(target_os ="linux")]
79-
if output.status.code().is_none(){
80-
use std::os::unix::process::ExitStatusExt;
81-
eprintln!(
82-
"===== signal ======\nExitStatusExt is None, the signal is: {:?}",
83-
output.status.signal()
84-
);
85-
}
86+
debug!(command:% = cmd.get_command().join(" ".as_ref()).to_string_lossy(),
87+
status:? = output.status.code(),
88+
stdout =&*stdout,
89+
stderr:%,
90+
signal:? ={
91+
#[cfg(unix)]
92+
{
93+
use std::os::unix::process::ExitStatusExtas _;
94+
output.status.signal()
95+
}
96+
#[cfg(not(unix))]
97+
{
98+
None
99+
}
100+
};
101+
"execute php test command");
86102

87103
if !condition(output){
88104
panic!("test php file `{}` failed", path);

‎phper-test/src/context.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
usecrate::utils;
1212
use std::{
1313
env,
14+
ffi::OsStr,
1415
fs::read_to_string,
1516
io::Write,
1617
ops::{Deref,DerefMut},
@@ -79,7 +80,7 @@ impl Context {
7980
script.as_ref().display().to_string(),
8081
];
8182
cmd.args(&args);
82-
ContextCommand{ cmd, args}
83+
ContextCommand{ cmd}
8384
}
8485

8586
pubfnfind_php_fpm(&self) ->Option<String>{
@@ -121,12 +122,15 @@ impl Context {
121122

122123
pubstructContextCommand{
123124
cmd:Command,
124-
args:Vec<String>,
125125
}
126126

127127
implContextCommand{
128-
pubfnget_args(&self) ->&[String]{
129-
&self.args
128+
pubfnget_command(&self) ->Vec<&OsStr>{
129+
let program =self.cmd.get_program();
130+
let args =self.cmd.get_args();
131+
letmut command =vec![program];
132+
command.extend(args);
133+
command
130134
}
131135
}
132136

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp