Skip to content

Commit

Permalink
Merge pull request #124 from yetanalytics/cli-server-tests
Browse files Browse the repository at this point in the history
CLI server tests
  • Loading branch information
kelvinqian00 authored Nov 9, 2023
2 parents 5ebac8a + 1915187 commit 33b2325
Show file tree
Hide file tree
Showing 13 changed files with 347 additions and 141 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ jobs:
- name: Setup CI environment
uses: yetanalytics/actions/[email protected]

- name: Log into DockerHub
if: ${{ matrix.target == 'test-unit' }}
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Run Makefile Target ${{ matrix.target }}
run: make ${{ matrix.target }}

Expand Down
12 changes: 6 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,19 @@ bundle: target/bundle
# Tests

test-unit:
clojure -Adev:cli:run-tests
clojure -Adev:cli:server:test:run-test

test-unit-onyx:
clojure -Adev:cli:onyx:run-onyx-tests
clojure -Adev:cli:onyx:onyx-test:run-onyx-test

test-cli:
clojure -A:cli:run validate-input -p dev-resources/profiles/cmi5/fixed.json -a dev-resources/personae/simple.json -m dev-resources/models/simple.json -o dev-resources/parameters/simple.json -v dev-resources/input/simple.json
clojure -A:cli:run-cli validate-input -p dev-resources/profiles/cmi5/fixed.json -a dev-resources/personae/simple.json -m dev-resources/models/simple.json -o dev-resources/parameters/simple.json -v dev-resources/input/simple.json

test-cli-comprehensive:
clojure -A:cli:run validate-input -i dev-resources/input/simple.json -v dev-resources/input/simple.json
clojure -A:cli:run-cli validate-input -i dev-resources/input/simple.json -v dev-resources/input/simple.json

test-cli-output:
clojure -A:cli:run generate -i dev-resources/input/simple.json
clojure -A:cli:run-cli generate -i dev-resources/input/simple.json

test-bundle-output: bundle
cd target/bundle; bin/run.sh generate -i ../../dev-resources/input/simple.json
Expand All @@ -63,4 +63,4 @@ validate-template:
ci: test-unit test-unit-onyx test-cli validate-template

server:
clojure -A:server
clojure -A:server:run-server
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,13 +303,13 @@ By default the server starts at http://localhost:9090

The API is configurable with the following runtime environment variables:

| Variable | Default | Notes | Example |
|---------------------|--------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------|-------------------|
| CREDENTIALS | <none> | Basic Authentication credentials required to call the API endpoints in the form of `username:password` | `datasim:datasim` |
| API_ROOT_PATH | <none> | Root path to prefix API routes. Must begin with a `/`, cannot end with a `/`. | `/foo` |
| API_HOST | `0.0.0.0` | Host on which to bind the API server. | `localhost` |
| API_PORT | `9090` | Port on which to bind the API server. | `8080` |
| API_ALLOWED_ORIGINS | <details>`https://yetanalytics.github.io,http://localhost:9091`<summary>(URLs)</summary></details> | CORS allowed origins for the API server, separated by commas. | `*` |
| Variable | Default | Notes | Example |
|---|---|---|---|
| CREDENTIALS | `username:password` | Basic Authentication credentials required to call the API endpoints in the form of `username:password` | `datasim:datasim` |
| API_ROOT_PATH | <none> | Root path to prefix API routes. Must begin with a `/`, cannot end with a `/`. | `/foo` |
| API_HOST | `0.0.0.0`| Host on which to bind the API server. | `localhost` |
| API_PORT | `9090` | Port on which to bind the API server. | `8080` |
| API_ALLOWED_ORIGINS | <details>`https://yetanalytics.github.io,http://localhost:9091`<summary>(URLs)</summary></details> | CORS allowed origins for the API server, separated by commas. | `*` |

Currently defaults are configured to work with the default settings in the DATASIM-UI project locally.

