Closed
Description
Since all access to EC2MetadataUtils is static, the class is very difficult to use in a properly tested application. It can't be mocked; you can't give canned answers when running in a non-EC2 environment.
If there were an EC2Metadata interface or abstract class of which there were a default implementation, then it would be easier to use.
A contrived example:
public class Application {
EC2Metadata metadata;
public static void main(String args[]) {
new Application(EC2MetadataUtils.getDefaultInstance());
}
public Application(EC2Metadata metadata) {
this.metadata = metadata;
LOG.info("We're running on " + metadata.getInstanceId());
}
}
public class ApplicationTest {
@Mock EC2Metadata metadata;
@Test public testApp() {
when(metadata.getDefaultInstance()).then(return "i-fakeinstance");
new Application(metadata);
verifyLoggedLine("We're running on i-fakeinstance");
}
}
As it stands today, I need to run a whole HTTP process that mimics the metadata server and somehow get the system property to point to it; and even that is a global setting for the whole JVM: parallel tests can interfere with each other. Or I can write my own EC2Metadata interface and use it throughout my app, but it's not something each developer should have to do.