© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 1@CoverosGene #DevOpsDays
Agility. Security. Delivered.
Creative Solutions to
Already Solved Problems II
Gene Gotimer
@CoverosGene
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 2@CoverosGene #DevOpsDays
Single email protection
When returning a form with Personally Identifying Information (PII):
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 3@CoverosGene #DevOpsDays
Irony training
On starting the annual, mandatory information security training:
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 4@CoverosGene #DevOpsDays
Trust us. It is safe.
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 5@CoverosGene #DevOpsDays
At least it's a standard
Browsers are configured with 2 home pages that cannot be changed.
Even in environments with no connectivity to those pages.
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 6@CoverosGene #DevOpsDays
booleans are confusing
In a test:
1298 if (condition1 && condition2)
1299 assertFalse("This will fail!", false);
1300 else
1301 assertTrue("successful", true);
which asserts that false is false or true is true.
No. It won't. Ever.
passes
passes
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 7@CoverosGene #DevOpsDays
Adding assert for sonar
assertTrue("Currently, test fails, but adding assert for sonar", true);
assertTrue(false);
Even if it doesn't need to fail
it will.
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 8@CoverosGene #DevOpsDays
How do I get this?
/**
* Creates a new chainable builder.
*
* @return A chainable builder
*/
public QuestionBuilder get() {
return this;
}
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 9@CoverosGene #DevOpsDays
Be verbose
String specialty = null;
if (mesg.getAppMeta() != null && mesg.getAppMeta().getAppType() != null
&& mesg.getAppMeta().getAppType().equals(AppType.FORM_123B.getDbValue())) {
if (mesg.getAppData() != null && mesg.getAppData().getSupplierType() != null
&& mesg.getAppData().getSupplierType().getType() != null) {
specialty = mesg.getAppData().getSupplierType().getType();
}
} else {
if (mesg.getAppData() != null && mesg.getAppData().getSpecialty() != null) {
if (mesg.getAppData().getSpecialty().getIsDoctor() != null
&& mesg.getAppData().getSpecialty().getIsDoctor()) {
specialty = "Primary Specialty: ";
specialty = getDoctorSpecialty(mesg, specialty);
} else {
if (mesg.getAppData().getSpecialty().getIsNonDoctorPractitioner() != null
&& mesg.getAppData().getSpecialty().getIsNonDoctorPractitioner()) {
…
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 10@CoverosGene #DevOpsDays
Very verbose
Hard-coded, in a test:
Logger.getRootLogger().setLevel(Level.DEBUG);
Added 500Mb of log output to every build.
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 11@CoverosGene #DevOpsDays
Just irritating
…
String authHost = "/auth/userDetailsList/" + contId;
;
if (authHost != null) {
…
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 12@CoverosGene #DevOpsDays
Really irritating
private void getXXX() {
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 13@CoverosGene #DevOpsDays
Guess which branch this is
/**
* @deprecated This is for testing only, remove before merge to master
* @param json
* @return
*/
@Deprecated()
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 14@CoverosGene #DevOpsDays
Documentation is important
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 15@CoverosGene #DevOpsDays
Unclear behavior
If we start with totalObjects being 5:
totalObjects = totalObjects++;
then we end with totalObjects being 5.
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 16@CoverosGene #DevOpsDays
No exceptions thrown here
An exception is created
…
} else {
new IllegalArgumentException("AppFormMap.createEvent: …");
}
…
but never thrown
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 17@CoverosGene #DevOpsDays
Always thrown here
…
} catch (FacadeException fe) {
respBuilder = processFacadeEx(respBuilder, fe);
// Putting business logic in here as the method
// always throws a facade exception
…
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 18@CoverosGene #DevOpsDays
I  null checks
if (user.getCode() != null) {
json.addProperty(CODE, user.getCode());
} else {
json.addProperty(CODE, null);
}
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 19@CoverosGene #DevOpsDays
And I  constants
/** The Constant I_INDICATOR. */
public static final String I_INDICATOR = "I";
/** The Constant N_INDICATOR. */
public static final String N_INDICATOR = "N";
/** The Constant P_INDICATOR. */
public static final String P_INDICATOR = "P";
/** The Constant Y_INDICATOR. */
public static final String Y_INDICATOR = "Y";
/** The Constant X_INDICATOR. */
public static final String X_INDICATOR = "X";
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 20@CoverosGene #DevOpsDays
In case the values ever change
public static final String ZERO = "0";
public static final int INT_ZERO = 0;

Creative Solutions to Already Solved Problems II

  • 1.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 1@CoverosGene #DevOpsDays Agility. Security. Delivered. Creative Solutions to Already Solved Problems II Gene Gotimer @CoverosGene
  • 2.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 2@CoverosGene #DevOpsDays Single email protection When returning a form with Personally Identifying Information (PII):
  • 3.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 3@CoverosGene #DevOpsDays Irony training On starting the annual, mandatory information security training:
  • 4.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 4@CoverosGene #DevOpsDays Trust us. It is safe.
  • 5.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 5@CoverosGene #DevOpsDays At least it's a standard Browsers are configured with 2 home pages that cannot be changed. Even in environments with no connectivity to those pages.
  • 6.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 6@CoverosGene #DevOpsDays booleans are confusing In a test: 1298 if (condition1 && condition2) 1299 assertFalse("This will fail!", false); 1300 else 1301 assertTrue("successful", true); which asserts that false is false or true is true. No. It won't. Ever. passes passes
  • 7.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 7@CoverosGene #DevOpsDays Adding assert for sonar assertTrue("Currently, test fails, but adding assert for sonar", true); assertTrue(false); Even if it doesn't need to fail it will.
  • 8.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 8@CoverosGene #DevOpsDays How do I get this? /** * Creates a new chainable builder. * * @return A chainable builder */ public QuestionBuilder get() { return this; }
  • 9.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 9@CoverosGene #DevOpsDays Be verbose String specialty = null; if (mesg.getAppMeta() != null && mesg.getAppMeta().getAppType() != null && mesg.getAppMeta().getAppType().equals(AppType.FORM_123B.getDbValue())) { if (mesg.getAppData() != null && mesg.getAppData().getSupplierType() != null && mesg.getAppData().getSupplierType().getType() != null) { specialty = mesg.getAppData().getSupplierType().getType(); } } else { if (mesg.getAppData() != null && mesg.getAppData().getSpecialty() != null) { if (mesg.getAppData().getSpecialty().getIsDoctor() != null && mesg.getAppData().getSpecialty().getIsDoctor()) { specialty = "Primary Specialty: "; specialty = getDoctorSpecialty(mesg, specialty); } else { if (mesg.getAppData().getSpecialty().getIsNonDoctorPractitioner() != null && mesg.getAppData().getSpecialty().getIsNonDoctorPractitioner()) { …
  • 10.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 10@CoverosGene #DevOpsDays Very verbose Hard-coded, in a test: Logger.getRootLogger().setLevel(Level.DEBUG); Added 500Mb of log output to every build.
  • 11.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 11@CoverosGene #DevOpsDays Just irritating … String authHost = "/auth/userDetailsList/" + contId; ; if (authHost != null) { …
  • 12.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 12@CoverosGene #DevOpsDays Really irritating private void getXXX() {
  • 13.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 13@CoverosGene #DevOpsDays Guess which branch this is /** * @deprecated This is for testing only, remove before merge to master * @param json * @return */ @Deprecated()
  • 14.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 14@CoverosGene #DevOpsDays Documentation is important
  • 15.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 15@CoverosGene #DevOpsDays Unclear behavior If we start with totalObjects being 5: totalObjects = totalObjects++; then we end with totalObjects being 5.
  • 16.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 16@CoverosGene #DevOpsDays No exceptions thrown here An exception is created … } else { new IllegalArgumentException("AppFormMap.createEvent: …"); } … but never thrown
  • 17.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 17@CoverosGene #DevOpsDays Always thrown here … } catch (FacadeException fe) { respBuilder = processFacadeEx(respBuilder, fe); // Putting business logic in here as the method // always throws a facade exception …
  • 18.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 18@CoverosGene #DevOpsDays I  null checks if (user.getCode() != null) { json.addProperty(CODE, user.getCode()); } else { json.addProperty(CODE, null); }
  • 19.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 19@CoverosGene #DevOpsDays And I  constants /** The Constant I_INDICATOR. */ public static final String I_INDICATOR = "I"; /** The Constant N_INDICATOR. */ public static final String N_INDICATOR = "N"; /** The Constant P_INDICATOR. */ public static final String P_INDICATOR = "P"; /** The Constant Y_INDICATOR. */ public static final String Y_INDICATOR = "Y"; /** The Constant X_INDICATOR. */ public static final String X_INDICATOR = "X";
  • 20.
    © COPYRIGHT 2019COVEROS, INC. ALL RIGHTS RESERVED. 20@CoverosGene #DevOpsDays In case the values ever change public static final String ZERO = "0"; public static final int INT_ZERO = 0;

Editor's Notes

  • #2 Creative solutions to already solved problems is the term one of our teams came up with for bad code. But it isn't just in code. For example, security.
  • #3 For security reasons, you have to password protect any PII you email. And then email the password. Maybe attackers won’t be able to read 2 emails in a row?
  • #4 Sometimes it is more subtle. Of course, maybe I wouldn’t have to take it annually if I didn't allow it to run at all.
  • #5 Sometimes it isn’t subtle. "It is an official email, so it is safe to click on the links below." Foolproof.
  • #6 And sometimes, you just have to go with the flow. Like forcing browsers to be configured with home pages that they can't reach.
  • #7 But there is code. Some amateur pointed me to a "long" test class that was barely over 1300 lines, but it did have this test at the end which either asserts that false is false or that true is true.
  • #8 Even when they understand asserts, some devs make suspicious decisions. Not only NOT fixing the test, but adding an assert that passes AND a separate one that fails.
  • #9 Or providing a CONVENIENCE method to return the object, as long as you have the object first so you can call the get method.
  • #10 So sometimes we err towards verbose, repeating calls over and over rather than using variables.
  • #11 Sometimes we really want to know what is going on during tests, even if the tests start failing because the disk fills up.
  • #12 Sometimes the code isn't actually wrong. It just has an irritating quality, like this lonely, but valid, semicolon which drove one developer nuts. Even though it is a tame irritant by many standards.
  • #13 Or this odd, but valid, getter that returns nothing and has nothing passed in.
  • #14 Or sometimes code is irritating for other reasons. Like this code that is in the master branch. Naturally. But at least it is documented.
  • #15 Because documentation is important. Or maybe Microsoft Word is a good editor for Gradle? Not sure which this was. Actually, I am.
  • #16 Sometimes we take short cuts that don't behave like we think they should.
  • #17 Because sometimes the heart is in the right place. But exceptions almost never occur if you don't throw them
  • #18 Sometimes they always get thrown. You'd be a fool not to rely on that, right?
  • #19 So sometimes we like to be really explicit about our intentions, like storing the value unless it is null, otherwise storing null.
  • #20 Or adding well-named constants WITH comments to explain what they are.
  • #21 Because constants are important in case a value ever needs to be changed. Thank you.