Expand Down
146 changes: 61 additions & 85 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -16,91 +16,67 @@
http-kit/http-kit {:mvn/version "2.7.0"}
cheshire/cheshire {:mvn/version "5.11.0"}}
:aliases
{:cli {:extra-paths ["src/cli"]
:extra-deps {org.clojure/tools.cli {:mvn/version "1.0.219"}}}
;; TODO: More CLI-specific name for :run alias
:run {:main-opts ["-m" "com.yetanalytics.datasim.cli"]}
:dev {:extra-paths ["dev-resources" "src/dev"]
:extra-deps {incanter/incanter-core {:mvn/version "1.9.3"}
incanter/incanter-charts {:mvn/version "1.9.3"}
criterium/criterium {:mvn/version "0.4.5"}}}
:test {:extra-paths ["src/test" "src/test_onyx"]
:extra-deps {same/ish {:mvn/version "0.1.6"}}}
:run-tests
{:extra-paths ["src/test"]
:extra-deps {same/ish {:mvn/version "0.1.6"}
io.github.cognitect-labs/test-runner {:git/tag "v0.5.1"
:git/sha "dfb30dd"}}
:main-opts ["-m" "cognitect.test-runner"
"-d" "src/test"]}
:run-onyx-tests
{:extra-paths ["src/test_onyx"]
:extra-deps {io.github.cognitect-labs/test-runner {:git/tag "v0.5.1"
:git/sha "dfb30dd"}}
:main-opts ["-m" "cognitect.test-runner"
"-d" "src/test_onyx"]}
:server
{:extra-paths ["src/server"]
:extra-deps
{;; Jetty deps - need to exclude and use v9.4.52 due to CVEs
io.pedestal/pedestal.jetty
{:mvn/version "0.6.0"
:exclusions [org.eclipse.jetty/jetty-server
org.eclipse.jetty/jetty-servlet
org.eclipse.jetty.alpn/alpn-api
org.eclipse.jetty/jetty-alpn-server
org.eclipse.jetty.http2/http2-server
org.eclipse.jetty.websocket/websocket-api
org.eclipse.jetty.websocket/websocket-servlet
org.eclipse.jetty.websocket/websocket-server]}
org.eclipse.jetty/jetty-server {:mvn/version "9.4.52.v20230823"}
org.eclipse.jetty/jetty-servlet {:mvn/version "9.4.52.v20230823"}
org.eclipse.jetty.alpn/alpn-api {:mvn/version "1.1.3.v20160715"}
org.eclipse.jetty/jetty-alpn-server {:mvn/version "9.4.52.v20230823"}
org.eclipse.jetty.http2/http2-server {:mvn/version "9.4.52.v20230823"}
;; Other server deps
io.pedestal/pedestal.service {:mvn/version "0.6.0"}
org.slf4j/slf4j-simple {:mvn/version "1.7.28"}
clj-http/clj-http {:mvn/version "3.12.3"}
environ/environ {:mvn/version "1.1.0"}
;; Buddy/BouncyCastle deps
buddy/buddy-auth {:mvn/version "3.0.323"
:exclusions [cheshire/cheshire
buddy/buddy-sign]}
buddy/buddy-sign {:mvn/version "3.5.346"
:exclusions [org.bouncycastle/bcprov-jdk18on]}
org.bouncycastle/bcprov-jdk18on {:mvn/version "1.75"}}
:main-opts ["-m" "com.yetanalytics.datasim.server"]}
:onyx
{:extra-paths ["onyx-resources" "src/onyx"]
:extra-deps {com.amazonaws/aws-java-sdk-s3 {:mvn/version "1.11.899"}
com.amazonaws/aws-java-sdk-core {:mvn/version "1.11.899"}
org.onyxplatform/onyx {:mvn/version "0.14.6"
:exclusions
;; TODO: More exclusions probably
[org.clojure/clojure
org.clojure/core.async
org.slf4j/slf4j-nop
com.amazonaws/aws-java-sdk-s3]}
aleph/aleph {:mvn/version "0.4.7-alpha7"}
com.fzakaria/slf4j-timbre {:mvn/version "0.3.20"}
org.onyxplatform/lib-onyx {:mvn/version "0.14.1.0"}
org.onyxplatform/onyx-http {:mvn/version "0.14.5.0"
:exclusions [aleph/aleph
io.netty/netty-all]}
;; for local repl
com.bhauman/rebel-readline {:mvn/version "0.1.4"}
;; for remote repl
nrepl/nrepl {:mvn/version "0.8.3"}
cider/cider-nrepl {:mvn/version "0.25.6"}
org.onyxplatform/onyx-peer-http-query {:mvn/version "0.14.5.1-SNAPSHOT"}
org.onyxplatform/onyx-amazon-s3 {:mvn/version "0.14.5.0"
:exclusions [org.clojure/clojure
org.onyxplatform/onyx
com.amazonaws/aws-java-sdk-s3]}}}
:onyx-dev
{:extra-paths ["src/onyx_dev"]}

{:dev {:extra-paths ["dev-resources" "src/dev"]
:extra-deps {incanter/incanter-core {:mvn/version "1.9.3"}
incanter/incanter-charts {:mvn/version "1.9.3"}
criterium/criterium {:mvn/version "0.4.5"}}}
:test {:extra-paths ["src/test" "src/test_onyx"]
:extra-deps {same/ish {:mvn/version "0.1.6"}
clj-test-containers/clj-test-containers {:mvn/version "0.7.4"}}}
:run-test {:extra-deps {io.github.cognitect-labs/test-runner {:git/tag "v0.5.1"
:git/sha "dfb30dd"}}
:main-opts ["-m" "cognitect.test-runner"
"-d" "src/test"]}
:cli {:extra-paths ["src/cli"]
:extra-deps {org.clojure/tools.cli {:mvn/version "1.0.219"}}}
:run-cli {:main-opts ["-m" "com.yetanalytics.datasim.cli"]}
:server {:extra-paths ["src/server"]
:extra-deps
{io.pedestal/pedestal.jetty {:mvn/version "0.6.1"}
io.pedestal/pedestal.service {:mvn/version "0.6.0"}
org.slf4j/slf4j-simple {:mvn/version "1.7.28"}
clj-http/clj-http {:mvn/version "3.12.3"}
environ/environ {:mvn/version "1.1.0"}
;; Buddy/BouncyCastle deps
buddy/buddy-auth {:mvn/version "3.0.323"
:exclusions [cheshire/cheshire
buddy/buddy-sign]}
buddy/buddy-sign {:mvn/version "3.5.346"
:exclusions [org.bouncycastle/bcprov-jdk18on]}
org.bouncycastle/bcprov-jdk18on {:mvn/version "1.75"}}}
:run-server {:main-opts ["-m" "com.yetanalytics.datasim.server"]}
:onyx {:extra-paths ["onyx-resources" "src/onyx"]
:extra-deps {com.amazonaws/aws-java-sdk-s3 {:mvn/version "1.11.899"}
com.amazonaws/aws-java-sdk-core {:mvn/version "1.11.899"}
org.onyxplatform/onyx {:mvn/version "0.14.6"
:exclusions
;; TODO: More exclusions probably
[org.clojure/clojure
org.clojure/core.async
org.slf4j/slf4j-nop
com.amazonaws/aws-java-sdk-s3]}
aleph/aleph {:mvn/version "0.4.7-alpha7"}
com.fzakaria/slf4j-timbre {:mvn/version "0.3.20"}
org.onyxplatform/lib-onyx {:mvn/version "0.14.1.0"}
org.onyxplatform/onyx-http {:mvn/version "0.14.5.0"
:exclusions [aleph/aleph
io.netty/netty-all]}
;; for local repl
com.bhauman/rebel-readline {:mvn/version "0.1.4"}
;; for remote repl
nrepl/nrepl {:mvn/version "0.8.3"}
cider/cider-nrepl {:mvn/version "0.25.6"}
org.onyxplatform/onyx-peer-http-query {:mvn/version "0.14.5.1-SNAPSHOT"}
org.onyxplatform/onyx-amazon-s3 {:mvn/version "0.14.5.0"
:exclusions [org.clojure/clojure
org.onyxplatform/onyx
com.amazonaws/aws-java-sdk-s3]}}}
:onyx-dev {:extra-paths ["src/onyx_dev"]}
:onyx-test {:extra-paths ["src/test_onyx"]}
:run-onyx-test {:extra-deps {io.github.cognitect-labs/test-runner {:git/tag "v0.5.1"
:git/sha "dfb30dd"}}
:main-opts ["-m" "cognitect.test-runner"
"-d" "src/test_onyx"]}
:depstar {:replace-deps ; tool usage is new in 2.x
{seancorfield/depstar {:mvn/version "2.0.165"}}
:ns-default hf.depstar
Expand Down
12 changes: 7 additions & 5 deletions src/cli/com/yetanalytics/datasim/cli.clj
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
(not subcommand)
(print "No subcommand entered.\n\n" summary)
:else
(case subcommand
"validate-input" (cli-input/validate-input rest-args)
"generate" (cli-gen/generate rest-args)
"generate-post" (cli-gen/generate-post rest-args)
(u/bail! errors)))))
(let [results (case subcommand
"validate-input" (cli-input/validate-input! rest-args)
"generate" (cli-gen/generate! rest-args)
"generate-post" (cli-gen/generate-post! rest-args)
(u/bail! errors))]
(when-some [errors (:errors results)]
(u/bail! errors))))))
21 changes: 12 additions & 9 deletions src/cli/com/yetanalytics/datasim/cli/generate.clj
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
(case tag
:fail
(let [{:keys [status error]} ret]
(u/bail! [(client/post-error-message status error)]))
{:errors [(client/post-error-message status error)]})
:success
(do
(dio/println-coll ret) ; Statement ID strings
Expand All @@ -145,8 +145,9 @@
(take post-limit))
{:keys [fail]} (client/post-statements post-options statements)]
(when (not-empty fail)
(u/bail! (for [{:keys [status error]} fail]
(client/post-error-message status error))))))
{:errors (map (fn [{:keys [status error]}]
(client/post-error-message status error))
fail)})))

