Test infrastructure: detect missing data types, enum not written out manually - #96

Open
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra
Open

Test infrastructure: detect missing data types, enum not written out manually#96
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra

Conversation

@konstibob

Copy link
Copy Markdown
Contributor

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.

Drive coverage from outside our code instead:

  • New DataTypeConformanceTest checks our enum against a list generated from
    zarr-python's data type registry and committed alongside it. What we lack is
    enumerated in KNOWN_UNSUPPORTED with a note on what each needs, and the
    assertion is bidirectional, so implementing a data type shows up as a
    deletion there and a stale entry fails too. Metadata-only: no I/O and no
    Python.
  • Two CI jobs keep that list current, split by who caused the problem. Per
    pull request it is checked against the zarr-python we pin; nightly, against
    the latest release. The nightly one is deliberately not a pull-request gate,
    since no pull request causes upstream to publish a version.

Also cut the interop tier's cost. It ran one uv run per test case, paying
interpreter startup plus import zarr, numpy every time; the test arrays were
never the expense. zarr-python now runs as one long-lived worker speaking JSON
lines over stdin/stdout. A worker rather than an up-front batch keeps per-test
semantics, so failures stay attributed to the test that caused them. Fixture
logic moved to zarr_fixtures.py, which both the worker and the CLI scripts
call, so the two cannot drift.

