Dev Estimate: 0
Test Estimate: 0.5
Here is the design:
(1) If credentials are passed to the constructor, they will always be used
(2) If credentials are supplied via env variables, they will always be used
(3) if no credentials are supplied, and EMULATED==true, then use emulator credentials
(4) otherwise4 throw error "you must supply credentials if you are not running in the emulator"
(5) UsePathStyleURI and URI to storage service should depend on crednetials used
Comments from @smarx
Assuming emulator if no credentials are supplied is a great idea.
What's bad is assuming the emulator even if I've supplied credentials. I have to write code like this:
process.env.EMULATED = false;
var tableService = azure.createTableService(account,key);
I can't remember for sure, but I think if I leave off that first line, I get a tableService object that tries to talk to localhost (compute emulator) but uses a bogus account and key (the ones I supplied). That means all calls will fail.
I couldn't actually find any way to run under the compute emulator and hit cloud storage without unsetting that environment variable. Given that it's popular advice to test against cloud storage even when running locally, I'm not sure why this hasn't come up more already. (I would think everyone would hit this, so maybe I'm missing some way to make it work?)
Stop reading there if you just want a simple bug report, but keep reading if you want a rant about this overall design. :-)
In general, I don't think the EMULATED environment variable should be used by the storage library at all. All it does is cause my code to work differently when I run locally versus when I run in the cloud, which is almost always a bad thing. (It also makes things work differently when I do "node server.js" versus running the compute emulator. This is also bad.) My workflow is:
1. Run locally against the storage emulator.
2. Run locally against cloud storage.
3. Run in the cloud against cloud storage.
4. Go to step 2.
Once I've switched my code to use true cloud storage, I never want to go back to the emulator. It's possible not everyone works this way, but then they can just write this:
var tableService = process.env.EMULATED ? azure.createTableService() : azure.createTableService(account, key);
The point is that the code would explicitly say what storage service it was talking to (emulator or cloud).
Some people use the two .cscfg files (.cloud.cscfg and .local.cscfg) to use different storage connection strings in different environments. That's another good option. I would personally keep my files the same, but other people might put a different string in their "local" file to use the emulator. (This would require adopting connection strings like the .NET library does, so I could have either an account/key combo or something that meant "use the storage emulator." The strings don't have to have the exact same format, but it might be a good idea.)
We should fix this. If credentials are supplied explicitly those credentials should be used regardless of if EMULATED is set.
#354: Improving credentials management