Skip to content

Commit 45a4744

Browse files
committed
Test in docker, simplify sig parity
1 parent 28060df commit 45a4744

File tree

9 files changed

+219
-110
lines changed

9 files changed

+219
-110
lines changed

.dockerignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.git
2+
.gitignore
3+
.docker-cache
4+
.bundle
5+
coverage
6+
pkg
7+
node_modules
8+
vendor/bundle
9+
.env

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ transloadit-*.gem
1515
env.sh
1616
.env
1717
vendor/bundle/
18+
.docker-cache/

Dockerfile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# syntax=docker/dockerfile:1
2+
3+
FROM ruby:3.3 AS base
4+
5+
RUN apt-get update \
6+
&& apt-get install -y --no-install-recommends \
7+
build-essential \
8+
git \
9+
curl \
10+
ca-certificates \
11+
&& rm -rf /var/lib/apt/lists/*
12+
13+
# Install Node.js for parity checks
14+
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
15+
&& apt-get install -y --no-install-recommends nodejs \
16+
&& npm install -g npm@latest \
17+
&& rm -rf /var/lib/apt/lists/*
18+
19+
WORKDIR /workspace

README.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,18 +476,45 @@ bundle install
476476
bundle exec rake test
477477
```
478478

479-
To also test parity against the Node.js reference implementation, run:
479+
To also test parity against the Node.js reference implementation, ensure you can run `npx transloadit smart_sig` and `npx transloadit sig` (the CLI downloads on demand), then run:
480480

481481
```bash
482482
TEST_NODE_PARITY=1 bundle exec rake test
483483
```
484484

485+
You can warm the CLI cache ahead of time with:
486+
487+
```bash
488+
TRANSLOADIT_KEY=... TRANSLOADIT_SECRET=... \
489+
npx --yes transloadit smart_sig --help
490+
TRANSLOADIT_KEY=... TRANSLOADIT_SECRET=... \
491+
npx --yes transloadit sig --algorithm sha384 --help
492+
```
493+
485494
To disable coverage reporting, run:
486495

487496
```bash
488497
COVERAGE=0 bundle exec rake test
489498
```
490499

500+
#### Run tests in Docker
501+
502+
```bash
503+
./scripts/test-in-docker.sh
504+
```
505+
506+
This builds a local image, runs `bundle install`, and executes `bundle exec rake test`. Pass a custom command to run something else (Bundler still installs first):
507+
508+
```bash
509+
./scripts/test-in-docker.sh bundle exec ruby -Itest test/unit/transloadit/test_request.rb
510+
```
511+
512+
The script forwards environment variables such as `TEST_NODE_PARITY` or credentials defined in `.env`, so you can combine parity checks and integration tests inside Docker:
513+
514+
```bash
515+
TEST_NODE_PARITY=1 ./scripts/test-in-docker.sh
516+
```
517+
491518
### Releasing on RubyGems
492519

493520
Let's say you wanted to release version `3.1.0`, here are the steps:

scripts/test-in-docker.sh

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
IMAGE_NAME=${IMAGE_NAME:-transloadit-ruby-sdk-dev}
5+
CACHE_DIR=.docker-cache
6+
7+
ensure_docker() {
8+
if ! command -v docker >/dev/null 2>&1; then
9+
echo "Docker is required to run this script." >&2
10+
exit 1
11+
fi
12+
13+
if ! docker info >/dev/null 2>&1; then
14+
if [[ -z "${DOCKER_HOST:-}" && -S "$HOME/.colima/default/docker.sock" ]]; then
15+
export DOCKER_HOST="unix://$HOME/.colima/default/docker.sock"
16+
fi
17+
fi
18+
19+
if ! docker info >/dev/null 2>&1; then
20+
echo "Docker daemon is not reachable. Start Docker (or Colima) and retry." >&2
21+
exit 1
22+
fi
23+
}
24+
25+
configure_platform() {
26+
if [[ -z "${DOCKER_PLATFORM:-}" ]]; then
27+
local arch
28+
arch=$(uname -m)
29+
if [[ "$arch" == "arm64" || "$arch" == "aarch64" ]]; then
30+
DOCKER_PLATFORM=linux/amd64
31+
fi
32+
fi
33+
}
34+
35+
ensure_docker
36+
configure_platform
37+
38+
if [[ $# -eq 0 ]]; then
39+
RUN_CMD='set -e; bundle install --jobs 4 --retry 3; bundle exec rake test'
40+
else
41+
printf -v USER_CMD '%q ' "$@"
42+
RUN_CMD="set -e; bundle install --jobs 4 --retry 3; ${USER_CMD}"
43+
fi
44+
45+
mkdir -p "$CACHE_DIR/bundle" "$CACHE_DIR/npm-cache"
46+
47+
BUILD_ARGS=()
48+
if [[ -n "${DOCKER_PLATFORM:-}" ]]; then
49+
BUILD_ARGS+=(--platform "$DOCKER_PLATFORM")
50+
fi
51+
BUILD_ARGS+=(-t "$IMAGE_NAME" -f Dockerfile .)
52+
53+
docker build "${BUILD_ARGS[@]}"
54+
55+
DOCKER_ARGS=(
56+
--rm
57+
--user "$(id -u):$(id -g)"
58+
-e HOME=/workspace
59+
-e BUNDLE_PATH=/workspace/$CACHE_DIR/bundle
60+
-e BUNDLE_APP_CONFIG=/workspace/$CACHE_DIR/bundle-config
61+
-e BUNDLE_CACHE_PATH=/workspace/$CACHE_DIR/bundle-cache
62+
-e npm_config_cache=/workspace/$CACHE_DIR/npm-cache
63+
-e TEST_NODE_PARITY="${TEST_NODE_PARITY:-0}"
64+
-v "$PWD":/workspace
65+
-w /workspace
66+
)
67+
68+
if [[ -n "${DOCKER_PLATFORM:-}" ]]; then
69+
DOCKER_ARGS+=(--platform "$DOCKER_PLATFORM")
70+
fi
71+
72+
if [[ -f .env ]]; then
73+
DOCKER_ARGS+=(--env-file "$PWD/.env")
74+
fi
75+
76+
exec docker run "${DOCKER_ARGS[@]}" "$IMAGE_NAME" bash -lc "$RUN_CMD"

test/test_helper.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
require "minitest/autorun"
1616
require "transloadit"
1717
require "vcr"
18+
require "open3"
19+
require "json"
1820

1921
VCR.configure do |c|
2022
c.cassette_library_dir = "test/fixtures/cassettes"
@@ -25,3 +27,49 @@
2527
def values_from_post_body(body)
2628
Addressable::URI.parse("?" + CGI.unescape(body)).query_values
2729
end
30+
31+
module TransloaditCliHelpers
32+
TRANSLOADIT_CLI_PACKAGE = ENV.fetch("TRANSLOADIT_CLI_PACKAGE", "[email protected]")
33+
34+
def run_transloadit_cli(command, payload, key:, secret:, algorithm: nil)
35+
return nil unless ENV["TEST_NODE_PARITY"] == "1"
36+
37+
env = {
38+
"TRANSLOADIT_KEY" => key,
39+
"TRANSLOADIT_SECRET" => secret,
40+
"TRANSLOADIT_AUTH_KEY" => key,
41+
"TRANSLOADIT_AUTH_SECRET" => secret
42+
}
43+
44+
args = [
45+
"npm", "exec", "--yes", "--package", TRANSLOADIT_CLI_PACKAGE, "--",
46+
"transloadit", command
47+
]
48+
args += ["--algorithm", algorithm] if algorithm
49+
50+
stdout, stderr, status = Open3.capture3(env, *args, stdin_data: JSON.dump(payload))
51+
raise "transloadit CLI #{command} failed: #{stderr}" unless status.success?
52+
53+
stdout.strip
54+
end
55+
56+
def run_transloadit_smart_sig(payload, key:, secret:)
57+
cli_payload = {
58+
workspace: payload.fetch(:workspace),
59+
template: payload.fetch(:template),
60+
input: payload.fetch(:input)
61+
}
62+
cli_payload[:url_params] = payload[:url_params] if payload.key?(:url_params)
63+
cli_payload[:expire_at_ms] = payload[:expire_at_ms] if payload.key?(:expire_at_ms)
64+
65+
run_transloadit_cli("smart_sig", cli_payload, key: key, secret: secret)
66+
end
67+
68+
def run_transloadit_sig(payload, key:, secret:, algorithm: nil)
69+
output = run_transloadit_cli("sig", payload, key: key, secret: secret, algorithm: algorithm)
70+
output && JSON.parse(output)
71+
end
72+
end
73+
74+
Minitest::Test.include(TransloaditCliHelpers)
75+

test/unit/transloadit/node-smartcdn-sig.ts

Lines changed: 0 additions & 89 deletions
This file was deleted.

test/unit/transloadit/test_request.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require "test_helper"
2+
require "multi_json"
23

34
describe Transloadit::Request do
45
it "must allow initialization" do
@@ -76,3 +77,30 @@
7677
end
7778
end
7879
end
80+
81+
describe "signature parity" do
82+
it "matches transloadit CLI sig output" do
83+
skip "Parity testing not enabled" unless ENV["TEST_NODE_PARITY"] == "1"
84+
85+
expires = "2025-01-02T00:00:00.000Z"
86+
params = {
87+
auth: {key: "cli-key", expires: expires},
88+
steps: {encode: {robot: "/video/encode"}}
89+
}
90+
91+
cli_result = run_transloadit_sig(params, key: "cli-key", secret: "cli-secret", algorithm: "sha384")
92+
refute_nil cli_result
93+
94+
cli_params_json = cli_result["params"]
95+
request = Transloadit::Request.new("/", "cli-secret")
96+
ruby_signature = request.send(:signature, cli_params_json)
97+
98+
assert_equal cli_result["signature"], ruby_signature
99+
100+
cli_params = JSON.parse(cli_params_json)
101+
assert_equal "cli-key", cli_params.dig("auth", "key")
102+
assert_equal expires, cli_params.dig("auth", "expires")
103+
assert_equal "/video/encode", cli_params.dig("steps", "encode", "robot")
104+
end
105+
end
106+

0 commit comments

Comments
 (0)