Marathon Based Development

Who I Am

Boaz Berman

Developer

3.5 years in Shavit

"The future is already here- it's just not evenly distributed", William Gibson

Agenda

  • Bullet One
  • Bullet Two
  • Bullet Three

Those methods are not a swiss knife, fit for every situation.

Those methods are an operation room, full of expensive machines.

Source Control System

Git

Dominates the market.

Fast, lightweight, has wide indestry support.

Repository, Branch, Commit

Squashing Commits

git reset --soft HEAD~3
git commit -m "New message for the combined commit"
git push --force

Merge vs Rebase

Git Workflow

Short Lived Feature Branches

Trunk Based Development

origin
local

Database Migrations

(Go) Migrate

mongodb-migrations

Never rename.

Add column, n versions later remove old column.

Clean Code

Do'nt Repeat Yourself

You Ain't Gonna Need It

SOLID

Keep It Simple Stupid

Occam's razor

  • Single Responsibility

  • Open/Closed Principle

  • Liskov Substitution

  • Interface Segregation

  • Dependency Inversion

Feature Toogles & Experiments

  function reticulateSplines(){
    // current implementation lives here
  }
  function reticulateSplines(){
    var useNewAlgorithm = false;
    // useNewAlgorithm = true; // UNCOMMENT IF YOU ARE WORKING 
    // ON THE NEW SR ALGORITHM
  
    if( useNewAlgorithm ){
      return enhancedSplineReticulation();
    }else{
      return oldFashionedSplineReticulation();
    }
  }
  
  function oldFashionedSplineReticulation(){
    // current implementation lives here
  }
  
  function enhancedSplineReticulation(){
    // TODO: implement better SR algorithm
  }

How do I introduce change?

Experiments

A/B Testing

Canary Release

QA In Production?

Using Feature Flags & Gradual Rollout to Testers

Stateless

Push state to the boundaries (Databases)

Server must sustain: 

  • No Session
  • No User Info
  • No Multi-phase processes
  • No side-effects

Each session is carried out as if it was the first time and responses are not dependent upon data from a previous session.

Testing

End To End (E2E)

  • Slowest
  • Focus on making sure no major breaks
  • No edge cases
  • Close to business language
public class GoogleSearch {
    static WebDriver driver = new FirefoxDriver();
    static Wait<WebDriver> wait = new WebDriverWait(driver, MAX_30_SECONDS);

    public static void main(String[] args) {
        boolean result;

        driver.get("http://www.google.com/");
        try {
            result = firstPageContainsQAANet();
        } catch(Exception e) {
            result = false;
        } finally {
            driver.close();
        }
 
        System.out.println("Test " + (result? "passed." : "failed."));
    }
 
    private static boolean firstPageContainsQAANet() {
        //type search query
        driver.findElement(By.name("q")).sendKeys("qa automation\n");
 
        // click search
        driver.findElement(By.name("btnG")).click();
 
        // Wait for search to complete
        wait.until(webDriver -> {
                System.out.println("Searching ...");
                return webDriver.findElement(By.id("resultStats")) != null;
        });
 
        // Look for QAAutomation.net in the results
        return driver.findElement(By.tagName("body")).getText().contains("qaautomation.net");
    }
}

Integration (Black-Box)

  • Slower
  • Focus on validation correctness of single service at a time
  • Validate correctness, not code quality
  • Boost confident while preserving test isolation and speed
@Test
public class SomeKeyGoogleService {

    public SearchServiceConnection searchService;

    @Before
    public void init() {
        // Initialize service
        searchService = ...;
    }

    @After
    public void clean() {
        // Do some cleaning
    }

    @Describe("Given Youtube service has results and there are existing indexed pages " +
        "When a phrase searched Then return Youtube with indexed results")
    public void usuallyThisWillBeAMeaningfullName() {
        // given
        youtubeMock.when("/searchResults?search=my%20search%20phrase")
            .thenReturn("{video: \"http://youtube.com/v?asd123@!ASd2134=\"}");
        db.insert(new IndexedPage("Welcome to my search phrase"));
        // when
        var returnContent = searchService.call("/search?s=my%20search%20phrase").result().asJson();
        // then
        expect(returnContent).toConsistOf(youtubeVideo("http://youtube.com/v?asd123@!ASd2134="),
             pageInfo("Welcome to my search phrase"));
    }
}

