Skip to content

Fail the example cloud tests when there is no resource key - #66

Merged
jwrosewell merged 2 commits into
rcfrom
test/example-cloud-tests-fail-without-a-key
Nov 8, 2026
Merged

jwrosewell merged 2 commits into
rcfrom
test/example-cloud-tests-fail-without-a-key

Conversation

@jwrosewell

@jwrosewell jwrosewell commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

For #64.

The problem

The cloud tests under examples/ skipped when no resource key was set, so a run with no key reported success having called nothing. Separately, KeyHelper.getOrSetResourceKey in both examples/device-detection/shared/.../KeyHelper.java and examples/ip-intelligence/shared/.../KeyHelper.java passed null to System.setProperty when it found no key and was told not to throw, which throws a NullPointerException.

The open drafts #59 and #57 do the same for the pipeline modules and the IP Intelligence cloud module. Neither touches examples/, and this pull request touches nothing else.

What changed

  1. The setProperty call is guarded. getOrSetResourceKey now keeps a key only when KeyUtils.isInvalidKey says it is valid, so a missing or invalid key is never stored.

  2. The tests fail rather than skip. Each KeyHelper gains requireTestResourceKey, and the Device Detection one also requireResourceKey for the TAC and native model tests, which read SuperResourceKey. They read _51DEGREES_RESOURCE_KEY, then _51DEGREES_RESOURCE_KEY_BESPOKE, then the names the file reads today in their current order, each as an environment variable, as its upper case name and then as a system property. Anything that is not a key, such as the empty string the example poms pass for an unset key, is passed over. With no key they fail with the wording agreed for all four languages.

    Test Names after the two shared ones The key must carry
    Device Detection GettingStartedCloudTest, MetadataCloudTest, MinimalExampleTest, GettingStartedWebCloudTest TestResourceKey device
    Device Detection NativeModelCloudTest, TacCloudTest SuperResourceKey hardware
    IP Intelligence GetAllPropertiesCloudTest, GettingStartedCloudTest, MetadataCloudTest, GettingStartedWebCloudTest 51DEGREES_RESOURCE_KEY, TestResourceKey ip
    IP Intelligence GettingStartedCloudMixedTest, GettingStartedWebCloudMixedTest 51DEGREES_RESOURCE_KEY, TestResourceKey ip and device

    The two IP Intelligence web cloud tests were missing from the issue's table but skipped in the same way, so they are included.

  3. The Device Detection web cloud test checks the page. GettingStartedWebCloudTest sends a Chrome 98 on Windows User-Agent and checks that the page says the cloud device detection engine detected the values, and that Browser Name is Chrome and Platform Name is Windows. A row that shows no value fails with "The cloud answered without BrowserName (reason), which is what a key that does not carry the device product gets."

  4. Unit tests. A new KeyHelperTest in each examples shared module covers the no key path of getOrSetTestResourceKey(false), the failure message word for word, the order the names are read in, and that a value that is not a key is passed over.

The configure.51degrees.com link in the message carries the repository's campaign tags, and common-ci scripts/utm-lint.ps1 reports the tree clean for 51degrees-java.

Variable order and #59

The order follows the decision for .NET, Node, Python and Java, which is the two shared names first and then the file's own names. Two differences are worth knowing for review.

  • Make every cloud test call the live service and fail when it cannot #59's LiveCloudKeys reads _51DEGREES_RESOURCE_KEY, RESOURCE_KEY, _51DEGREES_RESOURCE_KEY_BESPOKE, TestResourceKey, SUPER_RESOURCE_KEY, so it puts RESOURCE_KEY second and differs from the other languages on order. This pull request does not change Make every cloud test call the live service and fail when it cannot #59.
  • The issue asked for the example's own names first in the TAC and native model lookups. With the shared names first, a _51DEGREES_RESOURCE_KEY holding a key without the hardware product is used ahead of a SuperResourceKey that has it. CI sets neither shared name (the Build and Test log prints "No keys matching '_51DEGREES_RESOURCE_KEY*' were supplied"), so CI is unaffected.

How to verify

All runs are on ubuntu-latest with JDK 17, testing examples/device-detection and examples/ip-intelligence against the published 4.5.130 packages, once with no key and once with the bespoke key passed as -DTestResourceKey and -DSuperResourceKey, as ci/run-unit-tests.ps1 does.

1. With no key, every cloud test fails naming the variables and the product, none skips, and none ends with a NullPointerException.

On rc all 12 skipped with "Skipping test, no resource key found". Under Maven the three Device Detection tests named in the issue skip rather than throw, because the example poms pass TestResourceKey on as an empty string (the surefire report lists TestResourceKey=''), which is not null. The exception comes when the property is absent, which step 2 shows.

On this branch all 12 fail, for example:

