Majic.
This commit is contained in:
parent
52f6aa7281
commit
b5777bf9e8
31 changed files with 373 additions and 218 deletions
20
.builds/alpine.yaml
Normal file
20
.builds/alpine.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
image: alpine/latest
|
||||||
|
packages:
|
||||||
|
- g++
|
||||||
|
- make
|
||||||
|
- elixir
|
||||||
|
- file
|
||||||
|
- file-dev
|
||||||
|
sources:
|
||||||
|
- https://git.sr.ht/~href/gen_magic
|
||||||
|
tasks:
|
||||||
|
- setup: |
|
||||||
|
mix local.hex --force
|
||||||
|
- build: |
|
||||||
|
cd gen_magic
|
||||||
|
mix deps.get
|
||||||
|
MIX_ENV=test mix compile
|
||||||
|
- test: |
|
||||||
|
cd gen_magic
|
||||||
|
mix test
|
||||||
|
|
17
.builds/archlinux.yaml
Normal file
17
.builds/archlinux.yaml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
image: archlinux
|
||||||
|
packages:
|
||||||
|
- elixir
|
||||||
|
- file
|
||||||
|
sources:
|
||||||
|
- https://git.sr.ht/~href/gen_magic
|
||||||
|
tasks:
|
||||||
|
- setup: |
|
||||||
|
mix local.hex --force
|
||||||
|
- build: |
|
||||||
|
cd gen_magic
|
||||||
|
mix deps.get
|
||||||
|
MIX_ENV=test mix compile
|
||||||
|
- test: |
|
||||||
|
cd gen_magic
|
||||||
|
mix test
|
||||||
|
|
20
.builds/debian-oldstable.yaml
Normal file
20
.builds/debian-oldstable.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
image: debian/oldstable
|
||||||
|
packages:
|
||||||
|
- build-essential
|
||||||
|
- erlang
|
||||||
|
- erlang-dev
|
||||||
|
- elixir
|
||||||
|
- libmagic-dev
|
||||||
|
sources:
|
||||||
|
- https://git.sr.ht/~href/gen_magic
|
||||||
|
tasks:
|
||||||
|
- setup: |
|
||||||
|
mix local.hex --force
|
||||||
|
- build: |
|
||||||
|
cd gen_magic
|
||||||
|
mix deps.get
|
||||||
|
MIX_ENV=test mix compile
|
||||||
|
- test: |
|
||||||
|
cd gen_magic
|
||||||
|
mix test
|
||||||
|
|
20
.builds/debian-stable.yaml
Normal file
20
.builds/debian-stable.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
image: debian/stable
|
||||||
|
packages:
|
||||||
|
- build-essential
|
||||||
|
- erlang
|
||||||
|
- erlang-dev
|
||||||
|
- elixir
|
||||||
|
- libmagic-dev
|
||||||
|
sources:
|
||||||
|
- https://git.sr.ht/~href/gen_magic
|
||||||
|
tasks:
|
||||||
|
- setup: |
|
||||||
|
mix local.hex --force
|
||||||
|
- build: |
|
||||||
|
cd gen_magic
|
||||||
|
mix deps.get
|
||||||
|
MIX_ENV=test mix compile
|
||||||
|
- test: |
|
||||||
|
cd gen_magic
|
||||||
|
mix test
|
||||||
|
|
20
.builds/debian-testing.yaml
Normal file
20
.builds/debian-testing.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
image: debian/testing
|
||||||
|
packages:
|
||||||
|
- build-essential
|
||||||
|
- erlang
|
||||||
|
- erlang-dev
|
||||||
|
- elixir
|
||||||
|
- libmagic-dev
|
||||||
|
sources:
|
||||||
|
- https://git.sr.ht/~hrefhref/gen_magic
|
||||||
|
tasks:
|
||||||
|
- setup: |
|
||||||
|
mix local.hex --force
|
||||||
|
- build: |
|
||||||
|
cd gen_magic
|
||||||
|
mix deps.get
|
||||||
|
MIX_ENV=test mix compile
|
||||||
|
- test: |
|
||||||
|
cd gen_magic
|
||||||
|
mix test
|
||||||
|
|
22
.builds/fedora-latest.yaml
Normal file
22
.builds/fedora-latest.yaml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
image: fedora/latest
|
||||||
|
packages:
|
||||||
|
- make
|
||||||
|
- gcc
|
||||||
|
- kernel-devel
|
||||||
|
- erlang
|
||||||
|
- elixir
|
||||||
|
- file-devel
|
||||||
|
sources:
|
||||||
|
- https://git.sr.ht/~href/gen_magic
|
||||||
|
tasks:
|
||||||
|
- setup: |
|
||||||
|
sudo dnf -y group install 'Development Tools'
|
||||||
|
mix local.hex --force
|
||||||
|
- build: |
|
||||||
|
cd gen_magic
|
||||||
|
mix deps.get
|
||||||
|
MIX_ENV=test mix compile
|
||||||
|
- test: |
|
||||||
|
cd gen_magic
|
||||||
|
mix test
|
||||||
|
|
17
.builds/freebsd.yaml
Normal file
17
.builds/freebsd.yaml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
image: freebsd/latest
|
||||||
|
packages:
|
||||||
|
- elixir
|
||||||
|
- gmake
|
||||||
|
sources:
|
||||||
|
- https://git.sr.ht/~href/gen_magic
|
||||||
|
tasks:
|
||||||
|
- setup: |
|
||||||
|
mix local.hex --force
|
||||||
|
- build: |
|
||||||
|
cd gen_magic
|
||||||
|
mix deps.get
|
||||||
|
MIX_ENV=test mix compile
|
||||||
|
- test: |
|
||||||
|
cd gen_magic
|
||||||
|
mix test
|
||||||
|
|
19
CHANGELOG.md
19
CHANGELOG.md
|
@ -7,7 +7,24 @@ The format is based on [Keep a Changelog][1], and this project adheres to [Seman
|
||||||
[1]: https://keepachangelog.com/en/1.0.0/
|
[1]: https://keepachangelog.com/en/1.0.0/
|
||||||
[2]: https://semver.org/spec/v2.0.0.html
|
[2]: https://semver.org/spec/v2.0.0.html
|
||||||
|
|
||||||
## [Unreleased]
|
## majic [Unreleased]
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Forked gen_magic.
|
||||||
|
- Pool: `Majic.Pool`
|
||||||
|
- Unified API: `Majic.perform/1,2,3`
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- C port now using erl_interface
|
||||||
|
- `Majic.Server.reload/2,3`
|
||||||
|
- `Majic.Server.recycle/2,3`
|
||||||
|
- Bytes support: `Majic.Server.perform(ref, {:bytes, <<>>})`
|
||||||
|
- Builds on Musl
|
||||||
|
- Better error and timeout handling
|
||||||
|
|
||||||
|
## gen_majic [1.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
|
6
Makefile
6
Makefile
|
@ -1,5 +1,3 @@
|
||||||
# Apprentice binary
|
|
||||||
|
|
||||||
ERL_EI_INCLUDE:=$(shell erl -eval 'io:format("~s", [code:lib_dir(erl_interface, include)])' -s init stop -noshell | head -1)
|
ERL_EI_INCLUDE:=$(shell erl -eval 'io:format("~s", [code:lib_dir(erl_interface, include)])' -s init stop -noshell | head -1)
|
||||||
ERL_EI_LIB:=$(shell erl -eval 'io:format("~s", [code:lib_dir(erl_interface, lib)])' -s init stop -noshell | head -1)
|
ERL_EI_LIB:=$(shell erl -eval 'io:format("~s", [code:lib_dir(erl_interface, lib)])' -s init stop -noshell | head -1)
|
||||||
CFLAGS = -std=c99 -g -Wall -Werror
|
CFLAGS = -std=c99 -g -Wall -Werror
|
||||||
|
@ -9,9 +7,9 @@ LDLIBS = -lpthread -lei -lm -lmagic
|
||||||
PRIV = priv/
|
PRIV = priv/
|
||||||
RM = rm -Rf
|
RM = rm -Rf
|
||||||
|
|
||||||
all: priv/apprentice
|
all: priv/libmagic_port
|
||||||
|
|
||||||
priv/apprentice: src/apprentice.c
|
priv/libmagic_port: src/libmagic_port.c
|
||||||
mkdir -p priv
|
mkdir -p priv
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
|
|
72
README.md
72
README.md
|
@ -1,17 +1,24 @@
|
||||||
# GenMagic
|
# Majic
|
||||||
|
|
||||||
**GenMagic** provides supervised and customisable access to [libmagic](http://man7.org/linux/man-pages/man3/libmagic.3.html) using a supervised external process.
|
**Majic** provides a robust integration of [libmagic](http://man7.org/linux/man-pages/man3/libmagic.3.html) for Elixir.
|
||||||
|
|
||||||
With this library, you can start an one-off process to run a single check, or run the process as a daemon if you expect to run many checks.
|
With this library, you can start an one-off process to run a single check, or run the process as a daemon if you expect to run
|
||||||
|
many checks.
|
||||||
|
|
||||||
|
It is a friendly fork of [gen_magic](https://github.com/evadne/gen_magic) featuring a (arguably) more robust C-code
|
||||||
|
using erl_interface, built in pooling, unified/clean API, and an optional Plug.
|
||||||
|
|
||||||
|
This package is regulary tested on multiple platforms (Debian, macOS, Fedora, Alpine, FreeBSD) to ensure it'll work fine
|
||||||
|
in any environment.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
The package can be installed by adding `gen_magic` to your list of dependencies in `mix.exs`:
|
The package can be installed by adding `majic` to your list of dependencies in `mix.exs`:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
def deps do
|
def deps do
|
||||||
[
|
[
|
||||||
{:gen_magic, "~> 1.0.0"}
|
{:majic, "~> 1.0"}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
@ -22,34 +29,34 @@ Compilation of the underlying C program is automatic and handled by [elixir_make
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Depending on the use case, you may utilise a single (one-off) GenMagic process without reusing it as a daemon, or utilise a connection pool (such as Poolboy) in your application to run multiple persistent GenMagic processes.
|
Depending on the use case, you may utilise a single (one-off) Majic process without reusing it as a daemon, or utilise a connection pool (such as Poolboy) in your application to run multiple persistent Majic processes.
|
||||||
|
|
||||||
To use GenMagic directly, you can use `GenMagic.Helpers.perform_once/1`:
|
To use Majic directly, you can use `Majic.Helpers.perform_once/1`:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
iex(1)> GenMagic.perform(".", once: true)
|
iex(1)> Majic.perform(".", once: true)
|
||||||
{:ok,
|
{:ok,
|
||||||
%GenMagic.Result{
|
%Majic.Result{
|
||||||
content: "directory",
|
content: "directory",
|
||||||
encoding: "binary",
|
encoding: "binary",
|
||||||
mime_type: "inode/directory"
|
mime_type: "inode/directory"
|
||||||
}}
|
}}
|
||||||
```
|
```
|
||||||
|
|
||||||
To use the GenMagic server as a daemon, you can start it first, keep a reference, then feed messages to it as you require:
|
To use the Majic server as a daemon, you can start it first, keep a reference, then feed messages to it as you require:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
{:ok, pid} = GenMagic.Server.start_link([])
|
{:ok, pid} = Majic.Server.start_link([])
|
||||||
{:ok, result} = GenMagic.perform(path, server: pid)
|
{:ok, result} = Majic.perform(path, server: pid)
|
||||||
```
|
```
|
||||||
|
|
||||||
See `GenMagic.Server.start_link/1` and `t:GenMagic.Server.option/0` for more information on startup parameters.
|
See `Majic.Server.start_link/1` and `t:Majic.Server.option/0` for more information on startup parameters.
|
||||||
|
|
||||||
See `GenMagic.Result` for details on the result provided.
|
See `Majic.Result` for details on the result provided.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
When using `GenMagic.Server.start_link/1` to start a persistent server, or `GenMagic.Helpers.perform_once/2` to run an ad-hoc request, you can override specific options to suit your use case.
|
When using `Majic.Server.start_link/1` to start a persistent server, or `Majic.Helpers.perform_once/2` to run an ad-hoc request, you can override specific options to suit your use case.
|
||||||
|
|
||||||
| Name | Default | Description |
|
| Name | Default | Description |
|
||||||
| - | - | - |
|
| - | - | - |
|
||||||
|
@ -58,18 +65,18 @@ When using `GenMagic.Server.start_link/1` to start a persistent server, or `GenM
|
||||||
| `:recycle_threshold` | 10 | Number of cycles before the C process is replaced |
|
| `:recycle_threshold` | 10 | Number of cycles before the C process is replaced |
|
||||||
| `:database_patterns` | `[:default]` | Databases to load |
|
| `:database_patterns` | `[:default]` | Databases to load |
|
||||||
|
|
||||||
See `t:GenMagic.Server.option/0` for details.
|
See `t:Majic.Server.option/0` for details.
|
||||||
|
|
||||||
### Use Cases
|
### Use Cases
|
||||||
|
|
||||||
### Ad-Hoc Requests
|
### Ad-Hoc Requests
|
||||||
|
|
||||||
For ad-hoc requests, you can use the helper method `GenMagic.Helpers.perform_once/2`:
|
For ad-hoc requests, you can use the helper method `Majic.Helpers.perform_once/2`:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
iex(1)> GenMagic.perform(Path.join(File.cwd!(), "Makefile"), once: true)
|
iex(1)> Majic.perform(Path.join(File.cwd!(), "Makefile"), once: true)
|
||||||
{:ok,
|
{:ok,
|
||||||
%GenMagic.Result{
|
%Majic.Result{
|
||||||
content: "makefile script, ASCII text",
|
content: "makefile script, ASCII text",
|
||||||
encoding: "us-ascii",
|
encoding: "us-ascii",
|
||||||
mime_type: "text/x-makefile"
|
mime_type: "text/x-makefile"
|
||||||
|
@ -83,22 +90,22 @@ The Server should be run under a supervisor which provides resiliency.
|
||||||
Here we run it under a supervisor:
|
Here we run it under a supervisor:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
iex(1)> {:ok, pid} = Supervisor.start_link([{GenMagic.Server, name: :gen_magic}], strategy: :one_for_one)
|
iex(1)> {:ok, pid} = Supervisor.start_link([{Majic.Server, name: :gen_magic}], strategy: :one_for_one)
|
||||||
{:ok, #PID<0.199.0>}
|
{:ok, #PID<0.199.0>}
|
||||||
```
|
```
|
||||||
|
|
||||||
Now we can ask it to inspect a file:
|
Now we can ask it to inspect a file:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
iex(2)> GenMagic.perform(Path.expand("~/.bash_history"), server: :gen_magic)
|
iex(2)> Majic.perform(Path.expand("~/.bash_history"), server: :gen_magic)
|
||||||
{:ok, %GenMagic.Result{mime_type: "text/plain", encoding: "us-ascii", content: "ASCII text"}}
|
{:ok, %Majic.Result{mime_type: "text/plain", encoding: "us-ascii", content: "ASCII text"}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that in this case we have opted to use a named process.
|
Note that in this case we have opted to use a named process.
|
||||||
|
|
||||||
### Pool
|
### Pool
|
||||||
|
|
||||||
For concurrency *and* resiliency, you may start the `GenMagic.Pool`. By default, it will start a `GenMagic.Server`
|
For concurrency *and* resiliency, you may start the `Majic.Pool`. By default, it will start a `Majic.Server`
|
||||||
worker per online scheduler:
|
worker per online scheduler:
|
||||||
|
|
||||||
You can add a pool in your application supervisor by adding it as a child:
|
You can add a pool in your application supervisor by adding it as a child:
|
||||||
|
@ -107,18 +114,18 @@ You can add a pool in your application supervisor by adding it as a child:
|
||||||
children =
|
children =
|
||||||
[
|
[
|
||||||
# ...
|
# ...
|
||||||
{GenMagic.Pool, [name: YourApp.GenMagicPool, pool_size: 2]}
|
{Majic.Pool, [name: YourApp.MajicPool, pool_size: 2]}
|
||||||
]
|
]
|
||||||
|
|
||||||
opts = [strategy: :one_for_one, name: Pleroma.Supervisor]
|
opts = [strategy: :one_for_one, name: YourApp.Supervisor]
|
||||||
Supervisor.start_link(children, opts)
|
Supervisor.start_link(children, opts)
|
||||||
```
|
```
|
||||||
|
|
||||||
And then you can use it with `GenMagic.perform/2` with `pool: YourApp.GenMagicPool` option:
|
And then you can use it with `Majic.perform/2` with `pool: YourApp.MajicPool` option:
|
||||||
|
|
||||||
```
|
```
|
||||||
iex(1)> GenMagic.perform(Path.expand("~/.bash_history"), pool: YourApp.GenMagicPool)
|
iex(1)> Majic.perform(Path.expand("~/.bash_history"), pool: YourApp.MajicPool)
|
||||||
{:ok, %GenMagic.Result{mime_type: "text/plain", encoding: "us-ascii", content: "ASCII text"}}
|
{:ok, %Majic.Result{mime_type: "text/plain", encoding: "us-ascii", content: "ASCII text"}}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Check Uploaded Files
|
### Check Uploaded Files
|
||||||
|
@ -127,12 +134,12 @@ If you use Phoenix, you can inspect the file from your controller:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
def upload(conn, %{"upload" => %{path: path}}) do,
|
def upload(conn, %{"upload" => %{path: path}}) do,
|
||||||
{:ok, result} = GenMagic.perform(path, server: :gen_magic)
|
{:ok, result} = Majic.perform(path, server: :gen_magic)
|
||||||
text(conn, "Received your file containing #{result.content}")
|
text(conn, "Received your file containing #{result.content}")
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
Obviously, it will be more ideal if you have wrapped `GenMagic.Server` in a pool such as Poolboy, to avoid constantly starting and stopping the underlying C program.
|
Obviously, it will be more ideal if you have wrapped `Majic.Server` in a pool such as Poolboy, to avoid constantly starting and stopping the underlying C program.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
|
@ -147,8 +154,11 @@ find . -name *ex | xargs mix run test/soak.exs
|
||||||
|
|
||||||
## Acknowledgements
|
## Acknowledgements
|
||||||
|
|
||||||
During design and prototype development of this library, the Author has drawn inspiration from the following individuals, and therefore thanks all contributors for their generosity:
|
During design and prototype development of this library, the Author has drawn inspiration from the following individuals, and therefore
|
||||||
|
thanks all contributors for their generosity:
|
||||||
|
|
||||||
|
- [Evadne Wu](https://github.com/evadne)
|
||||||
|
- Original work
|
||||||
- Mr [James Every](https://github.com/devstopfix)
|
- Mr [James Every](https://github.com/devstopfix)
|
||||||
- Enhanced Elixir Wrapper (based on GenServer)
|
- Enhanced Elixir Wrapper (based on GenServer)
|
||||||
- Initial Hex packaging (v.0.22)
|
- Initial Hex packaging (v.0.22)
|
||||||
|
|
|
@ -1,17 +1,11 @@
|
||||||
defmodule GenMagic do
|
defmodule Majic do
|
||||||
@moduledoc """
|
|
||||||
Top-level namespace for GenMagic, the libmagic client for Elixir.
|
|
||||||
|
|
||||||
See `GenMagic.Server` or the README for usage.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Perform on `path`.
|
Perform on `path`.
|
||||||
|
|
||||||
An option of `server: ServerName`, `pool: PoolName` or `once: true` must be passed.
|
An option of `server: ServerName`, `pool: PoolName` or `once: true` must be passed.
|
||||||
"""
|
"""
|
||||||
|
@type name :: {:pool, atom()} | {:server, GenMagic.Server.t()} | {:once, true}
|
||||||
@type option :: name
|
@type option :: name
|
||||||
when name: {:pool, atom()} | {:server, GenMagic.Server.t()} | {:once, true}
|
|
||||||
|
|
||||||
@spec perform(GenMagic.Server.target(), [option()]) :: GenMagic.Server.result()
|
@spec perform(GenMagic.Server.target(), [option()]) :: GenMagic.Server.result()
|
||||||
def perform(path, opts, timeout \\ 5000) do
|
def perform(path, opts, timeout \\ 5000) do
|
||||||
|
@ -34,7 +28,7 @@ defmodule GenMagic do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp do_perform({mod, name}, path, timeout) do
|
defp do_perform({mod, name}, path, timeout) do
|
||||||
mod.perform(name, path, tiemout)
|
mod.perform(name, path, timeout)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
|
@ -1,7 +1,7 @@
|
||||||
defmodule GenMagic.Config do
|
defmodule Majic.Config do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
@otp_app Mix.Project.config()[:app]
|
@otp_app Mix.Project.config()[:app]
|
||||||
@executable_name "apprentice"
|
@executable_name "libmagic_port"
|
||||||
@startup_timeout 1_000
|
@startup_timeout 1_000
|
||||||
@process_timeout 30_000
|
@process_timeout 30_000
|
||||||
@recycle_threshold :infinity
|
@recycle_threshold :infinity
|
|
@ -1,10 +1,10 @@
|
||||||
defmodule GenMagic.Helpers do
|
defmodule Majic.Helpers do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Contains convenience functions for one-off use.
|
Contains convenience functions for one-off use.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
alias GenMagic.Result
|
alias Majic.Result
|
||||||
alias GenMagic.Server
|
alias Majic.Server
|
||||||
|
|
||||||
@spec perform_once(Path.t() | {:bytes, binary}, [Server.option()]) ::
|
@spec perform_once(Path.t() | {:bytes, binary}, [Server.option()]) ::
|
||||||
{:ok, Result.t()} | {:error, term()}
|
{:ok, Result.t()} | {:error, term()}
|
||||||
|
@ -16,9 +16,9 @@ defmodule GenMagic.Helpers do
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
iex(1)> {:ok, result} = GenMagic.Helpers.perform_once(".")
|
iex(1)> {:ok, result} = Majic.Helpers.perform_once(".")
|
||||||
iex(2)> result
|
iex(2)> result
|
||||||
%GenMagic.Result{content: "directory", encoding: "binary", mime_type: "inode/directory"}
|
%Majic.Result{content: "directory", encoding: "binary", mime_type: "inode/directory"}
|
||||||
"""
|
"""
|
||||||
def perform_once(path, options \\ []) do
|
def perform_once(path, options \\ []) do
|
||||||
with {:ok, pid} <- Server.start_link(options),
|
with {:ok, pid} <- Server.start_link(options),
|
|
@ -1,6 +1,6 @@
|
||||||
defmodule GenMagic.Pool do
|
defmodule Majic.Pool do
|
||||||
@behaviour NimblePool
|
@behaviour NimblePool
|
||||||
@moduledoc "Pool of `GenMagic.Server`"
|
@moduledoc "Pool of `Majic.Server`"
|
||||||
|
|
||||||
def child_spec(opts) do
|
def child_spec(opts) do
|
||||||
%{
|
%{
|
||||||
|
@ -25,7 +25,7 @@ defmodule GenMagic.Pool do
|
||||||
pool,
|
pool,
|
||||||
:checkout,
|
:checkout,
|
||||||
fn _, server ->
|
fn _, server ->
|
||||||
{GenMagic.Server.perform(server, path, timeout), server}
|
{Majic.Server.perform(server, path, timeout), server}
|
||||||
end,
|
end,
|
||||||
pool_timeout
|
pool_timeout
|
||||||
)
|
)
|
||||||
|
@ -46,7 +46,7 @@ defmodule GenMagic.Pool do
|
||||||
|
|
||||||
@impl NimblePool
|
@impl NimblePool
|
||||||
def init_worker(options) do
|
def init_worker(options) do
|
||||||
{:ok, server} = GenMagic.Server.start_link(options || [])
|
{:ok, server} = Majic.Server.start_link(options || [])
|
||||||
{:ok, server, options}
|
{:ok, server, options}
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
defmodule GenMagic.Result do
|
defmodule Majic.Result do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Represents the results obtained from libmagic.
|
Represents the results obtained from libmagic.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
defmodule GenMagic.Server do
|
defmodule Majic.Server do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Provides access to the underlying libmagic client, which performs file introspection.
|
Provides access to the underlying libmagic client, which performs file introspection.
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@ defmodule GenMagic.Server do
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@behaviour :gen_statem
|
@behaviour :gen_statem
|
||||||
alias GenMagic.Result
|
alias Majic.Result
|
||||||
alias GenMagic.Server.Data
|
alias Majic.Server.Data
|
||||||
alias GenMagic.Server.Status
|
alias Majic.Server.Status
|
||||||
import Kernel, except: [send: 2]
|
import Kernel, except: [send: 2]
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ defmodule GenMagic.Server do
|
||||||
Can be set to `:infinity`.
|
Can be set to `:infinity`.
|
||||||
|
|
||||||
Please note that, if you have chosen a custom timeout value, you should also pass it when
|
Please note that, if you have chosen a custom timeout value, you should also pass it when
|
||||||
using `GenMagic.Server.perform/3`.
|
using `Majic.Server.perform/3`.
|
||||||
|
|
||||||
- `:recycle_threshold`: Specifies the number of requests processed before the underlying C
|
- `:recycle_threshold`: Specifies the number of requests processed before the underlying C
|
||||||
program is recycled.
|
program is recycled.
|
||||||
|
@ -169,7 +169,7 @@ defmodule GenMagic.Server do
|
||||||
|
|
||||||
@impl :gen_statem
|
@impl :gen_statem
|
||||||
def init(options) do
|
def init(options) do
|
||||||
import GenMagic.Config
|
import Majic.Config
|
||||||
|
|
||||||
data = %Data{
|
data = %Data{
|
||||||
port_name: get_port_name(),
|
port_name: get_port_name(),
|
|
@ -1,4 +1,4 @@
|
||||||
defmodule GenMagic.Server.Data do
|
defmodule Majic.Server.Data do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
|
|
||||||
@type request :: {Path.t(), {pid(), term()}, requested_at :: integer()}
|
@type request :: {Path.t(), {pid(), term()}, requested_at :: integer()}
|
|
@ -1,4 +1,4 @@
|
||||||
defmodule GenMagic.Server.Status do
|
defmodule Majic.Server.Status do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Represents Status of the underlying Server.
|
Represents Status of the underlying Server.
|
||||||
"""
|
"""
|
||||||
|
@ -12,7 +12,7 @@ defmodule GenMagic.Server.Status do
|
||||||
recycling is enabled.
|
recycling is enabled.
|
||||||
"""
|
"""
|
||||||
@type t :: %__MODULE__{
|
@type t :: %__MODULE__{
|
||||||
state: GenMagic.Server.state(),
|
state: Majic.Server.state(),
|
||||||
cycles: non_neg_integer()
|
cycles: non_neg_integer()
|
||||||
}
|
}
|
||||||
|
|
10
mix.exs
10
mix.exs
|
@ -1,13 +1,13 @@
|
||||||
defmodule GenMagic.MixProject do
|
defmodule Majic.MixProject do
|
||||||
use Mix.Project
|
use Mix.Project
|
||||||
|
|
||||||
if :erlang.system_info(:otp_release) < '21' do
|
if :erlang.system_info(:otp_release) < '21' do
|
||||||
raise "GenMagic requires Erlang/OTP 21 or newer"
|
raise "Majic requires Erlang/OTP 21 or newer"
|
||||||
end
|
end
|
||||||
|
|
||||||
def project do
|
def project do
|
||||||
[
|
[
|
||||||
app: :gen_magic,
|
app: :majic,
|
||||||
version: "1.0.0",
|
version: "1.0.0",
|
||||||
elixir: "~> 1.7",
|
elixir: "~> 1.7",
|
||||||
elixirc_paths: elixirc_paths(Mix.env()),
|
elixirc_paths: elixirc_paths(Mix.env()),
|
||||||
|
@ -16,9 +16,9 @@ defmodule GenMagic.MixProject do
|
||||||
package: package(),
|
package: package(),
|
||||||
deps: deps(),
|
deps: deps(),
|
||||||
dialyzer: dialyzer(),
|
dialyzer: dialyzer(),
|
||||||
name: "GenMagic",
|
name: "Majic",
|
||||||
description: "File introspection with libmagic",
|
description: "File introspection with libmagic",
|
||||||
source_url: "https://github.com/evadne/gen_magic",
|
source_url: "https://github.com/hrefhref/majic",
|
||||||
docs: docs()
|
docs: docs()
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
defmodule GenMagicTest do
|
|
||||||
use GenMagic.MagicCase
|
|
||||||
alias GenMagic.Result
|
|
||||||
|
|
||||||
doctest GenMagic
|
|
||||||
@iterations 100
|
|
||||||
|
|
||||||
test "Makefile is text file" do
|
|
||||||
{:ok, pid} = GenMagic.Server.start_link([])
|
|
||||||
path = absolute_path("Makefile")
|
|
||||||
assert {:ok, %{mime_type: "text/x-makefile"}} = GenMagic.Server.perform(pid, path)
|
|
||||||
end
|
|
||||||
|
|
||||||
@tag external: true
|
|
||||||
test "Load test local files" do
|
|
||||||
{:ok, pid} = GenMagic.Server.start_link([])
|
|
||||||
|
|
||||||
files_stream()
|
|
||||||
|> Stream.cycle()
|
|
||||||
|> Stream.take(@iterations)
|
|
||||||
|> Stream.map(&assert {:ok, %Result{}} = GenMagic.Server.perform(pid, &1))
|
|
||||||
|> Enum.all?()
|
|
||||||
|> assert
|
|
||||||
end
|
|
||||||
|
|
||||||
test "Non-existent file" do
|
|
||||||
{:ok, pid} = GenMagic.Server.start_link([])
|
|
||||||
path = missing_filename()
|
|
||||||
assert_no_file(GenMagic.Server.perform(pid, path))
|
|
||||||
end
|
|
||||||
|
|
||||||
test "Named process" do
|
|
||||||
{:ok, pid} = GenMagic.Server.start_link(name: :gen_magic)
|
|
||||||
path = absolute_path("Makefile")
|
|
||||||
assert {:ok, %{cycles: 0}} = GenMagic.Server.status(:gen_magic)
|
|
||||||
assert {:ok, %{cycles: 0}} = GenMagic.Server.status(pid)
|
|
||||||
assert {:ok, %Result{} = result} = GenMagic.Server.perform(:gen_magic, path)
|
|
||||||
assert {:ok, %{cycles: 1}} = GenMagic.Server.status(:gen_magic)
|
|
||||||
assert {:ok, %{cycles: 1}} = GenMagic.Server.status(pid)
|
|
||||||
assert "text/x-makefile" = result.mime_type
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "custom database" do
|
|
||||||
setup do
|
|
||||||
database = absolute_path("elixir.mgc")
|
|
||||||
on_exit(fn -> File.rm(database) end)
|
|
||||||
{_, 0} = System.cmd("file", ["-C", "-m", absolute_path("test/elixir")])
|
|
||||||
[database: database]
|
|
||||||
end
|
|
||||||
|
|
||||||
test "recognises Elixir files", %{database: database} do
|
|
||||||
{:ok, pid} = GenMagic.Server.start_link(database_patterns: [database])
|
|
||||||
path = absolute_path("mix.exs")
|
|
||||||
assert {:ok, %Result{} = result} = GenMagic.Server.perform(pid, path)
|
|
||||||
assert "text/x-elixir" = result.mime_type
|
|
||||||
assert "us-ascii" = result.encoding
|
|
||||||
assert "Elixir module source text" = result.content
|
|
||||||
end
|
|
||||||
|
|
||||||
test "recognises Elixir files after a reload", %{database: database} do
|
|
||||||
{:ok, pid} = GenMagic.Server.start_link([])
|
|
||||||
path = absolute_path("mix.exs")
|
|
||||||
{:ok, %Result{mime_type: mime}} = GenMagic.Server.perform(pid, path)
|
|
||||||
refute mime == "text/x-elixir"
|
|
||||||
:ok = GenMagic.Server.reload(pid, [database])
|
|
||||||
assert {:ok, %Result{mime_type: "text/x-elixir"}} = GenMagic.Server.perform(pid, path)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,9 +0,0 @@
|
||||||
defmodule GenMagic.HelpersTest do
|
|
||||||
use GenMagic.MagicCase
|
|
||||||
doctest GenMagic.Helpers
|
|
||||||
|
|
||||||
test "perform_once" do
|
|
||||||
path = absolute_path("Makefile")
|
|
||||||
assert {:ok, %{mime_type: "text/x-makefile"}} = GenMagic.Helpers.perform_once(path)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,16 +0,0 @@
|
||||||
defmodule GenMagic.PoollTest do
|
|
||||||
use GenMagic.MagicCase
|
|
||||||
|
|
||||||
test "pool" do
|
|
||||||
{:ok, _} = GenMagic.Pool.start_link(name: TestPool, pool_size: 2)
|
|
||||||
assert {:ok, _} = GenMagic.Pool.perform(TestPool, absolute_path("Makefile"))
|
|
||||||
assert {:ok, _} = GenMagic.Pool.perform(TestPool, absolute_path("Makefile"))
|
|
||||||
assert {:ok, _} = GenMagic.Pool.perform(TestPool, absolute_path("Makefile"))
|
|
||||||
assert {:ok, _} = GenMagic.Pool.perform(TestPool, absolute_path("Makefile"))
|
|
||||||
assert {:ok, _} = GenMagic.Pool.perform(TestPool, absolute_path("Makefile"))
|
|
||||||
assert {:ok, _} = GenMagic.Pool.perform(TestPool, absolute_path("Makefile"))
|
|
||||||
assert {:ok, _} = GenMagic.Pool.perform(TestPool, absolute_path("Makefile"))
|
|
||||||
assert {:ok, _} = GenMagic.Pool.perform(TestPool, absolute_path("Makefile"))
|
|
||||||
assert {:ok, _} = GenMagic.Pool.perform(TestPool, absolute_path("Makefile"))
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,44 +0,0 @@
|
||||||
defmodule GenMagic.ServerTest do
|
|
||||||
use GenMagic.MagicCase
|
|
||||||
doctest GenMagic.Server
|
|
||||||
|
|
||||||
describe "recycle_threshold" do
|
|
||||||
test "resets" do
|
|
||||||
{:ok, pid} = GenMagic.Server.start_link(recycle_threshold: 3)
|
|
||||||
path = absolute_path("Makefile")
|
|
||||||
assert {:ok, %{cycles: 0}} = GenMagic.Server.status(pid)
|
|
||||||
assert {:ok, _} = GenMagic.Server.perform(pid, path)
|
|
||||||
assert {:ok, %{cycles: 1}} = GenMagic.Server.status(pid)
|
|
||||||
assert {:ok, _} = GenMagic.Server.perform(pid, path)
|
|
||||||
assert {:ok, %{cycles: 2}} = GenMagic.Server.status(pid)
|
|
||||||
assert {:ok, _} = GenMagic.Server.perform(pid, path)
|
|
||||||
Process.sleep(100)
|
|
||||||
assert {:ok, %{cycles: 0}} = GenMagic.Server.status(pid)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "resets before reply" do
|
|
||||||
{:ok, pid} = GenMagic.Server.start_link(recycle_threshold: 1)
|
|
||||||
path = absolute_path("Makefile")
|
|
||||||
assert {:ok, %{cycles: 0}} = GenMagic.Server.status(pid)
|
|
||||||
assert {:ok, _} = GenMagic.Server.perform(pid, path)
|
|
||||||
Process.sleep(100)
|
|
||||||
assert {:ok, %{cycles: 0}} = GenMagic.Server.status(pid)
|
|
||||||
assert {:ok, _} = GenMagic.Server.perform(pid, path)
|
|
||||||
Process.sleep(100)
|
|
||||||
assert {:ok, %{cycles: 0}} = GenMagic.Server.status(pid)
|
|
||||||
assert {:ok, _} = GenMagic.Server.perform(pid, path)
|
|
||||||
Process.sleep(100)
|
|
||||||
assert {:ok, %{cycles: 0}} = GenMagic.Server.status(pid)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
test "recycle" do
|
|
||||||
{:ok, pid} = GenMagic.Server.start_link([])
|
|
||||||
path = absolute_path("Makefile")
|
|
||||||
assert {:ok, %{cycles: 0}} = GenMagic.Server.status(pid)
|
|
||||||
assert {:ok, _} = GenMagic.Server.perform(pid, path)
|
|
||||||
assert {:ok, %{cycles: 1}} = GenMagic.Server.status(pid)
|
|
||||||
assert :ok = GenMagic.Server.recycle(pid)
|
|
||||||
assert {:ok, %{cycles: 0}} = GenMagic.Server.status(pid)
|
|
||||||
end
|
|
||||||
end
|
|
9
test/majic/helpers_test.exs
Normal file
9
test/majic/helpers_test.exs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
defmodule Majic.HelpersTest do
|
||||||
|
use Majic.MagicCase
|
||||||
|
doctest Majic.Helpers
|
||||||
|
|
||||||
|
test "perform_once" do
|
||||||
|
path = absolute_path("Makefile")
|
||||||
|
assert {:ok, %{mime_type: "text/x-makefile"}} = Majic.Helpers.perform_once(path)
|
||||||
|
end
|
||||||
|
end
|
69
test/majic/majic_test.exs
Normal file
69
test/majic/majic_test.exs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
defmodule MajicTest do
|
||||||
|
use Majic.MagicCase
|
||||||
|
alias Majic.Result
|
||||||
|
|
||||||
|
doctest Majic
|
||||||
|
@iterations 100
|
||||||
|
|
||||||
|
test "Makefile is text file" do
|
||||||
|
{:ok, pid} = Majic.Server.start_link([])
|
||||||
|
path = absolute_path("Makefile")
|
||||||
|
assert {:ok, %{mime_type: "text/x-makefile"}} = Majic.Server.perform(pid, path)
|
||||||
|
end
|
||||||
|
|
||||||
|
@tag external: true
|
||||||
|
test "Load test local files" do
|
||||||
|
{:ok, pid} = Majic.Server.start_link([])
|
||||||
|
|
||||||
|
files_stream()
|
||||||
|
|> Stream.cycle()
|
||||||
|
|> Stream.take(@iterations)
|
||||||
|
|> Stream.map(&assert {:ok, %Result{}} = Majic.Server.perform(pid, &1))
|
||||||
|
|> Enum.all?()
|
||||||
|
|> assert
|
||||||
|
end
|
||||||
|
|
||||||
|
test "Non-existent file" do
|
||||||
|
{:ok, pid} = Majic.Server.start_link([])
|
||||||
|
path = missing_filename()
|
||||||
|
assert_no_file(Majic.Server.perform(pid, path))
|
||||||
|
end
|
||||||
|
|
||||||
|
test "Named process" do
|
||||||
|
{:ok, pid} = Majic.Server.start_link(name: :gen_magic)
|
||||||
|
path = absolute_path("Makefile")
|
||||||
|
assert {:ok, %{cycles: 0}} = Majic.Server.status(:gen_magic)
|
||||||
|
assert {:ok, %{cycles: 0}} = Majic.Server.status(pid)
|
||||||
|
assert {:ok, %Result{} = result} = Majic.Server.perform(:gen_magic, path)
|
||||||
|
assert {:ok, %{cycles: 1}} = Majic.Server.status(:gen_magic)
|
||||||
|
assert {:ok, %{cycles: 1}} = Majic.Server.status(pid)
|
||||||
|
assert "text/x-makefile" = result.mime_type
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "custom database" do
|
||||||
|
setup do
|
||||||
|
database = absolute_path("elixir.mgc")
|
||||||
|
on_exit(fn -> File.rm(database) end)
|
||||||
|
{_, 0} = System.cmd("file", ["-C", "-m", absolute_path("test/elixir")])
|
||||||
|
[database: database]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "recognises Elixir files", %{database: database} do
|
||||||
|
{:ok, pid} = Majic.Server.start_link(database_patterns: [database])
|
||||||
|
path = absolute_path("mix.exs")
|
||||||
|
assert {:ok, %Result{} = result} = Majic.Server.perform(pid, path)
|
||||||
|
assert "text/x-elixir" = result.mime_type
|
||||||
|
assert "us-ascii" = result.encoding
|
||||||
|
assert "Elixir module source text" = result.content
|
||||||
|
end
|
||||||
|
|
||||||
|
test "recognises Elixir files after a reload", %{database: database} do
|
||||||
|
{:ok, pid} = Majic.Server.start_link([])
|
||||||
|
path = absolute_path("mix.exs")
|
||||||
|
{:ok, %Result{mime_type: mime}} = Majic.Server.perform(pid, path)
|
||||||
|
refute mime == "text/x-elixir"
|
||||||
|
:ok = Majic.Server.reload(pid, [database])
|
||||||
|
assert {:ok, %Result{mime_type: "text/x-elixir"}} = Majic.Server.perform(pid, path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
16
test/majic/pool_test.exs
Normal file
16
test/majic/pool_test.exs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
defmodule Majic.PoollTest do
|
||||||
|
use Majic.MagicCase
|
||||||
|
|
||||||
|
test "pool" do
|
||||||
|
{:ok, _} = Majic.Pool.start_link(name: TestPool, pool_size: 2)
|
||||||
|
assert {:ok, _} = Majic.Pool.perform(TestPool, absolute_path("Makefile"))
|
||||||
|
assert {:ok, _} = Majic.Pool.perform(TestPool, absolute_path("Makefile"))
|
||||||
|
assert {:ok, _} = Majic.Pool.perform(TestPool, absolute_path("Makefile"))
|
||||||
|
assert {:ok, _} = Majic.Pool.perform(TestPool, absolute_path("Makefile"))
|
||||||
|
assert {:ok, _} = Majic.Pool.perform(TestPool, absolute_path("Makefile"))
|
||||||
|
assert {:ok, _} = Majic.Pool.perform(TestPool, absolute_path("Makefile"))
|
||||||
|
assert {:ok, _} = Majic.Pool.perform(TestPool, absolute_path("Makefile"))
|
||||||
|
assert {:ok, _} = Majic.Pool.perform(TestPool, absolute_path("Makefile"))
|
||||||
|
assert {:ok, _} = Majic.Pool.perform(TestPool, absolute_path("Makefile"))
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,17 +1,17 @@
|
||||||
defmodule GenMagic.ApprenticeTest do
|
defmodule Majic.ApprenticeTest do
|
||||||
use GenMagic.MagicCase
|
use Majic.MagicCase
|
||||||
|
|
||||||
@tmp_path "/tmp/testgenmagicx"
|
@tmp_path "/tmp/testgenmagicx"
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
test "sends ready" do
|
test "sends ready" do
|
||||||
port = Port.open(GenMagic.Config.get_port_name(), GenMagic.Config.get_port_options([]))
|
port = Port.open(Majic.Config.get_port_name(), Majic.Config.get_port_options([]))
|
||||||
on_exit(fn -> send(port, {self(), :close}) end)
|
on_exit(fn -> send(port, {self(), :close}) end)
|
||||||
assert_ready_and_init_default(port)
|
assert_ready_and_init_default(port)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "stops" do
|
test "stops" do
|
||||||
port = Port.open(GenMagic.Config.get_port_name(), GenMagic.Config.get_port_options([]))
|
port = Port.open(Majic.Config.get_port_name(), Majic.Config.get_port_options([]))
|
||||||
on_exit(fn -> send(port, {self(), :close}) end)
|
on_exit(fn -> send(port, {self(), :close}) end)
|
||||||
assert_ready_and_init_default(port)
|
assert_ready_and_init_default(port)
|
||||||
send(port, {self(), {:command, :erlang.term_to_binary({:stop, :stop})}})
|
send(port, {self(), {:command, :erlang.term_to_binary({:stop, :stop})}})
|
||||||
|
@ -20,7 +20,7 @@ defmodule GenMagic.ApprenticeTest do
|
||||||
|
|
||||||
test "exits with non existent database with an error" do
|
test "exits with non existent database with an error" do
|
||||||
opts = [:use_stdio, :binary, :exit_status, {:packet, 2}, {:args, []}]
|
opts = [:use_stdio, :binary, :exit_status, {:packet, 2}, {:args, []}]
|
||||||
port = Port.open(GenMagic.Config.get_port_name(), opts)
|
port = Port.open(Majic.Config.get_port_name(), opts)
|
||||||
on_exit(fn -> send(port, {self(), :close}) end)
|
on_exit(fn -> send(port, {self(), :close}) end)
|
||||||
assert_ready(port)
|
assert_ready(port)
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ defmodule GenMagic.ApprenticeTest do
|
||||||
|
|
||||||
describe "port" do
|
describe "port" do
|
||||||
setup do
|
setup do
|
||||||
port = Port.open(GenMagic.Config.get_port_name(), GenMagic.Config.get_port_options([]))
|
port = Port.open(Majic.Config.get_port_name(), Majic.Config.get_port_options([]))
|
||||||
on_exit(fn -> send(port, {self(), :close}) end)
|
on_exit(fn -> send(port, {self(), :close}) end)
|
||||||
assert_ready_and_init_default(port)
|
assert_ready_and_init_default(port)
|
||||||
%{port: port}
|
%{port: port}
|
44
test/majic/server_test.exs
Normal file
44
test/majic/server_test.exs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
defmodule Majic.ServerTest do
|
||||||
|
use Majic.MagicCase
|
||||||
|
doctest Majic.Server
|
||||||
|
|
||||||
|
describe "recycle_threshold" do
|
||||||
|
test "resets" do
|
||||||
|
{:ok, pid} = Majic.Server.start_link(recycle_threshold: 3)
|
||||||
|
path = absolute_path("Makefile")
|
||||||
|
assert {:ok, %{cycles: 0}} = Majic.Server.status(pid)
|
||||||
|
assert {:ok, _} = Majic.Server.perform(pid, path)
|
||||||
|
assert {:ok, %{cycles: 1}} = Majic.Server.status(pid)
|
||||||
|
assert {:ok, _} = Majic.Server.perform(pid, path)
|
||||||
|
assert {:ok, %{cycles: 2}} = Majic.Server.status(pid)
|
||||||
|
assert {:ok, _} = Majic.Server.perform(pid, path)
|
||||||
|
Process.sleep(100)
|
||||||
|
assert {:ok, %{cycles: 0}} = Majic.Server.status(pid)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "resets before reply" do
|
||||||
|
{:ok, pid} = Majic.Server.start_link(recycle_threshold: 1)
|
||||||
|
path = absolute_path("Makefile")
|
||||||
|
assert {:ok, %{cycles: 0}} = Majic.Server.status(pid)
|
||||||
|
assert {:ok, _} = Majic.Server.perform(pid, path)
|
||||||
|
Process.sleep(100)
|
||||||
|
assert {:ok, %{cycles: 0}} = Majic.Server.status(pid)
|
||||||
|
assert {:ok, _} = Majic.Server.perform(pid, path)
|
||||||
|
Process.sleep(100)
|
||||||
|
assert {:ok, %{cycles: 0}} = Majic.Server.status(pid)
|
||||||
|
assert {:ok, _} = Majic.Server.perform(pid, path)
|
||||||
|
Process.sleep(100)
|
||||||
|
assert {:ok, %{cycles: 0}} = Majic.Server.status(pid)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "recycle" do
|
||||||
|
{:ok, pid} = Majic.Server.start_link([])
|
||||||
|
path = absolute_path("Makefile")
|
||||||
|
assert {:ok, %{cycles: 0}} = Majic.Server.status(pid)
|
||||||
|
assert {:ok, _} = Majic.Server.perform(pid, path)
|
||||||
|
assert {:ok, %{cycles: 1}} = Majic.Server.status(pid)
|
||||||
|
assert :ok = Majic.Server.recycle(pid)
|
||||||
|
assert {:ok, %{cycles: 0}} = Majic.Server.status(pid)
|
||||||
|
end
|
||||||
|
end
|
|
@ -8,7 +8,7 @@ defmodule Soak do
|
||||||
def perform_infinite([]), do: false
|
def perform_infinite([]), do: false
|
||||||
|
|
||||||
def perform_infinite(paths) do
|
def perform_infinite(paths) do
|
||||||
{:ok, pid} = GenMagic.Server.start_link(database_patterns: ["/usr/local/share/misc/*.mgc"])
|
{:ok, pid} = Majic.Server.start_link(database_patterns: ["/usr/local/share/misc/*.mgc"])
|
||||||
|
|
||||||
perform_infinite(paths, [], pid, 0)
|
perform_infinite(paths, [], pid, 0)
|
||||||
end
|
end
|
||||||
|
@ -19,7 +19,7 @@ defmodule Soak do
|
||||||
|
|
||||||
defp perform_infinite([path | paths], done, pid, count) do
|
defp perform_infinite([path | paths], done, pid, count) do
|
||||||
if rem(count, 1000) == 0, do: IO.puts(Integer.to_string(count))
|
if rem(count, 1000) == 0, do: IO.puts(Integer.to_string(count))
|
||||||
{:ok, %GenMagic.Result{}} = GenMagic.Server.perform(pid, path)
|
{:ok, %Majic.Result{}} = Majic.Server.perform(pid, path)
|
||||||
perform_infinite(paths, [path | done], pid, count + 1)
|
perform_infinite(paths, [path | done], pid, count + 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
defmodule GenMagic.MagicCase do
|
defmodule Majic.MagicCase do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
use ExUnit.CaseTemplate
|
use ExUnit.CaseTemplate
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue