Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
hernanrz committed Feb 21, 2016
0 parents commit 386ddf9
Show file tree
Hide file tree
Showing 12 changed files with 414 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/vendor/*
composer.phar
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"autoload": {
"psr-4": { "DataStream\\Emulator\\" : "src/", "DataStream\\" : "src/" }
}
}
99 changes: 99 additions & 0 deletions emulator/emulator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

namespace DataStream;

require dirname(__DIR__) . '/vendor/autoload.php';

if('Linux' == PHP_OS) {
echo "". "\033[34;34mE\033[0m" . "\033[33;33mm\033[0m" . "\033[1;31mu\033[0m";
}else {
echo "> Emu";
}

echo PHP_EOL;

if(count($argv) < 3) {
echo 'Usage: ' . basename(__FILE__) . ' [Config file] [port]' . PHP_EOL;

echo '* Config file: The JSON file containing emulation parameters' . PHP_EOL;
echo '* Port: Port number to bind the server' . PHP_EOL;

exit;
}

$configFileName = __DIR__ . DIRECTORY_SEPARATOR . $argv[1];
$port = $argv[2];

echo '* Reading configuration file ' . basename($configFileName) . '...';

if(file_exists($configFileName)) {

$configuration = json_decode(file_get_contents($configFileName), true);
echo ' [ok]' . PHP_EOL;

}else {

echo PHP_EOL . '[x] Could not find configuration file, exiting' . PHP_EOL;
exit;

}

$requiredVars = [
'sourceType',
];

$providedVars = array_keys($configuration);

$varDiff = array_diff($requiredVars, $providedVars);

if(!empty($varDiff)) {
echo '[x] One or more required variables are not present in the configuration file' . PHP_EOL;
echo ' Missing variable(s): ' . implode(" ", $varDiff) . PHP_EOL;
}

$dataSource = new Source;

switch ($configuration['sourceType']) {
case 'raw':
if(!isset($configuration['data'])) {
echo '[x] Source type is raw but data parameter was not provided' . PHP_EOL;
exit;
}

$dataSource->setData($configuration['data']);
break;

case 'file':
if(!isset($configuration['dataLocation'])) {
echo '[x] Source type is "file" but dataLocation parameter was not provided' . PHP_EOL;
exit;
}

$configuration['dataLocation'] = __DIR__ . $configuration['dataLocation'];

if(!file_exists($configuration['dataLocation'])) {
echo '[x] Could not find file '. $configuration['dataLocation'] . PHP_EOL;
exit;
}

$dataSource->loadFromFile($configuration['dataLocation']);
break;

default:
echo '[x] Unknown source type "'. $configuration['sourceType'] .'"' . PHP_EOL;
exit;
break;
}

$server = new Emulator\Server($port, $dataSource);

echo PHP_EOL . 'Listening on port ' . $port . ' press CTRL+C to exit' . PHP_EOL;

while(1) {
if(list($peerName, $msg) = $server->receive()) {
echo 'Got connection from ' . $peerName . PHP_EOL;
$server->dispatch();
}
}

echo PHP_EOL;
5 changes: 5 additions & 0 deletions emulator/testing.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"data": "yes",
"sourceType": "file",
"dataLocation": "\\..\\tests\\testfile.txt"
}
16 changes: 16 additions & 0 deletions src/Emulator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace DataStream\Emulator;


/**
* Emulator class
*/
class ClassName extends AnotherClass
{

function __construct(argument)
{
# code...
}
}
58 changes: 58 additions & 0 deletions src/Server.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace DataStream\Emulator;