FAILURE  fiftyone.devicedetection.examples.console.TacCloudTest.run
         java.lang.AssertionError: This test calls the live 51Degrees cloud service, so it needs a resource key and there is nothing to fall back on. None of _51DEGREES_RESOURCE_KEY, _51DEGREES_RESOURCE_KEY_BESPOKE, SuperResourceKey is set, as an environment variable or as a system property, tried in that order. The key has to carry the hardware product, because the test asks the service for the devices that match a TAC. To see the products a key carries, open https://cloud.51degrees.com/api/v4/accessibleproperties?resource=<key>. Create a key at https://configure.51degrees.com/?utm_source=code&utm_medium=example&utm_campaign=51degrees-java&utm_content=shared-src-main-java-fiftyone-devicedetection-examples-shared-keyhelper.java&utm_term=no-resource-key.
FAILURE  fiftyone.ipintelligence.examples.console.GettingStartedCloudMixedTest.gettingStartedCloudMixedTest
         java.lang.AssertionError: This test calls the live 51Degrees cloud service, so it needs a resource key and there is nothing to fall back on. None of _51DEGREES_RESOURCE_KEY, _51DEGREES_RESOURCE_KEY_BESPOKE, 51DEGREES_RESOURCE_KEY, TestResourceKey is set, as an environment variable or as a system property, tried in that order. The key has to carry the ip and device products, because the test asks the service for the network and location of an IP address, and whether a device is mobile. ...
TOTALS {'failure': 12, 'passed': 10}

The 10 that pass are the KeyHelperTest cases.

2. KeyHelper.getOrSetTestResourceKey(false) with no key set gives no NullPointerException, and System.getProperty("TestResourceKey") is still null afterwards.

getOrSetTestResourceKey_NoKey_StoresNothing clears the system property for the test and checks the environment does not set it. On rc it ends with java.lang.NullPointerException in both modules. On this branch it passes in both, in both jobs, and did not skip.

3. With the bespoke key, the device, ip and hardware tests pass.

A step that never prints the key asked accessibleproperties what the key carries:

product device: tier CloudV5Bespoke, 291 properties, of those used: IsMobile, PlatformName, PlatformVersion, BrowserName, BrowserVersion, HardwareVendor, HardwareName, HardwareModel
product hardware: tier CloudV5Bespoke, 1 properties, of those used: 
product ip: tier CloudV5Bespoke, 58 properties, of those used: RegisteredName, RegisteredOwner, Country, CountryCode, Latitude, Longitude, TimeZoneOffset

On this branch all 22 passed, the 12 cloud tests including TAC, native model and the page check of the web test.

TOTALS {'passed': 22}

What remains

  • The console cloud tests run the example and fail on anything it throws, but they do not read the answer, so a key that carries the product without a property the example prints shows "Unknown" and still passes. Only the Device Detection web test reads the answer.
  • The two IP Intelligence web cloud tests still accept any non-empty 200 page, as before.
  • The page check's failure path, a row showing no value, was not seen in a live run because the bespoke key carries both properties. Its wording is covered by answeredWithout_NoReason_SaysSo.
  • The web examples read ${TestResourceKey} from their configuration files, which looks at the environment before system properties. A developer who exports _51DEGREES_RESOURCE_KEY and a different TestResourceKey gets the test's key lookup and the page's key from different names.

Full build

The branch has rc merged in at 2299507, which brings #52, #54 and #57 and touches none of these files. common-ci's pull request build, run as a dry run with the bespoke key, built and tested da6b7e4 in all 15 configurations and every job passed (run 42397586757). In the Ubuntu Java 17 job the 12 cloud tests and both KeyHelperTest classes ran with none skipped, for example Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ... in fiftyone.devicedetection.examples.console.TacCloudTest.

The cloud tests under examples/ skipped when no resource key was set, so a
run with no key reported success having called nothing. Each now asks its
KeyHelper for the key, which reads _51DEGREES_RESOURCE_KEY, then
_51DEGREES_RESOURCE_KEY_BESPOKE, then the names the example reads today,
each as an environment variable and then as a system property, and fails
the test naming every name tried, the product the key has to carry, how to
see what a key carries and where to create one.

KeyHelper.getOrSetResourceKey passed a null key to System.setProperty,
which throws a NullPointerException, whenever no key was found and it was
asked not to throw. It now keeps only a valid key.

The Device Detection web cloud test sends a known User-Agent and checks
that the page shows the browser and platform the cloud engine detected,
rather than accepting any 200 response.
@jwrosewell
jwrosewell marked this pull request as ready for review November 8, 2026 23:44
@jwrosewell
jwrosewell merged commit c781d83 into rc Nov 8, 2026
2 checks passed
@jwrosewell
jwrosewell deleted the test/example-cloud-tests-fail-without-a-key branch November 8, 2026 23:44
Sign up for free to 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