2

I’m trying to debug something that happens a few days after another event, and would like to speed up the test without circumventing the date delay related code. Is there anyway to change the date in the ddev containers temporarily?

UltraBob
  • 220
  • 3
  • 12

1 Answers1

1

Thanks to help from this question and kind support from @rfay. I came up with this solution using the libfaketime

I created .ddev/web-build/Dockerfile with the following content:

ARG BASE_IMAGE
FROM $BASE_IMAGE
RUN apt-get update && apt-get install -y make build-essential
WORKDIR /
RUN git clone https://github.com/wolfcw/libfaketime.git
WORKDIR /libfaketime/src
RUN make install

I ran ddev start to make sure the container would still build.

Then added a command at .ddev/commands/host/faketime:

#!/bin/bash

## Description: Enable or disable faketime
## Usage: faketime on YYYY-mm-dd|off|status
## Example: "ddev faketime on 2020-05-04", "ddev faketime off", "ddev faketime status"

if [ $# -eq 0 ] ; then
 echo "usage faketime YYYY-mm-dd or faketime off"
fi

case $1 in
    on|true|enable)
    echo $1
    echo $2
    echo "turning on"
      if date -j -f "%Y-%m-%d" -j ${2} > /dev/null 2>&1
      then
        echo "time set to ${2} 11:00:00, restarting..."
      ddev config --web-environment=LD_PRELOAD="/usr/local/lib/faketime/libfaketime.so.1",FAKETIME="${2} 11:00:00" && ddev start
    else
      echo "faketime on usage:  ddev faketime on YYYY-MM-DD"
    fi
    ;;
    off|false|disable)
      echo "turning faketime off"
      ddev config --web-environment=LD_PRELOAD="" && ddev start
    ;;
    status)
      if grep -q 'FAKETIME' ${DDEV_APPROOT}/.ddev/config.yaml;
      then
        echo "faketime is on."
        ddev exec date +%F
      else
        echo "faketime is off."
        ddev exec date +%F
      fi
    ;;
  *)
    echo "invalid argument"
    ;;
esac

On a Mac, this allows me to run ddev faketime on 2020-05-4 to set the container date to May 4th, 2020, and ddev faketime off to turn it back off. On a unix based system, the date validation part of the script would need to be different.

if date -j -f "%Y-%m-%d" -j ${2} > /dev/null 2>&1;

would need to be something like

if date "+%Y-%m-%d" -d ${2} 2>&1;

faketime off and faketime on will both cause the containers to restart, while faketime status will just read whether the time is being faked and report the current container date.

For my purposes, setting the time to 11 AM was fine. I just cared about the date itself. For your application you may want to change the arguments and specify time as well.

UltraBob
  • 220
  • 3
  • 12