|
60 | 60 | -export([ read_not_really_compressed/1,
|
61 | 61 | read_compressed_cooked/1, read_compressed_cooked_binary/1,
|
62 | 62 | read_cooked_tar_problem/1,
|
63 |
| - write_compressed/1, compress_errors/1, catenated_gzips/1]). |
| 63 | + write_compressed/1, compress_errors/1, catenated_gzips/1, |
| 64 | + compress_async_crash/1]). |
64 | 65 |
|
65 | 66 | -export([ make_link/1, read_link_info_for_non_link/1, symlinks/1]).
|
66 | 67 |
|
@@ -135,7 +136,8 @@ groups() ->
|
135 | 136 | {compression, [],
|
136 | 137 | [read_compressed_cooked, read_compressed_cooked_binary,
|
137 | 138 | read_cooked_tar_problem, read_not_really_compressed,
|
138 |
| - write_compressed, compress_errors, catenated_gzips]}, |
| 139 | + write_compressed, compress_errors, catenated_gzips, |
| 140 | + compress_async_crash]}, |
139 | 141 | {links, [],
|
140 | 142 | [make_link, read_link_info_for_non_link, symlinks]}].
|
141 | 143 |
|
@@ -2312,6 +2314,57 @@ compress_errors(Config) when is_list(Config) ->
|
2312 | 2314 |
|
2313 | 2315 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
2314 | 2316 |
|
| 2317 | +compress_async_crash(suite) -> []; |
| 2318 | +compress_async_crash(doc) -> []; |
| 2319 | +compress_async_crash(Config) when is_list(Config) -> |
| 2320 | + ?line DataDir = ?config(data_dir, Config), |
| 2321 | + ?line Path = filename:join(DataDir, "test.gz"), |
| 2322 | + ExpectedData = <<"qwerty">>, |
| 2323 | + |
| 2324 | + ?line _ = ?FILE_MODULE:delete(Path), |
| 2325 | + ?line {ok, Fd} = ?FILE_MODULE:open(Path, [write, binary, compressed]), |
| 2326 | + ?line ok = ?FILE_MODULE:write(Fd, ExpectedData), |
| 2327 | + ?line ok = ?FILE_MODULE:close(Fd), |
| 2328 | + |
| 2329 | + % Test that when using async thread pool, the emulator doesn't crash |
| 2330 | + % when the efile port driver is stopped while a compressed file operation |
| 2331 | + % is in progress (being carried by an async thread). |
| 2332 | + ?line ok = compress_async_crash_loop(10000, Path, ExpectedData), |
| 2333 | + ?line ok = ?FILE_MODULE:delete(Path), |
| 2334 | + ok. |
| 2335 | + |
| 2336 | +compress_async_crash_loop(0, _Path, _ExpectedData) -> |
| 2337 | + ok; |
| 2338 | +compress_async_crash_loop(N, Path, ExpectedData) -> |
| 2339 | + Parent = self(), |
| 2340 | + {Pid, Ref} = spawn_monitor( |
| 2341 | + fun() -> |
| 2342 | + ?line {ok, Fd} = ?FILE_MODULE:open( |
| 2343 | + Path, [read, compressed, raw, binary]), |
| 2344 | + Len = byte_size(ExpectedData), |
| 2345 | + Parent ! {self(), continue}, |
| 2346 | + ?line {ok, ExpectedData} = ?FILE_MODULE:read(Fd, Len), |
| 2347 | + ?line ok = ?FILE_MODULE:close(Fd), |
| 2348 | + receive foobar -> ok end |
| 2349 | + end), |
| 2350 | + receive |
| 2351 | + {Pid, continue} -> |
| 2352 | + exit(Pid, shutdown), |
| 2353 | + receive |
| 2354 | + {'DOWN', Ref, _, _, Reason} -> |
| 2355 | + ?line shutdown = Reason |
| 2356 | + end; |
| 2357 | + {'DOWN', Ref, _, _, Reason2} -> |
| 2358 | + test_server:fail({worker_exited, Reason2}) |
| 2359 | + after 60000 -> |
| 2360 | + exit(Pid, shutdown), |
| 2361 | + erlang:demonitor(Ref, [flush]), |
| 2362 | + test_server:fail(worker_timeout) |
| 2363 | + end, |
| 2364 | + compress_async_crash_loop(N - 1, Path, ExpectedData). |
| 2365 | + |
| 2366 | +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 2367 | + |
2315 | 2368 | altname(doc) ->
|
2316 | 2369 | "Test the file:altname/1 function";
|
2317 | 2370 | altname(suite) ->
|
|
0 commit comments