Unit

  • Fastest
  • Focus on validation correctness of single [public] function at a time
  • Validate mostly code quality, but also correctness as a side effect*
  • Encourage clean code (SOLID, YAGNI etc..)
  • Easiest to write (purpose wise)
public class AlertAdderTest
{
    public SlackAlertAdder slackAlertAdder = mock(SlackAlertAdder.class);
    public FacebookAlertAdder facebookAlertAdder = mock(FacebookAlertAdder.class);

    public AlertAdder alertAdder = new AlertAdder(slackAlertAdder, facebookAlertAdder);

    @Test
    public void whatAnAlertIsAddedThenSlackAlertIsAdded()
    {
        Alert anAlert = new Info("Holy shit, watch out");

        alertAdder.add(anAlert);

        verify(slackAlertAdder).add(anAlert);
    }
}

Also

Consumer Driven Contract

    (PACT)

Component Testing

Mutation Testing

    (PIT)

Test Driven Development

Single artifact & Environment configuration

Central Logging

Logs are the stream of aggregated, time-ordered events collected from the output streams of all running services

Produce    ->    Collect    ->    Index       ->    Use

Service-wise

Fluentd/ Logstash

Elasticsearch

Kibana

12Factor: Logs

Also: Correlation Ids, Schema

Kibana Example

Tracing

Using correlation Ids we can create a flow of the data:

Monitoring

Counter counter = Counter
  .builder("instance")
  .description("indicates instance count of the object")
  .tags("dev", "performance")
  .register(registry);
 
counter.increment(2.0);
  
assertTrue(counter.count() == 2);
  
counter.increment(-1);
  
assertTrue(counter.count() == 2);
SimpleMeterRegistry registry = new SimpleMeterRegistry();
Timer timer = registry.timer("app.event");
timer.record(() -> {
    try {
        TimeUnit.MILLISECONDS.sleep(1500);
    } catch (InterruptedException ignored) { }
});
 
timer.record(3000, MILLISECONDS);
 
assertTrue(2 == timer.count());
assertTrue(4510 > timer.totalTime(MILLISECONDS) 
  && 4500 <= timer.totalTime(MILLISECONDS));

Micrometer

What to monitor?

A Key Performance Indicator (KPI) is a measurable value that demonstrates how effectively a company is achieving key business objectives.

Business Metrics are used to track all areas of business.

Mean time to failure (MTTF) is the length of time a device or other product is expected to last in operation. MTTF is one of many ways to evaluate the reliability of pieces of hardware or other technology.

Mean Time to Repair (MTTR) is a measure of how long it takes to get a product or subsystem up and running after a failure.

Continues Integration, Deployment & Delivery

Continues Integration

Continues Deployment

Continues Delivery

Practice that requires developers to integrate code into a shared repository several times a day. Each check-in is then verified by an automated build, allowing teams to detect problems early.

Designed to ensure that code can be deployed to production by delivering every change to a production-like environment and ensuring business applications and services function as expected.

Every change that passes the automated tests is deployed to production automatically.

Automation Server (Jenkins)

pipeline {
    agent any
    tools {
        maven 'Maven 3.3.9'
        jdk 'jdk8'
    }
    stages {
        stage ('Initialize') {
            steps {
                sh '''
                    echo "PATH = ${PATH}"
                    echo "M2_HOME = ${M2_HOME}"
                '''
            }
        }

        stage ('Build') {
            steps {
                sh 'mvn -Dmaven.test.failure.ignore=true install' 
            }
            post {
                success {
                    junit 'target/surefire-reports/**/*.xml' 
                }
            }
        }
    }
}

Automation Server (CircleCI)

version: 2
jobs:
   build:
     docker:
       - image: circleci/<language>:<version TAG>
     steps:
       - checkout
       - run: echo "hello world"
   deploy:
     docker:
       - image: java:8-jre-alpine
     steps:
       - run: java -jar my-app-*.jar

Containers & Orchestrators

A container image is a lightweight, stand-alone, executable package of a piece of software that includes everything needed to run it: code, runtime, system tools, system libraries, settings. Available for both Linux and Windows based apps, containerized software will always run the same, regardless of the environment. Containers isolate software from its surroundings, for example differences between development and staging environments and help reduce conflicts between teams running different software on the same infrastructure.

FROM alpine/git
WORKDIR /app
RUN git clone https://github.com/spring-projects/spring-petclinic.git

