Skip to content

Commit dcdd106

Browse files
authored
Merge pull request #24 from jmjoy/0.3.x-dev
2 parents af44121 + cfc66e9 commit dcdd106

File tree

17 files changed

+410
-107
lines changed

17 files changed

+410
-107
lines changed

.github/workflows/ci.yml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,15 @@ jobs:
4343
php-version: ${{ matrix.php-version }}
4444
tools: php-config
4545

46+
- name: Setup php-fpm
47+
run: |
48+
sudo apt-get install -y php${{ matrix.php-version }}-fpm
49+
sudo ln -s /usr/sbin/php-fpm${{ matrix.php-version }} /usr/sbin/php-fpm
50+
4651
- name: PHP version
47-
run: php-config || true
52+
run: |
53+
php-config || true
54+
/usr/sbin/php-fpm --version
4855
4956
- name: Install Rust Nightly
5057
uses: actions-rs/toolchain@v1
@@ -83,6 +90,9 @@ jobs:
8390

8491
- name: Cargo doc
8592
uses: actions-rs/cargo@v1
93+
env:
94+
RUSTDOCFLAGS: "-D warnings --cfg docsrs"
8695
with:
87-
toolchain: stable
96+
toolchain: nightly
8897
command: doc
98+
args: --workspace --no-deps --all-features

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ A library that allows us to write PHP extensions using pure Rust and using safe
4141
*sapi*
4242

4343
- [x] cli
44-
- [ ] fpm
44+
- [x] fpm
4545

4646
*debug*
4747

examples/hello/tests/integration.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use phper_test::test_php_scripts;
1+
use phper_test::cli::test_php_scripts;
22
use std::{env, path::Path};
33

44
#[test]

examples/http-client/tests/integration.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use phper_test::test_php_scripts;
1+
use phper_test::cli::test_php_scripts;
22
use std::{env, path::Path};
33

44
#[test]

examples/http-server/tests/integration.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use hyper::header::CONTENT_TYPE;
2-
use phper_test::test_long_term_php_script_with_condition;
2+
use phper_test::cli::test_long_term_php_script_with_condition;
33
use reqwest::Client;
44
use std::{env, path::Path, thread::sleep, time::Duration};
55
use tokio::runtime;

examples/logging/tests/integration.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use phper_test::test_php_scripts_with_condition;
1+
use phper_test::cli::test_php_scripts_with_condition;
22
use std::{env, path::Path, str};
33

44
#[test]

phper-alloc/src/lib.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,22 @@ impl<T: EAllocatable> Drop for EBox<T> {
8484
}
8585

8686
unsafe impl<T: EAllocatable> Send for EBox<T> {}
87+
88+
// TODO Write Erc for gc_refcounted holding types.
89+
// pub trait ERcAble {
90+
// // Increment the reference count;
91+
// fn incr(&mut self);
92+
//
93+
// /// Decrement the reference count and return old count.
94+
// fn decr(&mut self) -> usize;
95+
// }
96+
//
97+
// pub struct ERc<T> {
98+
// value: T,
99+
// }
100+
//
101+
// impl<T> ERc<T> {
102+
// pub fn new(value: T) -> Self {
103+
// Self { value }
104+
// }
105+
// }

phper-test/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ keywords = ["php", "binding"]
1010

1111
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1212

13+
[features]
14+
fpm = ["fastcgi-client", "tokio/full"]
15+
1316
[dependencies]
17+
fastcgi-client = { version = "0.7.0", optional = true }
18+
libc = "0.2.97"
1419
once_cell = "1.5.2"
20+
phper-macros = { version = "0.3.0", path = "../phper-macros" }
1521
tempfile = "3.1.0"
22+
tokio = { version = "1.7.0", optional = true }

phper-test/etc/php-fpm.conf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[global]
2+
error_log = /tmp/.php-fpm.log
3+
4+
[www]
5+
user = $USER
6+
group = $USER
7+
listen = 127.0.0.1:9000
8+
pm = static
9+
pm.max_children = 6
10+
pm.max_requests = 500

