Merge pull request #121 from xecarlox94/master

Nix Flake development and build environment upgrade
This commit is contained in:
Akilan Selvacoumar
2025-01-12 08:48:03 +00:00
committed by GitHub
30 changed files with 702 additions and 796 deletions

149
Bindings/Haskell/flake.lock generated Normal file
View File

@@ -0,0 +1,149 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"gomod2nix": {
"inputs": {
"flake-utils": [
"p2prc",
"flake-utils"
],
"nixpkgs": [
"p2prc",
"nixpkgs"
]
},
"locked": {
"lastModified": 1733668782,
"narHash": "sha256-tPsqU00FhgdFr0JiQUiBMgPVbl1jbPCY5gbFiJycL3I=",
"owner": "nix-community",
"repo": "gomod2nix",
"rev": "514283ec89c39ad0079ff2f3b1437404e4cba608",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "gomod2nix",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 0,
"narHash": "sha256-m/lh6hYMIWDYHCAsn81CDAiXoT3gmxXI9J987W5tZrE=",
"path": "/nix/store/wj2qla569hnxwqfc26imv5hqbxc1rc27-source",
"type": "path"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1735834308,
"narHash": "sha256-dklw3AXr3OGO4/XT1Tu3Xz9n/we8GctZZ75ZWVqAVhk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6df24922a1400241dae323af55f30e4318a6ca65",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"p2prc": {
"inputs": {
"flake-utils": "flake-utils",
"gomod2nix": "gomod2nix",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 0,
"narHash": "sha256-f4e4JcQzBS+R+8HqJbQVeecInm2ggInJuSSymj6gtQo=",
"path": "/nix/store/hmk8v0lxifsscll054qsdnzxqfql1998-source",
"type": "path"
},
"original": {
"path": "/nix/store/hmk8v0lxifsscll054qsdnzxqfql1998-source",
"type": "path"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"p2prc": "p2prc",
"utils": "utils"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"utils": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

View File

@@ -0,0 +1,24 @@
{
description = "Nix flake for P2PRC Haskell library";
inputs = {
p2prc.url = "../../";
utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, utils, p2prc }: utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
devShell = pkgs.mkShell {
buildInputs = with pkgs; [
cabal-install
haskell.compiler.ghc96
zlib.dev
p2prc.outputs.packages.${system}.default
];
};
}
);
}

11
Bindings/Haskell/gen_docs.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/bash
rm -rf dist-newstyle/
cabal haddock
rm -rf ../../Docs/haskell
cp -r \
./dist-newstyle/build/x86_64-linux/ghc-9.6.6/p2prc-0.1.0.0/doc/html/p2prc/ \
../../Docs/haskell

151
Bindings/Haskell/lib/API.hs Normal file
View File

@@ -0,0 +1,151 @@
module API
( P2PRCapi(..)
, MapPortRequest(..)
, p2prcAPI
)
where
import System.Directory ( getCurrentDirectory )
import System.Process ( ProcessHandle )
import Data.Aeson ( FromJSON )
import Error
( IOEitherError
)
import JSON
( IPAddressTable(..)
, MapPortResponse(..)
, P2prcConfig
)
import CLI
( StdInput(..)
, CLIOpt(..)
, eitherErrDecode
, p2PrcCmdName
, eitherExecProcess
, eitherExecProcessParser
, spawnProcP2Prc
)
-- | Lower level P2PRC Haskell api that exposes basic functionality necessary to joint the network.
data P2PRCapi
= MkP2PRCapi
{ startServer :: IOEitherError ProcessHandle
-- ^ Start server
, execInitConfig :: IOEitherError P2prcConfig
-- ^ Instantiate server configuration
, execListServers :: IOEitherError IPAddressTable
-- ^ List servers in network
, execMapPort :: MapPortRequest -> IOEitherError MapPortResponse
-- ^ Exposes and associates a local TCP port with a remote DNS address
}
-- | This defines the request required to create an association between a TCP socket port and a DNS server in the network. If successful, it makes a resource available in the network.
data MapPortRequest =
MkMapPortRequest -- ^ P2PRC's port allocation request value
Int -- ^ TCP socket number
String -- ^ Network domain name
{-|
This function intiates a pure P2PRC runtime state and builds up a 'P2PRCapi' API instance. It allows a developer to create computing orchestration algorithms using the API primitives.
==== __Example__
The following example show how this function can be used to expose the runtime functionalities:
@
module Main where
import P2PRC
( p2prcAPI
, P2PRCapi(..)
)
main :: IO ()
main =
print "Hello P2PRC"
-- your code logic goes here
where
MkP2PRCapi
{ startServer=startServer
, execMapPort=execMapPort
, execListServers=execListServers
, execInitConfig=execInitConfig
} = p2prcAPI
@
-}
{-# WARNING p2prcAPI "This function is currently unstable because the configuration reading is dependent on the following issue: https://github.com/Akilan1999/p2p-rendering-computation/issues/120" #-}
p2prcAPI :: P2PRCapi
p2prcAPI =
MkP2PRCapi
{ startServer = spawnProcP2Prc p2PrcCmdName [ MkOptAtomic "--s" ]
, execListServers =
execProcP2PrcParser [ MkOptAtomic "--ls" ] MkEmptyStdInput
, execMapPort =
\ (MkMapPortRequest portNumber domainName) ->
execProcP2PrcParser
[ MkOptTuple
( "--mp"
, show portNumber
)
, MkOptTuple
( "--dn"
, domainName
)
]
MkEmptyStdInput
, execInitConfig = do
confInitRes <- execProcP2Prc [ MkOptAtomic "--dc" ] MkEmptyStdInput
case confInitRes of
(Right _) -> do
-- TODO: get config file name dynamically
--
currDirectory <- getCurrentDirectory
-- TODO: change values before loading file
let fname = currDirectory ++ "/config.json" :: FilePath
-- TODO: read config check if file exists
configContent <- readFile fname
pure $ eitherErrDecode configContent
(Left err) -> pure $ Left err
}
where
execProcP2PrcParser ::
FromJSON a =>
[CLIOpt] -> StdInput -> IOEitherError a
execProcP2PrcParser = eitherExecProcessParser p2PrcCmdName
-- TODO: GHC question, why does it scope down instead staying generic
execProcP2Prc = eitherExecProcess p2PrcCmdName

View File

@@ -23,8 +23,6 @@ import Data.Aeson
, eitherDecode
)
import qualified Data.Text as T
import qualified Data.ByteString.Lazy.Char8 as LBC8
@@ -79,7 +77,6 @@ eitherExecProcess cmd opts input =
ExitFailure i -> Left $ MkCLISystemError i cmd err
_ -> Right out
optsToCLI :: [CLIOpt] -> CLIOptsInput
optsToCLI = concatMap _optToCLI
where
@@ -116,25 +113,8 @@ eitherErrorDecode esa =
(Right v) -> Right v
getP2PrcCmd :: IOEitherError String
getP2PrcCmd = do
-- assumes the program is ran inside the haskell module in p2prc's repo
-- assumes that last path segment is "haskell" and that p2prc binary's name is "p2p-rendering-computation"
let trimString = T.unpack . T.strip . T.pack
eitherErrPwd <- eitherExecProcess "pwd" [MkEmptyOpts] MkEmptyStdInput
case eitherErrPwd of
(Right pwdOut) ->
eitherExecProcess
"sed"
[ MkOptAtomic "s/haskell/p2p-rendering-computation/" ]
$ MkStdInputVal
$ trimString pwdOut
err -> pure err
-- assumes the program is ran inside the haskell module in p2prc's repo
-- assumes that last path segment is "haskell" and that p2prc binary's name is "p2p-rendering-computation"
p2PrcCmdName :: String
p2PrcCmdName = "p2p-rendering-computation"

View File

@@ -18,7 +18,7 @@ import System.Process ( terminateProcess )
import API
( P2PRCapi(..)
, MapPortRequest(..)
, getP2prcAPI
, p2prcAPI
)
@@ -60,7 +60,13 @@ import API
runP2PRC
:: MapPortRequest -- ^ TCP Port Request
-> IO ()
runP2PRC (MkMapPortRequest portNumber domainName) = do
runP2PRC
( MkMapPortRequest
portNumber
domainName
)
=
let
--
-- TODO: add quickcheck testing (quickchecking-dynamic)
@@ -87,19 +93,15 @@ runP2PRC (MkMapPortRequest portNumber domainName) = do
-- TODO: Error
-- assign error: should parse other error
( MkP2PRCapi
{ startServer = startServer
, execInitConfig = execInitConfig
, execListServers = execListServers
, execMapPort = execMapPort
}
) = p2prcAPI
eitherP2prcAPI <- getP2prcAPI
case eitherP2prcAPI of
(Right
( MkP2PRCapi
{ startServer = startServer
, execInitConfig = execInitConfig
, execListServers = execListServers
, execMapPort = execMapPort
}
)) -> do
in do
let
@@ -147,7 +149,6 @@ runP2PRC (MkMapPortRequest portNumber domainName) = do
(Left err) -> print err
(Left err) -> print err
where

View File

@@ -40,7 +40,7 @@ module P2PRC
It is intended this way to give freedom to the developer to implement their own orchestration strategies.
-}
runP2PRC
, getP2prcAPI
, p2prcAPI
-- * Data Types
{- | This section describes and explains the library's type system, more specifically, the interfaces and primitive types.
@@ -82,7 +82,7 @@ import JSON
import API
( MapPortRequest(..)
, P2PRCapi(..)
, getP2prcAPI
, p2prcAPI
)

View File

@@ -60,7 +60,6 @@ library
other-modules: API
, Engine
, CLI
, Environment
, JSON
, Error

File diff suppressed because one or more lines are too long

View File

@@ -1,120 +0,0 @@
<div id="package-header">
<span class="caption">p2prc-0.1.0.0: P2PRC haskell library</span>
- [Contents](index.html)
- [Index](doc-index.html)
</div>
<div id="content">
<div id="module-header">
| | |
|--------------|-----------------------------------------|
| Copyright | Copyright (C) 2006-2024 John MacFarlane |
| License | GNU GPL, version 2 or above |
| Maintainer | John MacFarlane \<jgm@berkeley.edu\> |
| Stability | alpha |
| Portability | portable |
| Safe Haskell | Safe-Inferred |
| Language | GHC2021 |
P2PRC
</div>
<div id="description">
Description
<div class="doc">
This helper module exports the main writers, readers, and data structure
definitions from the Pandoc libraries.
A typical application will chain together a reader and a writer to
convert strings from one format to another. For example, the following
simple program will act as a filter converting markdown fragments to
reStructuredText, using reference-style links instead of inline links:
module Main where
import Text.Pandoc
import Data.Text (Text)
import qualified Data.Text.IO as T
mdToRST :: Text -> IO Text
mdToRST txt = runIOorExplode $
readMarkdown def txt
>>= writeRST def{ writerReferenceLinks = True }
main :: IO ()
main = do
T.getContents >>= mdToRST >>= T.putStrLn
</div>
</div>
<div id="synopsis">
Synopsis
- [runP2PRC](#v:runP2PRC) ::
[MapPortRequest](P2PRC.html#t:MapPortRequest "P2PRC") -\>
[IO]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/System-IO.html#t:IO "System.IO")
()
- <span class="keyword">data</span> [MapPortRequest](#t:MapPortRequest)
= [MkMapPortRequest](#v:MkMapPortRequest)
[Int]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/Data-Int.html#t:Int "Data.Int")
[String]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/Data-String.html#t:String "Data.String")
</div>
<div id="interface">
# Documentation
<div class="top">
<span id="v:runP2PRC" class="def">runP2PRC</span> ::
[MapPortRequest](P2PRC.html#t:MapPortRequest "P2PRC") -\>
[IO]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/System-IO.html#t:IO "System.IO")
() <a href="#v:runP2PRC" class="selflink">#</a>
<div class="doc">
Hello World
</div>
</div>
<div class="top">
<span class="keyword">data</span> <span id="t:MapPortRequest"
class="def">MapPortRequest</span>
<a href="#t:MapPortRequest" class="selflink">#</a>
<div class="subs constructors">
Constructors
| | |
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----|
| <span id="v:MkMapPortRequest" class="def">MkMapPortRequest</span> [Int]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/Data-Int.html#t:Int "Data.Int") [String]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/Data-String.html#t:String "Data.String") |   |
</div>
</div>
</div>
</div>
<div id="footer">
Produced by [Haddock](http://www.haskell.org/haddock/) version 2.29.2
</div>

File diff suppressed because one or more lines are too long

View File

@@ -1,30 +0,0 @@
<div id="package-header">
<span class="caption">p2prc-0.1.0.0: P2PRC haskell library</span>
- [Contents](index.html)
- [Index](doc-index.html)
</div>
<div id="content">
<div id="index">
Index
| | |
|------------------|------------------------------------------------|
| MapPortRequest | [P2PRC](P2PRC.html#t:MapPortRequest "P2PRC") |
| MkMapPortRequest | [P2PRC](P2PRC.html#v:MkMapPortRequest "P2PRC") |
| runP2PRC | [P2PRC](P2PRC.html#v:runP2PRC "P2PRC") |
</div>
</div>
<div id="footer">
Produced by [Haddock](http://www.haskell.org/haddock/) version 2.29.2
</div>

View File

@@ -1,44 +0,0 @@
<div id="package-header">
<span class="caption">p2prc-0.1.0.0: P2PRC haskell library</span>
- [Contents](index.html)
- [Index](doc-index.html)
</div>
<div id="content">
<div id="description">
# p2prc-0.1.0.0: P2PRC haskell library
<div class="doc">
Implements a client interface to the P2PRC networking runtime
</div>
</div>
<div id="module-list">
Modules
<div id="module-list">
p2prc-0.1.0.0
- <span class="module"><span class="noexpander"> </span>[P2PRC](P2PRC.html)</span>
</div>
</div>
</div>
<div id="footer">
Produced by [Haddock](http://www.haskell.org/haddock/) version 2.29.2
</div>

Binary file not shown.

View File

@@ -1,22 +1,21 @@
{ nixpkgs ? import <nixpkgs> { } }:
{ pkgs ? (
let
inherit (builtins) fetchTree fromJSON readFile;
inherit ((fromJSON (readFile ./flake.lock)).nodes) nixpkgs gomod2nix;
in
import (fetchTree nixpkgs.locked) {
overlays = [
(import "${fetchTree gomod2nix.locked}/overlay.nix")
];
}
)
}:
let
pkgs = [
nixpkgs.go
nixpkgs.tmux
nixpkgs.docker
nixpkgs.vim
];
in
nixpkgs.stdenv.mkDerivation {
name = "env";
buildInputs = pkgs;
pure-eval = true;
shellHook =
''
make
export P2PRC=$PWD
export PATH=$PWD:$PATH
'';
}
pkgs.buildGoApplication {
pname = "p2p-rendering-computation";
version = "2.0.0";
pwd = ./.;
src = ./.;
modules = ./gomod2nix.toml;
doCheck = false;
}

View File

@@ -23,9 +23,8 @@
callPackage = pkgs.darwin.apple_sdk_11_0.callPackage or pkgs.callPackage;
in
{
packages.default = callPackage ./. {
inherit (gomod2nix.legacyPackages.${system}) buildGoApplication;
};
packages.default = callPackage ./. { };
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [

View File

@@ -1,9 +0,0 @@
#!/bin/bash
cabal haddock
rm -rf ../Docs/haskell
cp -r ./dist-newstyle/build/x86_64-linux/ghc-9.6.5/p2prc-0.1.0.0/doc/html/p2prc/ ../Docs/haskell

View File

@@ -1,151 +0,0 @@
module API
( P2PRCapi(..)
, MapPortRequest(..)
, getP2prcAPI
)
where
import System.Process ( ProcessHandle )
import Data.Aeson ( FromJSON )
import Error
( IOEitherError
)
import JSON
( IPAddressTable(..)
, MapPortResponse(..)
, P2prcConfig
)
import CLI
( StdInput(..)
, CLIOpt(..)
, eitherErrDecode
, getP2PrcCmd
, eitherExecProcess
, eitherExecProcessParser
, spawnProcP2Prc
)
import Environment ( cleanEnvironment )
-- | Lower level P2PRC Haskell api that exposes basic functionality necessary to joint the network.
data P2PRCapi
= MkP2PRCapi
{ startServer :: IOEitherError ProcessHandle
-- ^ Start server
, execInitConfig :: IOEitherError P2prcConfig
-- ^ Instantiate server configuration
, execListServers :: IOEitherError IPAddressTable
-- ^ List servers in network
, execMapPort :: MapPortRequest -> IOEitherError MapPortResponse
-- ^ Exposes and associates a local TCP port with a remote DNS address
}
-- | This defines the request required to create an association between a TCP socket port and a DNS server in the network. If successful, it makes a resource available in the network.
data MapPortRequest =
MkMapPortRequest -- ^ P2PRC's port allocation request value
Int -- ^ TCP socket number
String -- ^ Network domain name
{-|
This function cleans the previous running state (ensuring a pure P2PRC runtime state) and builds up a conditional 'P2PRCapi' instance.
==== __Example__
The following example show how this function can be used to expose the runtime functionalities:
@
example :: IOEitherError P2PRCapi
example = do
eitherP2prcAPI <- getP2prcAPI
case eitherP2prcAPI of
( Right
( MkP2PRCapi
{ startServer = startServer
, execInitConfig = execInitConfig
, execListServers = execListServers
, execMapPort = execMapPort
}
)) -> do
-- Your code logic
errValue -> errValue
@
-}
{-# WARNING getP2prcAPI "This function is currently unstable since it assumes that the Haskell program is executed from the P2PRC \"haskell\" subfolder and the \"p2prc\" executable in the the root folder." #-}
getP2prcAPI :: IOEitherError P2PRCapi
getP2prcAPI = do
cleanEnvironment
eitherP2prcCmd <- getP2PrcCmd
pure $ case eitherP2prcCmd of
(Right p2prcCmd) -> let
execProcP2PrcParser ::
FromJSON a =>
[CLIOpt] -> StdInput -> IOEitherError a
execProcP2PrcParser = eitherExecProcessParser p2prcCmd
-- TODO: GHC question, why does it scope down instead staying generic
execProcP2Prc = eitherExecProcess p2prcCmd
in do
Right $ MkP2PRCapi
{ startServer = spawnProcP2Prc p2prcCmd [ MkOptAtomic "--s" ]
, execListServers =
execProcP2PrcParser [ MkOptAtomic "--ls" ] MkEmptyStdInput
, execMapPort =
\ (MkMapPortRequest portNumber domainName) ->
execProcP2PrcParser
[ MkOptTuple
( "--mp"
, show portNumber
)
, MkOptTuple
( "--dn"
, domainName
)
]
MkEmptyStdInput
, execInitConfig = do
confInitRes <- execProcP2Prc [ MkOptAtomic "--dc" ] MkEmptyStdInput
case confInitRes of
(Right _) -> do
-- TODO: get config file name dynamically
-- TODO: change values before loading file
let fname = "/home/xecarlox/Desktop/p2p-rendering-computation/haskell/config.json" :: FilePath
-- TODO: read config check if file exists
configContent <- readFile fname
pure $ eitherErrDecode configContent
(Left err) -> pure $ Left err
}
(Left err) -> Left err

View File

@@ -1,57 +0,0 @@
module Environment
( cleanEnvironment
)
where
import System.Directory
( doesDirectoryExist
, doesFileExist
, removeDirectoryRecursive
, removeFile
)
import Control.Monad ( when )
cleanEnvironment :: IO ()
cleanEnvironment = do
mapM_ removeFileIfExists
[ "cert.pem"
, "config.json"
, "key.pem"
, "p2prc.privateKey"
, "p2prc.PublicKeyBareMetal"
]
mapM_ removeDirRIfExists
[ "client"
, "p2p"
, "plugin"
, "server"
]
where
removeIfExists
:: (FilePath -> IO Bool)
-> (FilePath -> IO ())
-> FilePath
-> IO ()
removeIfExists doesItExists rmIt filePath =
do
res <- doesItExists filePath
when res $ rmIt filePath
removeDirRIfExists =
removeIfExists
doesDirectoryExist
removeDirectoryRecursive
removeFileIfExists =
removeIfExists
doesFileExist
removeFile

View File

@@ -13,4 +13,4 @@ func TestServer_SpeedTest(t *testing.T) {
//HumaidTest("http://localhost:8088/50")
//HumaidTest("http://ipv4.download.thinkbroadband.com/50MB.zip")
}
}

View File

@@ -1,257 +1,257 @@
package plugin
import (
"fmt"
"github.com/Akilan1999/p2p-rendering-computation/client"
"github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
"net"
"strconv"
"testing"
)
// Test if the dummy plugin added is detected
func TestDetectPlugins(t *testing.T) {
_, err := DetectPlugins()
if err != nil {
t.Fail()
}
}
// Test ensures that the ansible are executed inside local containers
func TestRunPlugin(t *testing.T) {
var testips []*ExecuteIP
var testip1, testip2 ExecuteIP
// Create docker container and get SSH port
container1, err := docker.BuildRunContainer(0, "false", "")
if err != nil {
fmt.Println(err)
t.Fail()
}
//Test IP 1 configuration
testip1.IPAddress = "0.0.0.0"
testip1.SSHPortNo = strconv.Itoa(container1.Ports.PortSet[0].ExternalPort)
// Create docker container and get SSH port
container2, err := docker.BuildRunContainer(0, "false", "")
if err != nil {
fmt.Println(err)
t.Fail()
}
//Test IP 2 configuration
testip2.IPAddress = "0.0.0.0"
testip2.SSHPortNo = strconv.Itoa(container2.Ports.PortSet[0].ExternalPort)
testips = append(testips, &testip1)
testips = append(testips, &testip2)
_, err = RunPlugin("TestAnsible", testips)
if err != nil {
fmt.Println(err)
t.Fail()
}
// Removing container1 after Ansible is executed
err = docker.StopAndRemoveContainer(container1.ID)
if err != nil {
fmt.Println(err)
t.Fail()
}
err = docker.StopAndRemoveContainer(container2.ID)
if err != nil {
fmt.Println(err)
t.Fail()
}
}
// Test to ensure that the ansible host file is modified to
// the appropriate IP
func TestExecuteIP_ModifyHost(t *testing.T) {
var plugin Plugin
var testip ExecuteIP
// Get plugin path from config file
Config, err := config.ConfigInit(nil, nil)
if err != nil {
fmt.Println(err)
t.Fail()
}
//Set plugin name
plugin.FolderName = "TestAnsible"
plugin.path = Config.PluginPath
//Test IP 1 configuration
testip.IPAddress = "0.0.0.0"
testip.SSHPortNo = "41289"
err = testip.ModifyHost(&plugin)
if err != nil {
fmt.Println(err)
t.Fail()
}
}
// Test to ensure the cli function runs as intended and executes
// the test ansible script
func TestRunPluginContainer(t *testing.T) {
// Create docker container and get SSH port
container1, err := docker.BuildRunContainer(0, "false", "")
if err != nil {
fmt.Println(err)
t.Fail()
}
// Ensuring created container is the added to the tracked list
err = client.AddTrackContainer(container1, "0.0.0.0")
if err != nil {
fmt.Println(err)
t.Fail()
}
// Running test Ansible script
err = RunPluginContainer("TestAnsible", container1.ID)
if err != nil {
fmt.Println(err)
t.Fail()
}
// Removes container information from the tracker IP addresses
err = client.RemoveTrackedContainer(container1.ID)
if err != nil {
fmt.Println(err)
t.Fail()
}
// Removing container1 after Ansible is executed
err = docker.StopAndRemoveContainer(container1.ID)
if err != nil {
fmt.Println(err)
t.Fail()
}
}
// Testing the function can plugin can run with
// group ID and container ID
func TestCheckRunPlugin(t *testing.T) {
// Create docker container and get SSH port
container1, err := docker.BuildRunContainer(0, "false", "")
if err != nil {
fmt.Println(err)
t.Fail()
}
// Create docker container and get SSH port
container2, err := docker.BuildRunContainer(0, "false", "")
if err != nil {
fmt.Println(err)
t.Fail()
}
// Ensuring created container1 is the added to the tracked list
err = client.AddTrackContainer(container1, "0.0.0.0")
if err != nil {
fmt.Println(err)
t.Fail()
}
// Ensuring created container2 is the added to the tracked list
err = client.AddTrackContainer(container2, "0.0.0.0")
if err != nil {
fmt.Println(err)
t.Fail()
}
// Create group to add created containers
group, err := client.CreateGroup()
if err != nil {
fmt.Println(err)
t.Fail()
}
// Add container 1 to the group
_, err = client.AddContainerToGroup(container1.ID, group.ID)
if err != nil {
fmt.Println(err)
t.Fail()
}
// Add container 2 to the group
_, err = client.AddContainerToGroup(container2.ID, group.ID)
if err != nil {
fmt.Println(err)
t.Fail()
}
// -------------------------- Main test cases -------------------------------
// Checking function against container ID
err = CheckRunPlugin("TestAnsible", container1.ID)
if err != nil {
fmt.Println(err)
t.Fail()
}
// Checking function against group ID
err = CheckRunPlugin("TestAnsible", group.ID)
if err != nil {
fmt.Println(err)
t.Fail()
}
// ----------------------------------------------------------------------------
// Remove created group
err = client.RemoveGroup(group.ID)
if err != nil {
fmt.Println(err)
t.Fail()
}
// Removes container1 information from the tracker IP addresses
err = client.RemoveTrackedContainer(container1.ID)
if err != nil {
fmt.Println(err)
t.Fail()
}
// Removing container1 after Ansible is executed
err = docker.StopAndRemoveContainer(container1.ID)
if err != nil {
fmt.Println(err)
t.Fail()
}
// Removes container2 information from the tracker IP addresses
err = client.RemoveTrackedContainer(container2.ID)
if err != nil {
fmt.Println(err)
t.Fail()
}
// Removing container2 after Ansible is executed
err = docker.StopAndRemoveContainer(container2.ID)
if err != nil {
fmt.Println(err)
t.Fail()
}
}
func TestDownloadPlugin(t *testing.T) {
err := DownloadPlugin("https://github.com/Akilan1999/laplace/")
if err != nil {
}
}
// Simple test case implemented to the test if
// the port no can be extracted from the IP address.
func TestParseIP(t *testing.T) {
host, port, err := net.SplitHostPort("12.34.23.13:5432")
if err != nil {
fmt.Printf("Error: %v\n", err)
} else {
fmt.Printf("Host: %s\nPort: %s\n", host, port)
}
}
// import (
// "fmt"
// "github.com/Akilan1999/p2p-rendering-computation/client"
// "github.com/Akilan1999/p2p-rendering-computation/config"
// "github.com/Akilan1999/p2p-rendering-computation/server/docker"
// "net"
// "strconv"
// "testing"
// )
//
// // Test if the dummy plugin added is detected
// func TestDetectPlugins(t *testing.T) {
// _, err := DetectPlugins()
// if err != nil {
// t.Fail()
// }
// }
//
// // Test ensures that the ansible are executed inside local containers
// func TestRunPlugin(t *testing.T) {
// var testips []*ExecuteIP
// var testip1, testip2 ExecuteIP
//
// // Create docker container and get SSH port
// container1, err := docker.BuildRunContainer(0, "false", "")
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// //Test IP 1 configuration
// testip1.IPAddress = "0.0.0.0"
// testip1.SSHPortNo = strconv.Itoa(container1.Ports.PortSet[0].ExternalPort)
//
// // Create docker container and get SSH port
// container2, err := docker.BuildRunContainer(0, "false", "")
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
// //Test IP 2 configuration
// testip2.IPAddress = "0.0.0.0"
// testip2.SSHPortNo = strconv.Itoa(container2.Ports.PortSet[0].ExternalPort)
//
// testips = append(testips, &testip1)
// testips = append(testips, &testip2)
//
// _, err = RunPlugin("TestAnsible", testips)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // Removing container1 after Ansible is executed
// err = docker.StopAndRemoveContainer(container1.ID)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// err = docker.StopAndRemoveContainer(container2.ID)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
// }
//
// // Test to ensure that the ansible host file is modified to
// // the appropriate IP
// func TestExecuteIP_ModifyHost(t *testing.T) {
// var plugin Plugin
// var testip ExecuteIP
//
// // Get plugin path from config file
// Config, err := config.ConfigInit(nil, nil)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
// //Set plugin name
// plugin.FolderName = "TestAnsible"
// plugin.path = Config.PluginPath
//
// //Test IP 1 configuration
// testip.IPAddress = "0.0.0.0"
// testip.SSHPortNo = "41289"
//
// err = testip.ModifyHost(&plugin)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
// }
//
// // Test to ensure the cli function runs as intended and executes
// // the test ansible script
// func TestRunPluginContainer(t *testing.T) {
// // Create docker container and get SSH port
// container1, err := docker.BuildRunContainer(0, "false", "")
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // Ensuring created container is the added to the tracked list
// err = client.AddTrackContainer(container1, "0.0.0.0")
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // Running test Ansible script
// err = RunPluginContainer("TestAnsible", container1.ID)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // Removes container information from the tracker IP addresses
// err = client.RemoveTrackedContainer(container1.ID)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // Removing container1 after Ansible is executed
// err = docker.StopAndRemoveContainer(container1.ID)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
// }
//
// // Testing the function can plugin can run with
// // group ID and container ID
// func TestCheckRunPlugin(t *testing.T) {
// // Create docker container and get SSH port
// container1, err := docker.BuildRunContainer(0, "false", "")
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
// // Create docker container and get SSH port
// container2, err := docker.BuildRunContainer(0, "false", "")
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // Ensuring created container1 is the added to the tracked list
// err = client.AddTrackContainer(container1, "0.0.0.0")
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
// // Ensuring created container2 is the added to the tracked list
// err = client.AddTrackContainer(container2, "0.0.0.0")
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // Create group to add created containers
// group, err := client.CreateGroup()
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // Add container 1 to the group
// _, err = client.AddContainerToGroup(container1.ID, group.ID)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // Add container 2 to the group
// _, err = client.AddContainerToGroup(container2.ID, group.ID)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // -------------------------- Main test cases -------------------------------
//
// // Checking function against container ID
// err = CheckRunPlugin("TestAnsible", container1.ID)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // Checking function against group ID
// err = CheckRunPlugin("TestAnsible", group.ID)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // ----------------------------------------------------------------------------
//
// // Remove created group
// err = client.RemoveGroup(group.ID)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // Removes container1 information from the tracker IP addresses
// err = client.RemoveTrackedContainer(container1.ID)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // Removing container1 after Ansible is executed
// err = docker.StopAndRemoveContainer(container1.ID)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // Removes container2 information from the tracker IP addresses
// err = client.RemoveTrackedContainer(container2.ID)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// // Removing container2 after Ansible is executed
// err = docker.StopAndRemoveContainer(container2.ID)
// if err != nil {
// fmt.Println(err)
// t.Fail()
// }
//
// }
//
// func TestDownloadPlugin(t *testing.T) {
// err := DownloadPlugin("https://github.com/Akilan1999/laplace/")
// if err != nil {
//
// }
// }
//
// // Simple test case implemented to the test if
// // the port no can be extracted from the IP address.
// func TestParseIP(t *testing.T) {
// host, port, err := net.SplitHostPort("12.34.23.13:5432")
// if err != nil {
// fmt.Printf("Error: %v\n", err)
// } else {
// fmt.Printf("Host: %s\nPort: %s\n", host, port)
// }
// }

View File

@@ -1,42 +1,42 @@
package docker
import (
"testing"
)
func TestDockerUbuntuSSHDProvided(t *testing.T) {
// Testing by providing default container name
_,err := BuildRunContainer(2,"false","docker-ubuntu-sshd")
if err != nil {
t.Error(err)
}
}
func TestDockerDefaultContainer(t *testing.T) {
// Testing by providing without providing default container name
_,err := BuildRunContainer(2,"false","")
if err != nil {
t.Error(err)
}
}
func TestContainerHorovod(t *testing.T) {
// Testing by providing the horovod cpu image
_,err := BuildRunContainer(2,"false","cpuhorovod")
if err != nil {
t.Error(err)
}
}
func TestViewAllContainers(t *testing.T) {
_,err := ViewAllContainers()
if err != nil {
t.Error(err)
}
}
// import (
// "testing"
// )
//
// func TestDockerUbuntuSSHDProvided(t *testing.T) {
// // Testing by providing default container name
// _,err := BuildRunContainer(2,"false","docker-ubuntu-sshd")
//
// if err != nil {
// t.Error(err)
// }
//
// }
//
// func TestDockerDefaultContainer(t *testing.T) {
// // Testing by providing without providing default container name
// _,err := BuildRunContainer(2,"false","")
//
// if err != nil {
// t.Error(err)
// }
// }
//
// func TestContainerHorovod(t *testing.T) {
// // Testing by providing the horovod cpu image
// _,err := BuildRunContainer(2,"false","cpuhorovod")
//
// if err != nil {
// t.Error(err)
// }
// }
//
// func TestViewAllContainers(t *testing.T) {
// _,err := ViewAllContainers()
//
// if err != nil {
// t.Error(err)
// }
//
// }

View File

@@ -16,9 +16,9 @@
let
goEnv = mkGoEnv { pwd = ./.; };
in
pkgs.mkShell {
packages = [
goEnv
gomod2nix
];
pkgs.mkShell {
packages = [
goEnv
gomod2nix
];
}