From b1b2edf1b8fbc47a9482d9c2817bbedbaf99b6e3 Mon Sep 17 00:00:00 2001 From: Ed Bartosh Date: Wed, 18 Jul 2018 11:27:40 +0300 Subject: [PATCH] fpga_crihook: check if requested AF is programmed Check if programmed AF id is equal to the requested AF id after re-programming a device. --- cmd/fpga_crihook/main.go | 10 ++ cmd/fpga_crihook/main_test.go | 137 +++++++++++------- ...> afu_id_d8424dc4a4a3c413f89e433683f9040b} | 0 ...> afu_id_f7df405cbd7acf7222f144b0b93acd18} | 0 4 files changed, 95 insertions(+), 52 deletions(-) rename cmd/fpga_crihook/testdata/sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0/{afu_id_not_programmed_yet => afu_id_d8424dc4a4a3c413f89e433683f9040b} (100%) rename cmd/fpga_crihook/testdata/sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0/{afu_id_already_programmed => afu_id_f7df405cbd7acf7222f144b0b93acd18} (100%) diff --git a/cmd/fpga_crihook/main.go b/cmd/fpga_crihook/main.go index 22898bc1..28fbe5cc 100644 --- a/cmd/fpga_crihook/main.go +++ b/cmd/fpga_crihook/main.go @@ -189,6 +189,16 @@ func (he *hookEnv) programBitStream(params *fpgaParams, fpgaBitStreamPath string if err != nil { return fmt.Errorf("failed to program AFU %s to region %s: error: %v, output: %s", params.afu, params.region, err, string(output)) } + + programmedAfu, err := he.getProgrammedAfu(params.devNum) + if err != nil { + return err + } + + if programmedAfu != params.afu { + return fmt.Errorf("programmed function %s instead of %s", programmedAfu, params.afu) + } + return nil } diff --git a/cmd/fpga_crihook/main_test.go b/cmd/fpga_crihook/main_test.go index 0f42c6a2..7c7c945d 100644 --- a/cmd/fpga_crihook/main_test.go +++ b/cmd/fpga_crihook/main_test.go @@ -243,36 +243,61 @@ func TestValidateBitstream(t *testing.T) { } } +func genFpgaConfAction(he *hookEnv, afuIDTemplate string, returnError bool) fakeexec.FakeCombinedOutputAction { + return func() ([]byte, error) { + if returnError { + return []byte("error"), &fakeexec.FakeExitError{Status: 1} + } + he.afuIDTemplate = afuIDTemplate // emulate reprogramming + return []byte(""), nil + } +} + func TestProgramBitStream(t *testing.T) { tcases := []struct { - params *fpgaParams - expectedErr bool - fakeAction []fakeexec.FakeCombinedOutputAction + params *fpgaParams + afuIDTemplate string + newAFUIDTemplate string + expectedErr bool + fpgaconfErr bool }{ { params: &fpgaParams{ + devNum: "0", region: "ce48969398f05f33946d560708be108a", afu: "f7df405cbd7acf7222f144b0b93acd18"}, - expectedErr: false, - fakeAction: []fakeexec.FakeCombinedOutputAction{ - func() ([]byte, error) { return []byte(""), nil }, - }, + afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_d8424dc4a4a3c413f89e433683f9040b", + newAFUIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_f7df405cbd7acf7222f144b0b93acd18", + }, + { + params: &fpgaParams{"", "", ""}, + expectedErr: true, + fpgaconfErr: true, }, { params: &fpgaParams{ + devNum: "0", region: "ce48969398f05f33946d560708be108a", - afu: "f7df405cbd7acf7222f144b0b93acd18"}, - expectedErr: true, - fakeAction: []fakeexec.FakeCombinedOutputAction{ - func() ([]byte, error) { return []byte("error"), &fakeexec.FakeExitError{Status: 1} }, - }, + afu: "d8424dc4a4a3c413f89e433683f9040b"}, + afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/doesnt_exist", + expectedErr: true, + }, + { + params: &fpgaParams{ + devNum: "0", + region: "ce48969398f05f33946d560708be108a", + afu: "d8424dc4a4a3c413f89e433683f9040b"}, + afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_f7df405cbd7acf7222f144b0b93acd18", + newAFUIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_f7df405cbd7acf7222f144b0b93acd18", + expectedErr: true, }, } for _, tc := range tcases { - fcmd := fakeexec.FakeCmd{CombinedOutputScript: tc.fakeAction} - execer := fakeexec.FakeExec{CommandScript: genFakeActions(&fcmd, len(fcmd.CombinedOutputScript))} - he := newHookEnv("", "", &execer, "") + he := newHookEnv("", "", nil, tc.afuIDTemplate) + actions := []fakeexec.FakeCombinedOutputAction{genFpgaConfAction(he, tc.newAFUIDTemplate, tc.fpgaconfErr)} + fcmd := fakeexec.FakeCmd{CombinedOutputScript: actions} + he.execer = &fakeexec.FakeExec{CommandScript: genFakeActions(&fcmd, len(fcmd.CombinedOutputScript))} err := he.programBitStream(tc.params, "") if err != nil && !tc.expectedErr { t.Errorf("unexpected error: %v", err) @@ -282,34 +307,38 @@ func TestProgramBitStream(t *testing.T) { func TestProcess(t *testing.T) { tcases := []struct { - stdinJSON string - configJSON string - afuIDTemplate string - expectedErr bool - fakeCombinedOutputAction []fakeexec.FakeCombinedOutputAction + stdinJSON string + configJSON string + params *fpgaParams + afuIDTemplate string + newAFUIDTemplate string + expectedErr bool + fpgaconfErr bool + gbsInfoAction fakeexec.FakeCombinedOutputAction }{ { + params: &fpgaParams{ + devNum: "0", + region: "ce48969398f05f33946d560708be108a", + afu: "d8424dc4a4a3c413f89e433683f9040b"}, stdinJSON: "stdin-correct.json", configJSON: "config-correct.json", - afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_already_programmed", - expectedErr: false, - fakeCombinedOutputAction: []fakeexec.FakeCombinedOutputAction{ - func() ([]byte, error) { - return ioutil.ReadFile("testdata/gbs-info-correct.json") - }, - func() ([]byte, error) { return []byte(""), nil }, + afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_f7df405cbd7acf7222f144b0b93acd18", + gbsInfoAction: func() ([]byte, error) { + return ioutil.ReadFile("testdata/gbs-info-correct.json") }, }, { - stdinJSON: "stdin-correct.json", - configJSON: "config-correct.json", - afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_not_programmed_yet", - expectedErr: false, - fakeCombinedOutputAction: []fakeexec.FakeCombinedOutputAction{ - func() ([]byte, error) { - return ioutil.ReadFile("testdata/gbs-info-correct.json") - }, - func() ([]byte, error) { return []byte(""), nil }, + params: &fpgaParams{ + devNum: "0", + region: "ce48969398f05f33946d560708be108a", + afu: "f7df405cbd7acf7222f144b0b93acd18"}, + stdinJSON: "stdin-correct.json", + configJSON: "config-correct.json", + afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_d8424dc4a4a3c413f89e433683f9040b", + newAFUIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_f7df405cbd7acf7222f144b0b93acd18", + gbsInfoAction: func() ([]byte, error) { + return ioutil.ReadFile("testdata/gbs-info-correct.json") }, }, { @@ -331,7 +360,7 @@ func TestProcess(t *testing.T) { { stdinJSON: "stdin-correct.json", configJSON: "config-no-afu.json", - afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_not_programmed_yet", + afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_d8424dc4a4a3c413f89e433683f9040b", expectedErr: true, }, { @@ -342,30 +371,29 @@ func TestProcess(t *testing.T) { { stdinJSON: "stdin-correct.json", configJSON: "config-non-existing-bitstream.json", - afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_not_programmed_yet", + afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_d8424dc4a4a3c413f89e433683f9040b", expectedErr: true, }, { stdinJSON: "stdin-correct.json", configJSON: "config-correct.json", - afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_not_programmed_yet", + afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_d8424dc4a4a3c413f89e433683f9040b", expectedErr: true, - fakeCombinedOutputAction: []fakeexec.FakeCombinedOutputAction{ - func() ([]byte, error) { - return ioutil.ReadFile("testdata/gbs-info-no-accelerator-type-uuid.json") - }, + gbsInfoAction: func() ([]byte, error) { + return ioutil.ReadFile("testdata/gbs-info-no-accelerator-type-uuid.json") }, }, { + params: &fpgaParams{ + devNum: "0", + region: "ce48969398f05f33946d560708be108a", + afu: "d8424dc4a4a3c413f89e433683f9040b"}, stdinJSON: "stdin-correct.json", configJSON: "config-correct.json", - afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_not_programmed_yet", + afuIDTemplate: "testdata/sys/class/fpga/intel-fpga-dev.%s/intel-fpga-port.%s/afu_id_d8424dc4a4a3c413f89e433683f9040b", expectedErr: true, - fakeCombinedOutputAction: []fakeexec.FakeCombinedOutputAction{ - func() ([]byte, error) { - return ioutil.ReadFile("testdata/gbs-info-correct.json") - }, - func() ([]byte, error) { return []byte("error"), &fakeexec.FakeExitError{Status: 1} }, + gbsInfoAction: func() ([]byte, error) { + return ioutil.ReadFile("testdata/gbs-info-correct.json") }, }, } @@ -376,10 +404,15 @@ func TestProcess(t *testing.T) { t.Fatalf("can't open file %s: %v", tc.stdinJSON, err) } - fcmd := fakeexec.FakeCmd{CombinedOutputScript: tc.fakeCombinedOutputAction} - execer := fakeexec.FakeExec{CommandScript: genFakeActions(&fcmd, len(fcmd.CombinedOutputScript))} + he := newHookEnv("testdata/intel.com/fpga", tc.configJSON, nil, tc.afuIDTemplate) + + actions := []fakeexec.FakeCombinedOutputAction{ + tc.gbsInfoAction, + genFpgaConfAction(he, tc.newAFUIDTemplate, tc.fpgaconfErr), + } + fcmd := fakeexec.FakeCmd{CombinedOutputScript: actions} + he.execer = &fakeexec.FakeExec{CommandScript: genFakeActions(&fcmd, len(fcmd.CombinedOutputScript))} - he := newHookEnv("testdata/intel.com/fpga", tc.configJSON, &execer, tc.afuIDTemplate) err = he.process(stdin) if err != nil && !tc.expectedErr { diff --git a/cmd/fpga_crihook/testdata/sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0/afu_id_not_programmed_yet b/cmd/fpga_crihook/testdata/sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0/afu_id_d8424dc4a4a3c413f89e433683f9040b similarity index 100% rename from cmd/fpga_crihook/testdata/sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0/afu_id_not_programmed_yet rename to cmd/fpga_crihook/testdata/sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0/afu_id_d8424dc4a4a3c413f89e433683f9040b diff --git a/cmd/fpga_crihook/testdata/sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0/afu_id_already_programmed b/cmd/fpga_crihook/testdata/sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0/afu_id_f7df405cbd7acf7222f144b0b93acd18 similarity index 100% rename from cmd/fpga_crihook/testdata/sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0/afu_id_already_programmed rename to cmd/fpga_crihook/testdata/sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0/afu_id_f7df405cbd7acf7222f144b0b93acd18