blob: d4f9c868e2fd2adac2c6d5c106ab25f89a57cdc5 [file] [log] [blame] [edit]
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package wilco
import (
"bytes"
"context"
"time"
"chromiumos/tast/local/wilco"
"chromiumos/tast/testing"
)
func init() {
testing.AddTest(&testing.Test{
Func: ECEvent,
Desc: "Tests that userspace can receive events from the EC on Wilco devices",
Contacts: []string{
"campello@chromium.org", // Test maintainer.
"chromeos-wilco@google.com", // Possesses some more domain-specific knowledge.
"chromeos-kernel-test@google.com",
},
SoftwareDeps: []string{"wilco"},
Timeout: 10 * time.Second,
Attr: []string{"group:mainline"},
})
}
// ECEvent tests the Wilco EC is able to generate EC events and that the kernel
// properly passes them along to userspace to read. Normally, the EC triggers
// events on hardware changes, such as battery errors. For testing, we can
// send a special command to the EC, and the EC will generate a hardcoded fake
// event.
//
// See http://chromium.googlesource.com/chromiumos/third_party/kernel/+/283563c976eefc1ab2e83049665d42b23bda95b5/drivers/platform/chrome/wilco_ec/debugfs.c#221
// for the kernel driver that sends the test event command, and see
// http://chromium.googlesource.com/chromiumos/third_party/kernel/+/283563c976eefc1ab2e83049665d42b23bda95b5/drivers/platform/chrome/wilco_ec/event.c
// for the kernel driver that reads events from the EC.
func ECEvent(ctx context.Context, s *testing.State) {
// The format of this fake event chosen at
// http://issuetracker.google.com/139017129.
expectedECEvent := []byte{
0x07, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00,
0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00}
// We need exclusive access to |eventReadPath|, so ensure that
// wilco_dtc_supportd that controls it is shut down. No need to restart
// it when we're done.
if err := wilco.StopSupportd(ctx); err != nil {
s.Fatal("Unable to stop wilco_dtc_supportd: ", err)
}
// Before we start the test, clear the queue of events to ensure there are
// no stale events.
if err := wilco.ClearECEventQueue(ctx); err != nil {
s.Fatal("Unable to clear wilco EC event queue: ", err)
}
if err := wilco.TriggerECEvent(); err != nil {
s.Fatal("Unable to trigger EC event: ", err)
}
// Drain the queue of EC events and check each one for the expected payload.
// Stop when the queue is empty, or we receive an error reading the EC
// event. The maximum queue size is 16 so this is small enough to poll until
// empty.
for {
readCtx, cancel := context.WithDeadline(ctx, time.Now().Add(time.Second))
defer cancel()
s.Log("Performing blocking read of EC event file")
event, err := wilco.ReadECEvent(readCtx)
if err != nil {
s.Fatal("Unable to read EC data: ", err)
}
if bytes.Contains(event, expectedECEvent) {
s.Log("Received matching EC event")
break
}
s.Logf("Received a different EC event. "+
"The bytes read [% #x] do not contain the expected EC Event [% #x]. Continuing",
event, expectedECEvent)
}
}