(defn- post-sim!
[input options]
Expand All @@ -172,7 +173,7 @@
;; Subcommands
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn generate
(defn generate!
"Generate statements based on simulation `args` and print them to stdout."
[args]
(u/exec-subcommand
Expand All @@ -181,11 +182,12 @@
[["-h" "--help"]])
(fn [options]
(let [input (cli-input/sim-input options)]
(cli-input/assert-valid-input input)
(print-sim! input options)))
(if-some [errors (cli-input/validate-input* input)]
{:errors errors}
(print-sim! input options))))
args))

(defn generate-post
(defn generate-post!
"Generate statements based on simulation `args` and POST them to an LRS
(whose endpoint and other properties are also in `args`)."
[args]
Expand All @@ -196,6 +198,7 @@
[["-h" "--help"]])
(fn [options]
(let [input (cli-input/sim-input options)]
(cli-input/assert-valid-input input)
(post-sim! input options)))
(if-some [errors (cli-input/validate-input* input)]
{:errors errors}
(post-sim! input options))))
args))
15 changes: 8 additions & 7 deletions src/cli/com/yetanalytics/datasim/cli/input.clj
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
(random/rand-unbound-int (random/rng))
override-seed)))))

(defn assert-valid-input
(defn validate-input*
"Perform validation on `input` and fail w/ early termination if
it is not valid.
Expand All @@ -122,7 +122,7 @@
comprehensive spec from the options and check that."
[input]
(when-let [errors (not-empty (input/validate :input input))]
(u/bail! (errors/map-coll->strs errors))))
(errors/map-coll->strs errors)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Subcommand
Expand All @@ -135,7 +135,7 @@
(input/to-file input :json location)
(println (format "Input specification written to %s" location))))