FROM maven:3.5-jdk-8-alpine
WORKDIR /app
COPY --from=0 /app/spring-petclinic /app
RUN mvn install

FROM openjdk:8-jre-alpine
WORKDIR /app
COPY --from=1 /app/target/spring-petclinic-1.5.1.jar /app
CMD ["java -jar spring-petclinic-1.5.1.jar"]

Docker

Kubernetes

Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications.

Microservices

An approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deploy-able by fully automated deployment machinery.

N-Tier Architecture

Microservices

Tips:

Separate database per service

Collaborate on api with consumers

Past & Future compatible api (Objects)

Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure.

-- Melvyn Conway, 1967

Domain Driven Design

How do I "built around business capabilities"

Is about designing software based on models of the underlying domain. A model acts as a Ubiquitous Language to help communication between software developers and domain experts. It also acts as the conceptual foundation for the design of the software itself - how it's broken down into objects or functions. To be effective, a model needs to be unified - that is to be internally consistent so that there are no contradictions within it.

Bounded Context

Value objects, which represent a value that might have sub-parts (for example, a date may have a day, month and year)

Entities, which are objects with identity. For example, each Customer object has its own identity, so we know that two customers with the same name are not the same customer

Aggregate roots are objects that own other objects. This is a complex concept and works on the basis that there are some objects that don't make sense unless they have an owner.

Ubiquitous Language

DevOps

Code - code development and review, source code management tools, code merging
Build - continuous integration tools, build status
Test - continuous testing tools that provide feedback on business risks
Package - artifact repository, application pre-deployment staging
Release - change management, release approvals, release automation
Configure - infrastructure configuration and management, Infrastructure as Code tools
Monitor - applications performance monitoring, end–user experience

DevOps aims at shorter development cycles, increased deployment frequency, more dependable releases, in close alignment with business objectives.

Lean Development

shifted the focus from individual machines and their utilization, to the flow of the product through the total process. Toyota concluded that by right-sizing machines for the actual volume needed, introducing self-monitoring machines to ensure quality, lining the machines up in process sequence, pioneering quick setups so each machine could make small volumes of many part numbers, and having each process step notify the previous step of its current needs for materials, it would be possible to obtain low cost, high variety, high quality, and very rapid throughput times to respond to changing customer desires.

Lean Principles

Eliminate Waste

Unnecessary code or functionality

Starting more than can be completed

Delay in the software development process: Delays time to customer, slows down feedback loops

Unclear or constantly changing requirements

Bureaucracy

Slow or ineffective communication

Partially done work

Defects and quality issues

Task switching

Build Quality In

Pair programming: Avoid quality issues by combining the skills and experience of two developers instead of one

Test-driven development: Writing criteria for code before writing the code to ensure it meets business requirements

Incremental development and constant feedback

Minimize wait states: Reduce context switching, knowledge gaps, and lack of focus

Automation: Automate any tedious, manual process or any process prone to human error

Create Knowledge

Pair Programming

Code reviews

Documentation

Wiki – to let the knowledge base build up incrementally

Thoroughly commented code

Knowledge sharing sessions

Training

Use tools to manage requirements or user stories

Defer Commitment

This Lean principle encourages team to demonstrate responsibility by keeping their options open and continuously collecting information, rather than making decisions without the necessary data.

Deliver Fast

Build a simple solution, put it in front of customers, enhance incrementally based on customer feedback.

Common culprits

  • Thinking too far in advance about future requirements
  • Blockers that aren’t responded to with urgency
  • Over-engineering solutions and business requirements

Respect People

Optimize the Whole

"If you don't have the time to do it right, when will you have time to do it again?", John Wooden

Resources

  • Clean Code, Robert C. Martin
  • Growing Object Oriented Software, guided by tests- Steve Freeman & Nat Pryce
  • The Twelve Factor App- https://12factor.net/ 
  • Domain Driven Design- Eric Evans
  • Building Microservices- Sam Newman
  • The Pheonix Project- Gene Kim, Kevin Behr, George Spafford
  • Continues Delivery- Jez Humble & David Farley
  • Medium- https://medium.com/
  • Twitter
  • StackShare.io- https://stackshare.io/
  • Newsletters- SWLW, Alligator.io, DevOpsLinks

Marathon Based Development

By Boaz Berman

Marathon Based Development

  • 380