class_docstr: Test shared Alert class.
docstr: Alert Class - Merge - Create Merged Alert
docstr_tok: ["Alert","Class","-","Merge","-","Create","Merged","Alert"]
code: def test_merge(self):
      """Alert Class - Merge - Create Merged Alert"""
      # Example based on a CarbonBlack log
      record1 = {
          "alliance_data_virustotal": [],
          "alliance_link_virustotal": "",
          "alliance_score_virustotal": 0,
          "cmdline": "whoami",
          "comms_ip": "1.2.3.4",
          "hostname": "my-computer-name",
          "path": "/usr/bin/whoami",
          "streamalert:ioc": {"hello": "world"},
          "timestamp": 1234.5678,
          "username": "user",
      }
      alert1 = Alert(
          "RuleName",
          record1,
          {"aws-sns:topic"},
          created=datetime(year=2000, month=1, day=1),
          merge_by_keys=["hostname", "username"],
          merge_window=timedelta(minutes=5),
      )
  
      # Second alert has slightly different record and different outputs
      record2 = copy.deepcopy(record1)
      record2["streamalert:ioc"] = {"goodbye": "world"}
      record2["timestamp"] = 9999
      alert2 = Alert(
          "RuleName",
          record2,
          {"slack:channel"},
          created=datetime(year=2000, month=1, day=2),
          merge_by_keys=["hostname", "username"],
          merge_window=timedelta(minutes=5),
      )
  
      merged = Alert.merge([alert1, alert2])
      assert_is_instance(merged, Alert)
      assert_equal(
          {"slack:channel"}, merged.outputs
      )  # Most recent outputs were used
  
      expected_record = {
          "AlertCount": 2,
          "AlertTimeFirst": "2000-01-01T00:00:00.000000Z",
          "AlertTimeLast": "2000-01-02T00:00:00.000000Z",
          "MergedBy": {
              "hostname": "my-computer-name",
              "username": "user",
          },
          "OtherCommonKeys": {
              "alliance_data_virustotal": [],
              "alliance_link_virustotal": "",
              "alliance_score_virustotal": 0,
              "cmdline": "whoami",
              "comms_ip": "1.2.3.4",
              "path": "/usr/bin/whoami",
          },
          "ValueDiffs": {
              "2000-01-01T00:00:00.000000Z": {
                  "streamalert:ioc": {"hello": "world"},
                  "timestamp": 1234.5678,
              },
              "2000-01-02T00:00:00.000000Z": {
                  "streamalert:ioc": {"goodbye": "world"},
                  "timestamp": 9999,
              },
          },
      }
      assert_equal(expected_record, merged.record)
  
imports: import copy
  from datetime import datetime, timedelta
  import json
  from nose.tools import assert_equal, assert_false, assert_is_instance, assert_not_in, assert_raises, assert_true
  from streamalert.shared.alert import Alert, AlertCreationError
label_desc: Use image node_id 36 for calling the TestAlert obj's underlying member method code with example usage: obj.test_merge() without return types