Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/license_check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

name: "Run License Check"

on:
push:
branches:
- main
pull_request:

concurrency:
group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{ github.workflow }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

permissions:
contents: read

jobs:
rat:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- run: |
dev/check-license
66 changes: 66 additions & 0 deletions .github/workflows/validate-fixtures.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

name: "Validate Fixtures"

on:
push:
branches:
- main
pull_request:

concurrency:
group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{ github.workflow }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

permissions:
contents: read

jobs:
validate:
name: Validate fixture cases
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: '3.12'
- name: Install validator deps
run: python3 -m pip install -r dev/requirements.txt
- name: Validate cases.json
run: python3 dev/validate-fixtures.py
Comment thread
nssalian marked this conversation as resolved.
- name: Validator rejects malformed fixtures (self-test)
run: |
Comment thread
nssalian marked this conversation as resolved.
set -e
assert_reject() { # <desc> <cases-json>
d="$(mktemp -d)"
mkdir -p "$d/table-spec/types/x"
printf '%s' "$2" > "$d/table-spec/types/x/cases.json"
test -f "$d/table-spec/types/x/cases.json"
if python3 dev/validate-fixtures.py "$d" >/dev/null 2>&1; then
echo "self-test FAILED: validator accepted a malformed fixture ($1)"; exit 1
fi
echo "self-test ok: rejected ($1)"
rm -rf "$d"
}
assert_reject "valid:true with no decoded" '{"cases":[{"id":"a","valid":true,"input":"int","clause":"c","spec_ref":"s"}]}'
assert_reject "valid:false carrying decoded" '{"cases":[{"id":"a","valid":false,"input":"bad","decoded":{"type":"int"},"clause":"c","spec_ref":"s"}]}'
assert_reject "unknown property" '{"cases":[{"id":"a","valid":true,"input":"int","decoded":{"type":"int"},"clause":"c","spec_ref":"s","spec-ref":"typo"}]}'
assert_reject "duplicate id in a surface" '{"cases":[{"id":"a","valid":true,"input":"int","decoded":{"type":"int"},"clause":"c","spec_ref":"s"},{"id":"a","valid":true,"input":"long","decoded":{"type":"long"},"clause":"c","spec_ref":"s"}]}'
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,10 @@
*~
.idea/
.vscode/

# Apache RAT jar downloaded by dev/check-license
/lib/

# Python
__pycache__/
*.py[cod]
26 changes: 26 additions & 0 deletions dev/.rat-excludes
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

.gitignore
LICENSE
NOTICE
lib

# Fixture data and JSON Schemas have no comment syntax, so they cannot carry an
# Apache header; they are covered by the repository LICENSE and NOTICE at the root.
**/*.json
**/*.jsonl
78 changes: 78 additions & 0 deletions dev/check-license
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env bash

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

acquire_rat_jar () {

URL="https://repo.maven.apache.org/maven2/org/apache/rat/apache-rat/${RAT_VERSION}/apache-rat-${RAT_VERSION}.jar"

JAR="$rat_jar"

# Download rat launch jar if it hasn't been downloaded yet
if [ ! -f "$JAR" ]; then
# Download
printf "Attempting to fetch rat\n"
JAR_DL="${JAR}.part"
if [ $(command -v curl) ]; then
curl -L --silent "${URL}" > "$JAR_DL" && mv "$JAR_DL" "$JAR"
Comment thread
nssalian marked this conversation as resolved.
elif [ $(command -v wget) ]; then
wget --quiet "${URL}" -O "$JAR_DL" && mv "$JAR_DL" "$JAR"
else
printf "You do not have curl or wget installed, please install rat manually.\n"
exit 1
fi
fi

unzip -tq "$JAR" &> /dev/null
if [ $? -ne 0 ]; then
# We failed to download
rm "$JAR"
printf "Our attempt to download rat locally to ${JAR} failed. Please install rat manually.\n"
exit 1
fi
}

# Go to the project root directory
FWDIR="$(cd "`dirname "$0"`"/..; pwd)"
cd "$FWDIR"

if test -x "$JAVA_HOME/bin/java"; then
declare java_cmd="$JAVA_HOME/bin/java"
else
declare java_cmd=java
fi

export RAT_VERSION=0.17
export rat_jar="$FWDIR/lib/apache-rat-${RAT_VERSION}.jar"
mkdir -p "$FWDIR/lib"

[[ -f "$rat_jar" ]] || acquire_rat_jar || {
echo "Download failed. Obtain the rat jar manually and place it at $rat_jar"
exit 1
}

# --input-exclude-std GIT skips .git and anything .gitignore'd. Without it RAT
# flags the .git pointer *file* that git worktrees use, since its built-in SCM
# exclusion only covers .git directories.
"$java_cmd" -jar "$rat_jar" \
--input-exclude-file "$FWDIR/dev/.rat-excludes" \
--input-exclude-std GIT IDEA MAC \
--input-include-std HIDDEN_DIR \
--output-style missing-headers \
--log-level ERROR \
-- "$FWDIR" || exit 1

echo "RAT checks passed."
19 changes: 19 additions & 0 deletions dev/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

# Dependencies for the dev/ tooling (fixture validation).
jsonschema>=4.18,<5
49 changes: 49 additions & 0 deletions dev/schema/cases.base.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://iceberg.apache.org/verification/cases.base.schema.json",
"title": "Conformance cases (base)",
"description": "Structure shared by every table-spec surface's cases.json.",
"type": "object",
"required": ["cases"],
"additionalProperties": false,
"properties": {
"cases": {
"type": "array",
"items": { "$ref": "#/$defs/case" }
}
},
"$defs": {
"case": {
"type": "object",
Comment thread
nssalian marked this conversation as resolved.
"required": ["id", "valid", "input"],
"additionalProperties": false,
"properties": {
"id": { "type": "string", "minLength": 1 },
"valid": { "type": "boolean" },
"input": true,
"decoded": true,
"canonical": { "type": "string" },
"clause": { "type": "string" },
"spec_ref": { "type": "string" },
"normative_level": { "enum": ["must", "should"], "description": "must (default) or should. A should case is advisory (the spec only recommends the behavior); a runner must report a failed should distinctly from a pass, so the advisory tier stays visible rather than reading as inert." }
},
"allOf": [
{
"$comment": "a valid case must carry decoded",
"if": { "properties": { "valid": { "const": true } }, "required": ["valid"] },
"then": { "required": ["decoded"] }
},
{
"$comment": "an invalid case must not carry decoded",
"if": { "properties": { "valid": { "const": false } }, "required": ["valid"] },
"then": { "properties": { "decoded": false } }
},
{
"$comment": "canonical is only allowed on a valid case",
"if": { "required": ["canonical"] },
"then": { "properties": { "valid": { "const": true } }, "required": ["valid"] }
}
]
}
}
}
21 changes: 21 additions & 0 deletions dev/schema/cases.types.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://iceberg.apache.org/verification/cases.types.schema.json",
"title": "Conformance cases (types surface extension)",
"description": "Extra constraints for table-spec/types: every case cites the spec. Applied on top of cases.base.schema.json by dev/validate-fixtures.py.",
"type": "object",
"required": ["cases"],
"properties": {
"cases": {
"type": "array",
"items": {
"type": "object",
"required": ["clause", "spec_ref"],
"properties": {
"clause": { "type": "string", "minLength": 1 },
"spec_ref": { "type": "string", "minLength": 1 }
}
}
}
}
}
Loading