phper-test/src/cli.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
//! Test tools for php cli program.
2+
3+
use std::{
4+
panic::{catch_unwind, resume_unwind, UnwindSafe},
5+
path::Path,
6+
process::{Child, Output},
7+
};
8+
9+
use crate::{context::Context, utils};
10+
11+
/// Check your extension by executing the php script, if the all executing return success, than the test is pass.
12+
///
13+
/// - `exec_path` is the path of the make executable, which will be used to detect the path of
14+
/// extension lib.
15+
///
16+
/// - `scripts` is the path of your php test scripts.
17+
///
18+
/// See [example hello integration test](https://github.com/jmjoy/phper/blob/master/examples/hello/tests/integration.rs).
19+
pub fn test_php_scripts(exe_path: impl AsRef<Path>, scripts: &[&dyn AsRef<Path>]) {
20+
let condition = |output: Output| output.status.success();
21+
let scripts = scripts
22+
.into_iter()
23+
.map(|s| (*s, &condition as _))
24+
.collect::<Vec<_>>();
25+
test_php_scripts_with_condition(exe_path, &*scripts);
26+
}
27+
28+
/// Check your extension by executing the php script, if the all your specified checkers are pass, than the test is pass.
29+
///
30+
/// - `exec_path` is the path of the make executable, which will be used to detect the path of
31+
/// extension lib.
32+
///
33+
/// - `scripts` is the slice of the tuple, format is `(path of your php test script, checker function or closure)`.
34+
///
35+
/// See [example logging integration test](https://github.com/jmjoy/phper/blob/master/examples/logging/tests/integration.rs).
36+
pub fn test_php_scripts_with_condition(
37+
exe_path: impl AsRef<Path>,
38+
scripts: &[(&dyn AsRef<Path>, &dyn Fn(Output) -> bool)],
39+
) {
40+
let context = Context::get_global();
41+
let lib_path = utils::get_lib_path(exe_path);
42+
let tmp_php_ini_file = context.create_tmp_php_ini_file(&lib_path);
43+
44+
for (script, condition) in scripts {
45+
let mut cmd = context.create_command_with_tmp_php_ini_args(&tmp_php_ini_file, script);
46+
47+
let output = cmd.output().unwrap();
48+
let path = script.as_ref().to_str().unwrap();
49+
50+
let mut stdout = String::from_utf8(output.stdout.clone()).unwrap();
51+
if stdout.is_empty() {
52+
stdout.push_str("<empty>");
53+
}
54+
55+
let mut stderr = String::from_utf8(output.stderr.clone()).unwrap();
56+
if stderr.is_empty() {
57+
stderr.push_str("<empty>");
58+
}
59+
60+
println!(
61+
"===== command =====\n{} {}\n===== stdout ======\n{}\n===== stderr ======\n{}",
62+
&context.php_bin,
63+
cmd.get_args().join(" "),
64+
stdout,
65+
stderr,
66+
);
67+
#[cfg(target_os = "linux")]
68+
if output.status.code().is_none() {
69+
use std::os::unix::process::ExitStatusExt;
70+
println!(
71+
"===== signal ======\nExitStatusExt is None, the signal is: {:?}",
72+
output.status.signal()
73+
);
74+
}
75+
76+
if !condition(output) {
77+
panic!("test php file `{}` failed", path);
78+
}
79+
}
80+
}
81+
82+
/// Check your extension by executing the long term php script such as http server, if the all your
83+
/// specified checkers are pass, than the test is pass.
84+
pub fn test_long_term_php_script_with_condition(
85+
exe_path: impl AsRef<Path>,
86+
script: impl AsRef<Path>,
87+
condition: impl FnOnce(&Child) + UnwindSafe,
88+
) {
89+
let context = Context::get_global();
90+
let lib_path = utils::get_lib_path(exe_path);
91+
let tmp_php_ini_file = context.create_tmp_php_ini_file(lib_path);
92+
let mut command = context.create_command_with_tmp_php_ini_args(&tmp_php_ini_file, script);
93+
let mut child = command.spawn().unwrap();
94+
let r = catch_unwind(|| condition(&child));
95+
child.kill().unwrap();
96+
if let Err(e) = r {
97+
resume_unwind(e);
98+
}
99+
}

0 commit comments

Comments
 (0)