Full interop run: 129.3s -> 19.2s.

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.
Drive coverage from outside our code instead:
- ZarrTest.dataTypeProviderV3/V2 now derive from DataType.values(), so a new
data type is picked up by every test using them without anyone remembering
to extend a list.
- New DataTypeConformanceTest checks an external list (generated from
zarr-python's registry, committed as spec-data-types-v3.json) against our
enum. Each of the 11 data types we lack is enumerated in KNOWN_UNSUPPORTED
with a note on what it needs. The assertion is bidirectional, so
implementing a data type shows up as a deletion there and a stale entry
fails too. Metadata-only: 46 tests in 0.6s, no I/O and no Python.
- ZarrV3Test.dataTypeAndEndianProvider derives from the enum as well. The
hand-written version had already drifted, omitting INT64 and UINT64, so
8-byte byte-order handling was untested.
Also cut the interop tier's cost. It ran one `uv run` per test case, paying
interpreter startup plus `import zarr, numpy` roughly 136 times; the 16 KB
test arrays were never the expense. zarr-python now runs as one long-lived
worker speaking JSON lines over stdin/stdout. A worker rather than an
up-front batch keeps per-test semantics: each test still makes its own call
and asserts its own result, so failures stay attributed to the test that
caused them. Fixture logic moved to zarr_fixtures.py, which both the worker
and the existing CLI scripts call, so the two cannot drift.
Full interop run: 129.3s -> 19.2s for the same 174 passing tests.
Tag the interop tests `interop` and exclude them from `mvn test` by default,
so pull requests get the fast offline tiers and the cross-implementation
matrix moves to a nightly job. Interop coverage is not optional for a format
library: a zarr-java write followed by a zarr-java read passes even when
reader and writer share the same misreading of the spec, and only a second
implementation catches that.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@konstibob
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Test infrastructure: detect missing data types, enum not written out manually - #96

Open
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra
Open

Test infrastructure: detect missing data types, enum not written out manually#96
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra

Conversation

@konstibob

Copy link
Copy Markdown
Contributor

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.

Drive coverage from outside our code instead:

  • New DataTypeConformanceTest checks our enum against a list generated from
    zarr-python's data type registry and committed alongside it. What we lack is
    enumerated in KNOWN_UNSUPPORTED with a note on what each needs, and the
    assertion is bidirectional, so implementing a data type shows up as a
    deletion there and a stale entry fails too. Metadata-only: no I/O and no
    Python.
  • Two CI jobs keep that list current, split by who caused the problem. Per
    pull request it is checked against the zarr-python we pin; nightly, against
    the latest release. The nightly one is deliberately not a pull-request gate,
    since no pull request causes upstream to publish a version.

Also cut the interop tier's cost. It ran one uv run per test case, paying
interpreter startup plus import zarr, numpy every time; the test arrays were
never the expense. zarr-python now runs as one long-lived worker speaking JSON
lines over stdin/stdout. A worker rather than an up-front batch keeps per-test
semantics, so failures stay attributed to the test that caused them. Fixture
logic moved to zarr_fixtures.py, which both the worker and the CLI scripts
call, so the two cannot drift.

Full interop run: 129.3s -> 19.2s.

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.
Drive coverage from outside our code instead:
- ZarrTest.dataTypeProviderV3/V2 now derive from DataType.values(), so a new
data type is picked up by every test using them without anyone remembering
to extend a list.
- New DataTypeConformanceTest checks an external list (generated from
zarr-python's registry, committed as spec-data-types-v3.json) against our
enum. Each of the 11 data types we lack is enumerated in KNOWN_UNSUPPORTED
with a note on what it needs. The assertion is bidirectional, so
implementing a data type shows up as a deletion there and a stale entry
fails too. Metadata-only: 46 tests in 0.6s, no I/O and no Python.
- ZarrV3Test.dataTypeAndEndianProvider derives from the enum as well. The
hand-written version had already drifted, omitting INT64 and UINT64, so
8-byte byte-order handling was untested.
Also cut the interop tier's cost. It ran one `uv run` per test case, paying
interpreter startup plus `import zarr, numpy` roughly 136 times; the 16 KB
test arrays were never the expense. zarr-python now runs as one long-lived
worker speaking JSON lines over stdin/stdout. A worker rather than an
up-front batch keeps per-test semantics: each test still makes its own call
and asserts its own result, so failures stay attributed to the test that
caused them. Fixture logic moved to zarr_fixtures.py, which both the worker
and the existing CLI scripts call, so the two cannot drift.
Full interop run: 129.3s -> 19.2s for the same 174 passing tests.
Tag the interop tests `interop` and exclude them from `mvn test` by default,
so pull requests get the fast offline tiers and the cross-implementation
matrix moves to a nightly job. Interop coverage is not optional for a format
library: a zarr-java write followed by a zarr-java read passes even when
reader and writer share the same misreading of the spec, and only a second
implementation catches that.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@konstibob
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Test infrastructure: detect missing data types, enum not written out manually - #96

Open
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra
Open

Test infrastructure: detect missing data types, enum not written out manually#96
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra

Conversation

@konstibob

Copy link
Copy Markdown
Contributor

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.

Drive coverage from outside our code instead:

  • New DataTypeConformanceTest checks our enum against a list generated from
    zarr-python's data type registry and committed alongside it. What we lack is
    enumerated in KNOWN_UNSUPPORTED with a note on what each needs, and the
    assertion is bidirectional, so implementing a data type shows up as a
    deletion there and a stale entry fails too. Metadata-only: no I/O and no
    Python.
  • Two CI jobs keep that list current, split by who caused the problem. Per
    pull request it is checked against the zarr-python we pin; nightly, against
    the latest release. The nightly one is deliberately not a pull-request gate,
    since no pull request causes upstream to publish a version.

Also cut the interop tier's cost. It ran one uv run per test case, paying
interpreter startup plus import zarr, numpy every time; the test arrays were
never the expense. zarr-python now runs as one long-lived worker speaking JSON
lines over stdin/stdout. A worker rather than an up-front batch keeps per-test
semantics, so failures stay attributed to the test that caused them. Fixture
logic moved to zarr_fixtures.py, which both the worker and the CLI scripts
call, so the two cannot drift.

Full interop run: 129.3s -> 19.2s.

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.
Drive coverage from outside our code instead:
- ZarrTest.dataTypeProviderV3/V2 now derive from DataType.values(), so a new
data type is picked up by every test using them without anyone remembering
to extend a list.
- New DataTypeConformanceTest checks an external list (generated from
zarr-python's registry, committed as spec-data-types-v3.json) against our
enum. Each of the 11 data types we lack is enumerated in KNOWN_UNSUPPORTED
with a note on what it needs. The assertion is bidirectional, so
implementing a data type shows up as a deletion there and a stale entry
fails too. Metadata-only: 46 tests in 0.6s, no I/O and no Python.
- ZarrV3Test.dataTypeAndEndianProvider derives from the enum as well. The
hand-written version had already drifted, omitting INT64 and UINT64, so
8-byte byte-order handling was untested.
Also cut the interop tier's cost. It ran one `uv run` per test case, paying
interpreter startup plus `import zarr, numpy` roughly 136 times; the 16 KB
test arrays were never the expense. zarr-python now runs as one long-lived
worker speaking JSON lines over stdin/stdout. A worker rather than an
up-front batch keeps per-test semantics: each test still makes its own call
and asserts its own result, so failures stay attributed to the test that
caused them. Fixture logic moved to zarr_fixtures.py, which both the worker
and the existing CLI scripts call, so the two cannot drift.
Full interop run: 129.3s -> 19.2s for the same 174 passing tests.
Tag the interop tests `interop` and exclude them from `mvn test` by default,
so pull requests get the fast offline tiers and the cross-implementation
matrix moves to a nightly job. Interop coverage is not optional for a format
library: a zarr-java write followed by a zarr-java read passes even when
reader and writer share the same misreading of the spec, and only a second
implementation catches that.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@konstibob
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Test infrastructure: detect missing data types, enum not written out manually - #96

Open
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra
Open

Test infrastructure: detect missing data types, enum not written out manually#96
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra

Conversation

@konstibob

Copy link
Copy Markdown
Contributor

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.

Drive coverage from outside our code instead:

  • New DataTypeConformanceTest checks our enum against a list generated from
    zarr-python's data type registry and committed alongside it. What we lack is
    enumerated in KNOWN_UNSUPPORTED with a note on what each needs, and the
    assertion is bidirectional, so implementing a data type shows up as a
    deletion there and a stale entry fails too. Metadata-only: no I/O and no
    Python.
  • Two CI jobs keep that list current, split by who caused the problem. Per
    pull request it is checked against the zarr-python we pin; nightly, against
    the latest release. The nightly one is deliberately not a pull-request gate,
    since no pull request causes upstream to publish a version.

Also cut the interop tier's cost. It ran one uv run per test case, paying
interpreter startup plus import zarr, numpy every time; the test arrays were
never the expense. zarr-python now runs as one long-lived worker speaking JSON
lines over stdin/stdout. A worker rather than an up-front batch keeps per-test
semantics, so failures stay attributed to the test that caused them. Fixture
logic moved to zarr_fixtures.py, which both the worker and the CLI scripts
call, so the two cannot drift.

Full interop run: 129.3s -> 19.2s.

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.
Drive coverage from outside our code instead:
- ZarrTest.dataTypeProviderV3/V2 now derive from DataType.values(), so a new
data type is picked up by every test using them without anyone remembering
to extend a list.
- New DataTypeConformanceTest checks an external list (generated from
zarr-python's registry, committed as spec-data-types-v3.json) against our
enum. Each of the 11 data types we lack is enumerated in KNOWN_UNSUPPORTED
with a note on what it needs. The assertion is bidirectional, so
implementing a data type shows up as a deletion there and a stale entry
fails too. Metadata-only: 46 tests in 0.6s, no I/O and no Python.
- ZarrV3Test.dataTypeAndEndianProvider derives from the enum as well. The
hand-written version had already drifted, omitting INT64 and UINT64, so
8-byte byte-order handling was untested.
Also cut the interop tier's cost. It ran one `uv run` per test case, paying
interpreter startup plus `import zarr, numpy` roughly 136 times; the 16 KB
test arrays were never the expense. zarr-python now runs as one long-lived
worker speaking JSON lines over stdin/stdout. A worker rather than an
up-front batch keeps per-test semantics: each test still makes its own call
and asserts its own result, so failures stay attributed to the test that
caused them. Fixture logic moved to zarr_fixtures.py, which both the worker
and the existing CLI scripts call, so the two cannot drift.
Full interop run: 129.3s -> 19.2s for the same 174 passing tests.
Tag the interop tests `interop` and exclude them from `mvn test` by default,
so pull requests get the fast offline tiers and the cross-implementation
matrix moves to a nightly job. Interop coverage is not optional for a format
library: a zarr-java write followed by a zarr-java read passes even when
reader and writer share the same misreading of the spec, and only a second
implementation catches that.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@konstibob
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Test infrastructure: detect missing data types, enum not written out manually - #96

Open
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra
Open

Test infrastructure: detect missing data types, enum not written out manually#96
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra

Conversation

@konstibob

Copy link
Copy Markdown
Contributor

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.

Drive coverage from outside our code instead:

  • New DataTypeConformanceTest checks our enum against a list generated from
    zarr-python's data type registry and committed alongside it. What we lack is
    enumerated in KNOWN_UNSUPPORTED with a note on what each needs, and the
    assertion is bidirectional, so implementing a data type shows up as a
    deletion there and a stale entry fails too. Metadata-only: no I/O and no
    Python.
  • Two CI jobs keep that list current, split by who caused the problem. Per
    pull request it is checked against the zarr-python we pin; nightly, against
    the latest release. The nightly one is deliberately not a pull-request gate,
    since no pull request causes upstream to publish a version.

Also cut the interop tier's cost. It ran one uv run per test case, paying
interpreter startup plus import zarr, numpy every time; the test arrays were
never the expense. zarr-python now runs as one long-lived worker speaking JSON
lines over stdin/stdout. A worker rather than an up-front batch keeps per-test
semantics, so failures stay attributed to the test that caused them. Fixture
logic moved to zarr_fixtures.py, which both the worker and the CLI scripts
call, so the two cannot drift.

Full interop run: 129.3s -> 19.2s.

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.
Drive coverage from outside our code instead:
- ZarrTest.dataTypeProviderV3/V2 now derive from DataType.values(), so a new
data type is picked up by every test using them without anyone remembering
to extend a list.
- New DataTypeConformanceTest checks an external list (generated from
zarr-python's registry, committed as spec-data-types-v3.json) against our
enum. Each of the 11 data types we lack is enumerated in KNOWN_UNSUPPORTED
with a note on what it needs. The assertion is bidirectional, so
implementing a data type shows up as a deletion there and a stale entry
fails too. Metadata-only: 46 tests in 0.6s, no I/O and no Python.
- ZarrV3Test.dataTypeAndEndianProvider derives from the enum as well. The
hand-written version had already drifted, omitting INT64 and UINT64, so
8-byte byte-order handling was untested.
Also cut the interop tier's cost. It ran one `uv run` per test case, paying
interpreter startup plus `import zarr, numpy` roughly 136 times; the 16 KB
test arrays were never the expense. zarr-python now runs as one long-lived
worker speaking JSON lines over stdin/stdout. A worker rather than an
up-front batch keeps per-test semantics: each test still makes its own call
and asserts its own result, so failures stay attributed to the test that
caused them. Fixture logic moved to zarr_fixtures.py, which both the worker
and the existing CLI scripts call, so the two cannot drift.
Full interop run: 129.3s -> 19.2s for the same 174 passing tests.
Tag the interop tests `interop` and exclude them from `mvn test` by default,
so pull requests get the fast offline tiers and the cross-implementation
matrix moves to a nightly job. Interop coverage is not optional for a format
library: a zarr-java write followed by a zarr-java read passes even when
reader and writer share the same misreading of the spec, and only a second
implementation catches that.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@konstibob
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Test infrastructure: detect missing data types, enum not written out manually - #96

Open
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra
Open

Test infrastructure: detect missing data types, enum not written out manually#96
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra

Conversation

@konstibob

Copy link
Copy Markdown
Contributor

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.

Drive coverage from outside our code instead:

  • New DataTypeConformanceTest checks our enum against a list generated from
    zarr-python's data type registry and committed alongside it. What we lack is
    enumerated in KNOWN_UNSUPPORTED with a note on what each needs, and the
    assertion is bidirectional, so implementing a data type shows up as a
    deletion there and a stale entry fails too. Metadata-only: no I/O and no
    Python.
  • Two CI jobs keep that list current, split by who caused the problem. Per
    pull request it is checked against the zarr-python we pin; nightly, against
    the latest release. The nightly one is deliberately not a pull-request gate,
    since no pull request causes upstream to publish a version.

Also cut the interop tier's cost. It ran one uv run per test case, paying
interpreter startup plus import zarr, numpy every time; the test arrays were
never the expense. zarr-python now runs as one long-lived worker speaking JSON
lines over stdin/stdout. A worker rather than an up-front batch keeps per-test
semantics, so failures stay attributed to the test that caused them. Fixture
logic moved to zarr_fixtures.py, which both the worker and the CLI scripts
call, so the two cannot drift.

Full interop run: 129.3s -> 19.2s.

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.
Drive coverage from outside our code instead:
- ZarrTest.dataTypeProviderV3/V2 now derive from DataType.values(), so a new
data type is picked up by every test using them without anyone remembering
to extend a list.
- New DataTypeConformanceTest checks an external list (generated from
zarr-python's registry, committed as spec-data-types-v3.json) against our
enum. Each of the 11 data types we lack is enumerated in KNOWN_UNSUPPORTED
with a note on what it needs. The assertion is bidirectional, so
implementing a data type shows up as a deletion there and a stale entry
fails too. Metadata-only: 46 tests in 0.6s, no I/O and no Python.
- ZarrV3Test.dataTypeAndEndianProvider derives from the enum as well. The
hand-written version had already drifted, omitting INT64 and UINT64, so
8-byte byte-order handling was untested.
Also cut the interop tier's cost. It ran one `uv run` per test case, paying
interpreter startup plus `import zarr, numpy` roughly 136 times; the 16 KB
test arrays were never the expense. zarr-python now runs as one long-lived
worker speaking JSON lines over stdin/stdout. A worker rather than an
up-front batch keeps per-test semantics: each test still makes its own call
and asserts its own result, so failures stay attributed to the test that
caused them. Fixture logic moved to zarr_fixtures.py, which both the worker
and the existing CLI scripts call, so the two cannot drift.
Full interop run: 129.3s -> 19.2s for the same 174 passing tests.
Tag the interop tests `interop` and exclude them from `mvn test` by default,
so pull requests get the fast offline tiers and the cross-implementation
matrix moves to a nightly job. Interop coverage is not optional for a format
library: a zarr-java write followed by a zarr-java read passes even when
reader and writer share the same misreading of the spec, and only a second
implementation catches that.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@konstibob
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Test infrastructure: detect missing data types, enum not written out manually - #96

Open
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra
Open

Test infrastructure: detect missing data types, enum not written out manually#96
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra

Conversation

@konstibob

Copy link
Copy Markdown
Contributor

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.

Drive coverage from outside our code instead:

  • New DataTypeConformanceTest checks our enum against a list generated from
    zarr-python's data type registry and committed alongside it. What we lack is
    enumerated in KNOWN_UNSUPPORTED with a note on what each needs, and the
    assertion is bidirectional, so implementing a data type shows up as a
    deletion there and a stale entry fails too. Metadata-only: no I/O and no
    Python.
  • Two CI jobs keep that list current, split by who caused the problem. Per
    pull request it is checked against the zarr-python we pin; nightly, against
    the latest release. The nightly one is deliberately not a pull-request gate,
    since no pull request causes upstream to publish a version.

Also cut the interop tier's cost. It ran one uv run per test case, paying
interpreter startup plus import zarr, numpy every time; the test arrays were
never the expense. zarr-python now runs as one long-lived worker speaking JSON
lines over stdin/stdout. A worker rather than an up-front batch keeps per-test
semantics, so failures stay attributed to the test that caused them. Fixture
logic moved to zarr_fixtures.py, which both the worker and the CLI scripts
call, so the two cannot drift.

Full interop run: 129.3s -> 19.2s.

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.
Drive coverage from outside our code instead:
- ZarrTest.dataTypeProviderV3/V2 now derive from DataType.values(), so a new
data type is picked up by every test using them without anyone remembering
to extend a list.
- New DataTypeConformanceTest checks an external list (generated from
zarr-python's registry, committed as spec-data-types-v3.json) against our
enum. Each of the 11 data types we lack is enumerated in KNOWN_UNSUPPORTED
with a note on what it needs. The assertion is bidirectional, so
implementing a data type shows up as a deletion there and a stale entry
fails too. Metadata-only: 46 tests in 0.6s, no I/O and no Python.
- ZarrV3Test.dataTypeAndEndianProvider derives from the enum as well. The
hand-written version had already drifted, omitting INT64 and UINT64, so
8-byte byte-order handling was untested.
Also cut the interop tier's cost. It ran one `uv run` per test case, paying
interpreter startup plus `import zarr, numpy` roughly 136 times; the 16 KB
test arrays were never the expense. zarr-python now runs as one long-lived
worker speaking JSON lines over stdin/stdout. A worker rather than an
up-front batch keeps per-test semantics: each test still makes its own call
and asserts its own result, so failures stay attributed to the test that
caused them. Fixture logic moved to zarr_fixtures.py, which both the worker
and the existing CLI scripts call, so the two cannot drift.
Full interop run: 129.3s -> 19.2s for the same 174 passing tests.
Tag the interop tests `interop` and exclude them from `mvn test` by default,
so pull requests get the fast offline tiers and the cross-implementation
matrix moves to a nightly job. Interop coverage is not optional for a format
library: a zarr-java write followed by a zarr-java read passes even when
reader and writer share the same misreading of the spec, and only a second
implementation catches that.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@konstibob
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Test infrastructure: detect missing data types, enum not written out manually - #96

Open
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra
Open

Test infrastructure: detect missing data types, enum not written out manually#96
konstibob wants to merge 2 commits into
zarr-developers:mainfrom
konstibob:test/dtype-coverage-infra

Conversation

@konstibob

Copy link
Copy Markdown
Contributor

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.

Drive coverage from outside our code instead:

  • New DataTypeConformanceTest checks our enum against a list generated from
    zarr-python's data type registry and committed alongside it. What we lack is
    enumerated in KNOWN_UNSUPPORTED with a note on what each needs, and the
    assertion is bidirectional, so implementing a data type shows up as a
    deletion there and a stale entry fails too. Metadata-only: no I/O and no
    Python.
  • Two CI jobs keep that list current, split by who caused the problem. Per
    pull request it is checked against the zarr-python we pin; nightly, against
    the latest release. The nightly one is deliberately not a pull-request gate,
    since no pull request causes upstream to publish a version.

Also cut the interop tier's cost. It ran one uv run per test case, paying
interpreter startup plus import zarr, numpy every time; the test arrays were
never the expense. zarr-python now runs as one long-lived worker speaking JSON
lines over stdin/stdout. A worker rather than an up-front batch keeps per-test
semantics, so failures stay attributed to the test that caused them. Fixture
logic moved to zarr_fixtures.py, which both the worker and the CLI scripts
call, so the two cannot drift.

Full interop run: 129.3s -> 19.2s.

The dtype test providers mirrored our own DataType enum by hand, which made
them tautological: they could only assert that what we implemented is
implemented, so a data type we never added was invisible and no test could
fail for it. That is how float16 and string went unnoticed despite a broad
interop matrix.
Drive coverage from outside our code instead:
- ZarrTest.dataTypeProviderV3/V2 now derive from DataType.values(), so a new
data type is picked up by every test using them without anyone remembering
to extend a list.
- New DataTypeConformanceTest checks an external list (generated from
zarr-python's registry, committed as spec-data-types-v3.json) against our
enum. Each of the 11 data types we lack is enumerated in KNOWN_UNSUPPORTED
with a note on what it needs. The assertion is bidirectional, so
implementing a data type shows up as a deletion there and a stale entry
fails too. Metadata-only: 46 tests in 0.6s, no I/O and no Python.
- ZarrV3Test.dataTypeAndEndianProvider derives from the enum as well. The
hand-written version had already drifted, omitting INT64 and UINT64, so
8-byte byte-order handling was untested.
Also cut the interop tier's cost. It ran one `uv run` per test case, paying
interpreter startup plus `import zarr, numpy` roughly 136 times; the 16 KB
test arrays were never the expense. zarr-python now runs as one long-lived
worker speaking JSON lines over stdin/stdout. A worker rather than an
up-front batch keeps per-test semantics: each test still makes its own call
and asserts its own result, so failures stay attributed to the test that
caused them. Fixture logic moved to zarr_fixtures.py, which both the worker
and the existing CLI scripts call, so the two cannot drift.
Full interop run: 129.3s -> 19.2s for the same 174 passing tests.
Tag the interop tests `interop` and exclude them from `mvn test` by default,
so pull requests get the fast offline tiers and the cross-implementation
matrix moves to a nightly job. Interop coverage is not optional for a format
library: a zarr-java write followed by a zarr-java read passes even when
reader and writer share the same misreading of the spec, and only a second
implementation catches that.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@konstibob