/**
* Simple TCP server
*/
class Server
{

private $resource;

private $dataSource;

private $currentClient = null;

public $stopped = true;

function __construct($port, \DataStream\Source $dataSource, $host = '127.0.0.1')
{
$localSocket = 'tcp://' . $host . ':' . $port;

$this->dataSource = $dataSource;

$this->resource = stream_socket_server($localSocket);

$this->stopped = false;
}

public function receive()
{
$this->currentClient = stream_socket_accept($this->resource, -1, $peerName);
$msg = fread($this->currentClient, 1024); //Read whatever the client sends before returning, prevents connection reset errors
return [$peerName, $msg];
}

public function dispatch()
{
if (null == $this->currentClient) {
return false;
}

fwrite($this->currentClient, $this->getResponseData());
fclose($this->currentClient);

return true;
}

public function stop()
{
return $this->stopped = stream_socket_shutdown($this->resource, STREAM_SHUT_RDWR);
}

public function getResponseData()
{
return $this->dataSource->getData();
}
}
29 changes: 29 additions & 0 deletions src/Source.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace DataStream;

/**
* Data source loader
*/
class Source
{

protected $data = null;

public function loadFromFile($filePath)
{
$this->data = file_get_contents($filePath);
}

public function getData()
{
return $this->data;
}

public function setData($data)
{
$this->data = $data;

return $this;
}
}
26 changes: 26 additions & 0 deletions tests/DataSourceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

/**
* DataSource test
*/
class DataSourceTest extends PHPUnit_Framework_Testcase
{
public function testRawSource()
{
$source = new DataStream\Source;

$source->setData("hello this is a test");

$this->assertEquals("hello this is a test", $source->getData());
}

public function testFileSource()
{
$source = new DataStream\Source;

$source->loadFromFile(__DIR__ . '/testfile.txt');

$this->assertEquals(file_get_contents(__DIR__ . '/testfile.txt'), $source->getData());
}
}

39 changes: 39 additions & 0 deletions tests/ServerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

class ServerTest extends PHPUnit_Framework_TestCase
{
public function testServerBind()
{
$source = new DataStream\Source;

$source->setData("Testing");

$server = new DataStream\Emulator\Server("8080", $source);

$this->assertEquals(false, $server->stopped);

$server->stop();
}


public function testServerConn()
{

$source = new DataStream\Source;

$source->setData("Testing");

$server = new DataStream\Emulator\Server("8080", $source);

$server->receive();

$conn = stream_socket_client("tcp://127.0.0.1:8080");

$got = fread($conn, strlen("Testing"));

fclose($conn);
$server->stop();

$this->assertEquals($got, "Testing");
}
}
12 changes: 12 additions & 0 deletions tests/testfile.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
HTTP/1.1 200 OK
Content-Type: text/html

<html>
<head>
<title>Emu: works!</title>
</head>
<body>
<h1>It works</h1>
<p>Emu is working as intended, nice!</p>
</body>
</html>
52 changes: 52 additions & 0 deletions www/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">

<link rel="stylesheet" href="style.css" media="screen" title="no title" charset="utf-8">
<link href='https://fonts.googleapis.com/css?family=Voltaire|Quattrocento+Sans' rel='stylesheet' type='text/css'>

<title>Emu: server emulator</title>
</head>
<body>
<div class="title">
<span style="color: #00A3EE">E</span><span style="color: #F5D908">m</span><span style="color: #D80351">u</span>
</div>

<div class="wrapper">
Emu is a super simple server emulator written in <i title="The best programming language to be invented since BASIC">PHP</i>.
<br />
<br />
<p>
<b>Why is it called an emulator?</b>
<br />
Because <s>I couldn't think of a better name</s> it creates a server, but it will only serve whatever data you provide to it.
</p>
<br />
<p>
<b>How is this useful at all?</b>
<br />
I created this because some of the code in a different project makes several requests to a local API, so instead of installing another server I can just run Emu and test my code without much hassle.
</p>

<div class="links-section">
<div class="download-button">
<a href="#">Download</a>
<br />
<p>
Current version: 0.1
</p>
</div>
<div class="source-code-link download-button">
<a href="#">Source Code</a>
<br />
<p>
All PRs are welcome
</p>
</div>

</div>

</div>
</body>
</html>
Loading

0 comments on commit 386ddf9

Please sign in to comment.