(defn validate-input
(defn validate-input!
"Combine and validate the arguments given in `args` and write them
to `location` (if `location` is provided)."
[args]
Expand All @@ -144,8 +144,9 @@
["-h" "--help"])
(fn [{:keys [validated-input] :as options}]
(let [input (sim-input options)]
(assert-valid-input input)
(if validated-input
(write-input! input validated-input)
(write-input! input))))
(if-some [errors (validate-input* input)]
{:errors errors}
(if validated-input
(write-input! input validated-input)
(write-input! input)))))
args))
6 changes: 3 additions & 3 deletions src/main/com/yetanalytics/datasim/client.clj
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,8 @@
(if-let [batch (first batches)]
(let [{:keys [status body] :as response}
@(post-batch endpoint http-options batch)]
(if (= 200 status)
(if (<= 200 status 299)
;; Success!
;; FIXME: Shouldn't other codes like 204 be supported?
(let [statement-ids (decode-body body)]
(when print-ids?
(dio/println-coll statement-ids))
Expand Down Expand Up @@ -104,7 +103,8 @@
in-chan (a/chan buffer-in (partition-all batch-size))
out-chan (a/chan buffer-out) ; is this.. backpressure?
callback (fn [port {:keys [status body error] :as ret}]
(if (or (not= 200 status) error)
(if (or (not (<= 200 status 299))
error)
;; Error: Stop further processing
(do
(swap! run? not)
Expand Down
7 changes: 5 additions & 2 deletions src/main/com/yetanalytics/datasim/input.clj
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@
(defmethod validate :default [type-k _]
(throw-unknown-key type-k))

(defmethod validate :input
[_ {:keys [profiles personae-array models parameters] :as input}]
(defn- validate-input
[{:keys [profiles personae-array models parameters] :as input}]
(-> (concat (profile/validate-profiles profiles)
(personae/validate-personae-array personae-array)
(models/validate-models models)
Expand All @@ -151,6 +151,9 @@
vec
not-empty))

(defmethod validate :input [_ input]
(validate-input input))

(defmethod validate :profile [_ profile]
(profile/validate-profile profile))

Expand Down
Loading

0 comments on commit 33b2325

Please sign in to comment.